亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? gc.c

?? jffs2源代碼基于2。6內核
?? C
?? 第 1 頁 / 共 3 頁
字號:
/* * JFFS2 -- Journalling Flash File System, Version 2. * * Copyright (C) 2001-2003 Red Hat, Inc. * * Created by David Woodhouse <dwmw2@redhat.com> * * For licensing information, see the file 'LICENCE' in this directory. * * $Id: gc.c,v 1.137 2004/07/20 13:44:55 dwmw2 Exp $ * */#include <linux/kernel.h>#include <linux/mtd/mtd.h>#include <linux/slab.h>#include <linux/pagemap.h>#include <linux/crc32.h>#include <linux/compiler.h>#include <linux/stat.h>#include "nodelist.h"#include "compr.h"static int jffs2_garbage_collect_pristine(struct jffs2_sb_info *c, 					  struct jffs2_inode_cache *ic,					  struct jffs2_raw_node_ref *raw);static int jffs2_garbage_collect_metadata(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, 					struct jffs2_inode_info *f, struct jffs2_full_dnode *fd);static int jffs2_garbage_collect_dirent(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, 					struct jffs2_inode_info *f, struct jffs2_full_dirent *fd);static int jffs2_garbage_collect_deletion_dirent(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, 					struct jffs2_inode_info *f, struct jffs2_full_dirent *fd);static int jffs2_garbage_collect_hole(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,				      struct jffs2_inode_info *f, struct jffs2_full_dnode *fn,				      uint32_t start, uint32_t end);static int jffs2_garbage_collect_dnode(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,				       struct jffs2_inode_info *f, struct jffs2_full_dnode *fn,				       uint32_t start, uint32_t end);static int jffs2_garbage_collect_live(struct jffs2_sb_info *c,  struct jffs2_eraseblock *jeb,			       struct jffs2_raw_node_ref *raw, struct jffs2_inode_info *f);/* Called with erase_completion_lock held */static struct jffs2_eraseblock *jffs2_find_gc_block(struct jffs2_sb_info *c){	struct jffs2_eraseblock *ret;	struct list_head *nextlist = NULL;	int n = jiffies % 128;	/* Pick an eraseblock to garbage collect next. This is where we'll	   put the clever wear-levelling algorithms. Eventually.  */	/* We possibly want to favour the dirtier blocks more when the	   number of free blocks is low. */	if (!list_empty(&c->bad_used_list) && c->nr_free_blocks > c->resv_blocks_gcbad) {		D1(printk(KERN_DEBUG "Picking block from bad_used_list to GC next\n"));		nextlist = &c->bad_used_list;	} else if (n < 50 && !list_empty(&c->erasable_list)) {		/* Note that most of them will have gone directly to be erased. 		   So don't favour the erasable_list _too_ much. */		D1(printk(KERN_DEBUG "Picking block from erasable_list to GC next\n"));		nextlist = &c->erasable_list;	} else if (n < 110 && !list_empty(&c->very_dirty_list)) {		/* Most of the time, pick one off the very_dirty list */		D1(printk(KERN_DEBUG "Picking block from very_dirty_list to GC next\n"));		nextlist = &c->very_dirty_list;	} else if (n < 126 && !list_empty(&c->dirty_list)) {		D1(printk(KERN_DEBUG "Picking block from dirty_list to GC next\n"));		nextlist = &c->dirty_list;	} else if (!list_empty(&c->clean_list)) {		D1(printk(KERN_DEBUG "Picking block from clean_list to GC next\n"));		nextlist = &c->clean_list;	} else if (!list_empty(&c->dirty_list)) {		D1(printk(KERN_DEBUG "Picking block from dirty_list to GC next (clean_list was empty)\n"));		nextlist = &c->dirty_list;	} else if (!list_empty(&c->very_dirty_list)) {		D1(printk(KERN_DEBUG "Picking block from very_dirty_list to GC next (clean_list and dirty_list were empty)\n"));		nextlist = &c->very_dirty_list;	} else if (!list_empty(&c->erasable_list)) {		D1(printk(KERN_DEBUG "Picking block from erasable_list to GC next (clean_list and {very_,}dirty_list were empty)\n"));		nextlist = &c->erasable_list;	} else {		/* Eep. All were empty */		D1(printk(KERN_NOTICE "jffs2: No clean, dirty _or_ erasable blocks to GC from! Where are they all?\n"));		return NULL;	}	ret = list_entry(nextlist->next, struct jffs2_eraseblock, list);	list_del(&ret->list);	c->gcblock = ret;	ret->gc_node = ret->first_node;	if (!ret->gc_node) {		printk(KERN_WARNING "Eep. ret->gc_node for block at 0x%08x is NULL\n", ret->offset);		BUG();	}		/* Have we accidentally picked a clean block with wasted space ? */	if (ret->wasted_size) {		D1(printk(KERN_DEBUG "Converting wasted_size %08x to dirty_size\n", ret->wasted_size));		ret->dirty_size += ret->wasted_size;		c->wasted_size -= ret->wasted_size;		c->dirty_size += ret->wasted_size;		ret->wasted_size = 0;	}	D1(jffs2_dump_block_lists(c));	return ret;}/* jffs2_garbage_collect_pass * Make a single attempt to progress GC. Move one node, and possibly * start erasing one eraseblock. */int jffs2_garbage_collect_pass(struct jffs2_sb_info *c){	struct jffs2_inode_info *f;	struct jffs2_inode_cache *ic;	struct jffs2_eraseblock *jeb;	struct jffs2_raw_node_ref *raw;	int ret = 0, inum, nlink;	if (down_interruptible(&c->alloc_sem))		return -EINTR;	for (;;) {		spin_lock(&c->erase_completion_lock);		if (!c->unchecked_size)			break;		/* We can't start doing GC yet. We haven't finished checking		   the node CRCs etc. Do it now. */				/* checked_ino is protected by the alloc_sem */		if (c->checked_ino > c->highest_ino) {			printk(KERN_CRIT "Checked all inodes but still 0x%x bytes of unchecked space?\n",			       c->unchecked_size);			D1(jffs2_dump_block_lists(c));			spin_unlock(&c->erase_completion_lock);			BUG();		}		spin_unlock(&c->erase_completion_lock);		spin_lock(&c->inocache_lock);		ic = jffs2_get_ino_cache(c, c->checked_ino++);		if (!ic) {			spin_unlock(&c->inocache_lock);			continue;		}		if (!ic->nlink) {			D1(printk(KERN_DEBUG "Skipping check of ino #%d with nlink zero\n",				  ic->ino));			spin_unlock(&c->inocache_lock);			continue;		}		switch(ic->state) {		case INO_STATE_CHECKEDABSENT:		case INO_STATE_PRESENT:			D1(printk(KERN_DEBUG "Skipping ino #%u already checked\n", ic->ino));			spin_unlock(&c->inocache_lock);			continue;		case INO_STATE_GC:		case INO_STATE_CHECKING:			printk(KERN_WARNING "Inode #%u is in state %d during CRC check phase!\n", ic->ino, ic->state);			spin_unlock(&c->inocache_lock);			BUG();		case INO_STATE_READING:			/* We need to wait for it to finish, lest we move on			   and trigger the BUG() above while we haven't yet 			   finished checking all its nodes */			D1(printk(KERN_DEBUG "Waiting for ino #%u to finish reading\n", ic->ino));			up(&c->alloc_sem);			sleep_on_spinunlock(&c->inocache_wq, &c->inocache_lock);			return 0;		default:			BUG();		case INO_STATE_UNCHECKED:			;		}		ic->state = INO_STATE_CHECKING;		spin_unlock(&c->inocache_lock);		D1(printk(KERN_DEBUG "jffs2_garbage_collect_pass() triggering inode scan of ino#%u\n", ic->ino));		ret = jffs2_do_crccheck_inode(c, ic);		if (ret)			printk(KERN_WARNING "Returned error for crccheck of ino #%u. Expect badness...\n", ic->ino);		jffs2_set_inocache_state(c, ic, INO_STATE_CHECKEDABSENT);		up(&c->alloc_sem);		return ret;	}	/* First, work out which block we're garbage-collecting */	jeb = c->gcblock;	if (!jeb)		jeb = jffs2_find_gc_block(c);	if (!jeb) {		D1 (printk(KERN_NOTICE "jffs2: Couldn't find erase block to garbage collect!\n"));		spin_unlock(&c->erase_completion_lock);		up(&c->alloc_sem);		return -EIO;	}	D1(printk(KERN_DEBUG "GC from block %08x, used_size %08x, dirty_size %08x, free_size %08x\n", jeb->offset, jeb->used_size, jeb->dirty_size, jeb->free_size));	D1(if (c->nextblock)	   printk(KERN_DEBUG "Nextblock at  %08x, used_size %08x, dirty_size %08x, wasted_size %08x, free_size %08x\n", c->nextblock->offset, c->nextblock->used_size, c->nextblock->dirty_size, c->nextblock->wasted_size, c->nextblock->free_size));	if (!jeb->used_size) {		up(&c->alloc_sem);		goto eraseit;	}	raw = jeb->gc_node;				while(ref_obsolete(raw)) {		D1(printk(KERN_DEBUG "Node at 0x%08x is obsolete... skipping\n", ref_offset(raw)));		raw = raw->next_phys;		if (unlikely(!raw)) {			printk(KERN_WARNING "eep. End of raw list while still supposedly nodes to GC\n");			printk(KERN_WARNING "erase block at 0x%08x. free_size 0x%08x, dirty_size 0x%08x, used_size 0x%08x\n", 			       jeb->offset, jeb->free_size, jeb->dirty_size, jeb->used_size);			jeb->gc_node = raw;			spin_unlock(&c->erase_completion_lock);			up(&c->alloc_sem);			BUG();		}	}	jeb->gc_node = raw;	D1(printk(KERN_DEBUG "Going to garbage collect node at 0x%08x\n", ref_offset(raw)));	if (!raw->next_in_ino) {		/* Inode-less node. Clean marker, snapshot or something like that */		/* FIXME: If it's something that needs to be copied, including something		   we don't grok that has JFFS2_NODETYPE_RWCOMPAT_COPY, we should do so */		spin_unlock(&c->erase_completion_lock);		jffs2_mark_node_obsolete(c, raw);		up(&c->alloc_sem);		goto eraseit_lock;	}	ic = jffs2_raw_ref_to_ic(raw);	/* We need to hold the inocache. Either the erase_completion_lock or	   the inocache_lock are sufficient; we trade down since the inocache_lock 	   causes less contention. */	spin_lock(&c->inocache_lock);	spin_unlock(&c->erase_completion_lock);	D1(printk(KERN_DEBUG "jffs2_garbage_collect_pass collecting from block @0x%08x. Node @0x%08x(%d), ino #%u\n", jeb->offset, ref_offset(raw), ref_flags(raw), ic->ino));	/* Three possibilities:	   1. Inode is already in-core. We must iget it and do proper	      updating to its fragtree, etc.	   2. Inode is not in-core, node is REF_PRISTINE. We lock the	      inocache to prevent a read_inode(), copy the node intact.	   3. Inode is not in-core, node is not pristine. We must iget()	      and take the slow path.	*/	switch(ic->state) {	case INO_STATE_CHECKEDABSENT:		/* It's been checked, but it's not currently in-core. 		   We can just copy any pristine nodes, but have		   to prevent anyone else from doing read_inode() while		   we're at it, so we set the state accordingly */		if (ref_flags(raw) == REF_PRISTINE)			ic->state = INO_STATE_GC;		else {			D1(printk(KERN_DEBUG "Ino #%u is absent but node not REF_PRISTINE. Reading.\n", 				  ic->ino));		}		break;	case INO_STATE_PRESENT:		/* It's in-core. GC must iget() it. */		break;	case INO_STATE_UNCHECKED:	case INO_STATE_CHECKING:	case INO_STATE_GC:		/* Should never happen. We should have finished checking		   by the time we actually start doing any GC, and since 		   we're holding the alloc_sem, no other garbage collection 		   can happen.		*/		printk(KERN_CRIT "Inode #%u already in state %d in jffs2_garbage_collect_pass()!\n",		       ic->ino, ic->state);		up(&c->alloc_sem);		spin_unlock(&c->inocache_lock);		BUG();	case INO_STATE_READING:		/* Someone's currently trying to read it. We must wait for		   them to finish and then go through the full iget() route		   to do the GC. However, sometimes read_inode() needs to get		   the alloc_sem() (for marking nodes invalid) so we must		   drop the alloc_sem before sleeping. */		up(&c->alloc_sem);		D1(printk(KERN_DEBUG "jffs2_garbage_collect_pass() waiting for ino #%u in state %d\n",			  ic->ino, ic->state));		sleep_on_spinunlock(&c->inocache_wq, &c->inocache_lock);		/* And because we dropped the alloc_sem we must start again from the 		   beginning. Ponder chance of livelock here -- we're returning success		   without actually making any progress.		   Q: What are the chances that the inode is back in INO_STATE_READING 		   again by the time we next enter this function? And that this happens		   enough times to cause a real delay?		   A: Small enough that I don't care :) 		*/		return 0;	}	/* OK. Now if the inode is in state INO_STATE_GC, we are going to copy the	   node intact, and we don't have to muck about with the fragtree etc. 	   because we know it's not in-core. If it _was_ in-core, we go through	   all the iget() crap anyway */	if (ic->state == INO_STATE_GC) {		spin_unlock(&c->inocache_lock);		ret = jffs2_garbage_collect_pristine(c, ic, raw);		spin_lock(&c->inocache_lock);		ic->state = INO_STATE_CHECKEDABSENT;		wake_up(&c->inocache_wq);		if (ret != -EBADFD) {			spin_unlock(&c->inocache_lock);			goto release_sem;		}		/* Fall through if it wanted us to, with inocache_lock held */	}	/* Prevent the fairly unlikely race where the gcblock is	   entirely obsoleted by the final close of a file which had	   the only valid nodes in the block, followed by erasure,	   followed by freeing of the ic because the erased block(s)	   held _all_ the nodes of that inode.... never been seen but	   it's vaguely possible. */	inum = ic->ino;	nlink = ic->nlink;	spin_unlock(&c->inocache_lock);	f = jffs2_gc_fetch_inode(c, inum, nlink);	if (IS_ERR(f)) {		ret = PTR_ERR(f);		goto release_sem;	}	if (!f) {		ret = 0;		goto release_sem;	}	ret = jffs2_garbage_collect_live(c, jeb, raw, f);	jffs2_gc_release_inode(c, f); release_sem:	up(&c->alloc_sem); eraseit_lock:	/* If we've finished this block, start it erasing */	spin_lock(&c->erase_completion_lock); eraseit:	if (c->gcblock && !c->gcblock->used_size) {		D1(printk(KERN_DEBUG "Block at 0x%08x completely obsoleted by GC. Moving to erase_pending_list\n", c->gcblock->offset));		/* We're GC'ing an empty block? */		list_add_tail(&c->gcblock->list, &c->erase_pending_list);		c->gcblock = NULL;		c->nr_erasing_blocks++;		jffs2_erase_pending_trigger(c);	}	spin_unlock(&c->erase_completion_lock);	return ret;}static int jffs2_garbage_collect_live(struct jffs2_sb_info *c,  struct jffs2_eraseblock *jeb,				      struct jffs2_raw_node_ref *raw, struct jffs2_inode_info *f){	struct jffs2_node_frag *frag;	struct jffs2_full_dnode *fn = NULL;	struct jffs2_full_dirent *fd;	uint32_t start = 0, end = 0, nrfrags = 0;	int ret = 0;	down(&f->sem);	/* Now we have the lock for this inode. Check that it's still the one at the head	   of the list. */	spin_lock(&c->erase_completion_lock);	if (c->gcblock != jeb) {		spin_unlock(&c->erase_completion_lock);		D1(printk(KERN_DEBUG "GC block is no longer gcblock. Restart\n"));		goto upnout;

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
在线观看av一区| 久久综合色之久久综合| 日韩欧美精品三级| 中文字幕免费一区| 蜜臀av亚洲一区中文字幕| 丁香婷婷综合五月| 日韩一级免费观看| 一区二区三区日韩在线观看| 韩国欧美国产1区| 欧美日韩一区二区三区在线看| 亚洲国产精品v| 久久精品国产精品亚洲精品| 欧美天堂一区二区三区| 亚洲欧美怡红院| 国产美女一区二区| 日韩一区二区麻豆国产| 亚洲成人综合视频| 一本大道久久a久久精品综合| 久久九九全国免费| 精品制服美女丁香| 欧美一级日韩免费不卡| 亚洲一级在线观看| 一本色道久久综合亚洲91| 国产蜜臀97一区二区三区| 久草精品在线观看| 欧美videossexotv100| 日本不卡一区二区三区| 欧美主播一区二区三区美女| 亚洲免费在线看| 99re8在线精品视频免费播放| 亚洲国产电影在线观看| 国产69精品久久99不卡| 久久婷婷成人综合色| 韩国欧美一区二区| 久久久综合网站| 国产一区二区三区视频在线播放| 欧美成人伊人久久综合网| 蜜臀久久99精品久久久画质超高清| 欧美日韩精品专区| 午夜国产精品一区| 欧美一级高清片| 久久99久久精品欧美| 亚洲精品在线观| 国产成人鲁色资源国产91色综| 久久精品一区二区三区不卡牛牛 | 久久av老司机精品网站导航| 精品国产乱码久久久久久浪潮| 国内外成人在线| 国产三级精品视频| 99re这里只有精品首页| 亚洲国产成人av| 91精品国产综合久久久久久久久久| 偷拍日韩校园综合在线| 精品久久免费看| 成人一区二区三区| 亚洲精品日韩综合观看成人91| 欧美性大战久久| 另类人妖一区二区av| 国产日韩欧美一区二区三区乱码| 盗摄精品av一区二区三区| 亚洲精品免费在线| 91麻豆精品国产91久久久更新时间| 蜜桃精品视频在线观看| 国产婷婷精品av在线| 91丨国产丨九色丨pron| 视频一区国产视频| 精品国产a毛片| 99久久99久久综合| 欧美人妇做爰xxxⅹ性高电影| 亚洲成av人片在线| 日韩精品一区二区在线| 99久久伊人久久99| 婷婷综合久久一区二区三区| 国产日产欧美一区二区三区| 91老师片黄在线观看| 美女脱光内衣内裤视频久久网站| 久久久久久久久岛国免费| 欧洲在线/亚洲| 国产一区二区剧情av在线| 一区二区三区日韩精品视频| 日韩精品一区二区三区在线 | 日本一区二区不卡视频| 在线不卡一区二区| aaa欧美日韩| 狠狠色综合日日| 亚洲国产精品一区二区久久恐怖片 | 国产精品99久久久久久似苏梦涵| 亚洲乱码日产精品bd| 久久影视一区二区| 欧美精品色一区二区三区| 成人午夜视频免费看| 奇米精品一区二区三区四区| 亚洲精品视频在线观看免费| 国产午夜一区二区三区| 91麻豆精品国产91久久久更新时间 | 蜜臀99久久精品久久久久久软件| 怡红院av一区二区三区| 国产亚洲成av人在线观看导航| 欧美一区二视频| 色94色欧美sute亚洲线路一ni| 成人综合在线网站| 国产在线视频不卡二| 日韩精品一二区| 亚洲va天堂va国产va久| 亚洲天堂久久久久久久| 欧美韩国日本不卡| 欧美精品一区二区久久婷婷| 日韩午夜在线观看视频| 欧美人与禽zozo性伦| 欧美亚洲综合久久| 色老头久久综合| 一本色道久久综合亚洲91| 99精品国产一区二区三区不卡| 国产精品资源在线看| 极品尤物av久久免费看| 国产成人午夜片在线观看高清观看| 一区二区欧美视频| 日韩欧美在线综合网| 国产综合一区二区| 国产精品卡一卡二卡三| 久久精品一区蜜桃臀影院| 欧美刺激午夜性久久久久久久| 欧美一区二区三区啪啪| 欧美一区二区在线播放| 欧美日韩久久久| 欧美精品色综合| 欧美va日韩va| xvideos.蜜桃一区二区| 久久精品视频在线看| 国产欧美日韩在线观看| 中文字幕不卡在线播放| 亚洲视频一区在线观看| 一区二区三区波多野结衣在线观看| 亚洲精品国产无套在线观| 亚洲一区影音先锋| 日本一道高清亚洲日美韩| 另类调教123区| 成人激情午夜影院| 色婷婷av一区二区三区大白胸| 欧美综合在线视频| 日韩欧美中文字幕制服| 久久尤物电影视频在线观看| 中文字幕一区二区三区不卡在线| 亚洲一区二区高清| 久久电影网电视剧免费观看| 欧美精品久久99| 欧美日韩一区二区三区免费看| 91精品国产乱码| 久久久精品国产免大香伊 | 亚洲国产精品一区二区尤物区| 石原莉奈一区二区三区在线观看| 激情综合五月天| 色欲综合视频天天天| 91精品国产综合久久香蕉的特点| 国产欧美精品一区二区色综合 | 国产精品白丝jk黑袜喷水| 一本一本大道香蕉久在线精品| 欧洲中文字幕精品| 国产亚洲精品久| 亚洲国产精品欧美一二99| 国产精品538一区二区在线| 国产精品无遮挡| 亚洲国产cao| 国产999精品久久久久久绿帽| 欧美亚州韩日在线看免费版国语版| 精品一区二区三区免费播放| 国产亚洲一区二区三区| 国产精品久久久久aaaa| 五月婷婷欧美视频| www.66久久| 欧美精品一区二区三区蜜桃视频| 亚洲综合在线电影| 国产盗摄一区二区三区| 制服丝袜亚洲网站| 亚洲乱码一区二区三区在线观看| 国产精品一区二区在线观看不卡| 欧美日韩亚洲不卡| 亚洲天堂久久久久久久| 国产东北露脸精品视频| 日韩写真欧美这视频| 偷拍日韩校园综合在线| 91首页免费视频| 中文字幕精品一区二区精品绿巨人 | 色婷婷av一区二区三区软件| 久久精品视频网| 久久激情五月婷婷| 这里只有精品免费| 亚洲一区自拍偷拍| 亚洲国产精品av| 国产成人一级电影| 国产精品欧美极品| 日韩高清不卡在线| 欧美影院一区二区| 18成人在线视频| 岛国一区二区三区| 国产亚洲欧美在线| 国产福利一区二区三区| 久久网这里都是精品| 国产精品一区一区三区| 国产三级精品视频|