学习笔记5

第十一章 EXT2文件系统

一、EXT2文件系统

多年来,Linux一直使用EXT2(Card1995)作为默认文件系统。EXT3(EXT3,2014)EXT2的拓展。EXT3中增加的主要内容是一个日志文件,它将文件系统的变更记录在日志中。日志可在文件系统崩溃时更快地从错误中恢复。没有错误的EXT3文件系统与EXT2文件系统相同。

二、EXT2文件系统数据结构

  1. 通过mkfs创建虚拟磁盘

   Linux下,命令

   mke2fs [-b blksize -N ninodes] device nblocks

   在设备上创建有一个带有nblocks个块(每个块大小为blksize字节)ninodes个索引节点的EXT2文件系统。设备可以是真实设备,也可以是虚拟磁盘文件。如果未指定blksize,则默认块大小为1KB.如果未指定ninoides,mke2fs将根据nblocks计算一个默认的ninodes数。得到的EXT2文件系统可在Linux中使用。

2.虚拟磁盘布局

   Block#0:引导块  B0是引导块,文件系统不会使用它。它用来容纳一个引导程序,从磁盘引导操作系统。

3.超级块

   Block#1:超级块(在硬盘分区中字节偏移量为1024) B1是超级块,用于容纳整个文件系统的信息。

   大多数超级块字段的含义都非常明显。只有少数几个字段需要详细解释。

   s_first_data_block:0表示4KB块大小,1表示1KB块大小。它用于确定块组描述符的起始块,即s_first_data_block+1

   s_log_block_size:确定文件块大小,为1KB*(2**s_log_block_size),例如:0表示1KB块大小,1表示2KB块大小,2表示4KB块大小等。最常用的块大小是用于小文件系统的1KB和用于大文件系统的4KB

   s_mnt_count:已挂载文件系统的次数。当挂载计数达到max_mnt_count时,fsck会话将被迫检查文件系统的一致性。

   s_magic:标识文件系统类型的幻数。EXT2/3/4文件系统的幻数是0xEF53.

4.块组描述符

   Block#2:块组描述符块(硬盘上的s_first_data_block+1) EXT2将磁盘块分成几个组。每个组有8192个块(硬盘上的大小为32K)。每组用一个块组描述结构体来描述。

   由于一个虚拟硬盘(FD)只有1440个块,B2就只包含一个块组描述符。其余的都是0。在有大量块组的硬盘上,块组描述符可以跨越多个块。块组描述符可以跨越多个块。块组描述符中最重要的字段是bg_block_bitmapbg_inode_bitmapbg_inode_table,它们分别指向块组的块位图、索引节点位图和索引节点起始块。对于Linux格式的EXT2文件系统,保留了块3到块7.所以,bmap=8imap=9,inode_table=10

5.块和索引节点位图

   Block#8:块位图(Bmap)位图是用来描述某种项的位序列,例如磁盘块或索引节点。位图用于分配和回收项。在位图中,0位表示对应项处于FRREE状态,1位表示对应项处于IN_USE状态。一个软盘有1440个块,但是Block#0未被文件系统使用。所以,位图只有1439个有效位。无效位被视作IN_USE状态。

   Block#9:索引节点位图(Imap)一个索引节点就是用来代表一个文件的数据结构。EXT2文件系统是使用有限数量的索引节点创建的。各索引节点的状态用B9Imap中的一个位表示。

6.索引节点

   Block#10:索引(开始)节点 每个文件都用一个128字节(EXT4中是256字节)的唯一索引节点结构体表示。

   在索引节点结构体中,i_modeu162字节无符号整数。

   i_block[15]数组包含指向文件磁盘块的指针,这些磁盘块有:

   直接块:i_block[0]i_block[11],指向直接磁盘块。

   间接块:i_block[12]指向一个包含256个块编号(对于1KB NLKSIZE)的磁盘块,每个块编号指向一个磁盘块。

   双重间接块:i_block[13]指向一个指向256个块的块,每个块指向256个磁盘块。

   三重间接块:i_block[14]是三重间接块。

7.数据块

   紧跟在索引节点块后面的是文件存储数据块。

8.目录条目

   目录包含dir_entry结构,它是一种可扩充结构。名称字段包含1255个字符,不含终止NULL。所以dir_entryrec_len也各不相同。

三、邮差算法

  1. C语言中的Test-Set-Clear

在标准C语言程序中,最小的可寻址单元是一个字符或字节。在一系列位组成的位图中,通常需要对位进行操作。考虑字符buf[1024],它有1024个字节,用buf[i]表示,其中i=0,1,...1023。它还有8192个位,编号为012,···,8191

2.将索引节点号转换为磁盘上的索引节点

EXT2文件系统中,每个文件都有一个唯一的索引节点结构。在文件系统磁盘上,索引节点从inode_table块开始,每个磁盘包含

