ext2 文件系统解析

news/2024/9/22 11:31:13/文章来源:https://www.cnblogs.com/f66666/p/18353033

ext2文件系统整体布局

每个块组内部都有相关的元数据对该块组进行管理。如图所示,第一个块组中的元数据包括引导块、超级块、块组描述符、预留GDT块、数据块位图、inode位图、inode表和其它数据块。后续块组中有些是对超级块的备份,有些则没有第一个块组这么完整的元数据信息,而只有数据块位图、inode位图和inode表等元数据信息。也就是说块组其实分为两种,一种是有超级块的,比较复杂的块组(如图3下面淡棕色所示),另外一种是没有超级块的,比较简单的块组(如图3上面淡绿色所示)。
image
image

本次实验用1G大小文件模拟磁盘,对齐进行格式化ext2文件系统,然后查看其物理存储结构信息。

dd if=/dev/zero of=/tmp/bk bs=1024k count=1024
mkfs.ext2 /tmp/bk
dumpe2fs /dev/bk
hexdump -s 1024 -n 4096 /tmp/bk -C # 查看超级块信息,磁盘偏移量为1024,存储在第1个4k块中

1. 超级块super block

每个ext2文件系统都必须包含一个超级块,其中存储了该文件系统的大量基本信息,包括块的大小、每块组中包含的块数等。同时,系统会对超级块进行备份,备份被存放在其他块组的第一个块中,备份数量不确定,也就是其他块组可能没有超级块,也可能有。超级块的起始位置为其所在分区的第1024个字节,占用1KB的空间,如果初始化指定块大小1k,那么超级块在第二个块内,如果块大小为4k,超级块则存储在第一个块内,偏移量1024字节,内容占用长度1024字节。原因是:
image
超级块结构如下:
image
image

下图展示了超级块信息:
image

2. 块组描述符表BGT

磁盘分区格式化为ext2时,会将分区划分为多个块组block group,一个块组描述符用以描述一个块组的属性。块组描述符组由若干块组描述符组成,描述了文件系统中所有块组的属性,存放于超级块所在块的下一个块中。一个块组描述符的结构如下,单个描述符占用32字节,本次实验1G空间共划分8个bg:
image
核心属性介绍:

__le32 bg_block_bitmap; // 块位图所在的第一个块的块ID(地址信息)
__le32 bg_inode_bitmap; // inode位图所在的第一个块的块ID(地址信息)
__le32 bg_inode_table; // inode表所在的第一个块的块ID(地址信息)
__le16 bg_free_blocks_count; // 块组中未使用的块数
__le16 bg_free_inodes_count; // 块组中未使用的inode数
__le16 bg_used_dirs_count; // 块组分配的目录的inode数

下图展示了块组描述符部分GDT信息:
image

3. 块位图block bitmap和索引节点位图inode bitmap

块位图和inode位图的每一位分别指出块组中对应的那个块或inode是否被使用,在位图中,0位表示对应项处于FREE状态,1位表示对应项处于IN_USE状态。块位图是一个位图,一个二进制位代表一个块,记录块组中每个块的使用情况,标记哪些块已被分配,哪些是空闲的,帮助文件系统管理块的分配和释放,维护块的空闲状态。Inode位图是一个位图,记录块组中每个inode的使用情况,标记已分配和空闲的inode。 帮助文件系统管理inode的分配和释放,维护inode的空闲状态。
根据块组描述符找到对应的block位图:
image
inode位图:
image

4. inode表

inode表一列表的形式保存了文件的元数据信息,包括文件大小、扩展属性和时间等内容。由于inode结构的大小根据格式化文件系统的属性而有差异,因此该表占用的磁盘空间不定,大概若干个逻辑块的大小。关于文件名称与inode数据结构的关系是通过inode的id确定的,在文件夹中的文件存储包含文件名和inode的id信息,而通过该id可以计算出inode数据结构位于的块组位置和inode表位置。

/** Structure of an inode on the disk*/
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_flags;  /* File flags */union {struct {__le32  l_i_reserved1;} linux1;struct {__le32  h_i_translator;} hurd1;struct {__le32  m_i_reserved1;} masix1;} osd1;       /* OS dependent 1 */__le32  i_block[EXT2_N_BLOCKS];/* Pointers to blocks */__le32  i_generation; /* File version (for NFS) */__le32  i_file_acl; /* File ACL */__le32  i_dir_acl;  /* Directory ACL */__le32  i_faddr;  /* Fragment address */union {struct {__u8  l_i_frag; /* Fragment number */__u8  l_i_fsize;  /* Fragment size */__u16 i_pad1;__le16  l_i_uid_high; /* these 2 fields    */__le16  l_i_gid_high; /* were reserved2[0] */__u32 l_i_reserved2;} linux2;struct {__u8  h_i_frag; /* Fragment number */__u8  h_i_fsize;  /* Fragment size */__le16  h_i_mode_high;__le16  h_i_uid_high;__le16  h_i_gid_high;__le32  h_i_author;} hurd2;struct {__u8  m_i_frag; /* Fragment number */__u8  m_i_fsize;  /* Fragment size */__u16 m_pad1;__u32 m_i_reserved2[2];} masix2;} osd2;       /* OS dependent 2 */
};

5. 数据块

对于普通文件,数据块中存放文件的内容。对于目录文件,数据块存放目录项。

测试文件写入:

mkdir /t
mount /tmp/bk /t

image
image
找到对应磁盘位置,二进制打印13号的inode信息:
image
根据对应字段关系,找到inode里面存储文件对应数据块的数组,由于文件较小,分配了一个块,找到第一个4字节整数,解析得到文件块号为1598.然后二进制打印1598块内容,得到该文件存储内容与写入一致:
image
image

