詳解Linux Inode

程式設計師的貓 發表於 2021-01-18

一切都是檔案,Linux和其他類Unix作業系統通過將所有內容都視為檔案(甚至是硬體裝置)來保持一致性。 鍵盤,滑鼠,印表機,顯示器,硬碟,程式,甚至目錄都被視為Linux中的檔案。 常規檔案包含文字(文字檔案),音樂,視訊(多媒體檔案)等資料。除常規資料外,還有一些關於這些檔案的其他資料,例如它們的大小,所有權,許可權,時間戳等。 有關檔案的後設資料使用稱為inode(索引節點)的資料結構進行管理。

什麼是 inode?

每個Linux檔案或目錄 (從技術角度講,它們之間沒有本質的區別) 都有一個inode,而這個inode包含了所有檔案的後設資料 (也就是說,讀取檔案所需的管理資料都儲存在inode中)。例如,inode包含儲存檔案的所有塊的列表,該檔案所有者資訊、許可權以及為該檔案設定的所有其他屬性。從某種意義上講,你可以說檔案就是inode,並且檔名被附加到inode上以使人們更容易使用它們。

inode在檔案系統建立是確定,並且每個檔案系統都有一個inode集合。最大的目錄大小取決於不同的檔案系統。為了獲得更好的效能,通常將檔案放入不同的子目錄中,而不是將所有檔案放入同一個目錄。

什麼是inode number

inode是inode table中的一個條目,包含有關目錄和常規檔案的後設資料。inode是傳統Unix風格檔案系統 (比如ext3/ext4) 上的資料結構。Linux擴充套件檔案系統 (如ext2/ext3) 維護了一個inode的陣列:inode table。inode table包含該檔案系統中所有檔案的列表。inode table中的各個inode項具有唯一的編號 (該檔案系統唯一),即inode number。深入inode資料結構,我們發現它儲存瞭如下資訊:

  • 檔案型別: 普通檔案,目錄,管道等等
  • 許可權:可讀,可寫,可執行
  • 連結數:連結到該inode的硬連結數
  • User ID:檔案所有者
  • Group ID:所有者組ID
  • 檔案大小
  • 時間資訊
  • 屬性:比如,不可改變位
  • 訪問控制列表
  • 檔案資料儲存的實際位置
  • 其他後設資料

注意:inode中不儲存檔名資料

如何檢視inode資訊

如果你希望檢視檔案系統的inode資訊,你可以使用一些shell命令來檢視檔案系統的屬性

a. 顯示指定檔案資訊

你可以使用stat命令顯示某個檔案或目錄的inode資訊,你必須指定檔案或目錄名

# stat log.txt
  File: 'log.txt'
  Size: 212             Blocks: 8          IO Block: 4096   regular file
Device: fd01h/64769d    Inode: 591912      Links: 1
Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2018-11-26 11:27:13.683598803 +0800
Modify: 2018-12-06 17:18:49.799424595 +0800
Change: 2018-12-06 17:18:49.799424595 +0800
 Birth: -

命令的輸出告訴了你該檔案的各種時間資訊,它的所有權和許可權,以及檔案儲存的位置。儲存檔案資料的磁碟塊資訊也展示在stat命令的輸出中。

你也可以選擇只列出檔案的inode number:

# stat --format=%i log.txt
591912
b. 列印檔案的inode number

ls命令用於列出檔案/資料夾的資訊。引數 -i 說明需要顯示每個檔案的inode number。我們可以結合引數 -l 一起使用以列出詳細資訊:

# ls -li
total 16
592404 drwxr-xr-x 6 root root 4096 Nov  2 15:01 config
591900 -rw-r--r-- 1 root root  453 Nov 25 22:25 docker-compose-single.yml
592414 -rw-r--r-- 1 root root 2714 Nov  2 15:01 docker-compose.yml
592415 drwxr-xr-x 2 root root 4096 Nov  2 15:01 mariadb

輸出的第一列顯示了檔案的inode number。

c. 顯示檔案系統inode的使用資訊

預設情況下,df命令彙總可用和已用的磁碟空間。你可以通過傳遞 -i--inodes 選項來接收有關可用和已使用的inode報告。

# df -i
Filesystem      Inodes  IUsed   IFree IUse% Mounted on
udev           2032387    398 2031989    1% /dev
tmpfs          2037595   1224 2036371    1% /run
/dev/vda1      3276800 325180 2951620   10% /
tmpfs          2037595      7 2037588    1% /dev/shm
tmpfs          2037595      4 2037591    1% /run/lock
tmpfs          2037595     16 2037579    1% /sys/fs/cgroup
overlay        3276800 325180 2951620   10% /var/lib/docker/overlay2/c1955f95c338497d2f669ee0baf2706f93c2765001cafd3568b5af9ebfbe0dfd/merged
overlay        3276800 325180 2951620   10% /var/lib/docker/overlay2/85a6ee4a64760a9e52efa312094092121160030132aaaf4bd32ecf5585324dfd/merged
overlay        3276800 325180 2951620   10% /var/lib/docker/overlay2/692ed70766a4ee954c0f0f1b19d69b906c33ae54a618f8686f66e31e9ac05606/merged
shm            2037595      1 2037594    1% /var/lib/docker/containers/2a09d78972ebb74a7631dfd5e567a2b54282886ac8d8dc54dc1f5badffc692b8/mounts/shm
shm            2037595      1 2037594    1% /var/lib/docker/containers/fd9619309707c1026876a401ac22eaf8dd9bfbaceb237ee927017818a6ffa3ff/mounts/shm
shm            2037595      1 2037594    1% /var/lib/docker/containers/080d0d79e069041a2997dfaf2c07e69a0518ad44271dad4688f459958dac09c5/mounts/shm
tmpfs          2037595      4 2037591    1% /run/user/1000

如果分割槽包含很多小檔案,這些資訊可能會有幫助,這可能會比耗盡可用磁碟空間更快的耗盡可用的inode。

d. 列出檔案系統超級塊的資訊

你可以使用 tune2fs -l 命令來顯示所有與inode相關的資訊。

# tune2fs -l /dev/vda1  | grep inode
Filesystem features:      has_journal ext_attr resize_inode dir_index filetype needs_recovery extent sparse_super large_file uninit_bg
Free inodes:              2952348
First inode:              11
Journal inode:            8
First orphan inode:       221187
Journal backup:           inode blocks

目錄的inode結構

上面提到過,Linux中的目錄也被視為檔案。目錄是將檔名對映到其inode number的特殊檔案 (此對映稱為dentry)。因此,當我們說某個目錄包含檔案和其他目錄時,我們的意思是該目錄將這些檔案和目錄對映到它們的inode number。這就是目錄無法容納兩個具有相同名稱的檔案的原因,因為它無法使用兩個不同的inode number對映一個名稱。

當一個檔案通過其父目錄對映到它到inode時,那麼最頂層的目錄(即 / 目錄)如何對映到它的inode?實際上,/ 目錄的inode number是固定的,始終為2。

# stat /
File: '/'
  Size: 4096            Blocks: 8          IO Block: 4096   directory
Device: fd01h/64769d    Inode: 2           Links: 24
Access: (0755/drwxr-xr-x)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2018-07-24 17:05:52.740982553 +0800
Modify: 2018-12-21 18:02:05.258315357 +0800
Change: 2018-12-21 18:02:05.258315357 +0800
 Birth: -

連結

在命令 ls -l 的輸出中,許可權之後和所有者之前的列是連結計數。 連結計數是指檔案的硬連結數。 要理解硬連結,我們從連結開始。 連結是指向另一個檔案的指標。 在Linux世界中,存在兩種型別的連結:

a. 符號連結 (軟連結)

符號連結是一個單獨的檔案,其內容指向被連結的檔案。 要建立符號連結,請使用帶有-s選項的ln命令。 使用ln命令時,請確保首先引用原始檔案的名稱,然後引用要建立的連結的名稱。

# ln -s /home/opt/sync.sh filesync

這裡filesync是sync.sh的符號連結。 把它想象成一個快捷方式。 編輯filesync就像直接編輯原始檔案一樣。 如果我們刪除或移動原始檔案,連結將被破壞,我們的filesync檔案將不再可用。

ls -l 命令顯示生成的檔案是符號連結。 這由 ls -l 輸出的第一個位置中的字母l以及列表末尾的箭頭指示,該箭頭表示連結所指向的檔案。

# ls -l filesync 
lrwxrwxrwx 1 root root 20 Apr 7 06:08 filesync -> /home/opt/sync.sh

比較符號連結和原始檔案時,您會發現它們之間存在明顯差異。

# ls -il /home/opt/sync.sh filesync 
258674 lrwxrwxrwx 1 root root 20 Apr 7 06:08 filesync -> /home/opt/sync.sh
517333 -rw-r----- 1 root root 5 Apr 7 06:09 /home/opt/sync.sh

原始檔案只是一個直接連線到inode的檔案,而符號連結指向該檔案。 符號連結的大小是它引用的檔名稱的位元組數,因為符號連結中沒有其他資訊可用。

b. 硬連結

要了解硬連結是什麼,關鍵是要了解檔案的標識是其inode編號,而不是其名稱。 硬連結是一個引用inode的名稱。 這意味著如果file1有一個名為file2的硬連結,那麼這兩個檔案都引用相同的inode。 因此,當您為檔案建立硬連結時,您真正要做的就是為inode新增一個新名稱。 為此,請使用不帶選項的ln命令。

# ls -l /home/opt/sync.sh  
-rw-r----- 1 root root 5 Apr 7 06:09 /home/bobbin/sync.sh
# ln /home/opt/sync.sh synchro

讓我們來比較這兩個檔案

# ls -il /home/bobbin/sync.sh synchro 
517333 -rw-r----- 2 root root 5 Apr 7 06:09 /home/opt/sync.sh
517333 -rw-r----- 2 root root 5 Apr 7 06:09 synchro

關於硬連結的有趣之處在於原始檔案和連結之間沒有區別:它們只是連線到同一個inode的兩個名稱。

正如您必須注意到的,與軟連結不同,硬連結不是特殊檔案。 現在,連結計數是檔案硬連結的數字。 因此,建立硬連結後連結計數會增加,如上圖所示。 這些硬連結有兩個限制:

  • 目錄不能硬連結。 Linux不允許這樣做以維護目錄的非迴圈樹結構。
  • 無法跨檔案系統建立硬連結。 這兩個檔案必須位於相同的檔案系統上,因為不同的檔案系統具有不同的獨立inode表(不同檔案系統上具有相同inode編號的兩個檔案是不同的)。

結論

每個Linux檔案都有一個inode資料結構,inode包含檔案的所有屬性,但不包含檔名。 符號連結類似於指向原始檔案的快捷方式,而硬連結類似於檔案的一份拷貝。 原始檔案和硬連結之間沒有區別,他們都引用同一個inode。

本作品採用《CC 協議》,轉載必須註明作者和本文連結
你還差得遠吶!