INODES_PER_BLOCK=BLOCK_SIZE/sizeof(INODE)

个索引节点。每个索引节点都有一个唯一的索引节点号,ino=1,2,···,从1开始线性计数。

四、编程示例

  1. 显示超级块

以下C程序显示了EXT2文件系统的超级块。基本方法如下。

(1) 打开虚拟磁盘读取:int fd =open(vidsk.O_RDONLY)

(2) 将超级块(Block#11KB1024偏移量位置)读入char buf[1024]中。

(3) ext2_super_block*sp结构体指向buf[]。然后,利用sp->field访问超级块结构体的各个字段。

2.显示位图

3.显示根索引节点

4.显示目录条目

目录索引节点的各数据块均包含dir_entries

目录中每个数据块的内容都具有以下形式:

[inode rec_len name_len NAME] [inode rec_len name_len NAME]

五、遍历EXT2文件系统树

  1. 遍历算法

(1) 读取数据块。

(2) 读取块组描述符块(1+s_first_data_block),以访问组0描述符

(3) 读取InodeBeginBlock,获取/的索引节点,即INODE #2

(4) 将路径名称记为组件字符串

(5) 从(3)中的根索引节点开始,在其数据块中搜索name[0]

(6) 使用索引节点号ino来定位相应的索引节点。

(7) 由于(5)~(6)步将会重复n次,所以最好编写一个搜索函数

  1. 将路径名称转为索引节点
  2. 显示索引节点磁盘块

六、EXT2文件系统的实现

  1. 文件系统的结构
  2. 文件系统的级别

七、基本文件系统

  1. type.h文件

这类文件包括EXT2文件系统的数据结构类型,比如超块、组描述符、索引节点和目录条目结构。此外,它还包含打开文件表、挂载表、PROC结构体和文件系统常数。

  1. global.c文件
  2. 实用程序函数
  3. mount-root

mount_root.c文件:该文件包含mount_root()函数,在系统初始化期间调用该函数来挂载根文件系统。

  1. 基本文件系统的实现

八、mkdir算法

  1. mkdir算法

mkdir命令

mkdir pathname

创建了一个带路径名的新目录。将新目录的权限位设置为默认值0755(所有人可以访问和读写,其他人可以访问但只能读取)

2.creat算法

3.mkdir-creat的实现

rmdir命令

Rmdir dirname

  1. rmdir算法
  2. rmdir的实现

link命令

link old_file

  1. link算法
  2. unlink算法
  3. symlink算法

readlink函数

int readlink(file ,buffer)

读取符号文件的目标文件名并返回目标文件名的长度。readlink()算法如下

  1. readlink算法
  2. 其他1级函数

其他1级函数包括访问、chmodchown、更改文件的时间字段。所有这些函数 的操作方式均相同。

九、2级文件系统函数

2级文件系统实现了文件内容的读/写操作。它由以下函数组成:opencloselseekreadwriteopendirreaddir

  1. open算法

        Unix/Linux中,系统调用

        int open(char *filename, int flags);

     打开一个文件进行读或写,标记是O_RDONLYO_WRONLYO_WRONLY其中之一,可与打开O_CREATO_APPENDO_TRUNC标记逐位进行or组合。

  1. lseek
  2. close算法

close(int fd)操作可关闭文件描述符。

  1. 读取普通文件

Unix/Linux中,系统调用

int read(int fd,char *buf, int nbytes);

n个字节从打开的文件描述符读入用户空间中的缓冲区。read系统调用被路由到操作系统内核中的read函数。

  1. 写普通文件

Unix/Linux中,系统调用

int write(int fd, char buf[], int nbytes);

n个字节从 用户空间缓冲区写入打开的文件描述符,并返回写入的实际字节数。write系统调用被路由到操作系统内核中的write函数。

  1. opendir-readddir

Unix把所有目录都看作一个文件。因此,我们应该能够像开普通文件一样打开一个目录进行读取。

十、3级文件系统

  1. 挂载算法

mount filesys mount_point

可将某个文件系统挂载到mount_point目录上。它允许文件系统包括其他文件系统作为现有文件系统的一部分。挂载中使用的数据结构是挂载表和mount_point目录的内存minode

  1. 卸载算法

卸载文件系统操作可卸载已挂载的文件系统。它将挂载的文件系统与挂载点分开,其中文件系统可以是虚拟的diak名称或挂载点目录名称。

  1. 交叉挂载点

(1) 向下遍历

(2) 向上遍历

  1. 文件保护
  2. 实际uid和有效uid
  3. 文件锁定
  4. 编程项目3:整个文件系统的实现

十一、文件系统项目的拓展

      简单的EXT2文件系统使用1KB块大小,只有一个磁盘块组。它可以轻松进行以下拓展:

(1) 多个组

(2) 4KB大小的块

(3) 管道文件

(4) I/O缓冲

原文地址:https://www.cnblogs.com/lxhs/p/15418491.html