第五章 文件系統

5.1 根文件系統

  衆所周知,在一塊新的硬盤中安裝系統前必須要先分區並且格式化,然後才能裝系統。

  對於windows來說,分區完成以後,每個分區都是一個獨立的文件系統。也就意味着C盤和D盤是毫無關係的。訪問時也是各自獨立的。

  對於linux來說,所有的文件在linux主機上,若想使其能夠被訪問到,站在邏輯結構視角上看,它必須從一個稱爲根文件系統的位置開始,但是並不是說所有文件必須從根開始就不需要分區了,並非如此。爲了能夠實現多個文件系統獨立管理必須要進行分區。但是任何一個分區在分區完以後,不可以被獨立訪問,而是隻能夠與現有的根一起被訪問。

wKiom1jGSH7gDLEkAABJjIACHlI181.jpg

  當內核被啓動加載完成以後,其不提供任何多餘的可供用戶訪問的文件,同時其也不是可供用戶直接使用的有用的進程。所以內核必須要能夠啓動很多外部命令,包括shell程序、各種GUI或者CLI接口等等。而這些命令通常一般都是放在某一分區之上。但是系統中有那麼多分區,內核應該識別哪一個呢?爲了避免這種選擇上的困難,一般來說,無論分成多少個分區,一定有一個作爲系統盤的分區存在,而這個系統盤分區通常是內核啓動完以後第一個要加載的分區。

  如上圖所示,假設A分區是系統盤分區,內核認爲A分區是其必須第一個要加載的分區,於是當內核啓動完以後,爲了能夠幫助啓動各種外圍的其他程序,內核會自行在自己的工作空間中設置一個路徑,把它稱作根。然後把A(系統盤)分區上的所有內容直接關聯到根上。這也就意味着,如果要通過根路徑來訪問的任何文件其實都是在A分區上的文件。

  對於Linux來說,內核所能識別的第一個且必須第一個加載的文件系統就稱作根文件系統(rootfs)。

  一旦A分區被內核認爲是第一個要加載的分區,那麼B分區、C分區、D分區如何被訪問到?在windows中,A分區、B分區、C分區、D分區都是獨立的,想訪問哪個分區就直接去訪問。而在linux中,除A(系統盤)分區以外的任何分區要想被訪問到,必須與現有的根文件系統建立關聯關係。


5.2 常見的文件系統

  常見的文件系統有以下這些:

    Linux文件系統:ext2、ext3、ext4、xfs、btrfs、reiserfs、jfs、swap

      swap:交換分區

      iso9660:光盤文件系統

      ext4:centos6主流的文件系統

      btrfs:centos7自帶的文件系統

      xfs:centos7上推薦使用的文件系統

    Windows文件系統:fat32、ntfs

    Unix文件系統:FFS、UFS、JFS2

    網絡文件系統:NFS、CIFS

    集羣文件系統:GFS2、OCFS2

    分佈式文件系統:ceph、moosefs、mogilefs、Glusterfs、Lustre

  根據其是否支持“Journal”功能又分爲以下2種文件系統:

   日誌型文件系統:ext3、ext4、xfs、...

      日誌型文件系統存儲時先在日誌區寫元數據,如果發生斷電,可以通過日誌進行恢復

    非日誌型文件系統:ext2、vfat    

      非日誌型文件系統存儲時直接在元數據區寫元數據,一旦斷電,沒寫完的數據將損壞且無法恢復

  文件系統的組成部分:

    內核中的模塊:ext4、xfs、vfat等;

    用戶空間的管理工具:mkfs.ext4、mkfs.xfs、mkfs.vfat等

  從上面的信息就可以看出來,Linux支持衆多的文件系統,而每一個文件系統的調用接口又是不一樣的,這對程序員來說就頭疼了,如此多的文件系統,若想針對某文件系統進行編程,就必須瞭解衆多文件系統的調用接口,這樣一來就使得編程的難度大大增加。而事實上,程序員面對的並不是ext2等這類文件系統 ,而是虛擬文件系統(VFS)。VFS把所有文件系統不同的各種調用機制統一在同一個調用接口上了。所以程序員不管系統被格式化成什麼格式的,只要支持VFS,就可以直接調用VFS接口,由VFS去轉換成對特定類型的文件系統接口的調用。Linux衆多的文件系統中,只要遵循POSIX文件系統規範的一般都能夠被VFS所兼容。

  /proc/filesystems:當前內核支持的文件系統類型有哪些

    文件前面沒有nodev的表示是正在使用的文件系統

  文件系統的配置文件/etc/fstab:

    OS在初始時,會自動掛載此文件中定義的每個文件系統。這個文件的內容格式爲:

要掛載的設備    掛載點    文件系統類型    掛載選項    轉儲頻率    文件系統檢測次序(只有根可以爲1)

  要掛載的設備可以有以下幾類:

    設備文件:/dev/sda5

    卷標:LABEL=""

    UUID:UUID=""

    僞文件系統名稱:proc、sysfs、devtmpfs、configfs

  掛載點的要求:

    a) 此目錄沒有被其它進程使用

    b) 目錄必須事先存在

    c) 目錄中原有的文件將會暫時隱藏,卸載後可見

  轉儲頻率:每多少天做一次完全備份,0表示不備份,1表示每天備份,2表示每2天備份1次

  注意:swap分區的掛載點和文件系統類型都是swap。如果要讓文件系統自動掛載的同時啓用某功能,比如要啓用acl功能,只需要在掛載選項defaults後面加上,acl即可,如defaults,acl


5.3 ext文件系統的佈局結構

5.3.1 數據區佈局結構

wKiom1jGSbSCcPHRAAEAsngr3rs374.jpg

  任何一個文件系統都由數據和元數據組成,這裏以ext系統文件系統爲例。

  如上圖,數據區(數據空間)會被劃分爲一個個的塊組,而每個塊組當中又包含了超級塊、塊組描述符(GDT)、塊位圖(block bitmap)、Inode位圖(inode bitmap)、Inode表(inode table)和數據塊(data blocks)。

  每個塊組有多少個塊取決於塊的大小,爲了方便定位塊組中的塊於是定義了一個超級塊

  超級塊可以有多個備份,其內容如下:

    當前文件系統類型;

    當前文件系統包含多少個inode;

    當前文件系統共有多少個塊;

    當前文件系統每個塊的大小;

    空閒磁盤塊、引用磁盤塊、空閒inode、引用inode

  使用tune2fs -l /dev/sda1命令可以看/dev/sda1的超級塊信息。

  塊組描述符表(GDT)可以有多個備份,其內容如下:

    當前系統一共有多少個塊組

    每個塊組從第幾個塊開始到第幾個塊結束

  使用dumpe2fs /dev/sda1命令不僅可以看到/dev/sda1文件系統的超級塊信息,還可以看到塊組描述符的信息。

5.3.2 元數據區

  元數據區包含以下內容:

    Inode表(存儲inode)

    Inode bitmap(索引位圖)

    Block bitmap(塊位圖)


  能夠存儲單個文件所有屬性信息並以特定格式組織的存儲空間就稱爲Inode。

  Inode就是索引節點(Index node)。Inode包含以下內容:

    文件/目錄的大小;

    時間戳;

    權限;

    屬主、屬組;

    地址指針:文件使用了哪些塊存儲數據,用指針指向對應的數據塊的編號

      直接指針(直接指向數據塊)

      間接指針(指向另一個位置,另外一片連續的區域,象擴展分區一樣)

      三級指針

  訪問任何一個文件都要先找到其對應的inode,通過inode知道該文件的數據存儲在哪些塊中,然後找到對應的塊。

  硬盤中的大多數塊必須有其編號,並能夠被inode引用,纔可以正常使用。

  爲了實現inode的快速存儲,元數據區在格式化完成以後就已經把inode整個區間分好了,每個inode塊的大小是固定的,只不過這些inode是空閒的,沒被使用的。

  假設一個文件系統有100萬個inode,那麼如何區分inode是否空閒呢?

  我們假設每一個inode的前面有一個標誌位,1表示已經使用,0表示空閒。當要使用時就必須全局掃描,找到第一個空閒的inode,然後把要存儲inode信息填充其中。

  再假設數據區的每一個block塊的前面也有一個標誌位,1表示已經使用,0表示空閒。當要使用時也必須全局掃描,找到第一個空閒的block塊,然後把數據填充其中並建立與對應inode的映射關係。

  假設一個文件很大,可能需要多個block塊存儲其數據,就必須爲其分配多個連續的空閒塊來存儲,並將已使用的block的標誌位設爲1;

  假設一個文件很小,可能1個block塊就可以存儲其數據,就把其餘多餘的block標誌位設爲0

5.3.4 位圖索引

  想一個問題,如果硬盤有100G,爲了找一個空閒塊就要全盤掃描一遍,這樣的方式太低效了,爲了解決這個問題於是就有了二級索引。

  由於inode的量很大,從中找一個空閒的inode會很慢,這時候可以找一個連續的存儲空間,對inode做一個對位標識索引,第0位對應編號爲0的inode編號,第1位對應編號爲1的inode編號,以此類推。有N個二進制位,如果這個位爲1表示這個對應的inode已被使用,這個位爲0表示其對應的Inode空閒。當要創建inode時,就不用再全盤掃描了,只需要掃描這個二級索引(對位標識索引),如此一來,效率就大大提高了。而這個二級索引就是inode位圖索引(inode bitmap)。數據區以同樣的原理就有了塊位圖(block bitmap)

  inode bitmap:對位標識每個inode空閒與否的狀態信息

  如果整盤進行管理,假設整盤有100萬個塊,100萬個塊掃描一遍也挺耗時間的。所以無論是inode位圖還是block位圖,都不是全文件系統管理的,而是塊組管理的。

5.3.5 文件訪問過程

  a) 查索引節點(Inode)

  b) 在索引節點中找到磁盤塊的編號

  c) 在數據區找到對應的磁盤塊

5.3.6 目錄

wKioL1jGSzSj-LObAABRRoTzYLw573.jpg

  文件訪問時要先查inode,但是inode表中包含很多的inode,如何確定文件對應的Inode是哪個呢?這就是目錄的作用。

  目錄也是一個文件,存在數據區的一個塊中,目錄實質上就是一個路徑映射。

  目錄中存儲着以下內容:

  a) 一級目錄下所有的文件名列表

  b) 一級目錄下所有文件對應的inode編號

5.3.7 文件創建

  a) 在元數據區找一個空閒的inode塊存儲inode信息

  b) 在數據區找一個或一些空閒的block塊,並將其與inode建立映射關係

  c) 把數據填充至這些block塊中

  d) 把標誌位設爲1(正在使用中的狀態)

5.3.8 硬鏈接

  多個文件指向同一個inode,稱之爲硬鏈接。這些文件名稱可相同也可不同,不能鏈接不同文件系統的文件。

  硬鏈接特點:

  a) 只能對文件創建,不能應用於目錄;

  b) 不能跨文件系統;

  c) 創建硬鏈接會增加文件被鏈接的次數

5.3.9 軟鏈接

  軟鏈接又叫符號鏈接,這個文件包含了另一個文件的路徑名。可以是任意文件或目錄,可以鏈接不同文件系統的文件。

  軟鏈接特點:

  a) 可應用於目錄;

  b) 可以跨文件系統;

  c) 不會增加被鏈接文件的鏈接次數;

  d) 其大小爲指定的路徑所包含的字符個數

  創建軟鏈接:

ln [-s -v] SRC DEST


5.4 btrfs文件系統

5.4.1 btrfs文件系統介紹

  btrfs文件系統自centos7後開始支持。

  Btrfs(B-tree,Butter FS,Better FS),遵循GPL規範,由Oracle自2007年開始研發。

  Btrfs文件系統的核心特性:

  a) 支持寫時複製機制(CoW):複製、更新及替換指針,而非傳統的“就地”更新

  假設要修改一個文件,寫時複製機制就是先把這個文件複製一個副本出來,然後對這個副本進行修改,修改完以後將文件名的指針由指向原文件改爲指向這個副本。

  如此一來,原文件還在內存中,若副本修改有誤還可以通過恢復指針指向的方法還原成原文件

  b) 多物理卷支持

  btrfs可由多個底層物理卷組成,支持RAID,以聯機“添加”、“移除”、“修改”

  c) 支持數據及元數據校驗碼機制(CheckSum)

  存儲文件時,會將元數據的校驗碼和數據的校驗碼通過文件某些屬性擴展給保存下來。因此文件讀取時可以很方便、快速的去檢測文件是否受損,一旦受損還會自動嘗試進行修復

  d) 支持子卷(sub_volume,相當於ext系列文件系統的lvm/lvm2)

  可以將多個底層的物理設備(硬盤)組織成btrfs文件系統,這個btrfs文件系統可以直接掛載使用,也可以在內部創建子卷(就像在VG中創建LV一樣)

  e) 支持快照(快照是子卷的一個非完全副本,基於CoW機制實現的另外一個存儲空間剛開始爲0的一個卷)

  btrfs文件系統直接支持快照,而ext3/ext4要想支持快照必須使用lvm2來實現

  可以針對單個文件做快照,也可以針對卷做快照

  還支持對做好的快照再做一次快照,做累積性快照。類似於實現增量備份

  f) 支持透明壓縮機制

  當要存儲一個很大的文件,但又想節約空間的時候,可以把任何數據流發往btrfs文件系統時,自動能夠通過佔據CPU時鐘週期完成數據壓縮以後存放,對用戶來說這個過程是透明的。在讀取這些壓縮後存放的文件時,能夠自動解壓縮。

  有一個缺陷:壓縮和解壓縮會佔據更多的時鐘週期

  Btrfs主要設計目標是取代Linux早期一直使用的ext3、ext4,但事實上在ext3、ext4的缺陷暴露之後,在centos6上就提供了另外一種可用的文件系統(xfs)。

5.4.2 btrfs文件系統的實現

  mkfs.btrfs:創建btrfs文件系統

    -L|--label <name>:指定卷標

    -m|--metadata <profile>:指明元數據如何存放

      Valid values are raid0,raid1,raid5,raid6,raid10,single or dup

    -d|--data <type>:指明數據如何存放

      Valid values are raid0,raid1,raid5,raid6,raid10 or single

    -O|--features <feature1>[,<feature2>...]:在格式化時直接開啓指定的功能

      A list of filesystem features turned on at mkfs time.Not all features are supported by old kernels.

      To see all features run

        mkfs.btrfs -O list-all

  常用的btrfs文件系統的命令:

    btrfs:管理btrfs文件系統

btrfs filesystem show [--mounted|--all-devices|<uuid>]    #顯示btrfs文件系統信息
btrfs filesystem sync <path>                              #強制把指定btrfs文件系統緩存在內存中的數據同步到硬盤中
btrfs filesystem df <path> [<path>...]                    #查看已掛載的btrfs文件系統空間使用率
btrfs filesystem defragment [options] <file>|<dir> [<file>|<dir>...]     #消除磁盤碎片
btrfs filesystem resize [devid:][+/-]<size>[gkm]|[devid:]max <path>      #修改文件系統大小
btrfs filesystem label [<device>|<mount_point>] [<newlabel>]             #顯示或更新btrfs文件系統卷標

    掛載btrfs文件系統:

mount -t btrfs /dev/sdb MOUNT_POINT    #/dev/sdb這個位置只要是btrfs文件系統的底層物理卷之一,隨便寫哪個物理卷名均可

    透明壓縮機制:

mount -o compress={lzo|zlib} DEVICE MOUNT_POINT

    btrfs-convert:實現無損地將ext系列的文件系統動態轉換成btrfs文件系統或將btrfs文件系統降級爲ext系列的文件系統

    btrfsck:實現文件系統的檢測

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章