关于目录

在ext2文件系统中,目录是作为文件存储的。根目录总是在inode表的第二项,而其子目录则在根目录文件的内容中定义.目录不过是一种特殊的文件。每个目录也有一个inode,会对其分配数据块。数据块中存储的是用于描述目录下文件的目录项,目录下每个文件或目录对应一个目录项,记录了该文件的文件名和inode对应关系,文件类型。rec_len域是目录项的长度,把它与目录项的起始地址相加就得到下一个目录项的起始地址,因此说,rec_len可以被解释为指向下一个有效目录项的指针。为了删除一个目录项,把ext2_dir_entry_2的inode域置为0并适当增加前一个有效目录项rec_len域的值就可以了.

image
struct ext2_dir_entry_2 {
__le32 inode; // 文件入口的inode号,0表示该项未使用
__le16 rec_len; // 目录项长度,文件名是字符数组,不定长
__u8 name_len; // 文件名包含的字符数
__u8 file_type; // 文件类型
char name[255]; // 文件名
};
请注意:由上可知,以下情形可以改变目录内容:新增文件,删除文件,修改文件名,修改文件类型,修改目录下文件大小是不会修改目录的内容,也就是系统看到目录的修改时间不会变。修改目录内部目录里面的内容,也不会导致外层目录发生变化

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/781130.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

mac最新安装php各版本教程,和ghcr.io被墙的解决方法

2024年8月,很多国外链接都被墙了,导致mac安装php旧版本好困难,特意记录一下方法 1.brew tap shivammathur/php 超时问题如果 tap 超时, 则用浏览器打开 https://github.com/shivammathur/homebrew-php , 下载压缩包 或者直接百度云下载 百度云:https://pan.baidu.com/s/1lsp-E…

澳洲 WHV All In One

澳洲 WHV All In One 工作假期签证申请常见问题 Cambly 英语外教,真人视频口语对话练习课澳洲 WHV All In One WHVWorking Holiday VisaFor young adults who want an extended holiday and to work here to fund it.https://immi.homeaffairs.gov.au/visas/getting-a-visa/vi…

024.Vue3入门,父页面给子页面传递多种数据

1、App.vue代码如下:<template><Father/> </template><script setup> import Father from ./view/Father.vue </script><style> </style>2、Father.vue代码如下:<template><h3>父页面</h3><Child :FMsg=&quo…

小总结(1)

前言: 这篇总结本来想在学习reverse一周年的时候写的,回过头想想,我的大学生活不只有reverse,每一个成长的瞬间都应该被记录下来。 Happiness should be about everything and not a certain moment (至于为什么选择使用博客园写,我的GitHub使用无法将本地资源上传,导致…

023.Vue3入门,父页面给子页面传递数据

1、App.vue代码如下:<template><Father/> </template><script setup> import Father from ./view/Father.vue </script><style> </style>2、Father.vue代码如下:<template><h3>父页面</h3><Child :title=&qu…

022.Vue3入门,注册全局组件,在任何页面直接使用

1、main.js代码如下:// import ./assets/main.cssimport {createApp} from vue import App from ./App.vue import Config from "@/config.js"; import Testpage001 from "@/view/Testpage001.vue";const app = createApp(App);// 定义一个全局组件,名字为…

021.Vue3入门,注册全局组件,在任何页面直接使用

1、main.js代码如下:// import ./assets/main.cssimport {createApp} from vue import App from ./App.vue import Config from "@/config.js"; import Testpage001 from "@/view/Testpage001.vue";const app = createApp(App);// 定义一个全局组件,名字为…

支付三大黑盒之三账务核心

各位小伙伴大家好! 这次给大家揭秘支付三大黑盒的最后一个“账务核心”(另外两个是清结算对账、支付引擎),这账务核心可能是其中门槛最高的,因为他既要懂会计知识,又有懂技术如何实现高性能的记账。 下面我就用大白话+图片的方式给大家来详细介绍支付系统最后一个黑盒“账…

Linux环境安装SQL Server 数据库

SQL Server在Linux 上的支持版本包括Red Hat Enterprise Linux(RHEL)、SUSE Linux Enterprise Server(SLES)和Ubuntu。 一、在虚拟机上安装RHEL操作系统 链接:https://pan.baidu.com/s/1567NfZRF48PBXfUqxumvDA 提取码:bm7u 1、在虚拟机中创建Red Hat7.9 点击创建新的虚拟机选…

全网最适合入门的面向对象编程教程:35 Python的内置数据类型-文档字符串和__doc__属性

在 Python 中,文档字符串(Docstring)是一种用于为模块、类、方法或函数编写文档的字符串,通常放置在定义的开头,紧跟在声明之后。文档字符串使用三重引号(""" 或 )包围,可以跨越多行。全网最适合入门的面向对象编程教程:35 Python 的内置数据类型-文档…

VDI/VDE 2634 Part2 2002:05

VDI/VDE 2634 2002:05 第二部分[!NOTE] 原始PDF链接:https://www.doc88.com/p-57887264529548.htmlOptical 3-D measuring systems Optical systems based on area scanning Preliminary note Optical 3-D measuring systems are used as universal measuring and test equipm…

vue2父子组建传递数据

父子组建通信代码demo 父页面 父页面编写handleUploadNew 接收子组建uploadNew 传上来的对象 父页面传递tempUrl 给子页面初始化数据 <Upload :temp-url="tempUrl" @uploadNew="handleUploadNew" /> 子组件里面<i class="el-icon-delete&qu…