Path

磁碟被訪問了多少次?

  • July 30, 2018

這是關於通用 UFS

據我了解,當給出絕對路徑(例如/home/userU/file.txt:)時,每個目錄和文件都會訪問磁碟。因此,在這種情況下,磁碟被訪問 4 次

1 為/, 1 為home/, 1 為/userU, 1 為file.txt

我的問題是

  1. 如果給出一個硬連結/hL,指向上面文件的inode,訪問磁碟的順序是什麼?
  2. 如果給出一個軟連結/sL,指向上面的文件,訪問磁碟的順序是什麼?

假設在所有三種情況下最初都沒有記憶體任何 inode 或任何其他數據。

背景

假設我們有以下目錄設置:

$ ll
total 0
-rw-r--r-- 2 root root 0 Jul 29 23:36 afile.txt
-rw-r--r-- 2 root root 0 Jul 29 23:36 hL
lrwxrwxrwx 1 root root 9 Jul 30 01:22 sL -> afile.txt

現在讓我們看看你的2個問題。


問題

  1. 如果給出一個硬連結/hL,指向上面文件的inode,訪問磁碟的順序是什麼?

對於硬連結,它們擁有與它們指向的原始文件/目錄相同的 inode 引用。所以沒有額外的硬碟訪問來讀取它們。

例如:

$ stat hL | head -3
 File: ‘hL’
 Size: 0           Blocks: 0          IO Block: 4096   regular empty file
Device: fd00h/64768d    Inode: 667668      Links: 2

對比

$ stat afile.txt | head -3
 File: ‘afile.txt’
 Size: 0           Blocks: 0          IO Block: 4096   regular empty file
Device: fd00h/64768d    Inode: 667668      Links: 2

這兩個之間的唯一區別是名稱。因此,任一路徑都會產生相同數量的 HDD 訪問。

  1. 如果給出一個軟連結/sL,指向上面的文件,訪問磁碟的順序是什麼?

然而,對於軟連結,還有一個額外的 HDD 訪問。這種額外的訪問將針對文件sL所在目錄的元數據。然後這將返回詳細資訊,說明該文件實際上是一個符號連結,並且它指向另一個文件/目錄。

例如:

$ stat sL | head -3
 File: ‘sL’ -> ‘afile.txt’
 Size: 9           Blocks: 0          IO Block: 4096   symbolic link
Device: fd00h/64768d    Inode: 681295      Links: 1

在這裡,我們可以看到它的類型為“符號連結”,並且指向afile.txt. 還要注意它有一個不同的 inode(681295 與 667668),進一步證明它需要額外讀取。

那麼什麼是讀命令呢?

如果您使用strace針對這些文件/目錄執行命令的 Bash shell 本身,您可以了解事情是如何工作的。

[pid 18098] stat("/tmp/adir/hL", {st_mode=S_IFREG|0644, st_size=0, ...}) = 0
[pid 18098] open("/tmp/adir/hL", O_RDONLY) = 3
[pid 18098] fstat(3, {st_mode=S_IFREG|0644, st_size=0, ...}) = 0

這是命令的輸出more /tmp/adir/hL

對於/tmp/adir/hL

  • stat/open (/) → stat/open (tmp) → stat/open (adir) → stat/open (hL)

對於/tmp/adir/sL

  • stat/open (/) → stat/open (tmp) → stat/open (adir) → stat/open (sL) → stat/open (afile.txt)

更多細節

符號連結上的維基百科頁面也避開了所有這些:

儘管將連結值儲存在 inode 中節省了磁碟塊和磁碟讀取,但作業系統仍然需要解析連結中的路徑名,這總是需要讀取額外的 inode,並且通常需要讀取其他的,可能還有很多目錄,處理文件列表和每個文件的索引節點,直到找到與連結的路徑組件匹配的內容。只有當連結指向同一目錄中的文件時,“快速符號連結”才能提供比其他符號連結更好的性能。

參考

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