Btrfs
如何確定目錄/文件在哪個子卷上?
我想確定文件或目錄在哪個子卷上。例如,如果我有一個子卷掛載
/mnt/btrfs-subvol
和一個目錄/mnt/btrfs-subvol/some/dir
,我執行something /mnt/btrfs-subvol/some/dir
它會返回btrfs-subvol
.我能想到的最好的辦法就是往回
stat
走,用 256 的 inode 測試每個目錄,但我無法想像這是唯一的方法。或者也許執行也許until btrfs sub show `pwd`; cd ..;done; echo `pwd`
但我覺得應該有一個更優雅的解決方案。
如果您可以使用
stat
(POSIX 不需要)並且它的選項足夠豐富,那麼這個命令:stat --format=%m /mnt/btrfs-subvol/some/dir
會告訴你你想要什麼。注意
dir
可以是任何類型的文件,不一定是目錄。筆記:
- 手冊說
%m
表示掛載點;這在 Btrfs 的情況下有點誤導。我在 Kubuntu 18.04.5 LTS 中的測試表明,即使/mnt/btrfs-subvol/
不是顯式掛載點(即mount whatever /mnt/btrfs-subvol/
從未發生過)但它是子卷(在子卷內顯式掛載為/
or/mnt/
),那麼該命令會將其視為掛載點。無論如何,這似乎就是你想要的。- 輸出是在作業系統的目錄結構中有效的路徑,而不是在設備上的 Btrfs 目錄(和子卷)樹中有效的路徑(如果您不確定有什麼區別,請閱讀這個問題和我的答案)。再次看來,這種行為是你想要的。
- 該命令對 Btrfs 以外的文件系統有效(例如在我的 Kubuntu 中
stat --format=%m /dev/null
列印)。/dev
顯然,通常其他文件系統沒有子卷的概念。也許您應該首先檢查您所追求的文件是否存在於 Btrfs 文件系統中:stat --file-system --format=%T /mnt/btrfs-subvol/some/dir
如果您看到
btrfs
,則繼續執行主命令以查找子卷。不幸的是,單次呼叫stat
無法列印兩條資訊(您可以選擇有--file-system
或沒有)。
- 上面的結論意味著你需要執行
stat
兩次。不能保證他們會dir
在路徑下看到相同的內容/mnt/btrfs-subvol/some/dir
。如果在兩者之間發生一些(解除安裝)安裝怎麼辦?比較TOCTOU。在 Linux 中,我可以stat
使用文件描述符可靠地在同一個文件上執行兩個 s,而無需使用 TOCTOU:( stat --dereference --file-system --format=%T /proc/self/fd/3 stat --dereference --format=%m /proc/self/fd/3 ) 3</mnt/btrfs-subvol/some/dir
請注意,如果
dir
它本身是一個符號連結,則命令將跟隨它。您可能仍然想知道子卷以便稍後對其進行處理。無論如何,你把它當作一條路徑。在您使用它之前,情況可能會發生變化,TOCTOU 可能會打擊您。
如果您非常確定相關路徑在未經您同意的情況下不會改變其含義,那麼只需
stat
以簡單的方式使用 s 及其結果。
- 在我的測試中
stat --file-system …
表現得像stat --file-system --dereference …
. 這意味著如果目標文件是符號連結stat
,帶和不帶--file-system
(都沒有顯式)的 s 可能會產生不一致的結果。--dereference