Re: [RFC][PATCH] btrfs_get_tree_subvol(): switch from fc_mount() to vfs_create_mount()

Klara Modin
2025-05-06T18:59:02Z

On 2025-05-06 19:16:04 +0100, Al Viro wrote:
> On Tue, May 06, 2025 at 07:54:32PM +0200, Klara Modin wrote:
>
> > > > Though now I hit another issue which I don't know if it's related or
> > > > not. I'm using an overlay mount with squashfs as lower and btrfs as
> > > > upper. The mount fails with invalid argument and I see this in the log:
> > > >
> > > > overlayfs: failed to clone upperpath
> > >
> > > Seeing that you already have a kernel with that thing reverted, could
> > > you check if the problem exists there?
> >
> > Yeah, it works fine with the revert instead.
>
> Interesting... That message means that you've got clone_private_mount()
> returning an error; the thing is, mount passed to it has come from
> pathname lookup - it is *not* the mount created by that fc_mount() of
> vfs_create_mount() in the modified code. That one gets passed to
> mount_subvol() and consumed there (by mount_subtree()). All that is returned
> is root dentry; the mount passed to clone_private_mount() is created
> from scratch using dentry left by btrfs_get_tree_subvol() in its fc->root -
> see
> dentry = mount_subvol(ctx->subvol_name, ctx->subvol_objectid, mnt);
> ctx->subvol_name = NULL;
> if (IS_ERR(dentry))
> return PTR_ERR(dentry);
>
> fc->root = dentry;
> return 0;
> in the end of btrfs_get_tree_subvol().
>
> What's more, on the overlayfs side we managed to get to
> upper_mnt = clone_private_mount(upperpath);
> err = PTR_ERR(upper_mnt);
> if (IS_ERR(upper_mnt)) {
> pr_err("failed to clone upperpath\n");
> goto out;
> so the upper path had been resolved...
>
> OK, let's try to see what clone_private_mount() is unhappy about...
> Could you try the following on top of -next + braino fix and see
> what shows up? Another interesting thing, assuming you can get
> to shell after overlayfs mount failure, would be /proc/self/mountinfo
> contents and stat(1) output for upper path of your overlayfs mount...

ret = vfs_get_tree(dup_fc);
if (!ret) {
ret = btrfs_reconfigure_for_mount(dup_fc);
up_write(&dup_fc->root->d_sb->s_umount);
}
if (!ret)
mnt = vfs_create_mount(fc);
else
mnt = ERR_PTR(ret);
put_fs_context(dup_fc);

I tried replacing fc with dup_fc in vfs_create_mount and it seems to
work.