如何确定目录/文件位于哪个子卷?

如何确定目录/文件位于哪个子卷?

我想确定文件或目录位于哪个子卷上。例如,如果我有一个子卷挂载点/mnt/btrfs-subvol和一个目录/mnt/btrfs-subvol/some/dir,并且我运行something /mnt/btrfs-subvol/some/dir它会返回btrfs-subvol.

我能想到的最好办法就是返回,用stat256 的索引节点测试每个目录,但我无法想象这是唯一的方法。或者也许可以跑

until btrfs sub show `pwd`; cd ..;done; echo `pwd`

但我觉得应该有一个更优雅的解决方案。

答案1

如果你可以使用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/从未发生过),但它是一个子卷(在显式挂载为/或 的子卷内/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。如果中间发生一些(卸载)安装怎么办?比较托克图。在 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

相关内容