设为首页 - 加入收藏 ASP站长网(Aspzz.Cn)- 科技、建站、经验、云计算、5G、大数据,站长网!
热搜: 重新 试卷 创业者
当前位置: 首页 > 运营中心 > 建站资源 > 优化 > 正文

好文分享:EXT文件系统机制原理详解(9)

发布时间:2019-09-18 12:09 所属栏目:21 来源:骏马金龙
导读:注意,在第(5)步之前,由于data block还未被标记为未使用,在superblock中仍然认为这些data block是正在使用中的。这表示尽管文件已经被删除了,但空间却还没有释放,df也会将其统计到已用空间中(df是读取superbloc

注意,在第(5)步之前,由于data block还未被标记为未使用,在superblock中仍然认为这些data block是正在使用中的。这表示尽管文件已经被删除了,但空间却还没有释放,df也会将其统计到已用空间中(df是读取superblock中的数据块数量,并计算转换为空间大小)。

什么时候会发生这种情况呢?当一个进程正在引用文件时将该文件删除,就会出现文件已删除但空间未释放的情况。这时步骤已经进行到(4),外界无法再找到该文件,但由于进程在加载该文件时已经获取到了该文件所有的data block指针,该进程可以获取到该文件的所有数据,但却暂时不会释放该文件空间。直到该进程结束,文件系统才将未执行的步骤(5)继续完成。这也是为什么有时候du的统计结果比df小的原因,关于du和df统计结果的差别,详细内容见:详细分析du和df的统计结果为什么不一样。

  • 重命名文件分为同目录内重命名和非同目录内重命名。非同目录内重命名实际上是移动文件的过程,见下文。

同目录内重命名文件的动作仅仅只是修改所在目录data block中该文件记录的文件名部分,不是删除再重建的过程。

如果重命名时有文件名冲突(该目录内已经存在该文件名),则提示是否覆盖。覆盖的过程是覆盖目录data block中冲突文件的记录。例如/tmp/下有a.txt和a.log,若将a.txt重命名为a.log,则提示覆盖,若选择覆盖,则/tmp的data block中关于a.log的记录被覆盖,此时它的指针是指向a.txt的inode。

  • 移动文件

同文件系统下移动文件实际上是修改目标文件所在目录的data block,向其中添加一行指向inode table中待移动文件的inode指针,如果目标路径下有同名文件,则会提示是否覆盖,实际上是覆盖目录data block中冲突文件的记录,由于同名文件的inode记录指针被覆盖,所以无法再找到该文件的data block,也就是说该文件被标记为删除(如果多个硬链接数,则另当别论)。

所以在同文件系统内移动文件相当快,仅仅在所在目录data block中添加或覆盖了一条记录而已。也因此,移动文件时,文件的inode号是不会改变的。

对于不同文件系统内的移动,相当于先复制再删除的动作。见后文。

好文分享:ext文件系统机制原理详解

关于文件移动,在Linux环境下有一个非常经典网上却又没任何解释的问题:/tmp/a/a能覆盖为/tmp/a吗?答案是不能,但windows能。为什么不能?见mv的一个经典问题(mv的本质)。

6.3 存储和复制文件

  • 对于文件存储
  • (1).读取GDT,找到各个(或部分)块组imap中未使用的inode号,并为待存储文件分配inode号;
  • (2).在inode table中完善该inode号所在行的记录;
  • (3).在目录的data block中添加一条该文件的相关记录;
  • (4).将数据填充到data block中。
  • 注意,填充到data block中的时候会调用block分配器:一次分配4KB大小的block数量,当填充完4KB的data block后会继续调用block分配器分配4KB的block,然后循环直到填充完所有数据。也就是说,如果存储一个100M的文件需要调用block分配器100*1024/4=25600次。
  • 另一方面,在block分配器分配block时,block分配器并不知道真正有多少block要分配,只是每次需要分配时就分配,在每存储一个data block前,就去bmap中标记一次该block已使用,它无法实现一次标记多个bmap位。这一点在ext4中进行了优化。
  • (5)填充完之后,去inode table中更新该文件inode记录中指向data block的寻址指针。
  • 对于复制,完全就是另一种方式的存储文件。步骤和存储文件的步骤一样。

7 多文件系统关联

在单个文件系统中的文件操作和多文件系统中的操作有所不同。本文将对此做出非常详细的说明。

7.1 根文件系统的特殊性

这里要明确的是,任何一个文件系统要在Linux上能正常使用,必须挂载在某个已经挂载好的文件系统中的某个目录下,例如/dev/cdrom挂载在/mnt上,/mnt目录本身是在"/"文件系统下的。而且任意文件系统的一级挂载点必须是在根文件系统的某个目录下,因为只有"/"是自引用的。这里要说明挂载点的级别和自引用的概念。

假如/dev/sdb1挂载在/mydata上,/dev/cdrom挂载在/mydata/cdrom上,那么/mydata就是一级挂载点,此时/mydata已经是文件系统/dev/sdb1的入口了,而/dev/cdrom所挂载的目录/mydata/cdrom是文件系统/dev/sdb1中的某个目录,那么/mydata/cdrom就是二级挂载点。一级挂载点必须在根文件系统下,所以可简述为:文件系统2挂载在文件系统1中的某个目录下,而文件系统1又挂载在根文件系统中的某个目录下。

再解释自引用。首先要说的是,自引用的只能是文件系统,而文件系统表现形式是一个目录,所以自引用是指该目录的data block中,"."和".."的记录中的inode指针都指向inode table中同一个inode记录,所以它们inode号是相同的,即互为硬链接。而根文件系统是唯一可以自引用的文件系统。

  1. [root@xuexi /]# ll -ai / 
  2. total 102 
  3.  2 dr-xr-xr-x. 22 root root 4096 Jun 6 18:13 . 
  4.  2 dr-xr-xr-x. 22 root root 4096 Jun 6 18:13 ..  

由此也能解释cd /.和cd /..的结果都还是在根下,这是自引用最直接的表现形式。

  1. [root@xuexi tmp]# cd /. 
  2. [root@xuexi /]# 
  3. [root@xuexi tmp]# cd /.. 
  4. [root@xuexi /]# 

注意,根目录下的"."和".."都是"/"目录的硬链接,且其datablock中不记录名为"/"的条目,因此除去根目录下子目录数后的硬链接数为2。

  1. [root@server2 tmp]# a=$(ls -ld / | awk '{print $2}') 
  2. [root@server2 tmp]# b=$(ls -l / | grep "^d" |wc -l) 
  3. [root@server2 tmp]# echo $((a - b)) 

7.2 挂载文件系统的细节

挂载文件系统到某个目录下,例如"mount /dev/cdrom /mnt",挂载成功后/mnt目录中的文件全都暂时不可见了,且挂载后权限和所有者(如果指定允许普通用户挂载)等的都改变了,知道为什么吗?

下面就以通过"mount /dev/cdrom /mnt"为例,详细说明挂载过程中涉及的细节。

(编辑:ASP站长网)

网友评论
推荐文章
    热点阅读