Btrfs

如何確定目錄/文件在哪個子卷上?

  • January 30, 2021

我想確定文件或目錄在哪個子卷上。例如,如果我有一個子卷掛載/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

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