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

📄 inode.c

📁 嵌入式系统设计与实例开发实验教材二源码 多线程应用程序设计 串行端口程序设计 AD接口实验 CAN总线通信实验 GPS通信实验 Linux内核移植与编译实验 IC卡读写实验 SD驱动使
💻 C
📖 第 1 页 / 共 3 页
字号:
			}			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);		}	} else		ext2_free_data(inode, p, q);}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)))		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);		else			mark_buffer_dirty_inode(partial->bh, 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);		if (IS_SYNC(inode)) {			ll_rw_block (WRITE, 1, &partial->bh);			wait_on_buffer (partial->bh);		}		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);				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);				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);				ext2_free_branches(inode, &nr, &nr+1, 3);			}		case EXT2_TIND_BLOCK:			;	}	inode->i_mtime = inode->i_ctime = CURRENT_TIME;	if (IS_SYNC(inode))		ext2_sync_inode (inode);	else		mark_inode_dirty(inode);}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 > 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;	}	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 = 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);	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);	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 > 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);	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;	}	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);	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);		wait_on_buffer (bh);		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;}void ext2_write_inode (struct inode * inode, int wait){	lock_kernel();	ext2_update_inode (inode, wait);	unlock_kernel();}int ext2_sync_inode (struct inode *inode){	return ext2_update_inode (inode, 1);}

⌨️ 快捷键说明

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