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

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

?? inode.c

?? linux 下的文件管理的程序
?? C
?? 第 1 頁 / 共 3 頁
字號:
 *	This function verifies that chain (up to the missing link) had not
 *	changed, fills the missing link and does all housekeeping needed in
 *	inode (->i_blocks, etc.). In case of success we end up with the full
 *	chain to new block and return 0. Otherwise (== chain had been changed)
 *	we free the new blocks (forgetting their buffer_heads, indeed) and
 *	return -EAGAIN.
 */

static inline int ext2_splice_branch(struct inode *inode,
				     long block,
				     Indirect chain[4],
				     Indirect *where,
				     int num)
{
	int i;

	/* Verify that place we are splicing to is still there and vacant */

	/* Writer: pointers, ->i_next_alloc*, ->i_blocks */
	if (!verify_chain(chain, where-1) || *where->p)
		/* Writer: end */
		goto changed;

	/* That's it */

	*where->p = where->key;
	inode->u.ext2_i.i_next_alloc_block = block;
	inode->u.ext2_i.i_next_alloc_goal = le32_to_cpu(where[num-1].key);
	inode->i_blocks += num * inode->i_sb->s_blocksize/512;

	/* Writer: end */

	/* We are done with atomic stuff, now do the rest of housekeeping */

	inode->i_ctime = CURRENT_TIME;

	/* had we spliced it onto indirect block? */
	if (where->bh) {
		mark_buffer_dirty_inode(where->bh, inode);
		if (IS_SYNC(inode) || inode->u.ext2_i.i_osync) {
			ll_rw_block (WRITE, 1, &where->bh);
			wait_on_buffer(where->bh);
		}
	}

	if (IS_SYNC(inode) || inode->u.ext2_i.i_osync)
		ext2_sync_inode (inode);
	else
		mark_inode_dirty(inode);
	return 0;

changed:
	for (i = 1; i < num; i++)
		bforget(where[i].bh);
	for (i = 0; i < num; i++)
		ext2_free_blocks(inode, le32_to_cpu(where[i].key), 1);
	return -EAGAIN;
}

/*
 * Allocation strategy is simple: if we have to allocate something, we will
 * have to go the whole way to leaf. So let's do it before attaching anything
 * to tree, set linkage between the newborn blocks, write them if sync is
 * required, recheck the path, free and repeat if check fails, otherwise
 * set the last missing link (that will protect us from any truncate-generated
 * removals - all blocks on the path are immune now) and possibly force the
 * write on the parent block.
 * That has a nice additional property: no special recovery from the failed
 * allocations is needed - we simply release blocks and do not touch anything
 * reachable from inode.
 */

static int ext2_get_block(struct inode *inode, long iblock, struct buffer_head *bh_result, int create)
{
	int err = -EIO;
	int offsets[4];
	Indirect chain[4];
	Indirect *partial;
	unsigned long goal;
	int left;
	int depth = ext2_block_to_path(inode, iblock, offsets);

	if (depth == 0)
		goto out;

	lock_kernel();
reread:
	partial = ext2_get_branch(inode, depth, offsets, chain, &err);

	/* Simplest case - block found, no allocation needed */
	if (!partial) {
got_it:
		bh_result->b_dev = inode->i_dev;
		bh_result->b_blocknr = le32_to_cpu(chain[depth-1].key);
		bh_result->b_state |= (1UL << BH_Mapped);
		/* Clean up and exit */
		partial = chain+depth-1; /* the whole chain */
		goto cleanup;
	}

	/* Next simple case - plain lookup or failed read of indirect block */
	if (!create || err == -EIO) {
cleanup:
		while (partial > chain) {
			brelse(partial->bh);
			partial--;
		}
		unlock_kernel();
out:
		return err;
	}

	/*
	 * Indirect block might be removed by truncate while we were
	 * reading it. Handling of that case (forget what we've got and
	 * reread) is taken out of the main path.
	 */
	if (err == -EAGAIN)
		goto changed;

	if (ext2_find_goal(inode, iblock, chain, partial, &goal) < 0)
		goto changed;

	left = (chain + depth) - partial;
	err = ext2_alloc_branch(inode, left, goal,
					offsets+(partial-chain), partial);
	if (err)
		goto cleanup;

	if (ext2_splice_branch(inode, iblock, chain, partial, left) < 0)
		goto changed;

	bh_result->b_state |= (1UL << BH_New);
	goto got_it;

changed:
	while (partial > chain) {
		bforget(partial->bh);
		partial--;
	}
	goto reread;
}

