⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 inode.c

📁 linux的文件系统的部分代码的详细注释
💻 C
📖 第 1 页 / 共 4 页
字号:
changed:	while (partial > chain) {		brelse(partial->bh);/*释放各级目录块*/		partial--;	}	goto reread;}/*同步写页*/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);/*块位图*/}/*直接I/O*/static int ext2_direct_IO(int rw, struct inode * inode, struct kiobuf * iobuf, unsigned long blocknr, int blocksize){	return generic_direct_IO(rw, inode, iobuf, blocknr, blocksize, ext2_get_block);/*直接I/O*/}/*ext2文件系统中具体操作实现函数集*/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,	direct_IO: ext2_direct_IO,};/* * 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? */ /*查找第一个非0字或对零页进行比较*/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;/*声明描述索引块中的索引项指针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){	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 {				mark_inode_dirty(inode);/*标记inode为脏*/				ext2_free_blocks (inode, block_to_free, count);/*释放块*/			free_this:				block_to_free = nr;				count = 1;			}		}	}	if (count > 0) {		mark_inode_dirty(inode);/*标记inode为脏*/		ext2_free_blocks (inode, block_to_free, count);/*释放块*/	}}/** *	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--) {/*块深度减一后,不为0*/		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 = sb_bread(inode->i_sb, nr);			/*			 * 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);			ext2_free_blocks(inode, nr, 1);/*释放块*/			mark_inode_dirty(inode);/*标记inode脏*/		}	} else		ext2_free_data(inode, p, q);}/*截短清空inode*/void ext2_truncate (struct inode * inode){	u32 *i_data = inode->u.ext2_i.i_data;	int addr_per_block = EXT2_ADDR_PER_BLOCK(inode->i_sb);	int offsets[4];	Indirect chain[4];	Indirect *partial;	int nr = 0;	int n;	long iblock;	unsigned blocksize;	if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||	    S_ISLNK(inode->i_mode)))/*inode不是常规文件、目录、符号链接*/		return;/*直接返回*/	if (IS_APPEND(inode) || IS_IMMUTABLE(inode))		return;	ext2_discard_prealloc(inode);/*重新设置设备块组描述子和块组数据块位图*/	blocksize = inode->i_sb->s_blocksize;/*置块大小的值*/	iblock = (inode->i_size + blocksize-1)					>> EXT2_BLOCK_SIZE_BITS(inode->i_sb);	block_truncate_page(inode->i_mapping, inode->i_size, ext2_get_block);	n = ext2_block_to_path(inode, iblock, offsets);/*以逻辑块号为索引查找物理块*/	if (n == 0)		return;	if (n == 1) {		ext2_free_data(inode, i_data+offsets[0],					i_data + EXT2_NDIR_BLOCKS); /*释放一个数据块的链表*/		goto do_indirects;	}	partial = ext2_find_shared(inode, n, offsets, chain, &nr);	/* Kill the top of shared branch (already detached) */	if (nr) {		if (partial == chain)			mark_inode_dirty(inode);/*标记inode脏*/		else			mark_buffer_dirty_inode(partial->bh, inode);/*标记inode的缓冲区脏*/		ext2_free_branches(inode, &nr, &nr+1, (chain+n-1) - partial); /*释放一个块链表数组*/	}	/* Clear the ends of indirect blocks on the shared branch */	while (partial > chain) {		ext2_free_branches(inode,				   partial->p + 1,				   (u32*)partial->bh->b_data + addr_per_block,				   (chain+n-1) - partial); /*释放一个块链表数组*/		mark_buffer_dirty_inode(partial->bh, inode);/*标记inode的缓冲区脏*/		if (IS_SYNC(inode)) {/*inode标记为同步*/			ll_rw_block (WRITE, 1, &partial->bh);			wait_on_buffer (partial->bh);/*在等待队列上等待buffer写入设备*/		}		brelse (partial->bh);/*释放块在高速缓存中的缓冲区首部*/		partial--;	}do_indirects:	/* Kill the remaining (whole) subtrees */	switch (offsets[0]) {		default:			nr = i_data[EXT2_IND_BLOCK];			if (nr) {				i_data[EXT2_IND_BLOCK] = 0;				mark_inode_dirty(inode);/*标志inode脏*/				ext2_free_branches(inode, &nr, &nr+1, 1); /*释放一个块链表数组*/			}		case EXT2_IND_BLOCK:			nr = i_data[EXT2_DIND_BLOCK];			if (nr) {				i_data[EXT2_DIND_BLOCK] = 0;				mark_inode_dirty(inode);/*标志inode脏*/				ext2_free_branches(inode, &nr, &nr+1, 2); /*释放一个块链表数组*/			}		case EXT2_DIND_BLOCK:			nr = i_data[EXT2_TIND_BLOCK];			if (nr) {				i_data[EXT2_TIND_BLOCK] = 0;				mark_inode_dirty(inode);/*标志inode脏*/				ext2_free_branches(inode, &nr, &nr+1, 3); /*释放一个块链表数组*/			}		case EXT2_TIND_BLOCK:			;	}	/*文件的最后修改时间=节点的修改时间=当前时间*/	inode->i_mtime = inode->i_ctime = CURRENT_TIME;		if (IS_SYNC(inode))/*inode标志为需要同步*/		ext2_sync_inode (inode);/*同步inode到磁盘*/	else		mark_inode_dirty(inode);/*标志inode脏*/}/*用来读取一个指定的索引节点信息*/void ext2_read_inode (struct inode * inode){	struct buffer_head * bh;	struct ext2_inode * raw_inode;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -