Linux

如何分配 inode 編號

  • July 8, 2021

兩個已知事實:

  1. 在 linux 中,將文件從同一文件系統上的一個位置移動到另一個位置不會更改 inode(文件保持在“同一位置”,僅更改了所涉及的目錄)
  2. 但是,複製會生成一個帶有新 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

可能有用的參考資料

引用自:https://unix.stackexchange.com/questions/657334