Ext4文件系统解析(三)

1、前言

前文已经讲述了如何根据索引号获取实际的文件内容。对于文件而言,到了这里已经结束了。
但是对于文件夹来说,我们还需要从数据块中解析出对应的数据。
而在文件系统的实现中,文件夹的实际存储方式有着两种不同的实现,经典的线性布局方式和全新的Hash树布局。

2、经典线性布局

线性布局,顾名思义,文件夹的所有子项目以线性方式存储在数据块中。项目的存储结构如下:

#define EXT2_NAME_LEN 255
typedef struct {
  ub32 inode;   /* Inode number */
  ub16 rec_len; /* Directory entry length */
  union {
    struct {
      ub8 name_len; /* Name length */
      ub8 file_type;
    };
    ub16 name_len_v2; /* Name length */
  };
  b8 name[EXT2_NAME_LEN]; /* File name */
} app_ext4_dir_entry;
名称含义
inode索引号
rec_len当前结构的长度
name_len/name_len_v2名称长度
file_type开启file_type特性,用于存储文件类型。
name文件或文件夹名称

在内联文件夹中,通常使用线性布局的方式管理。

3、Hash树布局

Hash树布局是为了提升经典线性布局的性能而诞生的一种解决方案。即在原有的线性布局基础上加上Hash树,从而提升文件系统遍历的性能。
因此Hash树布局在实现上与经典线性布局完全兼容,也就是说,同样可以使用线性布局的方式遍历Hash树管理的文件系统。
Hash树的根节点中,前24个字节用于存储当前目录和父目录的app_ext4_dir_entry结构,紧接其后的就是app_ext4_dx_headerapp_ext4_dx_infoapp_ext4_dx_entry结构。其中app_ext4_dir_entry.indirect_levels代表Hash树的深度。
在其余节点中,前8个字节用于存储空的的app_ext4_dir_entry结构,然后是app_ext4_dx_infoapp_ext4_dx_entry结构。
而最后的叶子节点,就是原本的经典线性布局。

名称含义
app_ext4_dx_info.limit当前entry最大可以管理的app_ext4_dx_entry数,包含自身
app_ext4_dx_info.count实际管理的app_ext4_dx_entry数,包含自身。
app_ext4_dx_info.blockhash = 0 时指向的物理块号
app_ext4_dx_entry.hashhash值
app_ext4_dx_entry.blockhash值对应的块号。
typedef struct {
  ub32 reserved_zero;
  ub8 hash_version; /* 0 now, 1 at release */
  ub8 info_length;  /* 8 */
  ub8 indirect_levels;
  ub8 unused_flags;
} app_ext4_dx_header;

typedef struct {
  ub16 limit;  // maximum number of dx_entries that can follow this header
  ub16 count;  // actual number of dx_entries that can follow this header
  ub32 block;  // The block number that goes with the lowest hash value of
               // this block
} app_ext4_dx_info;

typedef struct {
  ub32 hash;
  ub32 block;
} app_ext4_dx_entry;

bool ReadIndex(const void *entry_data, b32 depth, b32 cur_depth,
                           CIndexList *dirlist) {
  scope::ScopedPtr<b8> dir_entry_data;
  app_ext4_dx_info *dx_info = NULL;
  if (depth) {
    app_ext4_dir_entry *dir_entry = (app_ext4_dir_entry *)entry_data;
    if (dir_entry->inode || dir_entry->name_len) return false;

    dx_info = (app_ext4_dx_info *)((b8 *)dir_entry + 8);
    ++cur_depth;
  } else {
    app_ext4_dx_header *dx_header = (app_ext4_dx_header *)entry_data;
    depth = dx_header->indirect_levels;
    dx_info = (app_ext4_dx_info *)((b8 *)dx_header + dx_header->info_length);
    cur_depth = 0;
  }

  dir_entry_data = new b8[ext_volume_->block_size_];
  app_ext4_dx_entry *dx_entry =
      (app_ext4_dx_entry *)((b8 *)dx_info + sizeof(app_ext4_dx_info));
  for (int i = 0; i < dx_info->count; i++) {
    if (i) {
      if (lseek64(ext_volume_->fd_,
                  block_list_[dx_entry->block] * (b64)ext_volume_->block_size_,
                  SEEK_SET) < 0)
        return false;
    } else {
      if (lseek64(ext_volume_->fd_,
                  block_list_[dx_info->block] * (b64)ext_volume_->block_size_,
                  SEEK_SET) < 0)
        return false;
    }

    if (ext_volume_->block_size_ !=
        read(ext_volume_->fd_, dir_entry_data, ext_volume_->block_size_))
      return false;

    if (depth == cur_depth) {
      if (!ReadLinear(dir_entry_data, dirlist)) return false;
    } else {
      if (!ReadIndex(dir_entry_data, depth, cur_depth, dirlist)) return false;
    }

    if (i)
      dx_entry =
          (app_ext4_dx_entry *)((b8 *)dx_entry + sizeof(app_ext4_dx_entry));
  }

  return true;
}


if (inode_info_->i_flags & EXT4_INDEX_FL) {
  if (!ReadIndex((b8 *)dir_entry_data + 24, 0, 0, dirlist)) return false;

  break;
}
  • 9
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值