文件系統基礎知識,看這一篇就夠了!

當初上課上的迷迷糊糊,最近我查閱了一些資料,將文件系統中的基礎知識有邏輯的整理出來。node

  1. 什麼是文件?
  2. unix中的目錄是什麼?
  3. 如何理解硬連接和軟連接?(文件共享)
  4. 目錄中是如何檢索文件的?
  5. 文件的邏輯結構和物理結構?或者說文件再磁盤上是如何被組織起來的?
  6. 空閒文件的組織與管理?
  7. 磁盤的組織與管理?

什麼是文件?

提到文件,大多數人的腦子中確定首先浮現的是pdf、jpg,mp3等文件。他們確實是文件,可是你腦子中所想的只是文件的文件體,也就是文件真正的數據(一些二進制流)所在。數據庫

那麼要對文件進行管理,只有這些數據不夠,還須要一些描述信息(文件名、文件內部標識、文件存儲地址、訪問權限、訪問時間),這些描述信息能夠稱爲文件說明,也能夠稱爲文件控制塊(FCB)。windows

因此unix中的文件 = 文件體 + 文件描述信息數據結構

下面思考一個問題:函數

XV6和全部的Unix文件系統都支持經過系統調用建立連接,給同一個文件指定多個名字。你能夠經過調用link系統調用,爲以前建立的文件「x/y」建立另外一個名字「x/z」。即便在windows中也能有建立快捷方式,將同一個文件重命名並存放在不一樣的位置。而兩個文件訪問的內容確是如出一轍的。

因此,在文件系統內部,文件描述符必然與某個對象關聯,而這個對象不依賴文件名spa

那麼這個對象就是你們熟知的inode(index node,索引結點)。inode是什麼,直接拿inode的數據結構來看是最好不過的了。除此以外,系統會爲每個inode分配一個惟一的編號設計

inode的數據結構:unix

  • 一般來講它有一個type字段,代表inode是文件仍是目錄。
  • nlink字段,也就是link計數器,用來跟蹤究竟有多少文件名指向了當前的inode。
  • size字段,代表了文件數據有多少個字節。
  • 不一樣文件系統中的表達方式可能不同,不過在XV6中接下來是一些block的編號,例如編號0,編號1,等等。XV6的inode中總共有12個block編號。這些被稱爲direct block number。這12個block編號指向了構成文件的前12個block。舉個例子,若是文件只有2個字節,那麼只會有一個block編號0,它包含的數字是磁盤上文件前2個字節的block的位置。
  • 以後還有一個indirect block number(當文件數據過於大的時候,用於擴展,此處咱們不詳細討論它)

從上面能夠知道,inode中存了文件體(也就是文件真實的數據)的地址,經過inode找到文件內容。這樣一層封裝,使得不一樣的文件名均可以映射到這個inode上來,從而找到文件數據。指針

但是,文件名去哪了呢?inode中的內容很像上面講的文件說明(文件描述信息),其實正是。不過偏偏缺了文件名。而文件名和inode編號之間必然有一個映射表,這張表又在哪裏呢?答案就在目錄對象

unix中的目錄是什麼?

目錄就是一個文件

一會兒可能沒法理解,仍是從你的思想出發,提到目錄你可能想到一個文件夾內部的結構。就大概這麼一張圖,也就是說目錄內部應該包括一些文件(此處的文件指的就是通常的文件以下圖中的mmap文件)和子目錄(下圖中的存儲管理、IO、基礎知識都仍是一個目錄)。

接下來就好理解了,目錄是一個文件,文件體(數據)中存的就是這些文件/子目錄的文件名和inode編號的映射表!

也就是說,對於每一個文件而言,其文件名和真實的數據是存儲在不一樣的物理位置上的。

舉個經典例子經過路徑查找文件的過程:/home/alex/main.py

/能夠理解爲根目錄,根目錄由於是固定的,因此其inode的位置是系統已知的。那麼先找到root的inode的編號(此處須要說明能夠經過inode編號直接計算出inode的地址,具體計算方式不在此贅述),讀取其信息,其那些文件體的地址,而後找到文件體,發現裏面都是文件名/子目錄名與inode編號的映射關係,逐一遍歷文件名(以後在檢索中還有其餘方式,此處爲線性檢索)而後找到匹配的「home」,查到它的inode編號,獲取其inode中的內容,而後找到真實的數據。以此類推,找到alex目錄文件的inode編號,繼而再找到main文件的inode編號。此時,main文件的inode中的指針指向的就是main.py真實的數據。

有一個很是有趣的現象,就是文件名是由其目錄所存儲的。而root文件沒有上一級目錄了,因此root是沒有文件名,或者說是一個空的文件名,只用一個/表示。/home/alex/main.py能夠理解爲空/home/alex/main.py。

如何理解硬連接和軟連接?

理解了inode概念,再來理解硬連接就不要太容易了!

硬連接感性的理解,就是爲同一個inode取了一個新名字,這樣新名字和舊名字對應的inode編號都是同一個文件。那麼爲何要設計硬連接呢?固然是由於要共享咯!同時須要注意的是,在inode中有個屬性叫作nlink,當有一個新的硬連接時,inode會將這個值加一,代表這個文件在被其餘人共享。當刪除這個硬連接時,inode會判斷nlink是否爲1,若爲1,則代表是這個文件最後一個主人要把我刪除,那麼在刪除硬連接的同時,數據也會被刪除;不然,直接將nlink減一便可。

硬連接存在的問題:文件的建立者不能刪除文件。由於文件被共享以後,只有文件的最後一個全部者才能刪除文件。

此處思考一個有趣的現象,是我本身的推測。爲何不直接將全部的文件描述存在目錄文件中呢?也就是說能不能讓目錄文件中的目錄項爲文件名與文件描述(原先inode中存儲的信息)的映射呢?這樣就不要先經過文件名找到inode,再經過inode找到文件描述了。

考慮一下,若是此時出現大量的硬連接,並且仍是對同一個文件的,那麼文件的文件描述就會被重複存儲。(數據庫中稱之爲傳遞依賴)那麼將這些文件描述分離出去,當作一個inode存儲,在原表中放置inode的編號。

引入軟連接,能夠解決上述的問題。軟連接實際上是存儲了被共享文件的路徑名,這個路徑名能夠是絕對路徑也能夠是相對路徑。因此軟連接的inode和被共享文件的inode不一樣,當經過軟連接查找文件時,實際上是先獲取到被共享文件的路徑名,而後循着這個路徑查找文件。這樣一來,若文件的建立者將文件刪除,那麼即便有着這個路徑名也沒法查找到對應的文件。

同時,軟連接也存在一些問題,就是每次都得經過路徑逐層查找,開銷較大。

目錄中是如何檢索文件的?

首先解答一個問題,就是目錄的結構是怎樣的?咱們如今可能很好回答,應該是樹狀結構的。沒錯,可是目錄結構最開始有單級目錄結構、二級目錄結構。再是樹狀結構,圖狀結構的。

單級目錄結構就是將全部的目錄項堆在一個表中。二級目錄結構是按照用戶分了一級出來,每一個用戶本身的目錄項仍是堆在一個表中。樹狀結構是對二級目錄結構的推廣,或者能夠稱之爲多級目錄結構。

檢索文件的方式:線性表、哈希表。線性表以前已經論述過了,哈希表也就是散列存儲,經過文件名直接輸入到散列函數中便可獲得inode編號。

未完待續...

相關文章
相關標籤/搜索