大三复习大三中print ext2文件系统_第1页
大三复习大三中print ext2文件系统_第2页
大三复习大三中print ext2文件系统_第3页
大三复习大三中print ext2文件系统_第4页
大三复习大三中print ext2文件系统_第5页
已阅读5页,还剩26页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、ext2 文件系统 请点评2.1. 总体布局 请点评知道,一个磁盘可以划分成多个分区,每个分区必须先用格式化工具(例如某种 mkfs 命令)格式化成某种格式的文件系统,然后才能文件,格式化的过程会在磁盘上写一些管理布局的信息。下图是一个磁盘分区格式化成 ext2 文件系统后的布局。图 29.2. ext2 文件系统的总体布局文件系统中的最小是块(Block),一个块究竟多大是在格式化时确定的,例如 mke2fs 的-b 选项可以设定块大小为 1024、2048 或4096 字节。而上图中启动块(Boot Block)的大小是确定的,就是 1KB,启动块是由 PC 标准规定的,用来磁盘分区信息和

2、启动信息,任何文件系统都不能使用启动块。启动块之后才是 ext2 文件系统的开始,ext2 文件系统将整个分区划成若干个同样大小的块组(Block Group),每个块组都由以下部分组成。超级块(Super Block)表这几部分该块组的描述信息。那么如何知道哪些块已经用用一个整块;超级块、块组描述符表、块位图、inode 位图、inode就需要三个数据块来存,即使第三个块只存了一个字节也需要占如某个分区的块大小是 1024 字节,某个文件是 2049 字节,那么一个块组中的块是这样利用的:数据块所有文件的数据,比块位图(Block Bitmap)损坏时就可以用其它拷贝来恢复,从而减少损失。组

3、描述符表就会拷贝到其它块组,这样当第 0 个块组的开头意外执行 e2fsck 检查文件系致性时,第 0 个块组中的超级块和块此它们都有多份拷贝。通常内核只用到第 0 个块组中的拷贝,当的数据,一旦块组描述符意外损坏就会丢失整个块组的数据,因这些信息是非常重要的,一旦超级块意外损坏就会丢失整个分区超级块类似,块组描述符表在每个块组的开头也都有一份拷贝,哪里开始是数据块,空闲的 inode 和数据块还有多少个等等。和块组的描述信息,例如在这个块组中从哪里开始是 inode 表,从个块组描述符。每个块组描述符(Group Descriptor)一个由很多块组描述符组成,整个分区分成多少个块组就对应有

4、多少块组描述符表(GDT,Group Descriptor Table)上次 mount 的时间等等。超级块在每个块组的开头都有一份拷贝。描述整个分区的文件系统信息,例如块大小、文件系统版本号、图就是整个块组中哪些块已用哪些块空闲的,它本身占空闲可用。和块位图类似,本身占一个块,其中每个 bit 表示一个 inode 是否inode 位图(inode Bitmap)示该块已用,这个bit 为 0 表示该块空闲可用。为什么用 df 命令统计整个磁盘的已用空间非常快呢?因为只需要查看每个块组的块位图即可,而不需要搜遍整个分区。相反,用 du 命令查看一个较大目录的已用空间就非常慢,因为不可避免地要

5、搜遍整个目录的所有文件。与此相联系的另一个问题是:在格式化一个分区时究竟会划出多少个块组呢?主要的限制在于块位图本身必须只占一个块。用 mke2fs 格式化时默认块大小是 1024 字节,可以用-b 参数指定块大小,现在设块大小指定为 b 字节,那么一个块可以有 8b 个bit,这样大小的一个块位图就可以表示 8b 个块的占用情况,因此一个块组最多可以有 8b 个块,如果整个分区有s 个块,那么就可以有s/(8b)个块组。格式化时可以用-g 参数指定一个块组有多少个块,但是通常不需要手动指定,mke2fs 工具会计算出最优的数值。一个块,其中的每个 bit 代表本块组中的一个块,这个 bit

6、为 1 表来文件数据或其它描述信息,哪些块仍然空闲可用呢?块位知道,一个文件除了数据需要之外,一些描述信息也需要,例如文件类型(常规、目录、符号等),权限,文根据不同的文件类型有以下几种情况数据块(Data Block)inode,一个块组中的所有 inode 组成了 inode 表。inode 表占多少个块在格式化时就要决定并写入块组描述符中, mke2fs 格式化工具的默认策略是一个块组有多少个 8KB 就分配多少个 inode。由于数据块占了整个块组的绝大部分,也可以近似认为数据块有多少个 8KB 就分配多少个 inode,换句话说,如果平均每个文件的大小是 8KB,当分区存满的时候 i

