Linux 核心--10.文件系统( 四 )


我们所需要的第一个inode是根文件系统的inode,它被存放在文件系统的超块中 。为读取某个EXT2 inode, 我们必须在适当数据块组的inode表中进行搜寻 。如果根inode号为42则我们需要数据块组0 inode表的第42个inode 。此根inode对应于一个EXT2目录,即根inode的mode域将它描叙成目录且其数据块包含EXT2目录入口 。home目录是许多目录的入口同时此目录给我们提供了大量描叙/home目录的inode 。我们必须读取此目录以找到rusling目录入口,此入口又提供了许多描叙/home/rusling目录的inode 。最后读取由/home/rusling目录描叙的inode指向的目录入口以找出.cshrc文件的inode号并从中取得包含在文件中信息的数据块 。



9.1.6改变EXT2文件系统中文件的大小
文件系统普遍存在的一个问题是碎块化 。一个文件所包含的数据块遍布整个文件系统,这使得对文件数据块的顺序访问越来越慢 。EXT2文件系统试图通过分配一个和当前文件数据块在物理位置上邻接或者至少位于同一个数据块组中的新块来解决这个问题 。只有在这种分配策略失败时才在其它数据块组中分配空间 。
当进程准备写某文件时, Linux文件系统首先检查数据是否已经超出了文件最后一个被分配的块空间 。如果是则必须为此文件分配一个新数据块 。进程将一直等待到此分配完成;然后将其余数据写入此文件 。EXT2块分配例程所作的第一件事是对此文件系统的EXT2超块加锁 。这是因为块分配和回收将导致超块中某些域的改变,Linux文件系统不能在同一时刻为多个进程进行此类服务 。如果另外一个进程需要分配更多的数据块时它必须等到此进程完成分配操作为止 。在超块上等待的进程将被挂起直到超块的控制权被其当前使用者释放 。对超块的访问遵循先来先服务原则,一旦进程取得了超块的控制则它必须保持到操作结束为止 。如果系统中空闲块不多则此分配的将失败,进程会释放对文件系统超块的控制 。

如果EXT2文件系统被设成预先分配数据块则我们可以从中取得一个 。预先分配块实际上并不存在,它们仅仅包含在已分配块的位图中 。我们试图为之分配新数据块文件所对应的VFS inode包含两个EXT2特殊域:prealloc_block和prealloc_count,它们分别代表第一个预先分配数据块的块号以及各自的数目 。如果没有使用预先分配块或块预先分配数据块策略,则EXT2文件系统必须分配一个新块 。它首先检查此文件最后一个块后的数据块是否空闲 。从逻辑上来说这是让其顺序访问更快的最有效块分配策略 。如果此块已被使用则它会在理想块周围64个块中选择一个 。这个块虽然不是最理想但和此文件的其它数据块都位于同一个数据块组中 。

如果此块还是不空闲则进程将在所有其它数据块组中搜寻,直到找到一空闲块 。块分配代码将在某个数据块组中寻找一个由8个空闲数据块组成的簇 。如果找不到那么它将取更小的尺寸 。如果使用了块预先分配则它将更新相应的prealloc_block和prealloc_count 。

找到空闲块后块分配代码将更新数据块组中的位图并在buffer cache中为它分配一个数据缓存 。这个数据缓存由文件系统支撑设备的标志符以及已分配块的块号来标志 。缓存中的数据被置0且缓存被标记成dirty以显示其内容还没有写入物理磁盘 。最后超块也被标记为dirty以表示它已被更新并解锁了 。如果有进程在等待这个超块则队列中的第一个进程将得到运行并取得对超块的独占控制 。如果数据块被填满则进程的数据被写入新数据块中,以上的整个过程将重复且另一个数据块被分配 。


9.2虚拟文件系统(VFS)




推荐阅读