diff options
Diffstat (limited to 'fs/autofs4')
-rw-r--r-- | fs/autofs4/expire.c | 4 | ||||
-rw-r--r-- | fs/autofs4/root.c | 50 |
2 files changed, 44 insertions, 10 deletions
diff --git a/fs/autofs4/expire.c b/fs/autofs4/expire.c index 08e33218a64a..b8ce02607d66 100644 --- a/fs/autofs4/expire.c +++ b/fs/autofs4/expire.c | |||
@@ -113,10 +113,6 @@ static int autofs4_direct_busy(struct vfsmount *mnt, | |||
113 | DPRINTK("top %p %.*s", | 113 | DPRINTK("top %p %.*s", |
114 | top, (int) top->d_name.len, top->d_name.name); | 114 | top, (int) top->d_name.len, top->d_name.name); |
115 | 115 | ||
116 | /* Not a mountpoint - give up */ | ||
117 | if (!d_mountpoint(top)) | ||
118 | return 1; | ||
119 | |||
120 | /* If it's busy update the expiry counters */ | 116 | /* If it's busy update the expiry counters */ |
121 | if (!may_umount_tree(mnt)) { | 117 | if (!may_umount_tree(mnt)) { |
122 | struct autofs_info *ino = autofs4_dentry_ino(top); | 118 | struct autofs_info *ino = autofs4_dentry_ino(top); |
diff --git a/fs/autofs4/root.c b/fs/autofs4/root.c index 3f0048582248..c8fe43a475e2 100644 --- a/fs/autofs4/root.c +++ b/fs/autofs4/root.c | |||
@@ -57,6 +57,9 @@ struct inode_operations autofs4_indirect_root_inode_operations = { | |||
57 | 57 | ||
58 | struct inode_operations autofs4_direct_root_inode_operations = { | 58 | struct inode_operations autofs4_direct_root_inode_operations = { |
59 | .lookup = autofs4_lookup, | 59 | .lookup = autofs4_lookup, |
60 | .unlink = autofs4_dir_unlink, | ||
61 | .mkdir = autofs4_dir_mkdir, | ||
62 | .rmdir = autofs4_dir_rmdir, | ||
60 | .follow_link = autofs4_follow_link, | 63 | .follow_link = autofs4_follow_link, |
61 | }; | 64 | }; |
62 | 65 | ||
@@ -337,15 +340,50 @@ static void *autofs4_follow_link(struct dentry *dentry, struct nameidata *nd) | |||
337 | if (oz_mode || !lookup_type) | 340 | if (oz_mode || !lookup_type) |
338 | goto done; | 341 | goto done; |
339 | 342 | ||
340 | status = try_to_fill_dentry(dentry, 0); | 343 | /* |
341 | if (status) | 344 | * If a request is pending wait for it. |
342 | goto out_error; | 345 | * If it's a mount then it won't be expired till at least |
346 | * a liitle later and if it's an expire then we might need | ||
347 | * to mount it again. | ||
348 | */ | ||
349 | if (autofs4_ispending(dentry)) { | ||
350 | DPRINTK("waiting for active request %p name=%.*s", | ||
351 | dentry, dentry->d_name.len, dentry->d_name.name); | ||
343 | 352 | ||
344 | if (!autofs4_follow_mount(&nd->mnt, &nd->dentry)) { | 353 | status = autofs4_wait(sbi, dentry, NFY_NONE); |
345 | status = -ENOENT; | 354 | |
346 | goto out_error; | 355 | DPRINTK("request done status=%d", status); |
347 | } | 356 | } |
348 | 357 | ||
358 | /* | ||
359 | * If the dentry contains directories then it is an | ||
360 | * autofs multi-mount with no root mount offset. So | ||
361 | * don't try to mount it again. | ||
362 | */ | ||
363 | spin_lock(&dcache_lock); | ||
364 | if (!d_mountpoint(dentry) && list_empty(&dentry->d_subdirs)) { | ||
365 | spin_unlock(&dcache_lock); | ||
366 | |||
367 | status = try_to_fill_dentry(dentry, 0); | ||
368 | if (status) | ||
369 | goto out_error; | ||
370 | |||
371 | /* | ||
372 | * The mount succeeded but if there is no root mount | ||
373 | * it must be an autofs multi-mount with no root offset | ||
374 | * so we don't need to follow the mount. | ||
375 | */ | ||
376 | if (d_mountpoint(dentry)) { | ||
377 | if (!autofs4_follow_mount(&nd->mnt, &nd->dentry)) { | ||
378 | status = -ENOENT; | ||
379 | goto out_error; | ||
380 | } | ||
381 | } | ||
382 | |||
383 | goto done; | ||
384 | } | ||
385 | spin_unlock(&dcache_lock); | ||
386 | |||
349 | done: | 387 | done: |
350 | return NULL; | 388 | return NULL; |
351 | 389 | ||