diff options
Diffstat (limited to 'fs/autofs4/root.c')
-rw-r--r-- | fs/autofs4/root.c | 50 |
1 files changed, 44 insertions, 6 deletions
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 | ||