如何分配 inode 編號
兩個已知事實:
- 在 linux 中,將文件從同一文件系統上的一個位置移動到另一個位置不會更改 inode(文件保持在“同一位置”,僅更改了所涉及的目錄)
- 但是,複製會生成一個帶有新 inode 的真正新文件。
有了這些資訊,我觀察到以下現象:
$ ls -li /tmp/*.db 1452722 -rw-r--r-- 1 omerda omerda 245760 Jul 7 12:33 /tmp/vf4.db $ $ cp /tmp/vf4.db /tmp/vf4.2.db $ ls -li /tmp/*.db # New inode introduced 1452719 -rw-r--r-- 1 omerda omerda 245760 Jul 7 12:38 /tmp/vf4.2.db 1452722 -rw-r--r-- 1 omerda omerda 245760 Jul 7 12:33 /tmp/vf4.db $ $ mv /tmp/vf4.2.db /tmp/vf4.db $ ls -li /tmp/*.db 1452719 -rw-r--r-- 1 omerda omerda 245760 Jul 7 12:38 /tmp/vf4.db $ $ cp /tmp/vf4.db /tmp/vf4.2.db $ ls -li /tmp/*.db # Original inode appears again! (1452722) 1452722 -rw-r--r-- 1 omerda omerda 245760 Jul 7 12:41 /tmp/vf4.2.db 1452719 -rw-r--r-- 1 omerda omerda 245760 Jul 7 12:41 /tmp/vf4.db $ $ mv /tmp/vf4.2.db /tmp/vf4.db $ ls -li /tmp/*.db 1452722 -rw-r--r-- 1 omerda omerda 245760 Jul 7 12:41 /tmp/vf4.db
這種“往返”總是導致原始 inode 再次附加到原始文件。我本來期望在每個副本中使用一個全新的 inode。
它如何重用相同的 inode?
編輯
在評論部分,一些人要求提供上下文。因此,上下文是一些 sqlite 包裝器使用這種不良做法來替換 db 文件,而 sqlite3 不會顯示有關替換的錯誤。但是,這不是關於 sqlite 的問題,請堅持主題和問題。
它如何重用相同的 inode?
在 ext4 中,inode 編號只是包含實際 inode 數據的表的索引。傳說告訴這就是“i”的意思,“索引”。它實際上並未儲存為單個連續表,但這沒關係。
您獲得的特定 inode 編號當時恰好是空閒的,並且文件系統程式碼確定性地實現選擇是有意義的,因此如果它在 1452719 之前選擇 1452722,那麼選擇 1452722 是有意義的再次,如果它現在是免費的,並且除了製作副本之外沒有進行其他更改。它不能為文件的特定化身永久保留 inode 編號,因為這將很快導致文件系統充滿為已刪除文件保留的不可用 inode 條目。
您不能指望獲得特定的 inode 編號,主要是因為系統上的某些其他程序可能正在同時創建文件,在重新創建文件之前保留您希望獲得的 inode 編號。或者其他程序可能會刪除文件,從而導致文件系統程式碼提供下一個文件。文件系統被組織成塊組及其關聯的 inode 的方式,也可能意味著簡單地增長文件可能會改變文件系統去尋找空閒 inode 的位置。或者它可能不會。所有 inode 編號告訴您的是辨識目前存在的文件,並且在創建新文件時,您只會得到一個與任何現有文件都不對應的文件。
而且,在其他類型的文件系統上,如 VFAT,沒有靜態 inode 編號,但您可能只是得到一個執行計數器。
系統重用相同的 inode 是因為文件系統層選擇這樣做。正如評論中提到的,這是一個實現細節。就我而言,這是
ext4
,但沒有理由為什麼不同的文件系統類型不應該以不同的方式使用(或重用)inode。您可能會找到一個沒有 inode 的文件系統,並且 inode 編號是根據請求動態合成的。tmpfs
文件系統不會以同樣的方式重用 inode 編號。# Create two files on ext4 touch file cp file copy ls -li file copy 133235 -rw-r--r-- 1 roaima roaima 0 Jul 7 11:13 copy 129071 -rw-r--r-- 1 roaima roaima 0 Jul 7 11:13 file # Remove one, copy the other back rm file cp copy file ls -li file copy 133235 -rw-r--r-- 1 roaima roaima 0 Jul 7 11:13 copy 129071 -rw-r--r-- 1 roaima roaima 0 Jul 7 11:13 file # Remove one, create an unexpected intervention, copy the other back rm file touch thing cp copy file ls -li file copy thing 133235 -rw-r--r-- 1 roaima roaima 0 Jul 7 11:13 copy 133237 -rw-r--r-- 1 roaima roaima 0 Jul 7 11:14 file 129071 -rw-r--r-- 1 roaima roaima 0 Jul 7 11:14 thing
現在讓我們在文件系統上重複
tmpfs
,例如/dev/shm
# Create two files on tmpfs touch file cp file copy ls -li file copy 369355 -rw-r--r-- 1 roaima roaima 0 Jul 7 11:27 copy 369354 -rw-r--r-- 1 roaima roaima 0 Jul 7 11:27 file # Remove one, copy the other back rm file cp copy file ls -li file copy 369355 -rw-r--r-- 1 roaima roaima 0 Jul 7 11:27 copy 368123 -rw-r--r-- 1 roaima roaima 0 Jul 7 11:28 file
可能有用的參考資料