1

I want to determine which subvolume a file or directory is on. For example, if I have a subvolume mount at /mnt/btrfs-subvol and a directory /mnt/btrfs-subvol/some/dir and I run something /mnt/btrfs-subvol/some/dir it returns btrfs-subvol.

The best I can think to do is to walk back, testing each directory with stat as I go for an inode of 256, but I can't imagine that is the only way of doing this. Or maybe run maybe

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

But I feel there should be a more elegant solution.

0

1 Answer 1

4

If you can use stat (which is not required by POSIX) and it's rich enough with options then this command:

stat --format=%m /mnt/btrfs-subvol/some/dir

will show you what you want. Note dir can be any type of file, not necessarily a directory.

Notes:

  • The manual says %m denotes the mountpoint; this is somewhat misleading in case of Btrfs. My tests in Kubuntu 18.04.5 LTS indicate that even if /mnt/btrfs-subvol/ is not an explicit mountpoint (i.e. mount whatever /mnt/btrfs-subvol/ never happened) but it's a subvolume (inside a subvolume explicitly mounted as / or /mnt/) then the command will treat it as a mountpoint. It seems this is what you want anyway.

  • The output is a path valid in the directory structure in the OS, not in the Btrfs directory (and subvolumes) tree on the device (if you're not sure what the difference is then read this question and my answer there). Again it seems this behavior is what you want.

  • The command is valid for filesystems other than Btrfs (e.g. stat --format=%m /dev/null prints /dev in my Kubuntu). Obviously in general other filesystems have no concept of subvolumes. Maybe you should check first if the file you're after lives in a Btrfs filesystem:

    stat --file-system --format=%T /mnt/btrfs-subvol/some/dir
    

    If you see btrfs then proceed with the main command to find the subvolume. Unfortunately a single invocation of stat cannot print both pieces of information (you go either with --file-system or without).

  • The above conclusion means you need to run stat two times. There is no guarantee they will see the same dir under the path /mnt/btrfs-subvol/some/dir. What if some (un)mounting happens in between? Compare TOCTOU. In Linux I am able to reliably run two stats on the same file without TOCTOU by using a file descriptor:

    ( stat --dereference --file-system --format=%T /proc/self/fd/3
      stat --dereference --format=%m /proc/self/fd/3 ) 3</mnt/btrfs-subvol/some/dir
    

    Note if dir itself is a symlink, the commands will follow it.

    Still you probably want to know the subvolume in order to do something with it later. You get it as a path anyway. Before you use it the situation may change and TOCTOU may hit you.

    If you are pretty sure the relevant paths don't change their meaning without your consent then just work with stats and their results in a straightforward way.

  • In my tests stat --file-system … behaves like stat --file-system --dereference …. This means stats with and without --file-system (both without explicit --dereference) may yield inconsistent results if the target file is a symlink.

1
  • Thank you, that is what I'm looking for. As you inferred, this is information that will be fed to another part of a script. I hadn't considered just looking for the mount point. I feel silly now. For my use, symlinks aren't an issue.
    – Nero gris
    Jan 30, 2021 at 1:58

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .