当前位置:首页 > 公众号精选 > Linux阅码场
[导读]本文以ext2文件系统为例来剖析一个真实的文件系统如何查找文件,这对于深入理解文件系统至关重要。1.准备文件系统镜像所用工具:dd、mkfs.ext2、hexdump、dumpe2fs、mount等工具1)制作100k大小镜像文件$ dd if=/dev/zero of=ext2...

本文以ext2文件系统为例来剖析一个真实的文件系统如何查找文件,这对于深入理解文件系统至关重要。

1.准备文件系统镜像

所用工具:dd、mkfs.ext2、hexdump、dumpe2fs、mount等工具

1)制作100k大小镜像文件

$ dd if=/dev/zero of=ext2.img bs=1k count=100
记录了100 0 的读入
记录了100 0 的写出
102400 bytes (102 kB, 100 KiB) copied, 0.00125457 s, 81.6 MB/s
2)格式化为ext2文件系统格式

$ mkfs.ext2 ext2.img
mke2fs 1.44.1 (24-Mar-2018)
丢弃设备块: 完成                            
创建含有 100 个块(每块 1k)和 16 个inode的文件系统

正在分配组表: 完成                            
正在写入inode表: 完成                            
写入超级块和文件系统账户统计信息: 已完成
3)查看文件系统信息

$ dumpe2fs ext2.img 
dumpe2fs 1.44.1 (24-Mar-2018)
Filesystem volume name:   
Last mounted on:          <not available>
Filesystem UUID:          3680e1d5-7f58-4324-9cbd-c7d382f0c3df
Filesystem magic number:  0xEF53
Filesystem revision #:    1 (dynamic)
Filesystem features:      ext_attr resize_inode dir_index filetype sparse_super large_file
Filesystem flags:         signed_directory_hash 
Default mount options:    user_xattr acl
Filesystem state:         clean
Errors behavior:          Continue
Filesystem OS type:       Linux
Inode count:              16
Block count:              100
Reserved block count:     5
Free blocks:              79
Free inodes:              5
First block:              1
Block size:               1024
Fragment size:            1024
Blocks per group:         8192
Fragments per group:      8192
Inodes per group:         16
Inode blocks per group:   2
Filesystem created:       Wed May 26 15:23:33 2021
Last mount time:          n/a
Last write time:          Wed May 26 15:23:33 2021
Mount count:              0
Maximum mount count:      -1
Last checked:             Wed May 26 15:23:33 2021
Check interval:           0 ()
Reserved blocks uid:      0 (user root)
Reserved blocks gid:      0 (group root)
First inode:              11
Inode size:           128
Default directory hash:   half_md4
Directory Hash Seed:      5b0daa29-c2a0-4ab1-b09e-50992d3b070d


组 0:(块 1-99)
  主 超级块位于 1,组描述符位于 2-2
  块位图位于 3 ( 2)
  Inode 位图位于 4 ( 3)
  Inode表位于 5-6 ( 4)
  79 个可用 块,5 个可用inode,2 个目录 
  可用块数: 21-99
  可用inode数: 12-16

这实际是是读取文件系统的超级块和块组描述符信息。我们可以看的创建的文件系统的总体信息:

Filesystem magic number:0xEF53  表示为ext2文件系统Inode count:              16      表示文件系统inode个数为16Block count:              100 表示文件系统块个数为100 Free blocks:              79    表示文件系统空闲块个数为79Free inodes:              5        表示文件系统空闲inode个数为5 First block:              1           第一个数据块编号为1(编号0保留为引导块) Block size:               1024    文件系统块大小为1kBlocks per group:         8192 每个块组8192个块Inodes per group:         16 每个块组个inode Inode blocks per group:   2     每个块组2个inode块 First inode:          11   分配的第一个inode号为11(除根inode外,根inode号为2)Inode size:          128    inode大小为128字节块组的信息(这里只有一个块组)   1 - 99号 超级块块编号为 1     块组描述符块编号为  2 块位图块编号为 3      inode位图块编号为 4
inode表位于5和6块
79 个可用 块,5 个可用inode,2 个目录 (一个为根目录一个为lost found,存放坏块) 可用块数:21-99   可用inode数:12-164)挂载文件系统并创建文件

创建一个挂载点目录:
$  mkdir root_dir

挂载:
$  sudo mount -t ext2 ext2.img  root_dir

查看文件:
$ ls -la
总用量 17
drwxr-xr-x 3 root  root   1024 5月  26 15:23 .
drwxrwxr-x 3 hanch hanch  4096 5月  26 15:28 ..
drwx------ 2 root  root  12288 5月  26 15:23 lost found
可以发现有三个目录:

 .
 ..
 lost found
实际上是根目录的数据块的内容(包含各个目录项)。

下面我们来创建一个目录,目录下创建文件:

$ sudo mkdir dir

$ cd dir/
$ su
# echo hello > test.txt
现在目录树是这样的:

$ tree
.
├── dir
│   └── test.txt
└── lost found [error opening dir]

2 directories, 1 file
后面我们会通过解析文件系统镜像来观察如何查找  /dir/test.txt 文件的

现在关注一下相关的索引节点:

$ cd  dir

$ ls -lai
总用量 3
12 drwxr-xr-x 2 root root 1024 5月  26 15:57 .
 2 drwxr-xr-x 4 root root 1024 5月  26 15:56 ..
13 -rw-r--r-- 1 root root    6 5月  26 15:57 test.txt
可以发现 /dir目录下:当前工作目录下索引节点为12(dir目录的),上一级目录的索引节点为2(根目录),test.txt文件的所有节点为13。记住这几个索引节点后面我们会通过解析文件系统镜像来获得。

2.解析文件系统镜像

1)dump文件系统镜像

$ hexdump -C ext2.img

00000000  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00000400  10 00 00 00 64 00 00 00  05 00 00 00 4f 00 00 00  |....d.......O...|
00000410  05 00 00 00 01 00 00 00  00 00 00 00 00 00 00 00  |................|
00000420  00 20 00 00 00 20 00 00  10 00 00 00 ae f8 ad 60  |. ... .........`|
00000430  ae f8 ad 60 01 00 ff ff  53 ef 00 00 01 00 00 00  |...`....S.......|
00000440  75 f7 ad 60 00 00 00 00  00 00 00 00 01 00 00 00  |u..`............|
...
*
00018c00  000 00 00 000 01 02  200 00 00 02 00 00 00  |................|
00018c10  000 02 02 2200 00  000 00 00 e8 03 08 01  |................|
00018c20  74 65 73 74 274 78 74  00 00 00 00 00 00 00 00  |test.txt........|
00018c30  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00019000
根据之前dumpe2fs的信息我们知道:

镜像文件中(均为16进制显示)

00000000 开始的1k大小  保留的引导块 

块1    00000400  开始的1k大小  保存磁盘的超级块 (dumpe2fs的部分信息从这里获得) 

块2     00000800   开始的1k大小  保存块组描述符    (dumpe2fs的部分信息从这里获得)

块3     00000c00 开始的1k大小  保存块位图  

块4     00001000    开始的1k大小   保存 Inode 位图  

块5 块6    00001400    开始的2k大小   保存 Inode表  

 剩下的为数据块

磁盘中的文件系统对象结构在内核如下文件定义:

fs/ext2/ext2.h

磁盘超级块:
 struct ext2_super_block {                                                 
         __le32  s_inodes_count;         /* Inodes count */                
         __le32  s_blocks_count;         /* Blocks count */
         __le32  s_r_blocks_count;       /* Reserved blocks count */
         __le32  s_free_blocks_count;    /* Free blocks count */
         __le32  s_free_inodes_count;    /* Free inodes count */
         __le32  s_first_data_block;     /* First Data Block */
         __le32  s_log_block_size;       /* Block size */
         __le32  s_log_frag_size;        /* Fragment size */
         __le32  s_blocks_per_group;     /* # Blocks per group */
         __le32  s_frags_per_group;      /* # Fragments per group */
         __le32  s_inodes_per_group;     /* # Inodes per group */
  ...
}

磁盘块组描述符:
struct ext2_group_desc                                                    
{
                                                                         
        __le32  bg_block_bitmap;                /* Blocks bitmap block */ 
        __le32  bg_inode_bitmap;                /* Inodes bitmap block */ 
        __le32  bg_inode_table;         /* Inodes table block */          
        __le16  bg_free_blocks_count;   /* Free blocks count */           
        __le16  bg_free_inodes_count;   /* Free inodes count */           
        __le16  bg_used_dirs_count;     /* Directories count */           
        __le16  bg_pad;                                                   
        __le32  bg_reserved[3];                                           
};                                                                        


磁盘inode:
 struct ext2_inode {                                                 
         __le16  i_mode;         /* File mode */                     
         __le16  i_uid;          /* Low 16 bits of Owner Uid */      
         __le32  i_size;         /* Size in bytes */                 
         __le32  i_atime;        /* Access time */                   
         __le32  i_ctime;        /* Creation time */                 
         __le32  i_mtime;        /* Modification time */             
         __le32  i_dtime;        /* Deletion Time */                 
         __le16  i_gid;          /* Low 16 bits of Group Id */       
         __le16  i_links_count;  /* Links count */                   
         __le32  i_blocks;       /* Blocks count */  
     ...
  __le32  i_block[EXT2_N_BLOCKS];/* Pointers to blocks */                
 ...
}; 


磁盘目录项:
struct ext2_dir_entry_2 {                                                    
        __le32  inode;                  /* Inode number */                   
        __le16  rec_len;                /* Directory entry length */         
        __u8    name_len;               /* Name length */                    
        __u8    file_type;                                                   
        char    name[];                 /* File name, up to EXT2_NAME_LEN */ 
};                                                                           

大家可以对照磁盘镜像文件和磁盘数据结构定义来解析出文件系统的超级块和块组描述符信息(可以发现和dumpe2fs工具显示的是一致的,例如镜像文件00000400 处四字节为10 00 00 00  是小端存储,所以为0x00000010=16);

3.路径名查找

下面开始我们的重头戏:查找文件系统中的  /dir/test.txt 文件

我们知道,使用文件系统给我最直观也是最大的好处是:用户可以通过一个路径名来访问文件,那么一个文件系统究竟如何来找到我们所需要的文件呢?下面我们详细来看ext2文件系统如何查找指定的文件的?(实际的内核中路径名查找比较复杂,考虑很多情况,如dentry cache查找、解析软链接文件、上级目录、挂载点等,当然如果目录分量是挂载点就会步进到相应文件系统的根目录,后面文件系统挂载专题会讲解,这里以简单的路径解析来让大家有个深刻的认识)。

1)查找根目录

万事开头难,对于访问一个目录上挂载的文件系统,内核路径名查找会判断并找到挂载的文件系统的根目录,这个过程在文件系统挂载的时候,会从磁盘上读取并在内存构建超级块实例,然后进行的最重要的一步是读取文件系统的根inode:

fs/ext2/super.c
ext2_fill_super
->root = ext2_iget(sb, EXT2_ROOT_INO)   //EXT2_ROOT_INO为2,系统定义好的
 ->raw_inode = ext2_get_inode(inode->i_sb, ino, 
本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

9月2日消息,不造车的华为或将催生出更大的独角兽公司,随着阿维塔和赛力斯的入局,华为引望愈发显得引人瞩目。

关键字: 阿维塔 塞力斯 华为

加利福尼亚州圣克拉拉县2024年8月30日 /美通社/ -- 数字化转型技术解决方案公司Trianz今天宣布,该公司与Amazon Web Services (AWS)签订了...

关键字: AWS AN BSP 数字化

伦敦2024年8月29日 /美通社/ -- 英国汽车技术公司SODA.Auto推出其旗舰产品SODA V,这是全球首款涵盖汽车工程师从创意到认证的所有需求的工具,可用于创建软件定义汽车。 SODA V工具的开发耗时1.5...

关键字: 汽车 人工智能 智能驱动 BSP

北京2024年8月28日 /美通社/ -- 越来越多用户希望企业业务能7×24不间断运行,同时企业却面临越来越多业务中断的风险,如企业系统复杂性的增加,频繁的功能更新和发布等。如何确保业务连续性,提升韧性,成...

关键字: 亚马逊 解密 控制平面 BSP

8月30日消息,据媒体报道,腾讯和网易近期正在缩减他们对日本游戏市场的投资。

关键字: 腾讯 编码器 CPU

8月28日消息,今天上午,2024中国国际大数据产业博览会开幕式在贵阳举行,华为董事、质量流程IT总裁陶景文发表了演讲。

关键字: 华为 12nm EDA 半导体

8月28日消息,在2024中国国际大数据产业博览会上,华为常务董事、华为云CEO张平安发表演讲称,数字世界的话语权最终是由生态的繁荣决定的。

关键字: 华为 12nm 手机 卫星通信

要点: 有效应对环境变化,经营业绩稳中有升 落实提质增效举措,毛利润率延续升势 战略布局成效显著,战新业务引领增长 以科技创新为引领,提升企业核心竞争力 坚持高质量发展策略,塑强核心竞争优势...

关键字: 通信 BSP 电信运营商 数字经济

北京2024年8月27日 /美通社/ -- 8月21日,由中央广播电视总台与中国电影电视技术学会联合牵头组建的NVI技术创新联盟在BIRTV2024超高清全产业链发展研讨会上宣布正式成立。 活动现场 NVI技术创新联...

关键字: VI 传输协议 音频 BSP

北京2024年8月27日 /美通社/ -- 在8月23日举办的2024年长三角生态绿色一体化发展示范区联合招商会上,软通动力信息技术(集团)股份有限公司(以下简称"软通动力")与长三角投资(上海)有限...

关键字: BSP 信息技术
关闭
关闭