iis服务器助手广告广告
返回顶部
首页 > 资讯 > 精选 >转 Ext2 文件系统的硬盘布局
  • 151
分享到

转 Ext2 文件系统的硬盘布局

2023-06-04 21:06:17 151人浏览 泡泡鱼
摘要

本文主要讲述 linux 上比较流行的 ext2 文件系统在硬盘分区上的详细布局情况。Ext2 文件系统加上日志支持的下一个版本是 ext3 文件系统,它和 ext2 文件系统在硬盘布局上是一样的,其差别仅仅是 ext3 文件系统在硬盘上多

本文主要讲述 linux 上比较流行的 ext2 文件系统在硬盘分区上的详细布局情况。Ext2 文件系统加上日志支持的下一个版本是 ext3 文件系统,它和 ext2 文件系统在硬盘布局上是一样的,其差别仅仅是 ext3 文件系统在硬盘上多出了一个特殊的 inode(可以理解为一个特殊文件),用来记录文件系统的日志,也即所谓的 journal。由于本文并不讨论日志文件,所以本文的内容对于 ext2 和 ext3 都是适用的。

[@more@]

前言

本文的资料来源是 Linux 内核中 ext3 文件系统的源代码。为了便于读者查阅源代码,本文中一些关键的技术词汇都使用了内核源代码中所使用的英语单词,而没有使用相应的中文翻译。(这种方法是否恰当,还请读者朋友们指教。)


转 Ext2 文件系统的硬盘布局
转 Ext2 文件系统的硬盘布局
转 Ext2 文件系统的硬盘布局
转 Ext2 文件系统的硬盘布局回页首


粗略的描述

对于 ext2 文件系统来说,硬盘分区首先被划分为一个个的 block,一个 ext2 文件系统上的每个 block 都是一样大小的,但是对于不同的 ext2 文件系统,block 的大小可以有区别。典型的 block 大小是 1024 bytes 或者 4096 bytes。这个大小在创建 ext2 文件系统的时候被决定,它可以由系统管理员指定,也可以由文件系统的创建程序根据硬盘分区的大小,自动选择一个较合理的值。这些 blocks 被聚在一起分成几个大的 block group。每个 block group 中有多少个 block 是固定的。

每个 block group 都相对应一个 group descriptor,这些 group descriptor 被聚在一起放在硬盘分区的开头部分,跟在 super block 的后面。所谓 super block,我们下面还要讲到。在这个 descriptor 当中有几个重要的 block 指针。我们这里所说的 block 指针,就是指硬盘分区上的 block 号数,比如,指针的值为 0,我们就说它是指向硬盘分区上的 block 0;指针的值为 1023,我们就说它是指向硬盘分区上的 block 1023。我们注意到,一个硬盘分区上的 block 计数是从 0 开始的,并且这个计数对于这个硬盘分区来说是全局性质的。

在 block group 的 group descriptor 中,其中有一个 block 指针指向这个 block group 的 block bitmap,block bitmap 中的每个 bit 表示一个 block,如果该 bit 为 0,表示该 block 中有数据,如果 bit 为 1,则表示该 block 是空闲的。注意,这个 block bitmap 本身也正好只有一个 block 那么大小。假设 block 大小为 S bytes,那么 block bitmap 当中只能记载 8*S 个 block 的情况(因为一个 byte 等于 8 个 bits,而一个 bit 对应一个 block)。这也就是说,一个 block group 最多只能有 8*S*S bytes 这么大。

在 block group 的 group descriptor 中另有一个 block 指针指向 inode bitmap,这个 bitmap 同样也是正好有一个 block 那么大,里面的每一个 bit 相对应一个 inode。硬盘上的一个 inode 大体上相对应于文件系统上的一个文件或者目录。关于 inode,我们下面还要进一步讲到。

在 block group 的 descriptor 中另一个重要的 block 指针,是指向所谓的 inode table。这个 inode table 就不止一个 block 那么大了。这个 inode table 就是这个 block group 中所聚集到的全部 inode 放在一起形成的。

一个 inode 当中记载的最关键的信息,是这个 inode 中的用户数据存放在什么地方。我们在前面提到,一个 inode 大体上相对应于文件系统中的一个文件,那么用户文件的内容存放在什么地方,这就是一个 inode 要回答的问题。一个 inode 通过提供一系列的 block 指针,来回答这个问题。这些 block 指针指向的 block,里面就存放了用户文件的内容。

2.1 回顾

现在我们回顾一下。硬盘分区首先被分为好多个 block。这些 block 聚在一起,被分成几组,也就是 block group。每个 block group 都有一个 group descriptor。所有这些 descriptor 被聚在一起,放在硬盘分区的开头部分,跟在 super block 的后面。从 group descriptor 我们可以通过 block 指针,找到这个 block group 的 inode table 和 block bitmap 等等。从 inode table 里面,我们就可以看到一个个的 inode 了。从一个 inode,我们通过它里面的 block 指针,就可以进而找到存放用户数据的那些 block。我们还要提一下,block 指针不是可以到处乱指的。一个 block group 的 block bitmap 和 inode bitmap 以及 inode table,都依次存放在这个 block group 的开头部分,而那些存放用户数据的 block 就紧跟在它们的后面。一个 block group 结束后,另一个 block group 又跟着开始。


转 Ext2 文件系统的硬盘布局
转 Ext2 文件系统的硬盘布局
转 Ext2 文件系统的硬盘布局
转 Ext2 文件系统的硬盘布局回页首


详细的布局情况

3.1 Super Block

所谓 ext2 文件系统的 super block,就是硬盘分区开头(开头的第一个 byte 是 byte 0)从 byte 1024 开始往后的一部分数据。由于 block size 最小是 1024 bytes,所以 super block 可能是在 block 1 中(此时 block 的大小正好是 1024 bytes),也可能是在 block 0 中。

硬盘分区上 ext3 文件系统的 super block 的详细情况如下。其中 __u32 是表示 unsigned 不带符号的 32 bits 的数据类型,其余类推。这是 Linux 内核中所用到的数据类型,如果是开发用户空间(user-space)的程序,可以根据具体计算机平台的情况,用 unsigned long 等等来代替。下面列表中关于 fragments 的部分可以忽略,Linux 上的 ext3 文件系统并没有实现 fragments 这个特性。另外要注意,ext3 文件系统在硬盘分区上的数据是按照 Intel 的 Little-endian 格式存放的,如果是在 PC 以外的平台上开发 ext3 相关的程序,要特别注意这一点。如果只是在 PC 上做开发,倒不用特别注意。

struct ext3_super_block { __u32 s_inodes_count;             __u32 s_blocks_count;             __u32 s_r_blocks_count;           __u32 s_free_blocks_count;  __u32 s_free_inodes_count;        __u32 s_first_data_block;         __u32 s_log_block_size;           __s32 s_log_frag_size;      __u32 s_blocks_per_group;         __u32 s_frags_per_group;          __u32 s_inodes_per_group;         __u32 s_mtime;              __u32 s_wtime;                    __u16 s_mnt_count;                __s16 s_max_mnt_count;            __u16 s_magic;                    __u16 s_state;                    __u16 s_errors;                   __u16 s_minor_rev_level;    __u32 s_lastcheck;                __u32 s_checkinterval;            __u32 s_creator_os;               __u32 s_rev_level;          __u16 s_def_resuid;               __u16 s_def_resgid;               __u32 s_first_ino;                __u16 s_inode_size;               __u16 s_block_group_nr;           __u32 s_feature_compat;     __u32 s_feature_incompat;         __u32 s_feature_ro_compat;  __u8  s_uuid[16];           char  s_volume_name[16];    char  s_last_mounted[64];   __u32 s_alGorithm_usage_bitmap;        __u8  s_prealloc_blocks;               __u8  s_prealloc_dir_blocks;           __u16 s_padding1;                __u8  s_journal_uuid[16];  __u32 s_journal_inum;            __u32 s_journal_dev;             __u32 s_last_orphan;       __u32 s_reserved[197];    };

