aboutsummaryrefslogtreecommitdiffstats
path: root/fs/autofs4/expire.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/autofs4/expire.c')
-rw-r--r--fs/autofs4/expire.c27
1 files changed, 8 insertions, 19 deletions
diff --git a/fs/autofs4/expire.c b/fs/autofs4/expire.c
index 9510d8d2e9cd..b493909e7492 100644
--- a/fs/autofs4/expire.c
+++ b/fs/autofs4/expire.c
@@ -316,19 +316,17 @@ struct dentry *autofs4_expire_direct(struct super_block *sb,
316 if (ino->flags & AUTOFS_INF_PENDING) 316 if (ino->flags & AUTOFS_INF_PENDING)
317 goto out; 317 goto out;
318 if (!autofs4_direct_busy(mnt, root, timeout, do_now)) { 318 if (!autofs4_direct_busy(mnt, root, timeout, do_now)) {
319 ino->flags |= AUTOFS_INF_NO_RCU; 319 ino->flags |= AUTOFS_INF_WANT_EXPIRE;
320 spin_unlock(&sbi->fs_lock); 320 spin_unlock(&sbi->fs_lock);
321 synchronize_rcu(); 321 synchronize_rcu();
322 spin_lock(&sbi->fs_lock); 322 spin_lock(&sbi->fs_lock);
323 if (!autofs4_direct_busy(mnt, root, timeout, do_now)) { 323 if (!autofs4_direct_busy(mnt, root, timeout, do_now)) {
324 ino->flags |= AUTOFS_INF_EXPIRING; 324 ino->flags |= AUTOFS_INF_EXPIRING;
325 smp_mb();
326 ino->flags &= ~AUTOFS_INF_NO_RCU;
327 init_completion(&ino->expire_complete); 325 init_completion(&ino->expire_complete);
328 spin_unlock(&sbi->fs_lock); 326 spin_unlock(&sbi->fs_lock);
329 return root; 327 return root;
330 } 328 }
331 ino->flags &= ~AUTOFS_INF_NO_RCU; 329 ino->flags &= ~AUTOFS_INF_WANT_EXPIRE;
332 } 330 }
333out: 331out:
334 spin_unlock(&sbi->fs_lock); 332 spin_unlock(&sbi->fs_lock);
@@ -446,7 +444,7 @@ struct dentry *autofs4_expire_indirect(struct super_block *sb,
446 while ((dentry = get_next_positive_subdir(dentry, root))) { 444 while ((dentry = get_next_positive_subdir(dentry, root))) {
447 spin_lock(&sbi->fs_lock); 445 spin_lock(&sbi->fs_lock);
448 ino = autofs4_dentry_ino(dentry); 446 ino = autofs4_dentry_ino(dentry);
449 if (ino->flags & AUTOFS_INF_NO_RCU) 447 if (ino->flags & AUTOFS_INF_WANT_EXPIRE)
450 expired = NULL; 448 expired = NULL;
451 else 449 else
452 expired = should_expire(dentry, mnt, timeout, how); 450 expired = should_expire(dentry, mnt, timeout, how);
@@ -455,7 +453,7 @@ struct dentry *autofs4_expire_indirect(struct super_block *sb,
455 continue; 453 continue;
456 } 454 }
457 ino = autofs4_dentry_ino(expired); 455 ino = autofs4_dentry_ino(expired);
458 ino->flags |= AUTOFS_INF_NO_RCU; 456 ino->flags |= AUTOFS_INF_WANT_EXPIRE;
459 spin_unlock(&sbi->fs_lock); 457 spin_unlock(&sbi->fs_lock);
460 synchronize_rcu(); 458 synchronize_rcu();
461 spin_lock(&sbi->fs_lock); 459 spin_lock(&sbi->fs_lock);
@@ -465,7 +463,7 @@ struct dentry *autofs4_expire_indirect(struct super_block *sb,
465 goto found; 463 goto found;
466 } 464 }
467 465
468 ino->flags &= ~AUTOFS_INF_NO_RCU; 466 ino->flags &= ~AUTOFS_INF_WANT_EXPIRE;
469 if (expired != dentry) 467 if (expired != dentry)
470 dput(expired); 468 dput(expired);
471 spin_unlock(&sbi->fs_lock); 469 spin_unlock(&sbi->fs_lock);
@@ -475,17 +473,8 @@ struct dentry *autofs4_expire_indirect(struct super_block *sb,
475found: 473found:
476 pr_debug("returning %p %pd\n", expired, expired); 474 pr_debug("returning %p %pd\n", expired, expired);
477 ino->flags |= AUTOFS_INF_EXPIRING; 475 ino->flags |= AUTOFS_INF_EXPIRING;
478 smp_mb();
479 ino->flags &= ~AUTOFS_INF_NO_RCU;
480 init_completion(&ino->expire_complete); 476 init_completion(&ino->expire_complete);
481 spin_unlock(&sbi->fs_lock); 477 spin_unlock(&sbi->fs_lock);
482 spin_lock(&sbi->lookup_lock);
483 spin_lock(&expired->d_parent->d_lock);
484 spin_lock_nested(&expired->d_lock, DENTRY_D_LOCK_NESTED);
485 list_move(&expired->d_parent->d_subdirs, &expired->d_child);
486 spin_unlock(&expired->d_lock);
487 spin_unlock(&expired->d_parent->d_lock);
488 spin_unlock(&sbi->lookup_lock);
489 return expired; 478 return expired;
490} 479}
491 480
@@ -496,7 +485,7 @@ int autofs4_expire_wait(struct dentry *dentry, int rcu_walk)
496 int status; 485 int status;
497 486
498 /* Block on any pending expire */ 487 /* Block on any pending expire */
499 if (!(ino->flags & (AUTOFS_INF_EXPIRING | AUTOFS_INF_NO_RCU))) 488 if (!(ino->flags & AUTOFS_INF_WANT_EXPIRE))
500 return 0; 489 return 0;
501 if (rcu_walk) 490 if (rcu_walk)
502 return -ECHILD; 491 return -ECHILD;
@@ -554,7 +543,7 @@ int autofs4_expire_run(struct super_block *sb,
554 ino = autofs4_dentry_ino(dentry); 543 ino = autofs4_dentry_ino(dentry);
555 /* avoid rapid-fire expire attempts if expiry fails */ 544 /* avoid rapid-fire expire attempts if expiry fails */
556 ino->last_used = now; 545 ino->last_used = now;
557 ino->flags &= ~AUTOFS_INF_EXPIRING; 546 ino->flags &= ~(AUTOFS_INF_EXPIRING|AUTOFS_INF_WANT_EXPIRE);
558 complete_all(&ino->expire_complete); 547 complete_all(&ino->expire_complete);
559 spin_unlock(&sbi->fs_lock); 548 spin_unlock(&sbi->fs_lock);
560 549
@@ -583,7 +572,7 @@ int autofs4_do_expire_multi(struct super_block *sb, struct vfsmount *mnt,
583 spin_lock(&sbi->fs_lock); 572 spin_lock(&sbi->fs_lock);
584 /* avoid rapid-fire expire attempts if expiry fails */ 573 /* avoid rapid-fire expire attempts if expiry fails */
585 ino->last_used = now; 574 ino->last_used = now;
586 ino->flags &= ~AUTOFS_INF_EXPIRING; 575 ino->flags &= ~(AUTOFS_INF_EXPIRING|AUTOFS_INF_WANT_EXPIRE);
587 complete_all(&ino->expire_complete); 576 complete_all(&ino->expire_complete);
588 spin_unlock(&sbi->fs_lock); 577 spin_unlock(&sbi->fs_lock);
589 dput(dentry); 578 dput(dentry);