Received: by 2002:a05:6a10:1287:0:0:0:0 with SMTP id d7csp5225439pxv; Wed, 28 Jul 2021 06:12:53 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwZuTOtK9zN9okEWdBWSaiRZzJNSMATpwDmPFbpsaeEFwA+fvrBEGSkvENreWLRHDFqPxBd X-Received: by 2002:a5d:9e4f:: with SMTP id i15mr23364834ioi.58.1627477973010; Wed, 28 Jul 2021 06:12:53 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1627477973; cv=none; d=google.com; s=arc-20160816; b=h4RegeP2DSeRIF+WXQgTrsY9FLcXEWFKKX6RpXYG7SXCGdYsAi+QJZrZpK9B6bYXt0 1XwGKFrx9sv//03UDhVNr+7kyNrTvx986cBGmpHYzwjCZxJyvWlk/F8lT3g2dONPKfYl YcdMgsCiyFUIjTUxzaH++5AD5ImQromMPMvGXH4j/eIw+qdCB1UBsRKda+165AZXczEJ oLsrY6KH6kPNWZSEQrXIXl7k1w/UWm+jujxQBu4ZA/mHC1NkIbgHj0NP71/Wz+6G/W5Z PH7HRVDFXWDWXaMT+giaRMfYTiSANCGDZ+nlOtEjLg1r7XhVSEaeyRfUBimrKtO+9SwF SPvQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:in-reply-to:content-disposition:mime-version :references:message-id:subject:cc:to:from:date; bh=84bUzS0weNKXtghaIjea7b9FzinOFtV8pe9gVbcVTvE=; b=l5HzoKggX5dtP6hjePzPaX68Q01GxoOPvbUKvyHgi5lFNAhzlxwPTQTXMb2qXMaKOo 6c6rsF4TyZFqzu4XC3aaMIwDAUQy8llzwGy2muxy6vaj+IC7LrYsYCuVE0TPsiCCQfuE RVPNHgQSBQOXGVguNXaMk8XXGpbKg+bu0fq7rLtrXkwwZPuVPNa907elK/YRT0jP5v9l pqwyPRZiiM8g1FXJ4mlUM4xZU1EBfEDNZNDNhYmhA/TLvqYX6MxmC1GjeHuvoPxMp6yP thBxHBLqEG68giFo5ZCrKEebMK3xxAj4lIl7/PpJCEsmCAjEN7o4j5lAzEK2W3efbIdk dpeA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-nfs-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-nfs-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id z13si6574843ile.110.2021.07.28.06.12.29; Wed, 28 Jul 2021 06:12:52 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-nfs-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-nfs-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-nfs-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236263AbhG1NMV (ORCPT + 99 others); Wed, 28 Jul 2021 09:12:21 -0400 Received: from mail.kernel.org ([198.145.29.99]:60464 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235204AbhG1NMV (ORCPT ); Wed, 28 Jul 2021 09:12:21 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id 6AE4760FED; Wed, 28 Jul 2021 13:12:16 +0000 (UTC) Date: Wed, 28 Jul 2021 15:12:13 +0200 From: Christian Brauner To: NeilBrown Cc: Christoph Hellwig , Josef Bacik , "J. Bruce Fields" , Chuck Lever , Chris Mason , David Sterba , Alexander Viro , linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-btrfs@vger.kernel.org Subject: Re: [PATCH 11/11] btrfs: use automount to bind-mount all subvol roots. Message-ID: <20210728131213.pgu3r4m4ulozrcav@wittgenstein> References: <162742539595.32498.13687924366155737575.stgit@noble.brown> <162742546558.32498.1901201501617899416.stgit@noble.brown> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline In-Reply-To: <162742546558.32498.1901201501617899416.stgit@noble.brown> Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org On Wed, Jul 28, 2021 at 08:37:45AM +1000, NeilBrown wrote: > All subvol roots are now marked as automounts. If the d_automount() > function determines that the dentry is not the root of the vfsmount, it > creates a simple loop-back mount of the dentry onto itself. If it > determines that it IS the root of the vfsmount, it returns -EISDIR so > that no further automounting is attempted. > > btrfs_getattr pays special attention to these automount dentries. > If it is NOT the root of the vfsmount: > - the ->dev is reported as that for the rest of the vfsmount > - the ->ino is reported as the subvol objectid, suitable transformed > to avoid collision. > > This way the same inode appear to be different depending on which mount > it is in. > > automounted vfsmounts are kept on a list and timeout after 500 to 1000 > seconds of last use. This is configurable via a module parameter. > The tracking and timeout of automounts is copied from NFS. > > Link: https://lore.kernel.org/r/162742546558.32498.1901201501617899416.stgit@noble.brown > Reported-by: kernel test robot > Signed-off-by: NeilBrown > --- > fs/btrfs/btrfs_inode.h | 2 + > fs/btrfs/inode.c | 108 ++++++++++++++++++++++++++++++++++++++++++++++++ > fs/btrfs/super.c | 1 > 3 files changed, 111 insertions(+) > > diff --git a/fs/btrfs/btrfs_inode.h b/fs/btrfs/btrfs_inode.h > index a4b5f38196e6..f03056cacc4a 100644 > --- a/fs/btrfs/btrfs_inode.h > +++ b/fs/btrfs/btrfs_inode.h > @@ -387,4 +387,6 @@ static inline void btrfs_print_data_csum_error(struct btrfs_inode *inode, > mirror_num); > } > > +void btrfs_release_automount_timer(void); > + > #endif > diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c > index 02537c1a9763..a5f46545fb38 100644 > --- a/fs/btrfs/inode.c > +++ b/fs/btrfs/inode.c > @@ -31,6 +31,7 @@ > #include > #include > #include > +#include > #include > #include "misc.h" > #include "ctree.h" > @@ -5782,6 +5783,8 @@ static int btrfs_init_locked_inode(struct inode *inode, void *p) > struct btrfs_iget_args *args = p; > > inode->i_ino = args->ino; > + if (args->ino == BTRFS_FIRST_FREE_OBJECTID) > + inode->i_flags |= S_AUTOMOUNT; > BTRFS_I(inode)->location.objectid = args->ino; > BTRFS_I(inode)->location.type = BTRFS_INODE_ITEM_KEY; > BTRFS_I(inode)->location.offset = 0; > @@ -5985,6 +5988,101 @@ static int btrfs_dentry_delete(const struct dentry *dentry) > return 0; > } > > +static void btrfs_expire_automounts(struct work_struct *work); > +static LIST_HEAD(btrfs_automount_list); > +static DECLARE_DELAYED_WORK(btrfs_automount_task, btrfs_expire_automounts); > +int btrfs_mountpoint_expiry_timeout = 500 * HZ; > +static void btrfs_expire_automounts(struct work_struct *work) > +{ > + struct list_head *list = &btrfs_automount_list; > + int timeout = READ_ONCE(btrfs_mountpoint_expiry_timeout); > + > + mark_mounts_for_expiry(list); > + if (!list_empty(list) && timeout > 0) > + schedule_delayed_work(&btrfs_automount_task, timeout); > +} > + > +void btrfs_release_automount_timer(void) > +{ > + if (list_empty(&btrfs_automount_list)) > + cancel_delayed_work(&btrfs_automount_task); > +} > + > +static struct vfsmount *btrfs_automount(struct path *path) > +{ > + struct fs_context fc; > + struct vfsmount *mnt; > + int timeout = READ_ONCE(btrfs_mountpoint_expiry_timeout); > + > + if (path->dentry == path->mnt->mnt_root) > + /* dentry is root of the vfsmount, > + * so skip automount processing > + */ > + return ERR_PTR(-EISDIR); > + /* Create a bind-mount to expose the subvol in the mount table */ > + fc.root = path->dentry; > + fc.sb_flags = 0; > + fc.source = "btrfs-automount"; > + mnt = vfs_create_mount(&fc); > + if (IS_ERR(mnt)) > + return mnt; Hey Neil, Sorry if this is a stupid question but wouldn't you want to copy the mount properties from path->mnt here? Couldn't you otherwise use this to e.g. suddenly expose a dentry on a read-only mount as read-write? Christian