我们可以看到,super block 一共有 1024 bytes 那么大。在 super block 中,我们第一个要关心的字段是 magic 签名,对于 ext2 和 ext3 文件系统来说,这个字段的值应该正好等于 0xEF53。如果不等的话,那么这个硬盘分区上肯定不是一个正常的 ext2 或 ext3 文件系统。从这里,我们也可以估计到,ext2 和 ext3 的兼容性一定是很强的,不然的话,Linux 内核的开发者应该会为 ext3 文件系统另选一个 magic 签名才对。

在 super block 中另一个重要的字段是 s_log_block_size。从这个字段,我们可以得出真正的 block 的大小。我们把真正 block 的大小记作 B,B = 1 << (s_log_block_size + 10),单位是 bytes。举例来说,如果这个字段是 0,那么 block 的大小就是 1024 bytes,这正好就是最小的 block 大小;如果这个字段是 2,那么 block 大小就是 4096 bytes。从这里我们就得到了 block 的大小这一非常重要的数据。

3.2 Group Descriptors

我们继续往下,看跟在 super block 后面的一堆 group descriptors。首先注意到 super block 是从 byte 1024 开始,一共有 1024 bytes 那么大。而 group descriptors 是从 super block 后面的第一个 block 开始。也就是说,如果 super block 是在 block 0,那么 group descriptors 就是从 block 1 开始;如果 super block 是在 block 1,那么 group descriptors 就是从 block 2 开始。因为 super block 一共只有 1024 bytes 那么大,所以不会超出一个 block 的边界。如果一个 block 正好是 1024 bytes 那么大的话,我们看到 group descriptors 就是紧跟在 super block 后面的了,没有留一点空隙。而如果一个 block 是 4096 bytes 那么大的话,那么在 group descriptors(从 byte 4096 开始)和 super block 的结尾之间,就有一定的空隙(4096 - 2048 bytes)。

那么硬盘分区上一共有多少个 block group,或者说一共有多少个 group descriptors,这我们要在 super block 中找答案。super block 中的 s_blocks_count 记录了硬盘分区上的 block 的总数,而 s_blocks_per_group 记录了每个 group 中有多少个 block。显然,文件系统上的 block groups 数量,我们把它记作 G,G = (s_blocks_count - s_first_data_block - 1) / s_blocks_per_group + 1。为什么要减去 s_first_data_block,因为 s_blocks_count 是硬盘分区上全部的 block 的数量,而在 s_first_data_block 之前的 block 是不归 block group 管的,所以当然要减去。最后为什么又要加一,这是因为尾巴上可能多出来一些 block,这些 block 我们要把它划在一个相对较小的 group 里面。

注意,硬盘分区上的所有这些 group descriptors 要能塞在一个 block 里面。也就是说 groups_count * descriptor_size 必须小于等于 block_size。

知道了硬盘分区上一共有多少个 block group,我们就可以把这么多个 group descriptors 读出来了。先来看看 group descriptor 是什么样子的。

struct ext3_group_desc{ __u32 bg_block_bitmap;       __u32 bg_inode_bitmap;       __u32 bg_inode_table;        __u16 bg_free_blocks_count;  __u16 bg_free_inodes_count;  __u16 bg_used_dirs_count;    __u16 bg_pad;                __u32 bg_reserved[3];       };

每个 group descriptor 是 32 bytes 那么大。从上面,我们看到了三个关键的 block 指针,这三个关键的 block 指针,我们已经在前面都提到过了。

3.3 Inode

前面都准备好了以后,我们现在终于可以开始读取文件了。首先要读的,当然是文件系统的根目录。注意,这里所谓的根目录,是相对于这一个文件系统或者说硬盘分区而言的,它并不一定是整个 Linux 操作系统上的根目录。这里的这个 root 目录存放在一个固定的 inode 中,这就是文件系统上的 inode 2。需要提到 inode 计数同 block 计数一样,也是全局性质的。这里需要特别注意的是,inode 计数是从 1 开始的,而前面我们提到过 block 计数是从 0 开始,这个不同在开发程序的时候要特别留心。(这一奇怪的 inode 计数方法,曾经让本文作者大伤脑筋。)

