From: Jeff Layton <jlayton@redhat.com>
To: Miklos Szeredi <miklos@szeredi.hu>
Cc: rwheeler@redhat.com, avati@redhat.com, viro@ZenIV.linux.org.uk,
bfoster@redhat.com, dhowells@redhat.com, eparis@redhat.com,
linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org,
mszeredi@suse.cz, Steven Whitehouse <swhiteho@redhat.com>,
Trond Myklebust <Trond.Myklebust@netapp.com>,
Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Subject: Re: [PATCH 2/9] vfs: check unlinked ancestors before mount
Date: Mon, 12 Aug 2013 09:33:38 -0400 [thread overview]
Message-ID: <20130812093338.2ed6468b@tlielax.poochiereds.net> (raw)
In-Reply-To: <1375975490-18673-3-git-send-email-miklos@szeredi.hu>
On Thu, 8 Aug 2013 17:24:43 +0200
Miklos Szeredi <miklos@szeredi.hu> wrote:
> From: Miklos Szeredi <mszeredi@suse.cz>
>
> We check submounts before doing d_drop() on a non-empty directory dentry in
> NFS (have_submounts()), but we do not exclude a racing mount. Nor do we
> prevent mounts to be added to the disconnected subtree using relative paths
> after the d_drop().
>
> This patch fixes these issues by checking for unlinked (unhashed, non-root)
> ancestors before proceeding with the mount. This is done after setting
> DCACHE_MOUNTED on the soon-to-be mountpoint and with the rename seqlock
> taken for write. This ensures that the only one of
> check_submounts_and_drop() or has_unlinked_ancestor() can succeed.
>
> Signed-off-by: Miklos Szeredi <mszeredi@suse.cz>
> CC: David Howells <dhowells@redhat.com>
> CC: Steven Whitehouse <swhiteho@redhat.com>
> CC: Trond Myklebust <Trond.Myklebust@netapp.com>
> CC: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> ---
> fs/dcache.c | 35 +++++++++++++++++++++++++++++++++++
> fs/internal.h | 1 +
> fs/namespace.c | 9 +++++++++
> 3 files changed, 45 insertions(+)
>
> diff --git a/fs/dcache.c b/fs/dcache.c
> index 020004d..1333445 100644
> --- a/fs/dcache.c
> +++ b/fs/dcache.c
> @@ -1103,6 +1103,41 @@ rename_retry:
> }
> EXPORT_SYMBOL(have_submounts);
>
> +static bool __has_unlinked_ancestor(struct dentry *dentry)
> +{
> + struct dentry *this;
> +
> + for (this = dentry; !IS_ROOT(this); this = this->d_parent) {
> + int is_unhashed;
> +
> + /* Need exclusion wrt. check_submounts_and_drop() */
> + spin_lock(&this->d_lock);
> + is_unhashed = d_unhashed(this);
> + spin_unlock(&this->d_lock);
> +
> + if (is_unhashed)
> + return true;
> + }
> + return false;
> +}
> +
> +/*
> + * Called by mount code to check if the mountpoint is reachable (e.g. NFS can
> + * unhash a directory dentry and then the complete subtree can become
> + * unreachable).
> + */
> +bool has_unlinked_ancestor(struct dentry *dentry)
> +{
> + bool found;
> +
> + /* Need exclusion wrt. check_submounts_and_drop() */
> + write_seqlock(&rename_lock);
> + found = __has_unlinked_ancestor(dentry);
> + write_sequnlock(&rename_lock);
> +
> + return found;
> +}
> +
> /*
> * Search the dentry child list of the specified parent,
> * and move any unused dentries to the end of the unused
> diff --git a/fs/internal.h b/fs/internal.h
> index 7c5f01c..d232355 100644
> --- a/fs/internal.h
> +++ b/fs/internal.h
> @@ -126,6 +126,7 @@ extern int invalidate_inodes(struct super_block *, bool);
> * dcache.c
> */
> extern struct dentry *__d_alloc(struct super_block *, const struct qstr *);
> +extern bool has_unlinked_ancestor(struct dentry *dentry);
>
> /*
> * read_write.c
> diff --git a/fs/namespace.c b/fs/namespace.c
> index 7b1ca9b..bb92a9c 100644
> --- a/fs/namespace.c
> +++ b/fs/namespace.c
> @@ -634,6 +634,15 @@ static struct mountpoint *new_mountpoint(struct dentry *dentry)
> }
> dentry->d_flags |= DCACHE_MOUNTED;
> spin_unlock(&dentry->d_lock);
> +
> + if (has_unlinked_ancestor(dentry)) {
> + spin_lock(&dentry->d_lock);
> + dentry->d_flags &= ~DCACHE_MOUNTED;
> + spin_unlock(&dentry->d_lock);
> + kfree(mp);
> + return ERR_PTR(-ENOENT);
> + }
> +
> mp->m_dentry = dentry;
> mp->m_count = 1;
> list_add(&mp->m_hash, chain);
Looks reasonable. For posterity, it might be worth mentioning the
potential regression that you described earlier (racing with rename
from another host). That way if someone hits it in the future they
might be able to zero in on this change as the culprit more easily.
Acked-by: Jeff Layton <jlayton@redhat.com>
next prev parent reply other threads:[~2013-08-12 13:33 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-08-08 15:24 [PATCH 0/9] [RFC v2] safely drop directory dentry on failed revalidate Miklos Szeredi
2013-08-08 15:24 ` [PATCH 1/9] vfs: check submounts and drop atomically Miklos Szeredi
2013-08-12 13:27 ` Jeff Layton
2013-08-08 15:24 ` [PATCH 2/9] vfs: check unlinked ancestors before mount Miklos Szeredi
2013-08-12 13:33 ` Jeff Layton [this message]
2013-08-08 15:24 ` [PATCH 3/9] afs: use check_submounts_and_drop() Miklos Szeredi
2013-08-08 15:24 ` [PATCH 4/9] gfs2: " Miklos Szeredi
2013-08-08 15:24 ` [PATCH 5/9] nfs: " Miklos Szeredi
2013-08-12 13:34 ` Jeff Layton
2013-08-08 15:24 ` [PATCH 6/9] sysfs: " Miklos Szeredi
2013-08-08 15:24 ` [PATCH 7/9] fuse: use d_materialise_unique() Miklos Szeredi
2013-08-08 15:24 ` [PATCH 8/9] fuse: clean up return in fuse_dentry_revalidate() Miklos Szeredi
2013-08-08 15:24 ` [PATCH 9/9] fuse: drop dentry on failed revalidate Miklos Szeredi
2013-08-21 5:40 ` [PATCH 0/9] [RFC v2] safely drop directory " Al Viro
2013-08-21 20:04 ` Ryusuke Konishi
2013-08-21 21:00 ` Al Viro
2013-08-21 23:47 ` Ryusuke Konishi
2013-08-29 3:51 ` Miklos Szeredi
2013-08-29 23:24 ` Ian Kent
2013-08-29 23:44 ` Ian Kent
2013-08-30 8:59 ` Miklos Szeredi
2013-09-01 0:56 ` Ian Kent
2013-09-01 1:00 ` Ian Kent
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20130812093338.2ed6468b@tlielax.poochiereds.net \
--to=jlayton@redhat.com \
--cc=Trond.Myklebust@netapp.com \
--cc=avati@redhat.com \
--cc=bfoster@redhat.com \
--cc=dhowells@redhat.com \
--cc=eparis@redhat.com \
--cc=gregkh@linuxfoundation.org \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=miklos@szeredi.hu \
--cc=mszeredi@suse.cz \
--cc=rwheeler@redhat.com \
--cc=swhiteho@redhat.com \
--cc=viro@ZenIV.linux.org.uk \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®