btrfs: don't show full path of bind mounts in subvol=
authorJosef Bacik <josef@toxicpanda.com>
Wed, 22 Jul 2020 15:12:46 +0000 (11:12 -0400)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 26 Aug 2020 08:29:03 +0000 (10:29 +0200)
[ Upstream commit 3ef3959b29c4a5bd65526ab310a1a18ae533172a ]

Chris Murphy reported a problem where rpm ostree will bind mount a bunch
of things for whatever voodoo it's doing.  But when it does this
/proc/mounts shows something like

  /dev/sda /mnt/test btrfs rw,relatime,subvolid=256,subvol=/foo 0 0
  /dev/sda /mnt/test/baz btrfs rw,relatime,subvolid=256,subvol=/foo/bar 0 0

Despite subvolid=256 being subvol=/foo.  This is because we're just
spitting out the dentry of the mount point, which in the case of bind
mounts is the source path for the mountpoint.  Instead we should spit
out the path to the actual subvol.  Fix this by looking up the name for
the subvolid we have mounted.  With this fix the same test looks like
this

  /dev/sda /mnt/test btrfs rw,relatime,subvolid=256,subvol=/foo 0 0
  /dev/sda /mnt/test/baz btrfs rw,relatime,subvolid=256,subvol=/foo 0 0

Reported-by: Chris Murphy <chris@colorremedies.com>
CC: stable@vger.kernel.org # 4.4+
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
fs/btrfs/super.c

index af5be060c651f0069a711f7028b81556ebc0313e..3a0cb745164f8b8f65001685f293203f24bb361b 100644 (file)
@@ -1225,6 +1225,7 @@ static int btrfs_show_options(struct seq_file *seq, struct dentry *dentry)
        struct btrfs_fs_info *info = btrfs_sb(dentry->d_sb);
        struct btrfs_root *root = info->tree_root;
        char *compress_type;
+       const char *subvol_name;
 
        if (btrfs_test_opt(info, DEGRADED))
                seq_puts(seq, ",degraded");
@@ -1311,8 +1312,13 @@ static int btrfs_show_options(struct seq_file *seq, struct dentry *dentry)
 #endif
        seq_printf(seq, ",subvolid=%llu",
                  BTRFS_I(d_inode(dentry))->root->root_key.objectid);
-       seq_puts(seq, ",subvol=");
-       seq_dentry(seq, dentry, " \t\n\\");
+       subvol_name = btrfs_get_subvol_name_from_objectid(info,
+                       BTRFS_I(d_inode(dentry))->root->root_key.objectid);
+       if (!IS_ERR(subvol_name)) {
+               seq_puts(seq, ",subvol=");
+               seq_escape(seq, subvol_name, " \t\n\\");
+               kfree(subvol_name);
+       }
        return 0;
 }