那么,我们先来看一下得到一个 inode 号数以后,怎样读取这个 inode 中的用户数据。在 super block 中有一个字段 s_inodes_per_group 记载了每个 block group 中有多少个 inode。用我们得到的 inode 号数除以 s_inodes_per_group,我们就知道了我们要的这个 inode 是在哪一个 block group 里面,这个除法的余数也告诉我们,我们要的这个 inode 是这个 block group 里面的第几个 inode;然后,我们可以先找到这个 block group 的 group descriptor,从这个 descriptor,我们找到这个 group 的 inode table,再从 inode table 找到我们要的第几个 inode,再以后,我们就可以开始读取 inode 中的用户数据了。

这个公式是这样的:block_group = (ino - 1) / s_inodes_per_group。这里 ino 就是我们的 inode 号数。而 offset = (ino - 1) % s_inodes_per_group,这个 offset 就指出了我们要的 inode 是这个 block group 里面的第几个 inode。

找到这个 inode 之后,我们来具体的看看 inode 是什么样的。

struct ext3_inode { __u16 i_mode;     __u16 i_uid;      __u32 i_size;     __u32 i_atime;    __u32 i_ctime;    __u32 i_mtime;    __u32 i_dtime;    __u16 i_gid;      __u16 i_links_count;           __u32 i_blocks;                __u32 i_flags;                 __u32 l_i_reserved1;           __u32 i_block[EXT3_N_BLOCKS];  __u32 i_generation;            __u32 i_file_acl;              __u32 i_dir_acl;               __u32 i_faddr;                 __u8  l_i_frag;                __u8  l_i_fsize;               __u16 i_pad1;                  __u16 l_i_uid_high;            __u16 l_i_gid_high;            __u32 l_i_reserved2;          };

我们看到在 inode 里面可以存放 EXT3_N_BLOCKS(= 15)这么多个 block 指针。用户数据就从这些 block 里面获得。15 个 blocks 不一定放得下全部的用户数据,在这里 ext3 文件系统采取了一种分层的结构。这组 15 个 block 指针的前 12 个是所谓的 direct blocks,里面直接存放的就是用户数据。第 13 个 block,也就是所谓的 indirect block,里面存放的全部是 block 指针,这些 block 指针指向的 block 才被用来存放用户数据。第 14 个 block 是所谓的 double indirect block,里面存放的全是 block 指针,这些 block 指针指向的 block 也被全部用来存放 block 指针,而这些 block 指针指向的 block,才被用来存放用户数据。第 15 个 block 是所谓的 triple indirect block,比上面说的 double indirect block 有多了一层 block 指针。作为练习,读者可以计算一下,这样的分层结构可以使一个 inode 中最多存放多少字节的用户数据。(计算所需的信息是否已经足够?还缺少哪一个关键数据?)

一个 inode 里面实际有多少个 block,这是由 inode 字段 i_size 再通过计算得到的。i_size 记录的是文件或者目录的实际大小,用它的值除以 block 的大小,就可以得出这个 inode 一共占有几个 block。注意上面的 i_blocks 字段,粗心的读者可能会以为是这一字段记录了一个 inode 中实际用到多少个 block,其实不是的。那么这一字段是干什么用的呢,读者朋友们可以借这个机会,体验一下阅读 Linux 内核源代码的乐趣。;-)

3.4 文件系统的目录结构

现在我们已经可以读取 inode 的内容了,再往后,我们将要读取文件系统上文件和目录的内容。读取文件的内容,只要把相应的 inode 的内容全部读出来就行了;而目录只是一种固定格式的文件,这个文件按照固定的格式记录了目录中有哪些文件,以及它们的文件名,和 inode 号数等等。

struct ext3_dir_entry_2 { __u32 inode;     __u16 rec_len;   __u8  name_len;  __u8  file_type; char  name[EXT3_NAME_LEN]; };

