📄 00000010.htm
字号:
这个主从修订版本号让安装代码能判断此文件系统是否支持只存在于 <BR> 某个特定版本文件系统中的属性。同时它还是特性兼容标志以帮助安 <BR> 装代码判断此文件系统的新特性是否可以安全使用。 <BR>Mount Count and Maximum Mount Count <BR> 系统使用它们来决定是否应对此文件系统进行全面检查。每次文件系 <BR> 统安装时此安装记数将递增,当它等于最大安装记数时系统将显示一 <BR> 条警告信息“maxumal mount count reached, running e2fsck is recommended”。 <BR>Block Group Number <BR> 超块的拷贝。 <BR>Block Size <BR> 以字节记数的文件系统块大小,如1024字节。 <BR>Blocks per Group <BR> 每个组中块数目。当文件系统创建时此块大小被固定下来。 <BR>Free Blocks <BR> 文件系统中空闲块数。 <BR>Free Inodes <BR> 文件系统中空闲Inode数。 <BR>First Inode <BR> 文件系统中第一个inode号。EXT2根文件系统中第一个inode将是指 <BR> 向'/'目录的目录入口。 <BR> <BR>9.1.3 EXT2 组标志符 <BR> <BR>每个数据块组都拥有一个描叙它结构。象超块一样,所有数据块组中的组描 <BR>叙符被复制到每个数据块组中以防文件系统崩溃。每个组描叙符包含以下信息: <BR> <BR> <BR> <BR>Blocks Bitmap <BR> 对应此数据块组的块分配位图的块号。在块分配和回收时使用。 <BR>Inode Bitmap <BR> 对应此数据块组的inode分配位图的块号。在inode分配和回收时使用。 <BR>Inode Table <BR> 对应数据块组的inode表的起始块号。每个inode用下面的EXT2 <BR> inode结构来表示。 <BR>Free blocks count, Free Inodes count, Used directory count <BR> <BR>组描叙符放置在一起形成了组描叙符表。每个数据块组在超块拷贝后包含整 <BR>个组描叙符表。EXT2文件系统仅使用第一个拷贝(在数据块组0中)。其它拷 <BR>贝都象超块拷贝一样用来防止主拷贝被破坏。 <BR> <BR>9.1.4 EXT2 目录 <BR> <BR> <BR>在EXT2文件系统中目录是用来创建和包含文件系统中文件存取路径的特殊文件。 <BR> <BR>目录文件是一组目录入口的链表,它们包含以下信息: <BR> <BR>inode <BR> 对应每个目录入口的inode。它被用来索引储存在数据块组的Inode表中 <BR> 的inode数组。 <BR> <BR>name length <BR> 以字节记数的目录入口长度。 <BR>name <BR> 目录入口的名称 <BR> <BR>每个目录的前两个入口总是"."和".."。它们分别表示当前目录和父目录。 <BR> <BR>9.1.5 在EXT2文件系统中搜寻文件 <BR> <BR>Linux文件名的格式与Unix类似,是一系列以"/"隔开的目录名并以文件名结尾。 <BR>/home/rusling/.cshrc中/home和/rusling都是目录名而文件名为.cshrc。象 <BR>Unix系统一样,Linux并不关心文件名格式本身,它可以由任意可打印字符组 <BR>成。为了寻找EXT2文件系统中表示此文件的inode,系统必须将文件名从目录 <BR>名中分离出来。 <BR> <BR>我们所需要的第一个inode是根文件系统的inode,它被存放在文件系统的超 <BR>块中。为读取某个EXT2 inode,我们必须在适当数据块组的inode表中进行搜 <BR>寻。如果根inode号为42则我们需要数据块组0 inode表的第42个inode。此 <BR>根inode对应于一个EXT2目录,即根inode的mode域将它描叙成目录且其数据 <BR>块包含EXT2目录入口。home目录是许多目录的入口同时此目录给我们提供了 <BR>大量描叙/home目录的inode。我们必须读取此目录以找到rusling目录入口, <BR>此入口又提供了许多描叙/home/rusling目录的inode。最后读取由/home/rusling <BR>目录描叙的inode指向的目录入口以找出.cshrc文件的inode号并从中取得包 <BR>含在文件中信息的数据块。 <BR> <BR> <BR> <BR>9.1.6 改变EXT2文件系统中文件的大小 <BR> <BR>文件系统普遍存在的一个问题是碎块化。一个文件所包含的数据块遍布整个 <BR>文件系统,这使得对文件数据块的顺序访问越来越慢。EXT2文件系统试图通 <BR>过分配一个和当前文件数据块在物理位置上邻接或者至少位于同一个数据块 <BR>组中的新块来解决这个问题。只有在这种分配策略失败时才在其它数据块组 <BR>中分配空间。 <BR> <BR>当进程准备写某文件时, <BR>Linux文件系统首先检查数据是否已经超出了文件最后一个被分配的块空间。 <BR>如果是则必须为此文件分配一个新数据块。进程将一直等待到此分配完成; <BR>然后将其余数据写入此文件。EXT2块分配例程所作的第一件事是对此文件系 <BR>统的EXT2超块加锁。这是因为块分配和回收将导致超块中某些域的改变, <BR>Linux文件系统不能在同一时刻为多个进程进行此类服务。如果另外一个进程 <BR>需要分配更多的数据块时它必须等到此进程完成分配操作为止。 <BR>在超块上等待的进程将被挂起直到超块的控制权被其当前使用者释放。对超 <BR>块的访问遵循先来先服务原则,一旦进程取得了超块的控制则它必须保持到 <BR>操作结束为止。如果系统中空闲块不多则此分配的将失败,进程会释放对文 <BR>件系统超块的控制。 <BR> <BR>如果EXT2文件系统被设成预先分配数据块则我们可以从中取得一个。预先分 <BR>配块实际上并不存在,它们仅仅包含在已分配块的位图中。我们试图为之分 <BR>配新数据块文件所对应的VFS inode包含两个EXT2特殊域:prealloc_block和 <BR>prealloc_count,它们分别代表第一个预先分配数据块的块号以及各自的数 <BR>目。如果没有使用预先分配块或块预先分配数据块策略,则EXT2文件系统必 <BR>须分配一个新块。它首先检查此文件最后一个块后的数据块是否空闲。从逻 <BR>辑上来说这是让其顺序访问更快的最有效块分配策略。如果此块已被使用则 <BR>它会在理想块周围64个块中选择一个。这个块虽然不是最理想但和此文件的 <BR>其它数据块都位于同一个数据块组中。 <BR> <BR>如果此块还是不空闲则进程将在所有其它数据块组中搜寻,直到找到一空闲 <BR>块。块分配代码将在某个数据块组中寻找一个由8个空闲数据块组成的簇。如 <BR>果找不到那么它将取更小的尺寸。如果使用了块预先分配则它将更新相应的 <BR>prealloc_block和prealloc_count。 <BR> <BR>找到空闲块后块分配代码将更新数据块组中的位图并在buffer <BR>cache中为它分配一个数据缓存。这个数据缓存由文件系统支撑设备的标志符 <BR>以及已分配块的块号来标志。缓存中的数据被置0且缓存被标记成dirty以显 <BR>示其内容还没有写入物理磁盘。最后超块也被标记为dirty以表示它已被更新 <BR>并解锁了。如果有进程在等待这个超块则队列中的第一个进程将得到运行并 <BR>取得对超块的独占控制。如果数据块被填满则进程的数据被写入新数据块中, <BR>以上的整个过程将重复且另一个数据块被分配。 <BR> <BR>9.2 虚拟文件系统(VFS) <BR> <BR>Linux核心中虚拟文件系统和实际文件系统间的关系。此虚拟文 <BR>件系统必须能够管理在任何时刻mount到系统的不同文件系统。它通过维护一 <BR>个描叙整个虚拟文件系统和实际已安装文件系统的结构来完成这个工作。 <BR> <BR>容易让人混淆的是VFS使用了和EXT2文件系统类似的方式:超块和inode来描 <BR>叙文件系统。象EXT2inode一样 VFSinode描叙系统中的文件和目录以及VFS中 <BR>的内容和拓扑结构。从现在开始我将用VFSinode和VFS超块来将它们和 <BR>EXT2 inode和超块进行区分。 <BR> <BR>文件系统初始化时将其自身注册到VFS中。它发生在系统启动和操作系统初 <BR>始化时。这些实际文件系统可以构造到核心中也可以设计成可加载模块。 <BR>文件系统模块可以在系统需要时进行加载,例如VFAT就被实现成一个核心 <BR>模块,当mount VFAT文件系统时它将被加载。mount一个基于块设备且包含 <BR>根文件系统的文件系统时,VFS必须读取其超块。每个文件系统类型的超块 <BR>读取例程必须了解文件系统的拓扑结构并将这些信息映射到VFS超块结构中。 <BR>VFS在系统中保存着一组已安装文件系统的链表及其VFS超块。每个VFS <BR>超块包含一些信息以及一个执行特定功能的函数指针。例如表示一个已安装 <BR>EXT2文件系统的超块包含一个指向EXT2相关inode读例程的指针。这个EXT2 <BR>inode读例程象所有文件系统相关读例程一样填充了VFS inode中的域。每个 <BR>VFS超块包含此文件系统中第一个VFS inode的指针。对于根文件系统此inode <BR>表示的是"/"目录。这种信息映射方式对EXT2文件系统非常有效但是对其它 <BR>文件系统要稍差。 <BR> <BR>系统中进程访问目录和文件时将使用系统调用遍历系统的VFS inode。 <BR> <BR>例如键入ls或cat命令则会引起虚拟文件系统对表示此文件系统的VFS inode <BR>的搜寻。由于系统中每个文件与目录都使用一个VFS inode来表示,所以许 <BR>多inode会被重复访问。这些inode被保存在inode cache中以加快访问速度。 <BR>如果某个inode不在inode cache中则必须调用一个文件系统相关例程来读取 <BR>此inode。对这个inode的读将把此它放到inode cache中以备下一次访问。 <BR>不经常使用的VFS inode将会从cache中移出。 <BR> <BR>所有Linux文件系统使用一个通用buffer cache来缓冲来自底层设备的数 <BR>据以便加速对包含此文件系统的物理设备的存取。 <BR> <BR>这个buffer <BR>cache与文件系统无关并被集成到Linux核心分配与读写数据缓存的机制中。 <BR>让Linux文件系统独立于底层介质和设备驱动好处很多。所有的块结构设备 <BR>将其自身注册到Linux核心中并提供基于块的一致性异步接口。象SCSI设备 <BR>这种相对复杂的块设备也是如此。当实际文件系统从底层物理磁盘读取数 <BR>据时,块设备驱动将从它们所控制的设备中读取物理块。buffer cache也 <BR>被集成到了块设备接口中。当文件系统读取数据块时它们将被保存在由
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -