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

📄 inode.c

📁 elinux jffs初始版本 具体了解JFFS的文件系统!
💻 C
📖 第 1 页 / 共 2 页
字号:
	*p = tmp;	mark_buffer_dirty(bh, 1);	if (IS_SYNC(inode) || inode->u.ext2_i.i_osync) {		ll_rw_block (WRITE, 1, &bh);		wait_on_buffer (bh);	}	inode->i_ctime = CURRENT_TIME;	inode->i_blocks += blocks;	inode->i_dirt = 1;	inode->u.ext2_i.i_next_alloc_block = new_block;	inode->u.ext2_i.i_next_alloc_goal = tmp;	brelse (bh);	return result;}struct buffer_head * ext2_getblk (struct inode * inode, long block,				  int create, int * err){	struct buffer_head * bh;	unsigned long b;	unsigned long addr_per_block = EXT2_ADDR_PER_BLOCK(inode->i_sb);	int addr_per_block_bits = EXT2_ADDR_PER_BLOCK_BITS(inode->i_sb);	*err = -EIO;	if (block < 0) {		ext2_warning (inode->i_sb, "ext2_getblk", "block < 0");		return NULL;	}	if (block > EXT2_NDIR_BLOCKS + addr_per_block +		(1 << (addr_per_block_bits * 2)) +		((1 << (addr_per_block_bits * 2)) << addr_per_block_bits)) {		ext2_warning (inode->i_sb, "ext2_getblk", "block > big");		return NULL;	}	/*	 * If this is a sequential block allocation, set the next_alloc_block	 * to this block now so that all the indblock and data block	 * allocations use the same goal zone	 */	ext2_debug ("block %lu, next %lu, goal %lu.\n", block, 		    inode->u.ext2_i.i_next_alloc_block,		    inode->u.ext2_i.i_next_alloc_goal);	if (block == inode->u.ext2_i.i_next_alloc_block + 1) {		inode->u.ext2_i.i_next_alloc_block++;		inode->u.ext2_i.i_next_alloc_goal++;	}	*err = -ENOSPC;	b = block;	if (block < EXT2_NDIR_BLOCKS)		return inode_getblk (inode, block, create, b, err);	block -= EXT2_NDIR_BLOCKS;	if (block < addr_per_block) {		bh = inode_getblk (inode, EXT2_IND_BLOCK, create, b, err);		return block_getblk (inode, bh, block, create,				     inode->i_sb->s_blocksize, b, err);	}	block -= addr_per_block;	if (block < (1 << (addr_per_block_bits * 2))) {		bh = inode_getblk (inode, EXT2_DIND_BLOCK, create, b, err);		bh = block_getblk (inode, bh, block >> addr_per_block_bits,				   create, inode->i_sb->s_blocksize, b, err);		return block_getblk (inode, bh, block & (addr_per_block - 1),				     create, inode->i_sb->s_blocksize, b, err);	}	block -= (1 << (addr_per_block_bits * 2));	bh = inode_getblk (inode, EXT2_TIND_BLOCK, create, b, err);	bh = block_getblk (inode, bh, block >> (addr_per_block_bits * 2),			   create, inode->i_sb->s_blocksize, b, err);	bh = block_getblk (inode, bh, (block >> addr_per_block_bits) & (addr_per_block - 1),			   create, inode->i_sb->s_blocksize, b, err);	return block_getblk (inode, bh, block & (addr_per_block - 1), create,			     inode->i_sb->s_blocksize, b, err);}struct buffer_head * ext2_bread (struct inode * inode, int block, 				 int create, int *err){	struct buffer_head * bh;	bh = ext2_getblk (inode, block, create, err);	if (!bh || 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;}void ext2_read_inode (struct inode * inode){	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;	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 > 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);		return;	}	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_panic (inode->i_sb, "ext2_read_inode",			    "group >= groups count");	group_desc = block_group >> EXT2_DESC_PER_BLOCK_BITS(inode->i_sb);	desc = block_group & (EXT2_DESC_PER_BLOCK(inode->i_sb) - 1);	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;	}		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 = gdp[desc].bg_inode_table +		(offset >> EXT2_BLOCK_SIZE_BITS(inode->i_sb));	if (!(bh = bread (inode->i_dev, block, inode->i_sb->s_blocksize))) {		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);	inode->i_mode = raw_inode->i_mode;	inode->i_uid = raw_inode->i_uid;	inode->i_gid = raw_inode->i_gid;	inode->i_nlink = raw_inode->i_links_count;	inode->i_size = raw_inode->i_size;	inode->i_atime = raw_inode->i_atime;	inode->i_ctime = raw_inode->i_ctime;	inode->i_mtime = raw_inode->i_mtime;	inode->u.ext2_i.i_dtime = raw_inode->i_dtime;	inode->i_blksize = PAGE_SIZE;	/* This is the optimal IO size (for stat), not the fs block size */	inode->i_blocks = raw_inode->i_blocks;	inode->i_version = ++event;	inode->u.ext2_i.i_new_inode = 0;	inode->u.ext2_i.i_flags = raw_inode->i_flags;	inode->u.ext2_i.i_faddr = 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_osync = 0;	inode->u.ext2_i.i_file_acl = raw_inode->i_file_acl;	inode->u.ext2_i.i_dir_acl = raw_inode->i_dir_acl;	inode->u.ext2_i.i_version = raw_inode->i_version;	inode->u.ext2_i.i_block_group = block_group;	inode->u.ext2_i.i_next_alloc_block = 0;	inode->u.ext2_i.i_next_alloc_goal = 0;	if (inode->u.ext2_i.i_prealloc_count)		ext2_error (inode->i_sb, "ext2_read_inode",			    "New inode has non-zero prealloc count!");	if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))		inode->i_rdev = to_kdev_t(raw_inode->i_block[0]);	else for (block = 0; block < EXT2_N_BLOCKS; block++)		inode->u.ext2_i.i_data[block] = raw_inode->i_block[block];	brelse (bh);	inode->i_op = NULL;	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;	else if (S_ISDIR(inode->i_mode))		inode->i_op = &ext2_dir_inode_operations;	else if (S_ISLNK(inode->i_mode))		inode->i_op = &ext2_symlink_inode_operations;	else if (S_ISCHR(inode->i_mode))		inode->i_op = &chrdev_inode_operations;	else if (S_ISBLK(inode->i_mode))		inode->i_op = &blkdev_inode_operations;	else if (S_ISFIFO(inode->i_mode))		init_fifo(inode);	if (inode->u.ext2_i.i_flags & EXT2_SYNC_FL)		inode->i_flags |= MS_SYNCHRONOUS;	if (inode->u.ext2_i.i_flags & EXT2_APPEND_FL)		inode->i_flags |= S_APPEND;	if (inode->u.ext2_i.i_flags & EXT2_IMMUTABLE_FL)		inode->i_flags |= S_IMMUTABLE;	if (inode->u.ext2_i.i_flags & EXT2_NOATIME_FL)		inode->i_flags |= MS_NOATIME;	return;	bad_inode:	make_bad_inode(inode);	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;	if ((inode->i_ino != EXT2_ROOT_INO &&	     inode->i_ino < EXT2_FIRST_INO(inode->i_sb)) ||	    inode->i_ino > 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 0;	}	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_panic (inode->i_sb, "ext2_write_inode",			    "group >= groups count");	group_desc = block_group >> EXT2_DESC_PER_BLOCK_BITS(inode->i_sb);	desc = block_group & (EXT2_DESC_PER_BLOCK(inode->i_sb) - 1);	bh = inode->i_sb->u.ext2_sb.s_group_desc[group_desc];	if (!bh)		ext2_panic (inode->i_sb, "ext2_write_inode",			    "Descriptor not loaded");	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 = gdp[desc].bg_inode_table +		(offset >> EXT2_BLOCK_SIZE_BITS(inode->i_sb));	if (!(bh = bread (inode->i_dev, block, inode->i_sb->s_blocksize))) {		ext2_error (inode->i_sb, "ext2_write_inode",			    "unable to read inode block - "			    "inode=%lu, block=%lu", inode->i_ino, block);		/*		 * Unfortunately we're in a lose-lose situation.  I think that		 * keeping the inode in-core with the dirty bit set is 		 * the worse option, since that will soak up inodes until		 * the end of the world.  Clearing the dirty bit is nasty if		 * we haven't succeeded in writing out, but it's less nasty		 * than the alternative. -- sct		 */		inode->i_dirt = 0;				return -EIO;	}		offset &= EXT2_BLOCK_SIZE(inode->i_sb) - 1;	raw_inode = (struct ext2_inode *) (bh->b_data + offset);	raw_inode->i_mode = inode->i_mode;	raw_inode->i_uid = inode->i_uid;	raw_inode->i_gid = inode->i_gid;	raw_inode->i_links_count = inode->i_nlink;	raw_inode->i_size = inode->i_size;	raw_inode->i_atime = inode->i_atime;	raw_inode->i_ctime = inode->i_ctime;	raw_inode->i_mtime = inode->i_mtime;	raw_inode->i_blocks = inode->i_blocks;	raw_inode->i_dtime = inode->u.ext2_i.i_dtime;	raw_inode->i_flags = inode->u.ext2_i.i_flags;	raw_inode->i_faddr = 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 = inode->u.ext2_i.i_file_acl;	raw_inode->i_dir_acl = inode->u.ext2_i.i_dir_acl;	raw_inode->i_version = inode->u.ext2_i.i_version;	if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))		raw_inode->i_block[0] = 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, 1);	inode->i_dirt = 0;	if (do_sync) {		ll_rw_block (WRITE, 1, &bh);		wait_on_buffer (bh);		if (buffer_req(bh) && !buffer_uptodate(bh)) {			ext2_error (inode->i_sb, 				    "IO error syncing ext2 inode ["				    "%s:%08lx]\n",				    kdevname(inode->i_dev), inode->i_ino);			err = -EIO;		}	}	brelse (bh);	return err;}void ext2_write_inode (struct inode * inode){	ext2_update_inode (inode, 0);}int ext2_sync_inode (struct inode *inode){	return ext2_update_inode (inode, 1);}

⌨️ 快捷键说明

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