diff options
author | Ian Kent <ikent@redhat.com> | 2016-11-24 08:03:42 +1100 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2016-12-03 20:51:49 -0500 |
commit | 60359741473438f66fef7297d1fa2435640dbe79 (patch) | |
tree | 3316c740550e8bd1ddc441385517e28d96e5468e /fs/autofs4/waitq.c | |
parent | cfaf86ab6ccdf0acf47ebe474a4a844114bc0e10 (diff) | |
download | linux-60359741473438f66fef7297d1fa2435640dbe79.tar.gz linux-60359741473438f66fef7297d1fa2435640dbe79.tar.bz2 linux-60359741473438f66fef7297d1fa2435640dbe79.zip |
autofs: use path_has_submounts() to fix unreliable have_submount() checks
If an automount mount is clone(2)ed into a file system that is propagation
private, when it later expires in the originating namespace, subsequent
calls to autofs ->d_automount() for that dentry in the original namespace
will return ELOOP until the mount is umounted in the cloned namespace.
Now that a struct path is available where needed use path_has_submounts()
instead of have_submounts() so we don't get false positives when checking
if a dentry is a mount point or contains mounts in the current namespace.
Link: http://lkml.kernel.org/r/20161011053423.27645.91233.stgit@pluto.themaw.net
Signed-off-by: Ian Kent <raven@themaw.net>
Cc: Al Viro <viro@ZenIV.linux.org.uk>
Cc: Eric W. Biederman <ebiederm@xmission.com>
Cc: Omar Sandoval <osandov@osandov.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/autofs4/waitq.c')
-rw-r--r-- | fs/autofs4/waitq.c | 10 |
1 files changed, 7 insertions, 3 deletions
diff --git a/fs/autofs4/waitq.c b/fs/autofs4/waitq.c index 38ef973f80e9..1278335ce366 100644 --- a/fs/autofs4/waitq.c +++ b/fs/autofs4/waitq.c @@ -250,8 +250,9 @@ autofs4_find_wait(struct autofs_sb_info *sbi, const struct qstr *qstr) static int validate_request(struct autofs_wait_queue **wait, struct autofs_sb_info *sbi, const struct qstr *qstr, - struct dentry *dentry, enum autofs_notify notify) + const struct path *path, enum autofs_notify notify) { + struct dentry *dentry = path->dentry; struct autofs_wait_queue *wq; struct autofs_info *ino; @@ -314,6 +315,7 @@ static int validate_request(struct autofs_wait_queue **wait, */ if (notify == NFY_MOUNT) { struct dentry *new = NULL; + struct path this; int valid = 1; /* @@ -333,7 +335,9 @@ static int validate_request(struct autofs_wait_queue **wait, dentry = new; } } - if (have_submounts(dentry)) + this.mnt = path->mnt; + this.dentry = dentry; + if (path_has_submounts(&this)) valid = 0; if (new) @@ -406,7 +410,7 @@ int autofs4_wait(struct autofs_sb_info *sbi, return -EINTR; } - ret = validate_request(&wq, sbi, &qstr, dentry, notify); + ret = validate_request(&wq, sbi, &qstr, path, notify); if (ret <= 0) { if (ret != -EINTR) mutex_unlock(&sbi->wq_mutex); |