struct buffer_head * ext2_getblk(struct inode * inode, long block, int create, int * err)
{
	struct buffer_head dummy;
	int error;

	dummy.b_state = 0;
	dummy.b_blocknr = -1000;
	error = ext2_get_block(inode, block, &dummy, create);
	*err = error;
	if (!error && buffer_mapped(&dummy)) {
		struct buffer_head *bh;
		bh = getblk(dummy.b_dev, dummy.b_blocknr, inode->i_sb->s_blocksize);
		if (buffer_new(&dummy)) {
			if (!buffer_uptodate(bh))
				wait_on_buffer(bh);
			memset(bh->b_data, 0, inode->i_sb->s_blocksize);
			mark_buffer_uptodate(bh, 1);
			mark_buffer_dirty_inode(bh, inode);
		}
		return bh;
	}
	return NULL;
}

struct buffer_head * ext2_bread (struct inode * inode, int block, 
				 int create, int *err)
{
	struct buffer_head * bh;
	int prev_blocks;
	
	prev_blocks = inode->i_blocks;
	
	bh = ext2_getblk (inode, block, create, err);
	if (!bh)
		return bh;
	
	/*
	 * If the inode has grown, and this is a directory, then perform
	 * preallocation of a few more blocks to try to keep directory
	 * fragmentation down.
	 */
	if (create && 
	    S_ISDIR(inode->i_mode) && 
	    inode->i_blocks > prev_blocks &&
	    EXT2_HAS_COMPAT_FEATURE(inode->i_sb,
				    EXT2_FEATURE_COMPAT_DIR_PREALLOC)) {
		int i;
		struct buffer_head *tmp_bh;
		
		for (i = 1;
		     i < EXT2_SB(inode->i_sb)->s_es->s_prealloc_dir_blocks;
		     i++) {
			/* 
			 * ext2_getblk will zero out the contents of the
			 * directory for us
			 */
			tmp_bh = ext2_getblk(inode, block+i, create, err);
			if (!tmp_bh) {
				brelse (bh);
				return 0;
			}
			brelse (tmp_bh);
		}
	}
	
	if (buffer_uptodate(bh))
		return bh;
	ll_rw_block (READ, 1, &bh);
	wait_on_buffer (bh);
	if (buffer_uptodate(bh))
		return bh;
	brelse (bh);
	*err = -EIO;
	return NULL;
}

static int ext2_writepage(struct page *page)
{
	return block_write_full_page(page,ext2_get_block);
}
static int ext2_readpage(struct file *file, struct page *page)
{
	return block_read_full_page(page,ext2_get_block);
}
static int ext2_prepare_write(struct file *file, struct page *page, unsigned from, unsigned to)
{
	return block_prepare_write(page,from,to,ext2_get_block);
}
static int ext2_bmap(struct address_space *mapping, long block)
{
	return generic_block_bmap(mapping,block,ext2_get_block);
}
struct address_space_operations ext2_aops = {
	readpage: ext2_readpage,
	writepage: ext2_writepage,
	sync_page: block_sync_page,
	prepare_write: ext2_prepare_write,
	commit_write: generic_commit_write,
	bmap: ext2_bmap
};

/*
 * Probably it should be a library function... search for first non-zero word
 * or memcmp with zero_page, whatever is better for particular architecture.
 * Linus?
 */
static inline int all_zeroes(u32 *p, u32 *q)
{
	while (p < q)
		if (*p++)
			return 0;
	return 1;
}