上面用到的 EXT3_NAME_LEN 是 255。注意,在硬盘分区上的 dir entry 不是固定长度的,每个 dir entry 的长度由上面的 rec_len 字段记录。


转 Ext2 文件系统的硬盘布局
转 Ext2 文件系统的硬盘布局
转 Ext2 文件系统的硬盘布局
转 Ext2 文件系统的硬盘布局回页首


小结

有了以上的这些信息,我们就可以读取一个 ext3 文件系统的全部内容了。如果读者有 windows 驱动程序开发的经验,从本文的信息,开发一个 Windows 下只读的 ext3 文件系统是可能的。但是要想又读又写,那还需要了解 Ext3 的日志文件的结构,而本文限于篇幅,并没有包括这方面的内容。



参考资料

1 Remy Card, Theodore Ts'o, Stephen Tweedie, Design and Implementation of the Second Extended Filesystem, Http://WEB.mit.edu/tytso/www/linux/ext2intro.html

2 Linux Kernel 2.4.18 Source Code, http://lxr.linux.no/source/fs/ext3/

--结束END--

本文标题: 转 Ext2 文件系统的硬盘布局

本文链接: https://www.lsjlt.com/news/239762.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 转 Ext2 文件系统的硬盘布局
    本文主要讲述 Linux 上比较流行的 ext2 文件系统在硬盘分区上的详细布局情况。Ext2 文件系统加上日志支持的下一个版本是 ext3 文件系统,它和 ext2 文件系统在硬盘布局上是一样的,其差别仅仅是 ext3 文件系统在硬盘上多...
    99+
    2023-06-04
  • linux如何修复/检查hda1磁盘上ext2文件系统的完整性
    ...
    99+
    2024-04-02
  • 云硬盘数据盘扩展分区及文件系统(Windows)
    在Windows系统中,云硬盘数据盘的扩展分区及文件系统可以通过以下步骤完成:1. 打开计算机管理工具。可以通过在开始菜单中搜索“计...
    99+
    2023-09-21
    Windows
  • 如何找回文件系统变没硬盘的数据
    文件系统变没说明这个盘的文件系统结构损坏了。在平时如果数据不重要,那么可以直接格式化就能用了。但是有的时候里面的数据很重要,那么就必须先恢复出数据再格式化。具体恢复方法可以看正文了解(不格式化的恢复方法) ...
    99+
    2024-04-02
  • 云服务器挂载硬盘系统盘放什么文件夹
    当你在云服务器上挂载硬盘时,系统盘通常用于安装操作系统和应用程序,而数据通常存储在挂载的硬盘上。因此,你应该将数据文件存储在挂载的硬盘上,而不是系统盘上。 在 Linux 系统中,通常将数据文件存储在 /data 目录下。你可以在挂载硬盘...
    99+
    2023-10-27
    文件夹 系统盘 硬盘
  • linux如何在hda1分区创建一个linux ext2的文件系统
    ...
    99+
    2024-04-02
  • 苹果mac系统怎么复制文件到移动硬盘?
    苹果因为系统稳定,常被用作办公设备。习惯了windows系统,初次使用苹果发现在苹果电脑中查找、复制文件并没有在windows中方便。那么,苹果系统复制文件在哪里?在苹果电脑我们要复制文件,需要通过【访达】找到文件所在位置。苹果系统怎么复制...
    99+
    2023-09-04
    macos windows microsoft
  • 如何转移Windows7系统C盘的用户文件夹
    Windows7的用户文件夹默认所在位置是系统盘(通常是C盘)下的“\Users”目录之内。而随着Windows里安装的软件越来越多,就会有越来越多的“用户生成文件”被保...
    99+
    2023-06-01
    Windows7 C盘 C 系统 文件夹 用户
  • 如何在Linux 中获取硬盘分区或文件系统的UUID
    本篇文章为大家展示了如何在Linux 中获取硬盘分区或文件系统的UUID,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。作为一个 Linux 系统管理员,你应该知道如何去查看分区的...
    99+
    2023-06-05
  • Linux系统如何查看硬盘大小等硬件信息
    这篇“Linux系统如何查看硬盘大小等硬件信息”文章,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要参考一下,对于“Linux系统如何查看硬盘大小等硬件信息”,小编整理了以下知识点,请大家跟着小编的步伐一步一步的慢慢...
    99+
    2023-06-28
  • 云计算学习路线教程大纲课件:EXT2/3/4文件系统
    云计算学习路线教程大纲课件:EXT2/3/4文件系统:索引式文件系统====================================================================================Ex...
    99+
    2023-06-04
  • Linux中如何管理EXT2、 EXT3和EXT4文件系统健康状况
    小编给大家分享一下Linux中如何管理EXT2、 EXT3和EXT4文件系统健康状况,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!怎么去查看 EXT2/EXT3/...
    99+
    2023-06-16
  • 【Linux】理解文件系统——软硬链接
    我们之前讨论的都是进程和被打开文件的关系,而如果一个文件是没有被打开呢?没有被打开的文件操作系统如何管理? 没有被打开的文件在磁盘上,所以磁盘上有大量的文件,这些文件要被静态管理起来,方便我们随时打开,而做这部分工作的我们称为文件系统。 ...
    99+
    2023-08-18
    linux 运维 服务器
  • 阿里云服务器硬盘会坏吗怎么修复系统文件
    格式化和重新分区:硬盘如果坏掉了,通常需要进行格式化和重新分区。在这种情况下,建议您选择一种新的磁盘格式,这样可以更容易地修复坏掉的硬盘。在重新分区时,您需要确保分区表没有损坏,并且分区的位置正确。如果您不确定如何正确地分区,建议您咨询阿...
    99+
    2023-10-27
    阿里 硬盘 服务器
  • Linux | Ubuntu20.04系统使用命令从移动硬盘/U盘拷贝文件到服务器上
    *确认自己移动硬盘、U盘的格式,本文为exfat格式 STEP1:把移动硬盘插到Ubuntu系统的主机上 查看disk默认位置 #查看移动硬盘/U盘在哪个位置命令fdisk -l#查询后出现了包含电脑系统的所有硬盘 查看最后的位置,...
    99+
    2023-10-26
    linux Powered by 金山文档
  • 如何查看win10系统的硬盘格式
    这篇文章将为大家详细讲解有关如何查看win10系统的硬盘格式,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。方法/步骤:方法一:首先打开win10电脑的“控制面板”界面,可以直接进行搜索或者在“开始菜单”中...
    99+
    2023-06-27
  • 微软官方公布Windows 10 系统和硬件要求
    微软已经公布了Windows 10运行硬件要求:处理器:1GHz或更快的处理器或SoC,内存:1GB(32-bit)或2 GB(64-bit),硬盘空间:16 GB(32-bit),20 GB(64-bit),显卡:Di...
    99+
    2023-06-15
    微软 Windows 10 硬件 系统 官方 要求
  • 最简单的win7系统硬盘分区图文方法介绍
    新买回来一台预装Win7系统的电脑,发现硬盘只有C盘一个分区,这样用起来太不方便了,需要给硬盘重新分区才行。一提到分区,很多用户可能首先会想到PQ这样的分区软件,其实在Win7中,不需要使用任何第三方软件,也不需要进入命...
    99+
    2023-05-26
    win7 系统硬盘分 图文 硬盘分区 系统 方法
  • 如何节约Vista系统的硬盘空间
    这篇文章主要讲解了“如何节约Vista系统的硬盘空间”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“如何节约Vista系统的硬盘空间”吧!一、关闭系统还原  “系统还原”可以帮人们在系统有问题...
    99+
    2023-06-14
  • Win7系统如何将桌面文件转移到D盘节省C盘空间
    1、在C盘中打开quo;文件夹;2、在“桌面”文件夹上点击右键,选择“属性”,在“桌面属性”对话框框的“位置”选项卡上,点击...
    99+
    2023-06-15
    Win7 桌面文件 D盘 C 系统
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作