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行同步磁盘超级块和内存中的超级块的值
.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行同步磁盘超级块和内存中的超级块的值
相关文章推荐
- EXT2的文件系统装载之内核函数ext2_fill_super分析
- ext2文件系统源代码之super.c
- EXT2文件系统笔记之ext2_fill_super
- EXT2的文件系统装载之内核函数ext2_fill_super分析
- EXT2 文件系统
- 认识EXT2文件系统
- Windows 7下读写Ext2/Ext3/Ext4文件系统
- ext2文件系统
- ext2文件系统错误
- Android文件系统的结构及目录用途、操作方法
- 戏说文件系统之ext2【上】
- (十三)linux文件系统详解(基于ext2文件系统)【转】
- 恢复ext2文件系统中的被删除文件--debugfs
- Bad magic number in super-block 当尝试打开 /dev/sda3 时 找不到有效的文件系统超级块.
- Linux ext2, ext3, ext4 文件系统解读[5]
- EXT2的文件操作方法
- 利用io端口读ext2文件系统
- ext2文件系统源代码之xattr_trusted.c
- Linux初学——EXT2文件系统
- (ext2,ext3,reiserfs,xfs,jfs)文件系统的性能测试