/**
 *	ext2_find_shared - find the indirect blocks for partial truncation.
 *	@inode:	  inode in question
 *	@depth:	  depth of the affected branch
 *	@offsets: offsets of pointers in that branch (see ext2_block_to_path)
 *	@chain:	  place to store the pointers to partial indirect blocks
 *	@top:	  place to the (detached) top of branch
 *
 *	This is a helper function used by ext2_truncate().
 *
 *	When we do truncate() we may have to clean the ends of several indirect
 *	blocks but leave the blocks themselves alive. Block is partially
 *	truncated if some data below the new i_size is refered from it (and
 *	it is on the path to the first completely truncated data block, indeed).
 *	We have to free the top of that path along with everything to the right
 *	of the path. Since no allocation past the truncation point is possible
 *	until ext2_truncate() finishes, we may safely do the latter, but top
 *	of branch may require special attention - pageout below the truncation
 *	point might try to populate it.
 *
 *	We atomically detach the top of branch from the tree, store the block
 *	number of its root in *@top, pointers to buffer_heads of partially
 *	truncated blocks - in @chain[].bh and pointers to their last elements
 *	that should not be removed - in @chain[].p. Return value is the pointer
 *	to last filled element of @chain.
 *
 *	The work left to caller to do the actual freeing of subtrees:
 *		a) free the subtree starting from *@top
 *		b) free the subtrees whose roots are stored in
 *			(@chain[i].p+1 .. end of @chain[i].bh->b_data)
 *		c) free the subtrees growing from the inode past the @chain[0].p
 *			(no partially truncated stuff there).
 */

static Indirect *ext2_find_shared(struct inode *inode,
				int depth,
				int offsets[4],
				Indirect chain[4],
				u32 *top)
{
	Indirect *partial, *p;
	int k, err;

	*top = 0;
	for (k = depth; k > 1 && !offsets[k-1]; k--)
		;
	partial = ext2_get_branch(inode, k, offsets, chain, &err);
	/* Writer: pointers */
	if (!partial)
		partial = chain + k-1;
	/*
	 * If the branch acquired continuation since we've looked at it -
	 * fine, it should all survive and (new) top doesn't belong to us.
	 */
	if (!partial->key && *partial->p)
		/* Writer: end */
		goto no_top;
	for (p=partial; p>chain && all_zeroes((u32*)p->bh->b_data,p->p); p--)
		;
	/*
	 * OK, we've found the last block that must survive. The rest of our
	 * branch should be detached before unlocking. However, if that rest
	 * of branch is all ours and does not grow immediately from the inode
	 * it's easier to cheat and just decrement partial->p.
	 */
	if (p == chain + k - 1 && p > chain) {
		p->p--;
	} else {
		*top = *p->p;
		*p->p = 0;
	}
	/* Writer: end */

	while(partial > p)
	{
		brelse(partial->bh);
		partial--;
	}
no_top:
	return partial;
}

/**
 *	ext2_free_data - free a list of data blocks
 *	@inode:	inode we are dealing with
 *	@p:	array of block numbers
 *	@q:	points immediately past the end of array
 *
 *	We are freeing all blocks refered from that array (numbers are
 *	stored as little-endian 32-bit) and updating @inode->i_blocks
 *	appropriately.
 */
static inline void ext2_free_data(struct inode *inode, u32 *p, u32 *q)
{
	int blocks = inode->i_sb->s_blocksize / 512;
	unsigned long block_to_free = 0, count = 0;
	unsigned long nr;

	for ( ; p < q ; p++) {
		nr = le32_to_cpu(*p);
		if (nr) {
			*p = 0;
			/* accumulate blocks to free if they're contiguous */
			if (count == 0)
				goto free_this;
			else if (block_to_free == nr - count)
				count++;
			else {
				/* Writer: ->i_blocks */
				inode->i_blocks -= blocks * count;
				/* Writer: end */
				ext2_free_blocks (inode, block_to_free, count);
				mark_inode_dirty(inode);
			free_this:
				block_to_free = nr;
				count = 1;
			}
		}
	}
	if (count > 0) {
		/* Writer: ->i_blocks */
		inode->i_blocks -= blocks * count;
		/* Writer: end */
		ext2_free_blocks (inode, block_to_free, count);
		mark_inode_dirty(inode);
	}
}

