Ext2的索引节点对象

来源:互联网 发布:ios post请求参数json 编辑:程序博客网 时间:2024/05/16 12:49

上一篇博文我们详细分析了VFS如何将具体文件系统ext2的超级快对象缓存到内存中,主要是利用了ext2_sb_info数据结构。ext2_fill_super函数最后的时候,会将传入该函数的super_block类型的参数sb赋予以下的值:
      sb->s_op = &ext2_sops;

 

其中,ext2_sops是将super_block的super_operations初始化以下方法的集合:
static struct super_operations ext2_sops = {
      .alloc_inode      = ext2_alloc_inode,
      .destroy_inode      = ext2_destroy_inode,
      .read_inode      = ext2_read_inode,
      .write_inode      = ext2_write_inode,
      .put_inode      = ext2_put_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
};


本篇博文,我们来讨论VFS如何将ext2的索引节点缓存到内存中。

 

在打开文件时,要执行路径名查找。对于不在目录项高速缓存内的路径名元素,会创建一个新的目录项对象和索引节点对象(参见“标准路经名查找”博文)。当VFS访问一个Ext2磁盘索引节点时,它会创建一个ext2_inode_info类型的索引节点描述符:
struct ext2_inode_info {
      __le32      i_data[15];
      __u32      i_flags;
      __u32      i_faddr;
      __u8      i_frag_no;
      __u8      i_frag_size;
      __u16      i_state;
      __u32      i_file_acl;
      __u32      i_dir_acl;
      __u32      i_dtime;

      /*
       * i_block_group is the number of the block group which contains
       * this file's inode.  Constant across the lifetime of the inode,
       * it is ued for making block allocation decisions - we try to
       * place a file's data blocks near its inode block, and new inodes
       * near to their parent directory's inode.
       */
      __u32      i_block_group;

      /*
       * i_next_alloc_block is the logical (file-relative) number of the
       * most-recently-allocated block in this file.  Yes, it is misnamed.
       * We use this for detecting linearly ascending allocation requests.
       */
      __u32      i_next_alloc_block;

      /*
       * i_next_alloc_goal is the *physical* companion to i_next_alloc_block.
       * it the the physical block number of the block which was most-recently
       * allocated to this file.  This give us the goal (target) for the next
       * allocation when we detect linearly ascending requests.
       */
      __u32      i_next_alloc_goal;
      __u32      i_prealloc_block;
      __u32      i_prealloc_count;
      __u32      i_dir_start_lookup;
#ifdef CONFIG_EXT2_FS_XATTR
      /*
       * Extended attributes can be read independently of the main file
       * data. Taking i_mutex even when reading would cause contention
       * between readers of EAs and writers of regular file data, so
       * instead we synchronize on xattr_sem when reading or changing
       * EAs.
       */
      struct rw_semaphore xattr_sem;
#endif
#ifdef CONFIG_EXT2_FS_POSIX_ACL
      struct posix_acl      *i_acl;
      struct posix_acl      *i_default_acl;
#endif
      rwlock_t i_meta_lock;
      struct inode      vfs_inode;
};

 

该描述符包含下列信息:
- 存放在vfs mode字段的整个VFS索引节点对象;
- ext2磁盘索引节点对象结构中的大部分字段(不保存在VFS索引节点中的那些字段);
- 块组中索引节点对应的索引i_block_group;
- i_next_alloc_block和i_next_alloc_goal分别存放着最近为文件分配的磁盘块的逻辑块号和物理块号;
- i_prealloc_block和i_prealloc_count字段,用于数据块预分配;
- xattr_sem字段,一个读写信号量,允许增强属性与文件数据同时读入;
- i_acl和i_default_acl字段,指向文件的访问控制列表。

 

当处理Ext2文件时,alloc_inode超级块方法是由ext2_alloc_inode()函数实现:

static struct inode *ext2_alloc_inode(struct super_block *sb)
{
      struct ext2_inode_info *ei;
      ei = (struct ext2_inode_info *)kmem_cache_alloc(ext2_inode_cachep, SLAB_KERNEL);
      if (!ei)
            return NULL;
#ifdef CONFIG_EXT2_FS_POSIX_ACL
      ei->i_acl = EXT2_ACL_NOT_CACHED;
      ei->i_default_acl = EXT2_ACL_NOT_CACHED;
#endif
      ei->vfs_inode.i_version = 1;
      return &ei->vfs_inode;
}

 

该函数的实现极其简单,它首先从ext2_inode_cachep slab分配器高速缓存得到一个ext2_inode_info数据结构,然后返回在这个ext2_inode_info数据结构中的索引节点对象的地址ei->vfs_inode。

 

我们看到,跟ext2_sb_info和ext2_group_desc不同,ext2_inode_info根本没有对应的buffer_head字段,也就是说,它只是把ext2_inode的某些字段拷贝进来,对位于磁盘的ext2_inode进行动态缓存,下面,我们就把ext2数据结构的VFS映像做个总结:

 

类型

磁盘数据结构

内存数据结构

缓存模式

Superblock

ext2_super_block

ext2_sb_info

总是缓存

Group descriptor

ext2_group_desc

ext2_group_desc

总是缓存

Block bitmap

Bit array in block

Bit array in buffer

动态缓存

inode bitmap

Bit array in block

Bit array in buffer

动态缓存

inode

ext2_inode

ext2_inode_info

动态缓存

Data block

Array of bytes

VFS buffer

动态缓存

Free inode

ext2_inode

None

从不缓存

Free block

Array of bytes

None

从不缓存