aboutsummaryrefslogtreecommitdiffstats
path: root/fs/autofs4/expire.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-01-16 14:31:50 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2011-01-16 14:31:50 -0500
commitf8206b925fb0eba3a11839419be118b09105d7b1 (patch)
tree5d41b356a043da09c816ed80bd79d1ea8b2b47e5 /fs/autofs4/expire.c
parent1b59be2a6cdcb5a12e18d8315c07c94a624de48f (diff)
parentf03c65993b98eeb909a4012ce7833c5857d74755 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs-2.6
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs-2.6: (23 commits) sanitize vfsmount refcounting changes fix old umount_tree() breakage autofs4: Merge the remaining dentry ops tables Unexport do_add_mount() and add in follow_automount(), not ->d_automount() Allow d_manage() to be used in RCU-walk mode Remove a further kludge from __do_follow_link() autofs4: Bump version autofs4: Add v4 pseudo direct mount support autofs4: Fix wait validation autofs4: Clean up autofs4_free_ino() autofs4: Clean up dentry operations autofs4: Clean up inode operations autofs4: Remove unused code autofs4: Add d_manage() dentry operation autofs4: Add d_automount() dentry operation Remove the automount through follow_link() kludge code from pathwalk CIFS: Use d_automount() rather than abusing follow_link() NFS: Use d_automount() rather than abusing follow_link() AFS: Use d_automount() rather than abusing follow_link() Add an AT_NO_AUTOMOUNT flag to suppress terminal automount ...
Diffstat (limited to 'fs/autofs4/expire.c')
-rw-r--r--fs/autofs4/expire.c51
1 files changed, 29 insertions, 22 deletions
diff --git a/fs/autofs4/expire.c b/fs/autofs4/expire.c
index cc1d01365905..3ed79d76c233 100644
--- a/fs/autofs4/expire.c
+++ b/fs/autofs4/expire.c
@@ -26,10 +26,6 @@ static inline int autofs4_can_expire(struct dentry *dentry,
26 if (ino == NULL) 26 if (ino == NULL)
27 return 0; 27 return 0;
28 28
29 /* No point expiring a pending mount */
30 if (ino->flags & AUTOFS_INF_PENDING)
31 return 0;
32
33 if (!do_now) { 29 if (!do_now) {
34 /* Too young to die */ 30 /* Too young to die */
35 if (!timeout || time_after(ino->last_used + timeout, now)) 31 if (!timeout || time_after(ino->last_used + timeout, now))
@@ -56,7 +52,7 @@ static int autofs4_mount_busy(struct vfsmount *mnt, struct dentry *dentry)
56 52
57 path_get(&path); 53 path_get(&path);
58 54
59 if (!follow_down(&path)) 55 if (!follow_down_one(&path))
60 goto done; 56 goto done;
61 57
62 if (is_autofs4_dentry(path.dentry)) { 58 if (is_autofs4_dentry(path.dentry)) {
@@ -283,6 +279,7 @@ struct dentry *autofs4_expire_direct(struct super_block *sb,
283 unsigned long timeout; 279 unsigned long timeout;
284 struct dentry *root = dget(sb->s_root); 280 struct dentry *root = dget(sb->s_root);
285 int do_now = how & AUTOFS_EXP_IMMEDIATE; 281 int do_now = how & AUTOFS_EXP_IMMEDIATE;
282 struct autofs_info *ino;
286 283
287 if (!root) 284 if (!root)
288 return NULL; 285 return NULL;
@@ -291,19 +288,21 @@ struct dentry *autofs4_expire_direct(struct super_block *sb,
291 timeout = sbi->exp_timeout; 288 timeout = sbi->exp_timeout;
292 289
293 spin_lock(&sbi->fs_lock); 290 spin_lock(&sbi->fs_lock);
291 ino = autofs4_dentry_ino(root);
292 /* No point expiring a pending mount */
293 if (ino->flags & AUTOFS_INF_PENDING) {
294 spin_unlock(&sbi->fs_lock);
295 return NULL;
296 }
297 managed_dentry_set_transit(root);
294 if (!autofs4_direct_busy(mnt, root, timeout, do_now)) { 298 if (!autofs4_direct_busy(mnt, root, timeout, do_now)) {
295 struct autofs_info *ino = autofs4_dentry_ino(root); 299 struct autofs_info *ino = autofs4_dentry_ino(root);
296 if (d_mountpoint(root)) {
297 ino->flags |= AUTOFS_INF_MOUNTPOINT;
298 spin_lock(&root->d_lock);
299 root->d_flags &= ~DCACHE_MOUNTED;
300 spin_unlock(&root->d_lock);
301 }
302 ino->flags |= AUTOFS_INF_EXPIRING; 300 ino->flags |= AUTOFS_INF_EXPIRING;
303 init_completion(&ino->expire_complete); 301 init_completion(&ino->expire_complete);
304 spin_unlock(&sbi->fs_lock); 302 spin_unlock(&sbi->fs_lock);
305 return root; 303 return root;
306 } 304 }
305 managed_dentry_clear_transit(root);
307 spin_unlock(&sbi->fs_lock); 306 spin_unlock(&sbi->fs_lock);
308 dput(root); 307 dput(root);
309 308
@@ -340,6 +339,10 @@ struct dentry *autofs4_expire_indirect(struct super_block *sb,
340 while ((dentry = get_next_positive_dentry(dentry, root))) { 339 while ((dentry = get_next_positive_dentry(dentry, root))) {
341 spin_lock(&sbi->fs_lock); 340 spin_lock(&sbi->fs_lock);
342 ino = autofs4_dentry_ino(dentry); 341 ino = autofs4_dentry_ino(dentry);
342 /* No point expiring a pending mount */
343 if (ino->flags & AUTOFS_INF_PENDING)
344 goto cont;
345 managed_dentry_set_transit(dentry);
343 346
344 /* 347 /*
345 * Case 1: (i) indirect mount or top level pseudo direct mount 348 * Case 1: (i) indirect mount or top level pseudo direct mount
@@ -399,6 +402,8 @@ struct dentry *autofs4_expire_indirect(struct super_block *sb,
399 } 402 }
400 } 403 }
401next: 404next:
405 managed_dentry_clear_transit(dentry);
406cont:
402 spin_unlock(&sbi->fs_lock); 407 spin_unlock(&sbi->fs_lock);
403 } 408 }
404 return NULL; 409 return NULL;
@@ -479,6 +484,8 @@ int autofs4_expire_run(struct super_block *sb,
479 spin_lock(&sbi->fs_lock); 484 spin_lock(&sbi->fs_lock);
480 ino = autofs4_dentry_ino(dentry); 485 ino = autofs4_dentry_ino(dentry);
481 ino->flags &= ~AUTOFS_INF_EXPIRING; 486 ino->flags &= ~AUTOFS_INF_EXPIRING;
487 if (!d_unhashed(dentry))
488 managed_dentry_clear_transit(dentry);
482 complete_all(&ino->expire_complete); 489 complete_all(&ino->expire_complete);
483 spin_unlock(&sbi->fs_lock); 490 spin_unlock(&sbi->fs_lock);
484 491
@@ -504,18 +511,18 @@ int autofs4_do_expire_multi(struct super_block *sb, struct vfsmount *mnt,
504 ret = autofs4_wait(sbi, dentry, NFY_EXPIRE); 511 ret = autofs4_wait(sbi, dentry, NFY_EXPIRE);
505 512
506 spin_lock(&sbi->fs_lock); 513 spin_lock(&sbi->fs_lock);
507 if (ino->flags & AUTOFS_INF_MOUNTPOINT) {
508 spin_lock(&sb->s_root->d_lock);
509 /*
510 * If we haven't been expired away, then reset
511 * mounted status.
512 */
513 if (mnt->mnt_parent != mnt)
514 sb->s_root->d_flags |= DCACHE_MOUNTED;
515 spin_unlock(&sb->s_root->d_lock);
516 ino->flags &= ~AUTOFS_INF_MOUNTPOINT;
517 }
518 ino->flags &= ~AUTOFS_INF_EXPIRING; 514 ino->flags &= ~AUTOFS_INF_EXPIRING;
515 spin_lock(&dentry->d_lock);
516 if (ret)
517 __managed_dentry_clear_transit(dentry);
518 else {
519 if ((IS_ROOT(dentry) ||
520 (autofs_type_indirect(sbi->type) &&
521 IS_ROOT(dentry->d_parent))) &&
522 !(dentry->d_flags & DCACHE_NEED_AUTOMOUNT))
523 __managed_dentry_set_automount(dentry);
524 }
525 spin_unlock(&dentry->d_lock);
519 complete_all(&ino->expire_complete); 526 complete_all(&ino->expire_complete);
520 spin_unlock(&sbi->fs_lock); 527 spin_unlock(&sbi->fs_lock);
521 dput(dentry); 528 dput(dentry);