ext2文件系统的super操作方法

来源:互联网 发布:马云多少钱收购淘宝 编辑:程序博客网 时间:2024/06/07 02:16
 
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[n] = ei->i_data[n];
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行同步磁盘超级块和内存中的超级块的值
原创粉丝点击