第七章 Linux文件系統(一)

1.文件系統特性

磁盤分區后還需要進行格式化后操作系統才能使用這個文件系統,為什么要格式化?

因為每個操作系統所設定的文件屬性、權限不一樣,因此需要將分區槽格式化,以成為操作系統能夠利用的"文件系統格式"。

傳統技術中,一個分區槽只能被格式化成為一個文件系統,所以我們可以說一個filesystem是一個partition。但由于新技術的發展,例如LVM與軟件磁盤陣列(software raid),可以將一個分區槽格式化為多個文件系統,也能將多個分區槽格式化為一個文件系統。所以說,通常我們稱"一個可被掛載的數據為一個文件系統而不是一個分區槽"。

文件系統通常將操作系統的文件權限(rwx)和文件屬性(擁有者、群組、時間參數等)分別存放在不同的區塊,權限與屬性放到inode中,至于實際數據放到data block中。另外,還有一個超級區塊:

  • superblock:記錄整個文件系統的整體信息,包括inode與block的總量、使用量、剩余量等。

  • inode:記錄文件的權限與相關屬性,一個文件占用一個inode,同時記錄此文件的數據所在的block號碼。

  • block:實際記錄文件的內容,若文件太大時,會占用多個block。

由于每個inode與block都有編號,而每個文件都會占用一個inode,inode內會放置有block號碼,也就能夠讀文件的實際數據。如下圖所示:

inode/block資料存取示意圖

假設一個文件的屬性與權限數據放到了inode4號,而這個inode記錄了文件數據的實際放置點是2、7、13、15,操作系統就能夠據此來排列磁盤的閱讀順序。這種數據存取方法我們稱為"索引式文件系統"。

還有慣用的是"隨身碟",文件系統一般為FAT格式:

FAT文件系統資料存取示意圖

這個文件系統沒有辦法一口氣知道4個block的號碼,它得將每個block讀出,才知道下一個block在哪。如果同一個文件數據寫入的block分散的厲害,磁盤頭就需要轉好幾圈才能完整讀取到文件的內容。

Linux的EXT2文件系統(inode)

文件系統一開始就將inode與block規劃好了,除非重新格式化,否則inode與block固定后就不再變動。但如果文件系統有幾百GB時,所有的inode與block放置在一起時很不明智的。

所以,EXT2文件系統在格式化的時候基本上時區分為多個區塊群組,每個群組都有自己獨立的inode/block/superblock系統。如下圖所示:

ext2文件系統示意圖
  • data block

用來放置文件內容數據,在EXT2文件系統中所支持的block大小有1K、2K、4K三種。

block大小產生的EXT2文件系統限制

除了大小限制還有什么限制?基本限制如下:

block的大小與數量在格式化完就不能在改變了

每個block內最多只能存放一個文件的數據

如果文件大于block的大小,則一個文件會占用多個block數量

如果文件小于block的大小,則該block的剩余容量就不能在被使用

  • inode table

inode記錄文件的屬性以及該文件實際數據放置在哪個block內。inode記錄的文件數據至少有以下這些:

該文件的存取模式(read/write/excute)

該文件的擁有者與群組(owner/group)

該文件的容量

該文件建立或狀態改變的事件(ctime)

最近一次的讀取時間(atime)

最近修改的時間(mtime)

定義文件特性的旗標(flag),如SetUID...

該文件真正內容的指向(pointer)

inode的特點:

數量與大小也是在格式化時就已經固定了

每個inode大小均固定為128bytes(新的ext4)

每個文件都只占用一個inode

文件系統能建立都文件數量與inode的數量有關

系統讀取文件時需要先找到inode,并分析inode記錄的權限與用戶是否符合,符合才能開始實際讀取block的內容

我們來分析以下EXT2的inode/block與文件大小的關系。inode要記錄的數據非常多,但大小只有128bytes,而inode記錄一個block號碼要花掉4byte,假設我有一個文件有400MB且每個block為4K時,那么至少要10w個block號碼記錄。inode哪有這么多可記錄的信息?為此我們系統將inode記錄與block號碼的區域定義為12個直接,1個間接,1個雙間接,1個三間接記錄區,結構如下所示:

inode結構示意圖

假設我們以1K block大小來說明:

12個直接指向:12*1K=12K
直接指向就是直接存放的block的數據,總共可記錄12筆

間接:256*1K=256K
拿到額外一個block專門存取block號碼,每個block號碼記錄花去4bytes,1K的大小能記錄256個block。

雙間接:2562561K=256^2K
第一層block會指定256個第二層,每個第二層可以指定256個block號碼

三間接:256256256*1K=256^3K
第一層block會指定256個第二層,每個第二層指定256個第三層,每個第三層指定256個block號碼

  • superblock

記錄整個文件系統相關信息的地方,主要記錄的信息有:

block與inode的總量

未使用與已使用的inode/block數量

block與inode的大小(block為1,2,4K;inode為128或256bytes)

filesystem的掛載時間、最近一次寫入數據的時間、最近一次檢驗磁盤的時間等文件系統的相關信息

一個valid bit數值,若此文件系統已被掛載,則valid bit為0,沒被掛載就為1。

一般來說,supderblock大小為1024bytes

我們說一個文件系統應該只有一個superblock,但是后續的block group可能還會有superblock,這是為了防止superblock死掉,進行的備份。

  • filesystem Description(文件系統描述說明)

這個區段描述每個block group的開始與結束的block號碼,以及說明每個區段(superblock、bitmap、inodemap、data block)分別介于哪一個block號碼之間。

  • block bitmap(區塊對照表)
    在新增文件的時候總會用到block,那怎么知道哪個block是空的呢,這就需要block bitmap的輔助了,能夠快速找到可使用的空間。

  • inode bitmap(inode對照表)
    這個和block bitmap相似的功能。記錄inode使用與未使用的號碼。

2.文件系統與目錄樹

2.1 目錄

在Linux下的文件系統建立一個目錄時,文件系統會給該目錄分配一個inode與至少一個block。其中,inode記錄該目錄的相關權限與屬性,并可以記錄分配到了哪塊block號碼;block記錄了這個目錄下的文件名與文件名占用的inode號碼數據。

可以使用命令"ls -il"選項查看某個目錄下的文件所占用的inode號碼

[jumpserver@xxx tomcat-analysis]$ ls -il
total 108
   239384 drwxr-xr-x. 2 jumpserver root  4096 Apr  2 14:12 bin
268848599 drwxr-xr-x. 3 jumpserver root  4096 Apr  3 10:41 conf
538441458 drwxr-xr-x. 2 jumpserver root  4096 Apr  2 14:12 lib
268848635 -rw-r--r--. 1 jumpserver root 56846 Sep 14  2016 LICENSE
537335010 drwxr-xr-x. 3 jumpserver root  4096 Apr 10 15:08 logs
268848636 -rw-r--r--. 1 jumpserver root  1239 Sep 14  2016 NOTICE
268848637 -rw-r--r--. 1 jumpserver root  8965 Sep 14  2016 RELEASE-NOTES
268848638 -rw-r--r--. 1 jumpserver root 16195 Sep 14  2016 RUNNING.txt
807646942 drwxr-xr-x. 2 jumpserver root    29 Apr  2 14:12 temp
   239395 drwxr-xr-x. 9 jumpserver root  4096 Apr  4 10:26 webapps
268848634 drwxr-xr-x. 3 jumpserver root    21 Apr  3 10:31 work

2.2 文件

在Linux下的EXT2下建立一個一般文件時,EXT2會分配一個inode和相對于該文件大小的block數量給該文件。

例如:假設block為4KB,我們要建立一個100KB的文件,那么Linux將分配一個inode和25個block來存儲該文件。注意:inode只有12個直接指向,因此還要多一個block來作為區塊號碼的記錄。

2.3 目錄樹讀取

inode本身并不記錄文件名,文件名的記錄在目錄的block中。所以我們在第五章文件與目錄的權限說明中,才會提到"新增、刪除、更名文件名與目錄的w權限有關"。

目錄樹是由根目錄開始讀起的,系統通過掛載的信息可以找到掛載點的inode號碼,此時就能夠得到根目錄的inode內容,根據該inode讀取根目錄的block內的文件名數據,再一層一層向下讀到正確的檔名。例如:我們想讀取"/etc/passwd"這個文件,系統由以下步驟:

[jumpserver@xxx tomcat-analysis]$ ll -di / /etc/ /etc/passwd
     128 dr-xr-xr-x. 18 root root 4096 Aug 10  2018 /
16777345 drwxr-xr-x. 91 root root 8192 Mar 30 03:45 /etc/
18615857 -rw-r--r--.  1 root root 1613 Mar 15 15:53 /etc/passwd
[jumpserver@host-172-16-13-249 tomcat-analysis]$
    1. / 的inode:通過掛載點的信息找到inode號碼為128的根目錄inode,且inode規范的權限讓我們可以讀取該block的內容(由r、x)
    1. / 的block:經過上面步驟取得block號碼,并找到該內容有/etc目錄的inode號碼(16777345)
    1. etc/ 的inode:讀取16777345號inode得知root具有r、x的權限,因此可以讀取etc/的block
  • 4.etc/ 的block:經過上個步驟取得block號碼,并找到該內容有passwd文件的inode號碼(18615857)

  • 5.passwd的inode:讀取18615857號inode得知root有r的權限,因此可以讀取passwd的block內容

  • 6.passwd的block:最后將該block內容的數據讀出來

2.4 磁盤讀取功能

當你的文件系統很大時,例如100GB,由于磁盤上面的數據總是來來去去,所以正規文件系統的文件通常無法連續卸載一起(block號碼不會連續),而是填入式的將數據填入未被使用的block中。這樣就會有所謂的"文件數據離散"問題。

它導致的結果就是讀取效率很低,因為磁盤讀取頭要在正規文件系統中反反復復的頻繁讀取。不過,你可以將整個文件系統的數據全部復制出來,將該系統重新格式化,再將數據復制回去可以解決這個問題。

EXT2/EXT3/EXT4 文件的存取與日志式文件系統的功能

假設我們想要新增一個文件,它的行為是怎樣的呢?

  • 1.先確定用戶對想要新增文件的目錄是否有w與x的權限;

  • 2.根據inode bitmap找到沒有使用的inode號碼,并將新文件的權限/屬性寫入;

  • 3.根據block bitmap找到沒有使用的block號碼,并將實際數據寫入block中,且更新的inode的block指向;

  • 4.將剛剛寫入的inode與block數據同步更新inode bitmap與block bitmap,并更新superblock的內容。

數據不一致的狀態:正常情況下,新增可以順利完成。如果在數據寫入inode table及data block后突然停電等突發狀況,最后一個superblock的同步更新步驟沒有做完,此時就會發生metadata的內容與實際數據存放區產生不一致。

早期的EXT2中,如果發生這個問題,系統在重啟的時候,就會把superblock記錄的valid bit(是否有掛載)與filesystem state(是否clean)等狀態來判斷是否需要進行數據一致性檢查。這樣的檢查真的很費時,metadata區域與實際數據存放區進行比對,要搜索整個filesystem!

日志式文件系統

為了避免上面的問題發生,后來想到一種方式:如果在我們的filesystem中規劃出一個區塊,該區塊專門記錄寫入活修訂文件的步驟:

  • 1.預備:當系統要寫入一個文件時,會先在日志記錄區塊中記錄某個文件準備要寫入的信息。

  • 2.實際寫入:開始寫入文件的權限與數據;開始更新metadata的數據。

  • 3.結束:完成數據與metadata的更新后,在日志記錄區塊中完成該文件的記錄。

EXT3/EXT4是EXT2的升級版本,并可向下兼容。我們可以用"dumpe2fs"查看輸出的訊息,可以發現superblock里面含有journal處理日志區塊的記錄。

3.Linux文件系統的運作

3.1 大文件的運作

所有的數據要加載到內存后CPU才能對該數據進行處理。如果你編輯一個大文件,編輯過程中又頻繁的要系統來寫入到磁盤中,由于磁盤寫入的速度比內存慢很多,因此會常常等待磁盤的寫入/讀取效率!

為了解決整個問題,Linux使用的方式是異步處理(asynchronously):

當系統加載一個文件到內存后,如果該文件沒有被動過,則在內存區段的文件數據會被設定為干凈(clean)的。但如果內存中但文件數據被改過,此時該內存的數據會被設定為臟的(Dirty),此時所有的動作都還在內存中執行,并沒有寫入磁盤中。系統會不定時的將內存中設定為"Dirty"的數據寫回磁盤。其實也就是緩沖的功能。

3.2 掛載點的意義

每個filesystem都有獨立的inode/block/superblock等信息,這個文件系統要能夠鏈接到目錄樹才能被我們使用。將文件系統與目錄樹結合的動作我們成為"掛載"。

注意:掛載點一定是目錄,該目錄為進入該文件系統的入口。

舉例來說,CentOS7.x應該有3個掛載點,分別是"/","/boot","/home"。如果我們觀察這3個目錄的inode號碼,可以發現:

由于XFS文件系統最頂層的目錄inode一般為128,因此可以發現"/","/boot","/home"為3個不同的fielsystem。(因為每行的文件屬性不相同,并且3個目錄掛載點也不同)。

4.XFS文件系統

CentOS7開始,預設的文件系統由EXT4變成了XFS文件系統。這是由于哪些原因?

4.1 EXT家族目前的問題:支持度最廣,但格式化很慢!

EXT文件系統對于文件格式化處理,采用但是預先規劃出所有的inode/block/metadata等數據。早期磁盤容量不大這個還沒什么問題,但現在磁盤容量越來越大。光是系統要預先分配inode與block就要消耗很長很長時間了。

4.2 XFS文件系統配置

XFS在文件系統資料分布上,主要有3個部分:數據區(data section)、文件系統活動登錄區(log section)、實時運作區(realtime section)。

  • 1.數據區(data section)

像EXT家族一樣,包括inode/datablock/superblock等,都放在這個區塊。這個數據去與EXT的block group類似,分為多個儲存區群組(allocation groups)來分別放置文件系統所需要的數據。

每個存儲區又包含:整個文件系統的superblock;剩余空間的管理機制;inode的分配與追蹤。此外,inode與block都是系統需要用到時,才動態配置產生,所以格式化很快!

  • 2.文件系統活動登錄區(log section)

主要來記錄文件系統的變化。如果文件系統因為某些故障損毀時,系統會拿這個登錄區來進行檢驗,查看系統掛掉前,文件系統正在做哪些動作。

  • 3.實時運作區(realtime section)

有文件要被建立時,XFS會在這個區段里找一個或多個extent區塊,將文件放置在這個區塊內,等分配完成后,再寫入data section的inode與block。extent區塊的大小要在格式化的時候就先指定,最小4K最大1GB。

4.3 XFS文件系統的描述數據觀察

有么有像EXT家族的dumpe2fs一樣可以觀察superblock內容的相關指令?我們可以用xfs_info。

xfs指令
  • 第1行里面的isize指inode的容量,每個有256bytes大小。agcount是儲存區群組的個數,一共是4個。agsize是指每個儲存區具有65536個block。配合第4行的block設定為4K,因此整個文件系統的容量是4655364K這么大。

  • 第2行sectsz指邏輯扇區(sector)的容量設定為512bytes。

  • 第4行bsize指block的容量,每個block為4K,共有262144個block在這個文件系統內。

  • 第5行第sunit與swidth與磁盤陣列第stripe相關性較高。下面說明。

  • 第7行internal指這個登錄區的位置在文件系統內,而不是外部設備的意思。占用4K*2560個block,總共月10MB的容量。

  • 第9行的realtime區域,里面的extent容量為4K。目前沒有使用。

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,333評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,491評論 3 416
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,263評論 0 374
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,946評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,708評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,186評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,255評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,409評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,939評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,774評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,976評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,518評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,209評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,641評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,872評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,650評論 3 391
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,958評論 2 373

推薦閱讀更多精彩內容