您的位置:首页 > 其它

ext2文件系统的super操作方法

2011-11-19 19:32 471 查看
static const struct super_operations ext2_sops = {

.alloc_inode = ext2_alloc_inode,

.destroy_inode = ext2_destroy_inode,

.write_inode = ext2_write_inode,

.delete_inode = ext2_delete_inode,

.put_super = ext2_put_super,

.write_super = ext2_write_super,

.statfs = ext2_statfs,

.remount_fs = ext2_remount,

.clear_inode = ext2_clear_inode,

.show_options = ext2_show_options,

#ifdef CONFIG_QUOTA

.quota_read = ext2_quota_read,

.quota_write = ext2_quota_write,

#endif

};

=======================================

static struct inode *ext2_alloc_inode(struct super_block *sb)

{

01 struct ext2_inode_info *ei;

02 ei = (struct ext2_inode_info *)kmem_cache_alloc(ext2_inode_cachep, GFP_KERNEL);

03 if (!ei)

04 return NULL;

05#ifdef CONFIG_EXT2_FS_POSIX_ACL

06 ei->i_acl = EXT2_ACL_NOT_CACHED;

07 ei->i_default_acl = EXT2_ACL_NOT_CACHED;

08#endif

09 ei->i_block_alloc_info = NULL;

10 ei->vfs_inode.i_version = 1;

11 return &ei->vfs_inode;

12}

第1行定义一个索引节点的内存数据结构

第2行使用kmem_cache_alloc函数分配空间。

第5-7行如果宏CONFIG_EXT2_FS_POSIX_ACL为真,则为文件控制列表的字段赋值

第11行返回内存索引节点的vfs_inode字段。

=======================================

static void ext2_destroy_inode(struct inode *inode)

{

kmem_cache_free(ext2_inode_cachep, EXT2_I(inode));

}

释放分配的空间

=====================================

int ext2_write_inode(struct inode *inode, int wait)

{

return ext2_update_inode(inode, wait);

}

static int ext2_update_inode(struct inode * inode, int do_sync)

{

01 struct ext2_inode_info *ei = EXT2_I(inode);

02 struct super_block *sb = inode->i_sb;

03 ino_t ino = inode->i_ino;

04 uid_t uid = inode->i_uid;

05 gid_t gid = inode->i_gid;

06 struct buffer_head * bh;

07 struct ext2_inode * raw_inode = ext2_get_inode(sb, ino, &bh);

08 int n;

09 int err = 0;

第1行定义一个内存索引节点的描述符并给它赋值

第2行对超级块进行赋值

第3-6行分别取出索引节点的几个字段

第7行定义一个磁盘索引节点并给它赋值。

11 if (IS_ERR(raw_inode))

12 return -EIO;

13 if (ei->i_state & EXT2_STATE_NEW)

14 memset(raw_inode, 0, EXT2_SB(sb)->s_inode_size);

15

16 ext2_get_inode_flags(ei);

17 raw_inode->i_mode = cpu_to_le16(inode->i_mode);

18 if (!(test_opt(sb, NO_UID32))) {

19 raw_inode->i_uid_low = cpu_to_le16(low_16_bits(uid));

20 raw_inode->i_gid_low = cpu_to_le16(low_16_bits(gid));

21 if (!ei->i_dtime) {

22 raw_inode->i_uid_high = cpu_to_le16(high_16_bits(uid));

23 raw_inode->i_gid_high = cpu_to_le16(high_16_bits(gid));

24 } else {

25 raw_inode->i_uid_high = 0;

26 raw_inode->i_gid_high = 0;

27 }

28 } else {

29 raw_inode->i_uid_low = cpu_to_le16(fs_high2lowuid(uid));

30 raw_inode->i_gid_low = cpu_to_le16(fs_high2lowgid(gid));

31 raw_inode->i_uid_high = 0;

32 raw_inode->i_gid_high = 0;

33 }

34 raw_inode->i_links_count = cpu_to_le16(inode->i_nlink);

35 raw_inode->i_size = cpu_to_le32(inode->i_size);

36 raw_inode->i_atime = cpu_to_le32(inode->i_atime.tv_sec);

37 raw_inode->i_ctime = cpu_to_le32(inode->i_ctime.tv_sec);

38 raw_inode->i_mtime = cpu_to_le32(inode->i_mtime.tv_sec);

39

40 raw_inode->i_blocks = cpu_to_le32(inode->i_blocks);

41 raw_inode->i_dtime = cpu_to_le32(ei->i_dtime);

42 raw_inode->i_flags = cpu_to_le32(ei->i_flags);

43 raw_inode->i_faddr = cpu_to_le32(ei->i_faddr);

44 raw_inode->i_frag = ei->i_frag_no;

45 raw_inode->i_fsize = ei->i_frag_size;

46 raw_inode->i_file_acl = cpu_to_le32(ei->i_file_acl);

初始化磁盘的索引节点,使用内存中的索引节点来进行初始化。

47 if (!S_ISREG(inode->i_mode))

48 raw_inode->i_dir_acl = cpu_to_le32(ei->i_dir_acl);

49 else {

50 raw_inode->i_size_high = cpu_to_le32(inode->i_size >> 32);

51 if (inode->i_size > 0x7fffffffULL) {

52 if (!EXT2_HAS_RO_COMPAT_FEATURE(sb,

53 EXT2_FEATURE_RO_COMPAT_LARGE_FILE) ||

54 EXT2_SB(sb)->s_es->s_rev_level ==

55 cpu_to_le32(EXT2_GOOD_OLD_REV)) {

59 lock_kernel();

60 ext2_update_dynamic_rev(sb);

61 EXT2_SET_RO_COMPAT_FEATURE(sb,

62 EXT2_FEATURE_RO_COMPAT_LARGE_FILE);

63 unlock_kernel();

64 ext2_write_super(sb);

65 }

66 }

67 }

对索引节点的是文件,目录等。然后对它的文件控制列表属性进行设置。

69 raw_inode->i_generation = cpu_to_le32(inode->i_generation);

70 if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) {

71 if (old_valid_dev(inode->i_rdev)) {

72 raw_inode->i_block[0] =

73 cpu_to_le32(old_encode_dev(inode->i_rdev));

74 raw_inode->i_block[1] = 0;

75 } else {

76 raw_inode->i_block[0] = 0;

77 raw_inode->i_block[1] =

78 cpu_to_le32(new_encode_dev(inode->i_rdev));

79 raw_inode->i_block[2] = 0;

80 }

81 } else for (n = 0; n < EXT2_N_BLOCKS; n++)

