aboutsummaryrefslogtreecommitdiffstats
path: root/fs/autofs4
diff options
context:
space:
mode:
authorIan Kent <raven@themaw.net>2013-09-08 04:47:23 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2013-09-08 22:07:47 -0400
commitac8387199656b019dcef5e3bbe029c2e9b01a195 (patch)
tree0527b48b9293e395fda4048bedcd410cc802eda8 /fs/autofs4
parent2d8646510120bb1eb251ae3381e950805a877763 (diff)
autofs4 - fix device ioctl mount lookup
When reconnecting to automounts at startup an autofs ioctl is used to find the device and inode of existing mounts so they can be used to open a file descriptor of possibly covered mounts. At this time the the caller might not yet "own" the mount so it can trigger calling ->d_automount(). This causes automount to hang when trying to reconnect to direct or offset mount types. Consequently kern_path() can't be used but kern_path_mountpoint() can be. Signed-off-by: Ian Kent <raven@themaw.net> Cc: Jeff Layton <jlayton@redhat.com> Cc: Al Viro <viro@ZenIV.linux.org.uk> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/autofs4')
-rw-r--r--fs/autofs4/dev-ioctl.c23
1 files changed, 12 insertions, 11 deletions
diff --git a/fs/autofs4/dev-ioctl.c b/fs/autofs4/dev-ioctl.c
index 743c7c2c949d..0f00da329e71 100644
--- a/fs/autofs4/dev-ioctl.c
+++ b/fs/autofs4/dev-ioctl.c
@@ -183,13 +183,14 @@ static int autofs_dev_ioctl_protosubver(struct file *fp,
183 return 0; 183 return 0;
184} 184}
185 185
186/* Find the topmost mount satisfying test() */
186static int find_autofs_mount(const char *pathname, 187static int find_autofs_mount(const char *pathname,
187 struct path *res, 188 struct path *res,
188 int test(struct path *path, void *data), 189 int test(struct path *path, void *data),
189 void *data) 190 void *data)
190{ 191{
191 struct path path; 192 struct path path;
192 int err = kern_path(pathname, 0, &path); 193 int err = kern_path_mountpoint(AT_FDCWD, pathname, &path, 0);
193 if (err) 194 if (err)
194 return err; 195 return err;
195 err = -ENOENT; 196 err = -ENOENT;
@@ -197,10 +198,9 @@ static int find_autofs_mount(const char *pathname,
197 if (path.dentry->d_sb->s_magic == AUTOFS_SUPER_MAGIC) { 198 if (path.dentry->d_sb->s_magic == AUTOFS_SUPER_MAGIC) {
198 if (test(&path, data)) { 199 if (test(&path, data)) {
199 path_get(&path); 200 path_get(&path);
200 if (!err) /* already found some */
201 path_put(res);
202 *res = path; 201 *res = path;
203 err = 0; 202 err = 0;
203 break;
204 } 204 }
205 } 205 }
206 if (!follow_up(&path)) 206 if (!follow_up(&path))
@@ -486,12 +486,11 @@ static int autofs_dev_ioctl_askumount(struct file *fp,
486 * mount if there is one or 0 if it isn't a mountpoint. 486 * mount if there is one or 0 if it isn't a mountpoint.
487 * 487 *
488 * If we aren't supplied with a file descriptor then we 488 * If we aren't supplied with a file descriptor then we
489 * lookup the nameidata of the path and check if it is the 489 * lookup the path and check if it is the root of a mount.
490 * root of a mount. If a type is given we are looking for 490 * If a type is given we are looking for a particular autofs
491 * a particular autofs mount and if we don't find a match 491 * mount and if we don't find a match we return fail. If the
492 * we return fail. If the located nameidata path is the 492 * located path is the root of a mount we return 1 along with
493 * root of a mount we return 1 along with the super magic 493 * the super magic of the mount or 0 otherwise.
494 * of the mount or 0 otherwise.
495 * 494 *
496 * In both cases the the device number (as returned by 495 * In both cases the the device number (as returned by
497 * new_encode_dev()) is also returned. 496 * new_encode_dev()) is also returned.
@@ -519,9 +518,11 @@ static int autofs_dev_ioctl_ismountpoint(struct file *fp,
519 518
520 if (!fp || param->ioctlfd == -1) { 519 if (!fp || param->ioctlfd == -1) {
521 if (autofs_type_any(type)) 520 if (autofs_type_any(type))
522 err = kern_path(name, LOOKUP_FOLLOW, &path); 521 err = kern_path_mountpoint(AT_FDCWD,
522 name, &path, LOOKUP_FOLLOW);
523 else 523 else
524 err = find_autofs_mount(name, &path, test_by_type, &type); 524 err = find_autofs_mount(name, &path,
525 test_by_type, &type);
525 if (err) 526 if (err)
526 goto out; 527 goto out;
527 devid = new_encode_dev(path.dentry->d_sb->s_dev); 528 devid = new_encode_dev(path.dentry->d_sb->s_dev);