/**
 *	ext2_free_branches - free an array of branches
 *	@inode:	inode we are dealing with
 *	@p:	array of block numbers
 *	@q:	pointer immediately past the end of array
 *	@depth:	depth of the branches to free
 *
 *	We are freeing all blocks refered from these branches (numbers are
 *	stored as little-endian 32-bit) and updating @inode->i_blocks
 *	appropriately.
 */
static void ext2_free_branches(struct inode *inode, u32 *p, u32 *q, int depth)
{
	struct buffer_head * bh;
	unsigned long nr;

	if (depth--) {
		int addr_per_block = EXT2_ADDR_PER_BLOCK(inode->i_sb);
		for ( ; p < q ; p++) {
			nr = le32_to_cpu(*p);
			if (!nr)
				continue;
			*p = 0;
			bh = bread (inode->i_dev, nr, inode->i_sb->s_blocksize);
			/*
			 * A read failure? Report error and clear slot
			 * (should be rare).
			 */ 
			if (!bh) {
				ext2_error(inode->i_sb, "ext2_free_branches",
					"Read failure, inode=%ld, block=%ld",
					inode->i_ino, nr);
				continue;
			}
			ext2_free_branches(inode,
					   (u32*)bh->b_data,
					   (u32*)bh->b_data + addr_per_block,
					   depth);
			bforget(bh);
			/* Writer: ->i_blocks */
			inode->i_blocks -= inode->i_sb->s_blocksize / 512;
			/* Writer: end */
			ext2_free_blocks(inode, nr, 1);
			mark_inode_dirty(inode);
		}
	} else
		ext2_free_data(inode, p, q);
}

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
国产成人免费视频一区| 亚洲曰韩产成在线| 日韩激情视频在线观看| 成人毛片在线观看| 91精品国产91热久久久做人人| 中文字幕高清一区| 日本不卡一区二区| 欧美三片在线视频观看| 欧美国产在线观看| 麻豆精品国产传媒mv男同| 91视频你懂的| 另类专区欧美蜜桃臀第一页| 成人av电影在线播放| 欧美电影精品一区二区| 亚洲成人精品一区| 99久久婷婷国产综合精品| 久久久综合网站| 麻豆精品视频在线| 欧美精品粉嫩高潮一区二区| 亚洲你懂的在线视频| 国产成人免费视频精品含羞草妖精 | 欧美日本在线观看| 日韩伦理av电影| 国产福利视频一区二区三区| 欧美不卡一二三| 日本欧美一区二区三区乱码 | 天天色天天操综合| 日本乱人伦一区| 久久网站热最新地址| 看电视剧不卡顿的网站| 欧美一卡2卡三卡4卡5免费| 亚洲大片一区二区三区| 色8久久精品久久久久久蜜| 亚洲色图.com| 91在线视频18| 国产精品对白交换视频 | 日韩中文欧美在线| 精品视频一区三区九区| 亚洲资源中文字幕| 欧美调教femdomvk| 亚洲图片自拍偷拍| 欧美日韩在线播放三区| 亚洲成av人片在线观看无码| 欧美三级视频在线观看| 99久久99精品久久久久久| 国产精品的网站| 91社区在线播放| 亚洲精选一二三| 在线观看av一区二区| 亚洲综合视频在线| 欧美视频精品在线| 天天综合网天天综合色| 欧美一级在线观看| 久久国产婷婷国产香蕉| 2020国产精品| 成人激情免费视频| 亚洲精品免费一二三区| 欧美亚洲免费在线一区| 天天综合日日夜夜精品| 日韩无一区二区| 国产一区不卡精品| 国产精品视频一区二区三区不卡| 成人美女视频在线观看| 亚洲精品国产一区二区三区四区在线| 日本韩国精品在线| 午夜av区久久| 精品女同一区二区| 粉嫩绯色av一区二区在线观看 | 欧美三级电影一区| 日本网站在线观看一区二区三区 | 国产丝袜欧美中文另类| 成人蜜臀av电影| 亚洲午夜三级在线| 日韩午夜激情免费电影| 懂色av噜噜一区二区三区av| 亚洲手机成人高清视频| 欧美日韩精品欧美日韩精品| 久久精品国产免费看久久精品| 久久人人爽爽爽人久久久| 99视频一区二区| 亚洲18影院在线观看| 精品av综合导航| 99精品久久99久久久久| 水野朝阳av一区二区三区| 久久蜜臀精品av| 色婷婷激情久久| 久久99热这里只有精品| 亚洲国产精品成人综合色在线婷婷| 91网站在线播放| 奇米精品一区二区三区在线观看一| 国产午夜一区二区三区| 欧美在线free| 国产福利一区二区三区视频 | 日本一区二区三区高清不卡| 色综合天天狠狠| 理论片日本一区| 国产乱淫av一区二区三区| 亚洲日本中文字幕区| 日韩欧美中文一区| av爱爱亚洲一区| 六月丁香综合在线视频| 亚洲欧美自拍偷拍色图| 日韩精品一区二区三区在线观看 | 亚洲国产精品二十页| 欧美曰成人黄网| 激情偷乱视频一区二区三区| 亚洲黄色小视频| 精品对白一区国产伦| 欧美性生活影院| 国产成人av电影在线| 天天av天天翘天天综合网 | 4438x成人网最大色成网站| 国产91丝袜在线播放0| 午夜精品免费在线观看| 国产精品国产自产拍高清av王其| 欧美一区午夜视频在线观看| 9人人澡人人爽人人精品| 久久av中文字幕片| 亚洲国产一区二区三区青草影视| 国产婷婷色一区二区三区四区| 91麻豆精品国产91| 色菇凉天天综合网| 国产成人精品免费在线| 麻豆国产精品一区二区三区 | 日日噜噜夜夜狠狠视频欧美人 | 日韩免费福利电影在线观看| 洋洋av久久久久久久一区| 欧美一区午夜视频在线观看| 99re热这里只有精品视频| 精品一区二区三区在线播放 | 国产精品久久久久影院| 欧美不卡视频一区| 9191久久久久久久久久久| 色综合色综合色综合色综合色综合| 国产一区二区三区免费播放| 日韩精品免费专区| 亚洲自拍偷拍麻豆| 亚洲色欲色欲www在线观看| 国产日韩欧美a| 精品成人一区二区三区四区| 91精品国产色综合久久ai换脸 | 成人在线一区二区三区| 裸体一区二区三区| 日韩av网站免费在线| 亚洲国产一二三| 成人在线综合网站| 国产成人免费在线| 国产精品一二一区| 激情图片小说一区| 久久9热精品视频| 久久激五月天综合精品| 蜜桃视频第一区免费观看| 日韩精品成人一区二区在线| 亚洲444eee在线观看| 午夜视黄欧洲亚洲| 亚洲成人久久影院| 午夜av一区二区| 日日骚欧美日韩| 免费av成人在线| 久久精品99国产精品| 九色|91porny| 黑人巨大精品欧美黑白配亚洲 | 中文字幕欧美一| 中文字幕中文在线不卡住| 日本一区二区三区国色天香| 日本一区二区三区dvd视频在线| 久久久久久久久久久99999| 精品精品国产高清a毛片牛牛| 精品国产网站在线观看| 久久久亚洲国产美女国产盗摄| 久久一二三国产| 中文字幕精品在线不卡| 亚洲欧美一区二区视频| 一区二区三区四区高清精品免费观看| 亚洲老司机在线| 香蕉久久一区二区不卡无毒影院 | 亚洲激情自拍偷拍| 亚洲五码中文字幕| 日本午夜精品一区二区三区电影 | 亚洲另类色综合网站| 一区二区三区在线免费观看| 亚洲bdsm女犯bdsm网站| 日韩精品国产精品| 美女视频一区二区三区| 日韩欧美中文一区| 国产欧美一区二区在线观看| 国产精品美女久久久久aⅴ国产馆| 综合网在线视频| 亚洲午夜电影网| 精品综合免费视频观看| 丰满白嫩尤物一区二区| 91成人网在线| 日韩欧美中文字幕制服| 亚洲国产精华液网站w| 亚洲精品福利视频网站| 日本不卡一二三| 国产成人鲁色资源国产91色综 | 东方aⅴ免费观看久久av| 97久久精品人人做人人爽50路| 欧美性xxxxx极品少妇|