82 raw_inode->i_block
= ei->i_data
;

83 mark_buffer_dirty(bh);

84 if (do_sync) {

85 sync_dirty_buffer(bh);

86 if (buffer_req(bh) && !buffer_uptodate(bh)) {

87 printk ("IO error syncing ext2 inode [%s:%08lx]\n",

88 sb->s_id, (unsigned long) ino);

89 err = -EIO;

90 }

91 }

92 ei->i_state &= ~EXT2_STATE_NEW;

93 brelse (bh);

94 return err;

95}

第83行使用mark_buffer_dirty函数标记缓存区头部为脏

第93行减小对缓存区的引用。

=======================================

void ext2_delete_inode (struct inode * inode)

{

01 truncate_inode_pages(&inode->i_data, 0);

02

03 if (is_bad_inode(inode))

04 goto no_delete;

05 EXT2_I(inode)->i_dtime = get_seconds();

06 mark_inode_dirty(inode);

07 ext2_update_inode(inode, inode_needs_sync(inode));

08

09 inode->i_size = 0;

10 if (inode->i_blocks)

11 ext2_truncate (inode);

12 ext2_free_inode (inode);

13

14 return;

15no_delete:

16 clear_inode(inode);

17}

第3行对判断节点是否为错误的节点

第5行对节点的时间字段进行赋值

第6行标识节点为脏节点

第7行更新这个节点

第12行释放这个节点。

=======================================

static void ext2_put_super (struct super_block * sb)

{

01 int db_count;

02 int i;

03 struct ext2_sb_info *sbi = EXT2_SB(sb);

04 ext2_xattr_put_super(sb);

05 if (!(sb->s_flags & MS_RDONLY)) {

06 struct ext2_super_block *es = sbi->s_es;

08 es->s_state = cpu_to_le16(sbi->s_mount_state);

09 ext2_sync_super(sb, es);

10 }

11 db_count = sbi->s_gdb_count;

12 for (i = 0; i < db_count; i++)

13 if (sbi->s_group_desc[i])

14 brelse (sbi->s_group_desc[i]);

15 kfree(sbi->s_group_desc);

16 kfree(sbi->s_debts);

17 percpu_counter_destroy(&sbi->s_freeblocks_counter);

18 percpu_counter_destroy(&sbi->s_freeinodes_counter);

19 percpu_counter_destroy(&sbi->s_dirs_counter);

20 brelse (sbi->s_sbh);

21 sb->s_fs_info = NULL;

22 kfree(sbi->s_blockgroup_lock);

23 kfree(sbi);

24 return;

25}

第3行对内存中的超级块进行赋值,使用EXT2_SB宏。

第4行当文件系统被卸载的时候,会被调用

第5行判断超级块的标志

第9行同步磁盘的超级块和内存中的超级块。

第12-14行循环进行减少sbi->s_group_desc[i]的引用

第15-23行分别释放空间。

======================================

void ext2_write_super (struct super_block * sb)

{

01 struct ext2_super_block * es;

02 lock_kernel();

03 if (!(sb->s_flags & MS_RDONLY)) {

04 es = EXT2_SB(sb)->s_es;

06 if (es->s_state & cpu_to_le16(EXT2_VALID_FS)) {

07 ext2_debug ("setting valid to 0\n");

08 es->s_state &= cpu_to_le16(~EXT2_VALID_FS);

09 es->s_free_blocks_count = cpu_to_le32(ext2_count_free_blocks(sb));

10 es->s_free_inodes_count = cpu_to_le32(ext2_count_free_inodes(sb));

11 es->s_mtime = cpu_to_le32(get_seconds());

12 ext2_sync_super(sb, es);

13 } else

14 ext2_commit_super (sb, es);

15 }

16 sb->s_dirt = 0;

17 unlock_kernel();

18}

第3行对超级块的标识的判断

第6-11行分别对磁盘超级块赋值

第12行同步磁盘超级块和内存中的超级块的值
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: