Inode

inode（index node）是指在許多“類Unix文件系統”中的一種數據結構，用於描述文件系統對象（包括文件、目錄、設備文件、socket、管道等）。每個inode保存了文件系統對象數據的屬性和磁盤塊位置。文件系統對象屬性包含了各種元數據（如：最後修改時間） ，也包含用戶組（owner）和權限數據。

**命名**
Unix先驅丹尼斯·裡奇說，inode這個命名的來源可能是文件系統的存儲組織為一個扁平數組，分層目錄資訊使用一個數作為文件系統這個扁平數組的索引值（index）。

**細節**
Unix上的文件描述符、文件表與inode表 
文件系統創建（格式化）時，就把存儲區域分為兩大連續的存儲區域。一個用來保存文件系統對象的元信息數據，這是由inode組成的表，每個inode默認是256字節或者128字節。另一個用來保存“文件系統對象”的內容數據，劃分為512字節的扇區，以及由8個扇區組成的4K字節的塊。塊是讀寫時的基本單位。一個文件系統的inode的總數一般情況下是固定的。這限制了該文件系統所能存儲的文件系統對象的總數目。典型的實現下，所有inode佔用了文件系統1%左右的存儲容量。
文件系統中每個“文件系統對象”對應一個“inode”數據，並用一個整數值來辨識。這個整數常被稱為inode號碼（“i-number”或“inode number”）。由於文件系統的inode表的存儲位置、總條目數量都是固定的，因此可以用inode號碼去索引查找inode表。
Inode存儲了文件系統對象的一些元信息，如所有者、訪問權限（讀、寫、執行）、類型（是文件還是目錄）、內容修改時間、inode修改時間、上次訪問時間、對應的文件系統存儲塊的地址，等等。知道了1個文件的inode號碼，就可以在inode元數據中查出文件內容數據的存儲地址。 
文件名與目錄名是“文件系統對象”便於使用的別名。一個文件系統對象可以有多個別名，但只能有一個inode，並用這個inode來索引文件系統對象的存儲位置。- inode不包含文件名或目錄名的字符串，只包含文件或目錄的“元信息”。- Unix的文件系統的目錄也是一種文件。打開目錄，實際上就是讀取“目錄文件”。目錄文件的結構是一系列目錄項（dirent）的列表。每個目錄項，由兩部分組成：所包含文件或目錄的名字，以及該文件或目錄名對應的inode號碼。
*文件系統中的一個文件是指存放在其所屬目錄的“目錄文件”中的一個目錄項，其所對應的inode的類別為“文件”；文件系統中的一個目錄是指存放在其“父目錄文件”中的一個目錄項，其所對應的inode的類別為“目錄”。可見，多個“文件”可以對應同一個inode；多個“目錄”可以對應同一個inode。
*文件系統中如果兩個文件或者兩個目錄具有相同的inode號碼，那麼就稱它們是“硬鏈接”關係。實際上都是這個inode的別名。換句話說，一個inode對應的所有文件（或目錄）中的每一個，都對應著文件系統某個“目錄文件”中唯一的一個目錄項。
*創建一個目錄時，實際做了3件事：在其“父目錄文件”中增加一個條目；分配一個inode；再分配一個存儲塊，用來保存當前被創建目錄包含的文件與子目錄。被創建的“目錄文件”中自動生成兩個子目錄的條目，名稱分別是：“.”和“..”。前者與該目錄具有相同的inode號碼，因此是該目錄的一個“硬鏈接”。後者的inode號碼就是該目錄的父目錄的inode號碼。所以，任何一個目錄的"硬鏈接"總數，總是等於它的子目錄總數（含隱藏目錄）加2。即每個“子目錄文件”中的“..”條目，加上它自身的“目錄文件”中的“.”條目，再加上“父目錄文件”中的對應該目錄的條目。- 通過文件名打開文件，實際上是分成三步實現：首先，操作系統找到這個文件名對應的inode號碼；其次，通過inode號碼，獲取inode信息；最後，根據inode信息，找到文件數據所在的block，讀出數據。
Linux系統使用struct inode作為數據結構名稱。BSD派生的系統，使用vnode名稱，其中v表示“virtual file system”。

**POSIX inode**
POSIX 標準強制規範的文件系統的行為受到傳統 UNIX 文件系統的深刻影響。可以用短語“文件序列號”來形容inode，定義為文件系統範圍的唯一文件標識符。上述的文件序列號和包含此文件的設備ID一起，在整個系統上對應唯一的文件。
在POSIX系統上，可使用stat系統調用取得文件的下列屬性： 
*以字節為單位表示的文件大小。
*設備ID，標識容納該文件的設備。
*文件所有者的User ID。
*文件的Group ID
*文件的模式（mode），確定了文件的類型，以及它的所有者、它的group、其它用戶訪問此文件的權限。
*額外的系統與用戶標誌（flag），用來保護該文件。
*3個時間戳，記錄了inode自身被修改（ctime, inode change time）、文件內容被修改（mtime, modification time）、最後一次訪問（atime, access time）的時間。
*1個鏈接數，表示有多少個硬鏈接指向此inode。
*到文件系統存儲位置的指針。通常是1K字節或者2K字節的存儲容量為基本單位。
可以查詢一個文件的inode號碼及一些元信息。 

**推論**
一個文件系統對象可以有多個名字，這些具有硬鏈接關係的文件系統對象名字具有相同的inode號碼，彼此是平等的。即首個被創建的文件並沒有特殊的地位。這與符號鏈接不同。一個符號鏈接文件有自己的inode，符號鏈接文件的內容是它所指向的文件的名字。因此刪除符號鏈接所指向的文件，將導致這個符號鏈接文件在訪問時報錯。
*刪除一個文件或目錄，實際上是把它的inode的鏈接數減1。這並不影響指向此inode的別的硬鏈接。
*一個inode如果沒有硬鏈接，此時inode的鏈接數為0，文件系統將回收該inode所指向的存儲塊，並回收該inode自身。
*從一個inode，通常是無法確定是用哪個文件名查到此inode號碼的。打開一個文件後，操作系統實際上就拋掉了文件名，只保留了inode號碼來訪問文件的內容。庫函數getcwd()用來查詢當前工作目錄的絕對路徑名。其實現是從當前工作目錄的inode逐級查找其上級目錄的inode，最後拼出整個絕對路徑的名字。
*歷史上，對目錄的硬鏈接是可能的。這可以使目錄結構成為一個有向圖，而不是通常的目錄樹的有向無環圖。一個目錄甚至可以是自身的父目錄。現代文件系統一般禁止這些混淆狀態，只有根目錄保持了特例：根目錄是自身的父目錄。這項限制最著名的一個例外可在Mac OS X（10.5或更高版本）上找到：它允許超級用戶建立目錄的硬鏈接。
*一個文件或目錄在文件系統內部移動時，其inode號碼不變。文件系統碎片整理可能會改變一個文件的物理存儲位置，但其inode號碼不變。非UNIX的FAT及其衍生的文件系統是無法實現inode不變這一特點。
*inode文件系統中安裝新庫十分容易。當一些進程正在使用一個庫時，其它進程可以替換該庫文件名字的inode號碼指向新創建的inode，隨後對該庫的訪問都被自動引導到新inode所指向的新的庫文件的內容。這減少了替換庫時重啟系統的需要。而舊的inode的鏈接數已經為0，在使用舊函式庫的進程結束後，舊的inode與舊函式庫文件會被系統自動回收。
*一些文件系統，由於inode表在文件系統創建時就已經確定並且不能再動態增加，新增的文件數量可能會用盡inode。這導致文件系統還有空閒的存儲空間，但已經沒有空閒的inode可供使用了。例如，一個電子郵件服務器可能會被大量的小文件用盡所有inode，但是卻沒有填滿文件存儲空間。部分文件系統，如JFS和XFS，能夠動態地增加inode，因此不會用盡inode。

**實際考慮**
系統管理員使用的很多程序往往用inode號碼來替代文件名來訪問文件系統。例如磁盤完整性檢查程序fsck或pfiles。因此，inode號碼與文件全路徑名的互查是需要的。可以用find帶參數選項-inum，ls帶參數選項(-i做到。

**參考文獻**

**外部鏈接 **
  Anatomy Of The Linux File Systemdate=20160211033517 -  Inode definition date=20200727100213 -  Great and Clear Explanation on Inodes, Symlinks, Hardlinks date=20201112032435 -  理解inode date=20201022182124 -  一天一點學習Linux之inode詳解 date=20200928145010