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

📄 inode.c

📁 linux的文件系统的部分代码的详细注释
💻 C
📖 第 1 页 / 共 4 页
字号:
	unsigned long block_group;	unsigned long group_desc;	unsigned long desc;	unsigned long block;	unsigned long offset;	struct ext2_group_desc * gdp;       /*节点号!=根节点&&节点号<第一个节点号||节点号>总节点计数时,         *出错则输出错误信息         */	if ((inode->i_ino != EXT2_ROOT_INO && inode->i_ino != EXT2_ACL_IDX_INO &&	     inode->i_ino != EXT2_ACL_DATA_INO &&	     inode->i_ino < EXT2_FIRST_INO(inode->i_sb)) ||	    inode->i_ino > le32_to_cpu(inode->i_sb->u.ext2_sb.s_es->s_inodes_count)) {		ext2_error (inode->i_sb, "ext2_read_inode",			    "bad inode number: %lu", inode->i_ino);		goto bad_inode;	}	/*该索引节点所在的块组号=索引节点号/每组中所有节点数*/	block_group = (inode->i_ino - 1) / EXT2_INODES_PER_GROUP(inode->i_sb);	/*如果索引节点所在的块组号>=文件系统中总块号*/	if (block_group >= inode->i_sb->u.ext2_sb.s_groups_count) {		ext2_error (inode->i_sb, "ext2_read_inode",			    "group >= groups count");		goto bad_inode;	}	/*组描述符在组描述表中的块号=块组号/每块中组描述符数,	 *每个组描述符是32字节大小,在一个1KB大小的块中可存储32个组描述符,	 *每个块用一个组描述符表示,	 *因为组描述符已读入buffer中形成组描述表s_group_desc[]数组,	 *组描述表是以buffer为数组元素的,	 *每个buffer大小为一个数据块,	 *所以需要确定组描述符在组描述表的那一块	 *以及是该块中的第几组描述符	 */	group_desc = block_group >> EXT2_DESC_PER_BLOCK_BITS(inode->i_sb);	/*组描述符具体是该块中第几个描述符	 * =组号对每块中组描述符作相与运算	 */	desc = block_group & (EXT2_DESC_PER_BLOCK(inode->i_sb) - 1);	/*通过s_group_desc[]数组找到这个组描述符所在块在高速缓存中的缓冲区首部*/	bh = inode->i_sb->u.ext2_sb.s_group_desc[group_desc];	if (!bh) {		ext2_error (inode->i_sb, "ext2_read_inode",			    "Descriptor not loaded");		goto bad_inode;	}       /*通过缓冲区首部找到数据区,找到组描述符后,        *就可以通过组描述符结构中的bg_inode_table        *找到索引节点表首块在高速缓存中的地址        */	gdp = (struct ext2_group_desc *) bh->b_data;	/*	 * Figure out the offset within the block group inode table	 */	 /*计算该索引节点在块中的偏移位置*/	offset = ((inode->i_ino - 1) % EXT2_INODES_PER_GROUP(inode->i_sb)) *		EXT2_INODE_SIZE(inode->i_sb);	/*计算索引节点所在块的地址,	 *有了block和offset就可以找到索引节点了	 */	block = le32_to_cpu(gdp[desc].bg_inode_table) +		(offset >> EXT2_BLOCK_SIZE_BITS(inode->i_sb));	if (!(bh = sb_bread(inode->i_sb, block))) {		ext2_error (inode->i_sb, "ext2_read_inode",			    "unable to read inode block - "			    "inode=%lu, block=%lu", inode->i_ino, block);		goto bad_inode;	}	/*计算该索引节点在块中的偏移位置*/	offset &= (EXT2_BLOCK_SIZE(inode->i_sb) - 1);	/*得到索引节点*/	raw_inode = (struct ext2_inode *) (bh->b_data + offset);       /*从该节点raw_inode中读出信息填充inode*/	inode->i_mode = le16_to_cpu(raw_inode->i_mode);	inode->i_uid = (uid_t)le16_to_cpu(raw_inode->i_uid_low);	inode->i_gid = (gid_t)le16_to_cpu(raw_inode->i_gid_low);	if(!(test_opt (inode->i_sb, NO_UID32))) {		inode->i_uid |= le16_to_cpu(raw_inode->i_uid_high) << 16;		inode->i_gid |= le16_to_cpu(raw_inode->i_gid_high) << 16;	}	inode->i_nlink = le16_to_cpu(raw_inode->i_links_count);	inode->i_size = le32_to_cpu(raw_inode->i_size);	inode->i_atime = le32_to_cpu(raw_inode->i_atime);	inode->i_ctime = le32_to_cpu(raw_inode->i_ctime);	inode->i_mtime = le32_to_cpu(raw_inode->i_mtime);	inode->u.ext2_i.i_dtime = le32_to_cpu(raw_inode->i_dtime);	/* We now have enough fields to check if the inode was active or not.	 * This is needed because nfsd might try to access dead inodes	 * the test is that same one that e2fsck uses	 * NeilBrown 1999oct15	 */	if (inode->i_nlink == 0 && (inode->i_mode == 0 || inode->u.ext2_i.i_dtime)) {		/* this inode is deleted */		brelse (bh);/*释放块在高速缓存中的缓冲区首部*/		goto bad_inode;	}	inode->i_blksize = PAGE_SIZE;	/* This is the optimal IO size (for stat), not the fs block size */	inode->i_blocks = le32_to_cpu(raw_inode->i_blocks);	inode->i_version = ++event;	inode->u.ext2_i.i_flags = le32_to_cpu(raw_inode->i_flags);	inode->u.ext2_i.i_faddr = le32_to_cpu(raw_inode->i_faddr);	inode->u.ext2_i.i_frag_no = raw_inode->i_frag;	inode->u.ext2_i.i_frag_size = raw_inode->i_fsize;	inode->u.ext2_i.i_file_acl = le32_to_cpu(raw_inode->i_file_acl);	if (S_ISREG(inode->i_mode))		inode->i_size |= ((__u64)le32_to_cpu(raw_inode->i_size_high)) << 32;	else		inode->u.ext2_i.i_dir_acl = le32_to_cpu(raw_inode->i_dir_acl);	inode->i_generation = le32_to_cpu(raw_inode->i_generation);	inode->u.ext2_i.i_prealloc_count = 0;	inode->u.ext2_i.i_block_group = block_group;	/*	 * NOTE! The in-memory inode i_data array is in little-endian order	 * even on big-endian machines: we do NOT byteswap the block numbers!	 */	for (block = 0; block < EXT2_N_BLOCKS; block++)		inode->u.ext2_i.i_data[block] = raw_inode->i_block[block];      /*赋上操作函数集实例*/	if (inode->i_ino == EXT2_ACL_IDX_INO ||	    inode->i_ino == EXT2_ACL_DATA_INO)		/* Nothing to do */ ;	else if (S_ISREG(inode->i_mode)) {		inode->i_op = &ext2_file_inode_operations;		inode->i_fop = &ext2_file_operations;		inode->i_mapping->a_ops = &ext2_aops;	} else if (S_ISDIR(inode->i_mode)) {		inode->i_op = &ext2_dir_inode_operations;		inode->i_fop = &ext2_dir_operations;		inode->i_mapping->a_ops = &ext2_aops;	} else if (S_ISLNK(inode->i_mode)) {		if (!inode->i_blocks)			inode->i_op = &ext2_fast_symlink_inode_operations;		else {			inode->i_op = &page_symlink_inode_operations;			inode->i_mapping->a_ops = &ext2_aops;		}	} else 		init_special_inode(inode, inode->i_mode,				   le32_to_cpu(raw_inode->i_block[0]));	brelse (bh);/*释放块在高速缓存中的缓冲区首部*/		/*节点属性设置*/	inode->i_attr_flags = 0;	if (inode->u.ext2_i.i_flags & EXT2_SYNC_FL) {		inode->i_attr_flags |= ATTR_FLAG_SYNCRONOUS;		inode->i_flags |= S_SYNC;	}	if (inode->u.ext2_i.i_flags & EXT2_APPEND_FL) {		inode->i_attr_flags |= ATTR_FLAG_APPEND;		inode->i_flags |= S_APPEND;	}	if (inode->u.ext2_i.i_flags & EXT2_IMMUTABLE_FL) {		inode->i_attr_flags |= ATTR_FLAG_IMMUTABLE;		inode->i_flags |= S_IMMUTABLE;	}	if (inode->u.ext2_i.i_flags & EXT2_NOATIME_FL) {		inode->i_attr_flags |= ATTR_FLAG_NOATIME;		inode->i_flags |= S_NOATIME;	}	return;	bad_inode:	make_bad_inode(inode);/*由于I/O错误,标记inode已损坏*/	/*make_bad_inode - mark an inode bad due to an I/O error*/	return;}/*更新索引节点*/static int ext2_update_inode(struct inode * inode, int do_sync){	struct buffer_head * bh;	struct ext2_inode * raw_inode;	unsigned long block_group;	unsigned long group_desc;	unsigned long desc;	unsigned long block;	unsigned long offset;	int err = 0;	struct ext2_group_desc * gdp;       /*inode合法性检查*/	if ((inode->i_ino != EXT2_ROOT_INO &&	     inode->i_ino < EXT2_FIRST_INO(inode->i_sb)) ||	    inode->i_ino > le32_to_cpu(inode->i_sb->u.ext2_sb.s_es->s_inodes_count)) {		ext2_error (inode->i_sb, "ext2_write_inode",			    "bad inode number: %lu", inode->i_ino);		return -EIO;	}		/*块组号=索引节点号/每块组节点数*/	block_group = (inode->i_ino - 1) / EXT2_INODES_PER_GROUP(inode->i_sb);	/*如果索引节点所在的块组号>=文件系统中总块号*/	if (block_group >= inode->i_sb->u.ext2_sb.s_groups_count) {		ext2_error (inode->i_sb, "ext2_write_inode",			    "group >= groups count");		return -EIO;	}	/*块组描述符对应的块号=块组号*每块的块组描述符数*/	group_desc = block_group >> EXT2_DESC_PER_BLOCK_BITS(inode->i_sb);	/*计算描述符在块内的偏移*/	desc = block_group & (EXT2_DESC_PER_BLOCK(inode->i_sb) - 1);	/*通过s_group_desc[]数组找到这个组描述符所在块在高速缓存中的缓冲区首部*/	bh = inode->i_sb->u.ext2_sb.s_group_desc[group_desc];	if (!bh) {		ext2_error (inode->i_sb, "ext2_write_inode",			    "Descriptor not loaded");		return -EIO;	}	/*得到描述符所在的buffer*/	gdp = (struct ext2_group_desc *) bh->b_data;	/*	 * Figure out the offset within the block group inode table	 */	 /*节点在每块组内的偏移地址=索引节点号%每块节点数*节点大小*/	offset = ((inode->i_ino - 1) % EXT2_INODES_PER_GROUP(inode->i_sb)) *		EXT2_INODE_SIZE(inode->i_sb);	/*计算块号*/	block = le32_to_cpu(gdp[desc].bg_inode_table) +		(offset >> EXT2_BLOCK_SIZE_BITS(inode->i_sb));	/*读出节点表块*/	if (!(bh = sb_bread(inode->i_sb, block))) {		ext2_error (inode->i_sb, "ext2_write_inode",			    "unable to read inode block - "			    "inode=%lu, block=%lu", inode->i_ino, block);		return -EIO;	}	/*块内偏移*/	offset &= EXT2_BLOCK_SIZE(inode->i_sb) - 1;	/*得到索引节点*/	raw_inode = (struct ext2_inode *) (bh->b_data + offset);       /*用inode填写row_inode*/	raw_inode->i_mode = cpu_to_le16(inode->i_mode);	if(!(test_opt(inode->i_sb, NO_UID32))) {		raw_inode->i_uid_low = cpu_to_le16(low_16_bits(inode->i_uid));		raw_inode->i_gid_low = cpu_to_le16(low_16_bits(inode->i_gid));/* * Fix up interoperability with old kernels. Otherwise, old inodes get * re-used with the upper 16 bits of the uid/gid intact */		if(!inode->u.ext2_i.i_dtime) {			raw_inode->i_uid_high = cpu_to_le16(high_16_bits(inode->i_uid));			raw_inode->i_gid_high = cpu_to_le16(high_16_bits(inode->i_gid));		} else {			raw_inode->i_uid_high = 0;			raw_inode->i_gid_high = 0;		}	} else {		raw_inode->i_uid_low = cpu_to_le16(fs_high2lowuid(inode->i_uid));		raw_inode->i_gid_low = cpu_to_le16(fs_high2lowgid(inode->i_gid));		raw_inode->i_uid_high = 0;		raw_inode->i_gid_high = 0;	}	raw_inode->i_links_count = cpu_to_le16(inode->i_nlink);	raw_inode->i_size = cpu_to_le32(inode->i_size);	raw_inode->i_atime = cpu_to_le32(inode->i_atime);	raw_inode->i_ctime = cpu_to_le32(inode->i_ctime);	raw_inode->i_mtime = cpu_to_le32(inode->i_mtime);	raw_inode->i_blocks = cpu_to_le32(inode->i_blocks);	raw_inode->i_dtime = cpu_to_le32(inode->u.ext2_i.i_dtime);	raw_inode->i_flags = cpu_to_le32(inode->u.ext2_i.i_flags);	raw_inode->i_faddr = cpu_to_le32(inode->u.ext2_i.i_faddr);	raw_inode->i_frag = inode->u.ext2_i.i_frag_no;	raw_inode->i_fsize = inode->u.ext2_i.i_frag_size;	raw_inode->i_file_acl = cpu_to_le32(inode->u.ext2_i.i_file_acl);	if (S_ISDIR(inode->i_mode))		raw_inode->i_dir_acl = cpu_to_le32(inode->u.ext2_i.i_dir_acl);	else {		raw_inode->i_size_high = cpu_to_le32(inode->i_size >> 32);		if (inode->i_size > 0x7fffffffULL) {			struct super_block *sb = inode->i_sb;			if (!EXT2_HAS_RO_COMPAT_FEATURE(sb,					EXT2_FEATURE_RO_COMPAT_LARGE_FILE) ||			    EXT2_SB(sb)->s_es->s_rev_level ==					cpu_to_le32(EXT2_GOOD_OLD_REV)) {			       /* If this is the first large file				* created, add a flag to the superblock.				*/				lock_kernel();				ext2_update_dynamic_rev(sb);				EXT2_SET_RO_COMPAT_FEATURE(sb,					EXT2_FEATURE_RO_COMPAT_LARGE_FILE);				unlock_kernel();				ext2_write_super(sb);			}		}	}		raw_inode->i_generation = cpu_to_le32(inode->i_generation);	if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))		raw_inode->i_block[0] = cpu_to_le32(kdev_t_to_nr(inode->i_rdev));	else for (block = 0; block < EXT2_N_BLOCKS; block++)		raw_inode->i_block[block] = inode->u.ext2_i.i_data[block];	mark_buffer_dirty(bh);	if (do_sync) {		/*发出设备写请求*/		ll_rw_block (WRITE, 1, &bh);		/*在等待队列上等待buffer写入设备*/		wait_on_buffer (bh);		/*将buffer设置成req和uptodate状态*/		if (buffer_req(bh) && !buffer_uptodate(bh)) {			printk ("IO error syncing ext2 inode ["				"%s:%08lx]\n",				bdevname(inode->i_dev), inode->i_ino);			err = -EIO;		}	}	brelse (bh);/*释放块在高速缓存中的缓冲区首部*/	return err;}/*将inode结构中数据写入到硬盘*/void ext2_write_inode (struct inode * inode, int wait){	lock_kernel();/*给内核上锁*/	ext2_update_inode (inode, wait);/*调用更新inode的函数*/	unlock_kernel();/*给内核解锁*/}/*把节点缓存中数据写入设备*/int ext2_sync_inode (struct inode *inode){	return ext2_update_inode (inode, 1);/*调用更新inode的函数*/}

⌨️ 快捷键说明

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