7、node 表会得到比较充分的利用,数据块也不浪费。如果这个分区存的都是很大的文件(比如),则数据块用完的时候 inode 会有一些浪费,如果这个分区存的都是很小的文件(比如源代码),则有可能数据块还没用完 inode 就已经用完了,数据块可能有很大的浪费。如果用户在格式化时能够对这个分区以后要的文件大小做一个,也可以用 mke2fs 的-i 参数手动指定每多少个字节分配一个 inode。息,这些信息存在 inode 中而不是数据块中。每个文件都有一个件大小,创建/修改/时间等,也就是 ls -l 命令看到的那些信inode 表(inode Table)因为目录的数据块保存着它下边所有文件和目录

8、的名字,如果一个目录4096,目录的大小总是数据块的整数倍。为什么有的目录大有的目录小?为什么各目录的大小都是 4096 的整数倍?因为这个分区的块大小是$ ls -l total 32drwxr-xr-x 114 akaedu akaedu 12288 2008-10-25 11:33 akaedudrwxr-xr-x 114 ftpftp4096 2008-10-25 10:30 ftpdrwx 2 rootroot16384 2008-07-04 05:58 lost+found现在做几个小实验来理解这些概念。例如在 home 目录下 ls -l:对于常规文件,文件的数据 在数据块中。对

9、于目录,该目录下的所有文件名和目录名 在数据块中,注意文件名保存在它所在目录的数据块中,除文件名之外,ls -l 命令看到的其它信息都保存在该文件的 inode中。注意这个概念:目录也是一种文件,是一种特殊类型的文件。对于符号 ,如果目标路径名较短则直接保存在 inode中以便更快地查找,如果目标路径名较长则分配一个数据块来保存。设备文件、FIFO 和 socket 等特殊文件没有数据块,设备文件的主设备号和次设备号保存在 inode 中。$ toucho$ ln -s ./o halo$ ls -l total 0lrwxrwxrwx 1 akaedu akaedu 7 2008-10-25

10、 15:04 halo- ./o-rw-r-r- 1 akaedu akaedu 0 2008-10-25 15:04o内核根据设备号找到相应的驱动程序。再比如:地方写了 1, 5 这两个数字,表示主设备号和次设备号,该文件时,表内核中的一个设备驱动程序,也没有数据块,原本应该写文件大小的据块,文件大小是 0。zero 文件的类型是c,表示字符设备文件,它代到它其实是一块内核缓冲区的标识,不在磁盘上保存数据,因此没有数xconsole 文件的类型是p(表示 pipe),是一个 FIFO 文件,后面会讲$ ls -l /dev.prw-r 1 syslog adm0 2008-10-25 11:

11、39 xconsolecrw-rw-rw- 1 root root1,5 2008-10-24 16:44 zero给这个目录。再比如:中的文件很多,一个块装不下这么多文件名,就可能分配的数据块o 是刚创建的,字节数为 0,符号文件文件 halo 指向o,字节数却是 7,为什么呢?其实 7 就是“./o”这 7 个字符,符号文件o2 和o 除了文件名不一样之外,别的属性都一模一样,并且o说,o 和o2 是同一个文件在文件系统中的两个名字,ls -l 第二$ mkdir a$ mkdir a/b$ ls -ld adrwxr-xr-x 3 akaedu akaedu 4096 2008-10-2

12、5 16:15 a出来的。再研究一下目录的硬数:所以用 ls -l 看它们的属性是一模一样的,因为都是从这个 inode 里读硬数也保存在 inode 中。既然是同一个文件,inode 当然只有一个,字可以保存在不同目录的数据块中,或者说可以位于不同的路径下),栏的数字是硬数,表示一个文件在文件系统中有几个名字(这些名的属性发生了变化,第二栏的数字原本是 1,现在变成 2 了。从根本上$ ln ./oo2$ ls -l total 0lrwxrwxrwx 1 akaedu akaedu 7 2008-10-25 15:04 halo- ./o-rw-r-r- 2 akaedu akaedu 0

13、 2008-10-25 15:04o-rw-r-r- 2 akaedu akaedu 0 2008-10-25 15:04o2就保存着这样一个路径名。再试试硬:$ dd if=/dev/zero of=fs count=256 bs=4K,但不能创建目录的硬。2.2. 实例剖析 请点评如果要格式化一个分区来研究文件系统格式则必须有一个空闲的磁盘分区,为了方便实验,把一个文件当作分区来格式化,然后分析这个文件中的数据来印证上面所讲的要点。首先创建一个 1MB 的文件并清零:意,目录的硬只能这种方式创建,用 ln 命令可以创建目录的符号b 的硬数是 2,这两个名字分别是 a 目录下的b 和 b 目

14、录下的.。注这 3 个名字分别是当前目录下的 a,a 目录下的.和b 目录下的.。目录首先创建目录a,然后在它下面创建子目录 a/b。目录 a 的硬数是 3,$ ls -la a total 20drwxr-xr-x 3 akaedu akaedu 4096 2008-10-25 16:15 .drwxr-xr-x 115 akaedu akaedu 12288 2008-10-25 16:14 .drwxr-xr-x 2 akaedu akaedu 4096 2008-10-25 16:15 b$ ls -la a/b total 8drwxr-xr-x 2 akaedu akaedu 40

15、96 2008-10-25 16:15 .drwxr-xr-x 3 akaedu akaedu 4096 2008-10-25 16:15 .$ mke2fs fsmke2fs 1.40.2 (12-Jul-2007)fs is not a block spel device. Proceed anyway? (y,n) (输入 y 回车) Filesystem label=OS type: LinuxBlock size=1024 (log=0) Fragment size=1024 (log=0)128 inodes, 1024 blocks51 blocks (4.98%)for the

16、 super user data block=1um filesystem blocks=10485761 block groupcount 和 bs 参数表示拷贝多少次,每次拷多少字节。做好之后对文件 fs 进行格式化,也就是把这个文件的数据块合起来看成一个 1MB 的磁盘分区,在这个分区上再划分出块组。拷贝了 1M 个 0 x00 到 fs 文件。if 和 of 参数表示输入文件和输出文件,穷大的,不管从哪里开始读,读出来的都是字节 0 x00。因此这个命令操作传给设备号为 1, 5 的驱动程序。/dev/zero 这个文件可以看作是无看到/dev/zero 是一个特殊的设备文件,它没有磁

17、盘数据块,对它进行读文件开头的 1M(2564K)字节拷贝成文件名为 fs 的文件。刚才一个文件的一部分拷贝成另一个文件。这个命令的作用是把/dev/zero知道 cp 命令可以把一个文件拷贝成另一个文件,而 dd 命令可以把$ dumpe2fs fsdumpe2fs 1.40.2 (12-Jul-2007) Filesystem volume name: Last mounted on:Filesystem UUID:8e1f3b7a-4d1f-41dc-8928-526e43b2fd74 Filesystemnumber: 0 xEF53Filesystem revi#:1 (dynami

18、c)所以给出提示,要求确认是否真的要格式化,输入 y 回车完成格式化。现在 fs 的大小仍然是 1MB,但不再是全 0 了,其中已经有了块组和描述信息。用 dumpe2fs 工具可以查看这个分区的超级块和块组描述符表中的信息:fs 是常规文件而不是块设备文件,mke2fs 认为用户有可能是误操作了,格式化一个真正的分区应该指定块设备文件名,例如/dev/sda1,而这个8192 blocks per group, 8192 fragments per group128 inodes per groupWriting inode tables: doneWriting superblocks a

19、nd filesystem accounting information: doneThis filesystem will be automatically checked every 27 mounts or180 days, whichever comes. Use tune2fs -c or -i to override.Filesystem features:resize_inode dir_index filetype sparse_superFilesystem flags:signed directory hash Default mount options:(none)Fil

20、esystem se:cleanErrors behavior:Continue Filesystem OS type:Linux Inode count:128Block count:1024block count:51Free blocks:986Free inodes:117block:1Block size:1024Fragment size:1024GDT blocks:3Blocks per group:8192Fragments per group:8192Inodes per group:128Inode blocks per group: 16Filesystem creat

