From: Al Viro <viro@ZenIV.linux.org.uk>
To: David Howells <dhowells@redhat.com>
Cc: raven@themaw.net, npiggin@kernel.dk, autofs@linux.kernel.org,
linux-fsdevel@vger.kernel.org
Subject: Re: [PATCH 01/18] Add a dentry op to handle automounting rather than abusing follow_link() [ver #4]
Date: Sun, 16 Jan 2011 00:09:47 +0000 [thread overview]
Message-ID: <20110116000947.GO19804@ZenIV.linux.org.uk> (raw)
In-Reply-To: <20110113215405.19406.73651.stgit@warthog.procyon.org.uk>
On Thu, Jan 13, 2011 at 09:54:05PM +0000, David Howells wrote:
> @@ -1038,12 +1147,14 @@ static int do_lookup(struct nameidata *nd, struct qstr *name,
> - __follow_mount_rcu(nd, path, inode);
> + if (unlikely(!__follow_mount_rcu(nd, path, inode, false)) &&
> + nameidata_drop_rcu(nd))
> + return -ECHILD;
Gotcha. That's what'd been causing fun with autofs. Look: we run into
automount. __follow_mount_rcu() fails. nd->path *AND* path contain
vfsmounts/dentries we hadn't grabbed references to. nameidata_drop_rcu()
brings nd->path to normal. Good for it, but path is *still* not grabbed.
And LOOKUP_RCU is gone, so when the caller feeds it to path_to_nameidata()
the fun things start happening. We drop nd->dentry, for starters. And
replace it with ungrabbed dentry we just got from dcache. Better yet,
if automount dentry had been sitting on top of mountpoint (e.g. it was
a direct autofs mountpoint), we'll drop nd->mnt and replace it with
vfsmount we hadn't grabbed. Then we'll proceed to treat both as if they'd
been grabbed, eventually doing path_put() on the suckers.
vfsmount will stay around, since it's mounted and thus mntput() optimizations
will assume we are not dropping the last reference and not free the sucker.
dentry, OTOH, will be freed after a few time through that. At which point
it gets reused and we are left with complete crap. E.g. with vfsmount
mounted on that mountpoint, its ->mnt_root pointing to dentry from completely
unrelated fs. Keep walking into that and you'll get _that_ dentry freed
under whoever might be using it, etc.
Fix is trivial: if __follow_mount_rcu() succeeds (the normal case) just
return 0. Otherwise, try nameidata_drop_rcu(); if it fails, we bugger off.
So far it's equivalent to your variant, but if nameidata_drop_rcu() succeeds,
we fall through to non-RCU case instead of just returning 0.
I've dropped the following into for-next; autofs seems to be working fine
with it. I'll fold that into your first patch in #untested.
AFS issue is completely separate story; that one is mine and it's old.
Just that now it became more visible; earlier it only messed the expiry
logics (by screwing ->mnt_ghosts accounting). I've a half-finished fix
for that, but it needs more beating (and will be stable@ fodder, BTW).
Later...
commit c737c31d6f1ba4eb3f1aec523741ed49d5f6a22a
Author: Al Viro <viro@zeniv.linux.org.uk>
Date: Sat Jan 15 18:10:31 2011 -0500
[foldme] fix do_lookup() handling of automount in RCU case
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
diff --git a/fs/namei.c b/fs/namei.c
index 9367fea..8f7b41a 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -1277,24 +1277,25 @@ static int do_lookup(struct nameidata *nd, struct qstr *name,
done2:
path->mnt = mnt;
path->dentry = dentry;
- if (unlikely(!__follow_mount_rcu(nd, path, inode, false)) &&
- nameidata_drop_rcu(nd))
+ if (likely(__follow_mount_rcu(nd, path, inode, false)))
+ return 0;
+ if (nameidata_drop_rcu(nd))
return -ECHILD;
- } else {
- dentry = __d_lookup(parent, name);
- if (!dentry)
- goto need_lookup;
+ /* fallthru */
+ }
+ dentry = __d_lookup(parent, name);
+ if (!dentry)
+ goto need_lookup;
found:
- if (dentry->d_flags & DCACHE_OP_REVALIDATE)
- goto need_revalidate;
+ if (dentry->d_flags & DCACHE_OP_REVALIDATE)
+ goto need_revalidate;
done:
- path->mnt = mnt;
- path->dentry = dentry;
- err = follow_managed(path, nd->flags);
- if (unlikely(err < 0))
- return err;
- *inode = path->dentry->d_inode;
- }
+ path->mnt = mnt;
+ path->dentry = dentry;
+ err = follow_managed(path, nd->flags);
+ if (unlikely(err < 0))
+ return err;
+ *inode = path->dentry->d_inode;
return 0;
need_lookup:
next prev parent reply other threads:[~2011-01-16 0:09 UTC|newest]
Thread overview: 46+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-01-13 21:53 [PATCH 00/18] Introduce automount support in the VFS [ver #4] David Howells
2011-01-13 21:54 ` [PATCH 01/18] Add a dentry op to handle automounting rather than abusing follow_link() " David Howells
2011-01-16 0:09 ` Al Viro [this message]
2011-01-16 1:17 ` Al Viro
2011-01-16 18:12 ` David Howells
2011-01-13 21:54 ` [PATCH 02/18] Add a dentry op to allow processes to be held during pathwalk transit " David Howells
2011-01-13 21:54 ` [PATCH 03/18] From: David Howells <dhowells@redhat.com> " David Howells
2011-01-13 21:54 ` [PATCH 04/18] AFS: Use d_automount() rather than abusing follow_link() " David Howells
2011-01-13 21:54 ` [PATCH 05/18] NFS: " David Howells
2011-01-13 21:54 ` [PATCH 06/18] CIFS: " David Howells
2011-01-13 21:54 ` [PATCH 07/18] Remove the automount through follow_link() kludge code from pathwalk " David Howells
2011-01-13 21:54 ` [PATCH 08/18] autofs4: Add d_automount() dentry operation " David Howells
2011-01-13 21:54 ` [PATCH 09/18] autofs4: Add d_manage() " David Howells
2011-01-14 13:51 ` Ian Kent
2011-01-14 14:37 ` Nick Piggin
2011-01-14 15:35 ` David Howells
2011-01-14 15:46 ` Nick Piggin
2011-01-14 15:47 ` Nick Piggin
2011-01-13 21:54 ` [PATCH 10/18] autofs4: Remove unused code " David Howells
2011-01-13 21:54 ` [PATCH 11/18] autofs4: Clean up inode operations " David Howells
2011-01-13 21:55 ` [PATCH 12/18] autofs4: Clean up dentry " David Howells
2011-01-13 21:55 ` [PATCH 13/18] autofs4: Clean up autofs4_free_ino() " David Howells
2011-01-14 16:03 ` Al Viro
2011-01-13 21:55 ` [PATCH 14/18] autofs4: Fix wait validation " David Howells
2011-01-13 21:55 ` [PATCH 15/18] autofs4: Add v4 pseudo direct mount support " David Howells
2011-01-13 21:55 ` [PATCH 16/18] autofs4: Bump version " David Howells
2011-01-13 21:55 ` [PATCH 17/18] Remove a further kludge from __do_follow_link() " David Howells
2011-01-13 21:55 ` [PATCH 18/18] Allow d_manage() to be used in RCU-walk mode " David Howells
2011-01-14 7:02 ` [PATCH 00/18] Introduce automount support in the VFS " Al Viro
2011-01-14 7:05 ` Al Viro
2011-01-14 11:20 ` David Howells
2011-01-14 11:43 ` David Howells
2011-01-14 11:54 ` David Howells
2011-01-14 11:54 ` David Howells
2011-01-14 15:46 ` Al Viro
2011-01-14 17:26 ` [PATCH 19/18] Unexport do_add_mount() and add in follow_automount(), not ->d_automount() David Howells
2011-01-14 17:30 ` David Howells
2011-01-14 17:43 ` Al Viro
2011-01-14 17:56 ` Al Viro
2011-01-14 18:06 ` Al Viro
2011-01-14 22:07 ` Nick Piggin
2011-01-15 13:30 ` Al Viro
2011-01-15 18:33 ` Nick Piggin
2011-01-16 0:24 ` Al Viro
2011-01-16 1:21 ` Nick Piggin
2011-01-15 18:46 ` Nick Piggin
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=20110116000947.GO19804@ZenIV.linux.org.uk \
--to=viro@zeniv.linux.org.uk \
--cc=autofs@linux.kernel.org \
--cc=dhowells@redhat.com \
--cc=linux-fsdevel@vger.kernel.org \
--cc=npiggin@kernel.dk \
--cc=raven@themaw.net \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.