21、ed:Sun Dec 16 14:56:59 2007 Last mount time:n/aLast write time:Sun Dec 16 14:56:59 2007Mount count:0um mount count:30Last checked:Sun Dec 16 14:56:59 2007开始,因此Group 0 占据第 1 个到第 1023 个块,共 1023 个块。块位共有 1024 个块,第 0 个块是启动块,启动块之后才算 ext2 文件系统的根据上面讲过的知识简单计算一下,块大小是 1024 字节,1MB 的分区Checkerval:15552000 (6 mont

22、hs)Next check after:Fri Jun 13 14:56:59 2008 blocks uid:0 (user root)blocks gid:0 (group root) inode:11Inode size:128Defauirectory hash: tea Directory Hash Seed:6d0e58bd-b9db-41ae-92b3-4563a02a5981Group 0: (Blocks 1-1023)Primary superblock at 1, Group descriptors at 2-2 GDT blocks at 3-5Block bitmap

23、 at 6 (+5), Inode bitmap at 7 (+6)Inode table at 8-23 (+7)986 free blocks, 117 free inodes, 2 directoriesFree blocks: 38-1023Free inodes: 12-128128 inodes per group, 8 inodes per block, so: 16 blocks for inode table放在这里“失物招领”了。现在可以在/mnt 目录下添加删除文件,这些操作会自动保存到文件 fs中。然后把这个分区 umount 下来,以确保所有的改动都保存到文件中了。有

24、错误的块挂在这个目录下,因为这些块不知道是谁的,找不到主,就lost+found 目录由 e2fsck 工具使用,如果在检查磁盘时发现错误,就把表示当前目录,.表示上一级目录,而根目录的.和.都表示根目录本身。根目录下自动生成三个子目录:.,.和 lost+found。其它子目录下的.会把它的数据块中的数据当作分区格式来解释。文件系统格式化之后在-o loop 选项告诉 mount 这是一个常规文件而不是一个块设备文件。mount$ sudo mount -o loop fs /mnt$ cd /mnt/$ ls -la total 17drwxr-xr-x 3 akaedu akaedu 1

25、024 2008-10-25 12:20 .drwxr-xr-x 21 rootroot4096 2008-08-18 08:54 .drwx 2 rootroot12288 2008-10-25 12:20 lost+found分区对应 128 个 inode,这些数据都和 dumpe2fs 的输出吻合。用常规文件制作而成的文件系统也可以像磁盘分区一样 mount 到某个目录,例如:此只要一个块组就够了。默认是每 8KB 分配一个inode,因此 1MB 的图占一个块,共有 10248=8192 个 bit,足够表示这 1023 个块了,因输出的信息。从 000000 开始的 1KB 是启动

26、块,由于这不是一个真正的磁盘分区,启动块的内容全部为零。从 000400 到 0007ff 的 1KB 是超级块,对照着 dumpe2fs 的输出信息,详细分析如下:图 29.3. 超级块其中以*开头的行表示这一段数据全是零因此省略了。下面详细分析 od$ od -tx1 -Ax fs000000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00*000400 80 00 00 00 00 04 00 00 33 00 00 00 da 03 00 00000410 75 00 00 00 01 00 00 00 00 00 00 00 00 00

27、 00 00.不过也不影响理解。现在用二进制查看工具查看这个文件系统的所有字节,并且同 dumpe2fs 工具的输出信息相比较,就可以很好地理解文件系统的布局了。中添加删除过文件,跟着做下面的步骤时结果可能和我写的不太一样,注意,下面的实验步骤是对新创建的文件系统做的,如果你在文件系统$ sudo umount /mnt.Group 0: (Blocks 1-1023)Primary superblock at 1, Group descriptors at 2-2超级块中从 0004d0 到末尾的 204 个字节是填充字节,保留未用,上图未画出。注意,ext2 文件系统中各字段都是按小端的,

28、如果把字节在文件中的位置看作地址,那么靠近文件开头的是低地址,存低字节。各字段的位置、长度和含义详见ULK。从 000800 开始是块组描述符表,这个文件系统较小,只有一个块组描述符,对照着 dumpe2fs 的输出信息分析如下:图 29.4. 块组描述符整个文件系统是 1MB,每个块是 1KB,应该有 1024 个块,除去启动块还有 1023 个块,分别为 1-1023,它们全都属于 Group 0。其中, Block 1 是超级块,接下来的块组描述符,块位图是 Block 6,因此中间的Block 2-5 是块组描述符表,其中 Block 3-5 保留未用。块组描 述符还,inode 位图

29、是 Block 7,inode 表是从 Block 8 开始的,那么inode 表到哪个块结束呢?由于超级块中每个块组有 128 个 inode,每个 inode 的大小是 128 字节,因此共占 16 个块,inode 表的范围是Block 8-23。从 Block 24 开始就是数据块了。块组描述符中,空闲的数据块有986 个,由于文件系统是新创建的,空闲块是连续的 Block 38-1023,GDT blocks at 3-5Block bitmap at 6 (+5), Inode bitmap at 7 (+6)Inode table at 8-23 (+7)986 free blo

30、cks, 117 free inodes, 2 directoriesFree blocks: 38-1023Free inodes: 12-128.001c00 ff 07 00 00 00 00 00 00 00 00 00 00 00 00 00 00001c10ff*中的 1 就变得不连续了。块组描述符,空闲的 inode 有 117 个,由于文件系统是新创建的,空闲的 inode 也是连续的,inode从 1 到 128,空闲的 inode从 12 到 128。从 inode 位图可以看出,前 11 位都是 1,表示前 11 个inode 已用:到的顺序来看。以后随着文件系统的使用和

31、添加删除文件,块位图管是 0 还是 1 都没有意义。可见,块位图每个字节中的位应该按从低位最后一个字节的低 7 位),接下来的位已经超出了文件系统的空间,不在块位图中,Block 38-1023 对应的位都是 0(一直到 001870 那一行001800ff 1f 00 00 00 00 00 00 00 00 00 00 00001810 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00*001870 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 80001880ff*用掉了前面的Block 24-37

32、。从块位图中可以看出,前 37 位(前 4 个字节加最后一个字节的低 5 位)都是 1,就表示Block 1-37 已用:Inode: 2 Type: directoryMode: 0755 Flags: 0 x0 Generation: 0User: 1000 Group: 1000Size: 1024File ACL: 0Directory ACL: 0Links: 3 Blockcount: 2的 inode 信息:在 debugfs 的提示符下输入 s/命令,这时在新的一屏中显示根目录$ debugfs fsdebugfs 1.40.2 (12-Jul-2007) debugfs: h

33、elp连续了。001c00 这一行的 128 位就表示了所有 inode,因此下面的行不管是 0还是 1 都没有意义。已用的 11 个 inode 中,前 10 个 inode 是被 ext2文件系统保留的,其中第 2 个 inode 是根目录,第 11 个 inode 是 lost+found 目录,块组描述符也该组有两个目录,就是根目录和 lost+found。探索文件系统还有一个很有用的工具debugfs,它提供一个命令行界面,可以对文件系统做 ,例如查看信息、恢复数据、修正文件系统中的错误。下面用 debugfs 打开 fs 文件,然后在提示符下输入 help 看看它都能做哪些事情:以

34、后随着文件系统的使用和添加删除文件,inode 位图中的 1 就变得不把以上信息和 od 命令的输出对照起来分析:图 29.5. 根目录的 inode上图中的 st_mode 以八进制表示,包含了文件类型和文件权限,最的 4 表示文件类型为目录(各种文件类型的编码详见 s (2)),低位的 755 表示权限。Size 是 1024,说明根目录现在只有一个数据块。Links为3 表示根目录有三个硬 ,分别是根目录下的.和.,以及lost+founddebugfs: quit按q 退出这一屏,然后用 quit 命令退出 debugfs:Fragment: Address: 0Number: 0Si

35、ze: 0ctime: 0 x4764cc3b - Sun Dec 16 14:56:59 2007atime: 0 x4764cc3b - Sun Dec 16 14:56:59 2007mtime: 0 x4764cc3b - Sun Dec 16 14:56:59 2007 BLOCKS:(0):24TOTAL: 1编码文件类型子目录下的.。注意,虽然通常用/表示根目录,但是并没有名为/的硬,事实上,/是路径分隔符,不能在文件名中出现。这里的 Blockcount 是以 512 字节为一个块来数的,并非格式化文件系统时所指定的块大小,磁盘的最小读写称为扇区(Sector),通常是 512

36、 字节,所以 Blockcount 是磁盘的物理块数量,而区的逻辑块数量。根目录数据块的位置由上图中的 Blocks0,也就是第 24 个块,它在文件系统中的位置是 240 x400=0 x6000,从 od 命令的输出中找到 006000 地址,它的格式是这样:图 29.6. 根目录的数据块目录的数据块由许多不定长的组成,每条描述该目录下的一个文件,在上图中用框表示。第一条描述 inode 号为 2 的文件,也就是根目录本身,该的总长度为 12 字节,其中文件名的长度为 1 字节,文件类型为 2(见下表,注意此处的文件类型编码和 st_mode 不一致),文件名是.。表 29.1. 目录中的

37、文件类型编码第二条也是描述 inode 号为 2 的文件(根目录),该总长度为一直延续到该数据块的末尾,描述 inode 号为 11 的文件第三条面全是 0 字节。如果要在根目录下创建新的文件,可以把第三条截短,在原来的 0 字节处创建新的。如果该目录下的文件名太多,一会填充到 inode 的个数据块不够用,则会分配新的数据块,块中读出来的。列出了 inode 号、长度和文件名,这些信息都是从根目录的数据块2 (12) .2 (12) .11 (1000) lost+foundBlocks1字段。debugfs 也提供了 cd、ls 等命令,不需要 mount 就可以查看这个文件系统中的目录,

38、例如用 ls 查看根目录:(lost+found 目录),该的总长度为 1000 字节(和前面两条加起来是 1024 字节),文件类型为 2,文件名字符串是 lost+found,后12 字节,其中文件名的长度为2 字节,文件类型为2,文件名字符串是.。编码文件类型0Unknown1Regular file2Directory3Character device4Block device5Named pipe6Socket7Symbolic link习题 请点评1、请读者仿照对根目录的分析,自己分析 lost+found 目录的inode 和数据块的格式。2、mount 这个文件系统,在里面添加

39、删除文件,然后 umount 下来,再次分析它的格式,和原来的结果比较一下看哪些字节发生了变化。2.3. 数据块寻址 请点评如果一个文件有多个数据块,这些数据块很可能不是连续存放的,应该如何寻址到每个块呢?根据上面的分析,根目录的数据块是通过其inode 中的索引项 Blocks0找到的,事实上,这样的索引项一共有 15个,从 Blocks0到 Blocks14,每个索引项占 4 字节。前 12 个索引项,例如上面的例子中 Blocks0字段保存着 24,就表示第都表示块24 个块是该文件的数据块,如果块大小是 1KB,这样可以表示从 0 字节到 12KB 的文件。如果剩下的三个索引项 Blo

40、cks12到 Blocks14也是这么用的,就只能表示最大 15KB 的文件了,这是远远不够的,事实上,剩下的三个索引项都是间接索引。索引项 Blocks12所指向的块并非数据块,而是称为间接寻址块(Indirect Block),其中存放的都是类似 Blocks0这种索引项,再由索引项指向数据块。设块大小是 b,那么一个间接寻址块中可以存放 b/4个索引项,指向 b/4 个数据块。所以如果把 Blocks0到 Blocks12都用上,最多可以表示 b/4+12 个数据块,对于块大小是 1K 的情况,最大可表示 268K 的文件。如下图所示,注意文件的数据块是从 0 开始的,Blocks0指向

41、第 0 个数据块,Blocks11指向第 11 个数据块,Blocks12所指向的间接寻址块的第一个索引项指向第 12 个数据块,依此类推。图 29.7. 数据块的寻址从上图可以看出,索引项 Blocks13指向两级的间接寻址块,最多可表示(b/4)2+b/4+12 个数据块,对于 1K 的块大小最大可表示 64.26MB 的文件。索引项 Blocks14指向三级的间接寻址块,最多可表示 (b/4)3+(b/4)2+b/4+12 个数据块,对于 1K 的块大小最大可表示 16.06GB的文件。可见,这种寻址方式对于不超过 12 个数据块的小文件是非常快的,文件中的任意数据只需要两次读盘操作,一

42、次读 inode(也就是读索引项)一次读数据块。而大文件中的数据则需要最多五次读盘操,录数据块的位置从根目录的数据块中找出文件名为 opt 的,从中读出它的inode 号读出 opt 目录的inode,从中找出它的数据块的位置从 opt 目录的数据块中找出文件名为 file 的,从中读出它的 inode 号读出 file 文件的inode1. 读出 inode 表中第 2 项,也就是根目录的 inode,从中找出根目作:inode、一级间接寻址块、二级间接寻址块、三级间接寻址块、数据块。实际上,磁盘中的 inode 和数据块往往已经被内核缓存了,读大文件的效率也不会太低。2.4. 文件和目录操

43、作的系统函数 请点评本节简要介绍一下文件和目录操作常用的系统函数,常用的文件操作命令如 ls、cp、mv 等也是基于这些函数实现的。本节的侧重点在于讲解这些函数的工作原理,而不是如何使用它们,理解了实现原理之后再看这些函数的用法就很简单了,请读者自己查阅 Man Page 了解其用法。s (2)函数 文件的 inode,然后把 inode 中的各种文件属性填入一个 struct s 结构体传出给调用者。s (1)命令是基于 s 函数实现的。s 需要根据传入的文件路径找到 inode,假设一个路径是/opt/file则查找的顺序是:但是和s函数有一点不同,当文件是一个符号时,s(2)函数文件本身

44、的 inode。ac s(2)函数检查执行当前进程的用户是否 限 某个文件,传入文件路径和要执行的 操作(读/写/执行),ac s 函数取出文件 inode中的 st_mode 字段,比较一下 权限,然后返回 0 表示允许 ,返回-1 表示错误或不允许 。od(2)和 fod(2)函数改变文件的权限,也就是修改 inode 中的 st_mode 字段。这两个函数的区别类似于 s/fs。od(1)命令是基于od 函数实现的。n(2)/fn(2)/ln(2)改变文件的所有者和组,也就是修改 inode中的 User 和 Group 字段,只有超级用户才能正确调用这几个函数,这几个函数之间的区别类似

45、于 s/fs/ls。n(1)命令是基于n函数实现的。utime(2)函数改变文件的时间和修改时间,也就是修改 inode 中的atime 和 mtime 字段。touch(1)命令是基于 utime 函数实现的。truncate(2)和 ftruncate(2)函数把文件截断到某个长度,如果新的长度比原来的长度短,则后面的数据被截掉了,如果新的长度比原来的长度传出的是它所指向的目标文件的 inode,而 ls函数传出的就是符号述符,传出 inode 信息,ls(2)函数也是传入路径传出 inode 信息,还有另外两个类似s的函数:fs(2)函数传入一个已打开的文件描长,则后面多出来的部分用 0

46、 填充,这需要修改 inode 中的 Blocks 索引项以及块位图中相应的bit。这两个函数的区别类似于 s/fs。link(2)函数创建硬,其原理是在目录的数据块中添加一条新,其中的 inode 号字段和原文件相同。symlink(2)函数创建一个符号,这需要创建一个新的 inode,其中 st_mode 字段的文件类型是符号,原文件的路径保存在 inode 中或者分配一个数据块来保存。ln(1)命令是基于 link 和 symlink 函数实现的。unlink(2)函数删除一个。如果是符号则这个符号的inode 和数据块,清除 inode 位图和块位图中相应的位。如果是硬则从目录的数据块

47、中清除一条文件名 ,如果当前文件的硬 数已经是 1 了还要删除它,就同时 它的 inode 和数据块,清除 inode 位图和块位图中相应的位,这样就真的删除文件了。unlink(1)命令和 rm(1)命令是基于 unlink 函数实现的。rename(2)函数改变文件名,需要修改目录数据块中的文件名,如果原文件名和新文件名不在一个目录下则需要从原目录数据块中清除一条然后添加到新目录的数据块中。mv(1)命令是基于 rename 函数实现的,因此在同一分区的不同目录中移动文件并不需要和删除文件的 inode 和数据块,只需要一个改名操作,即使要移动整个目录,这个目录下有很多子目录和文件也要随着

48、一起移动,移动操作也只是对顶级目录的改名操作,很快就能完成。但是,如果在不同的分区之间移动文struct dirent ino_td_ino;/* inode number */件就必须 和删除 inode 和数据块,如果要移动整个目录,所有子目录和文件都要 删除,这就很慢了。readlink(2)函数 一个符号 所指向的目标路径,其原理是从符号的 inode 或数据块中读出保存的数据,这就是目标路径。mkdir(2)函数创建新的目录,要做的操作是在它的父目录数据块中添加一条 ,然后分配新的 inode 和数据块,inode 的 st_mode 字段的文件类型是目录,在数据块中填两个 ,分别是.和.,由于.表示父目录,因此父目录的硬 数要加 1。mkdir(1)命令是基于 mkdir 函数实现的。rmdir(2)函数删除一个目录,这个目录必须是空的(只包含.和.)才能删除,要做的操作是 它的 inode 和数据块,清除 inode 位图和块位图中相应的位,清

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论