aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorIan Kent <raven@themaw.net>2008-07-24 00:30:09 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-07-24 13:47:31 -0400
commit5f6f4f28b6ba543beef8bad91aa6f69c7ffeee51 (patch)
tree72f3aac56d49c7bea7940f8d8b6e8ca559e3ae1c /fs
parent391b52f98cf2e9bff227dad8bf9ea206fec43fa4 (diff)
autofs4: don't make expiring dentry negative
Correct the error of making a positive dentry negative after it has been instantiated. The code that makes this error attempts to re-use the dentry from a concurrent expire and mount to resolve a race and the dentry used for the lookup must be negative for mounts to trigger in the required cases. The fact is that the dentry doesn't need to be re-used because all that is needed is to preserve the flag that indicates an expire is still incomplete at the time of the mount request. This change uses the the dentry to check the flag and wait for the expire to complete then discards it instead of attempting to re-use it. Signed-off-by: Ian Kent <raven@themaw.net> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs')
-rw-r--r--fs/autofs4/autofs_i.h6
-rw-r--r--fs/autofs4/inode.c6
-rw-r--r--fs/autofs4/root.c118
3 files changed, 52 insertions, 78 deletions
diff --git a/fs/autofs4/autofs_i.h b/fs/autofs4/autofs_i.h
index c3d352d7fa93..69b1497b0029 100644
--- a/fs/autofs4/autofs_i.h
+++ b/fs/autofs4/autofs_i.h
@@ -52,7 +52,7 @@ struct autofs_info {
52 52
53 int flags; 53 int flags;
54 54
55 struct list_head rehash; 55 struct list_head expiring;
56 56
57 struct autofs_sb_info *sbi; 57 struct autofs_sb_info *sbi;
58 unsigned long last_used; 58 unsigned long last_used;
@@ -112,8 +112,8 @@ struct autofs_sb_info {
112 struct mutex wq_mutex; 112 struct mutex wq_mutex;
113 spinlock_t fs_lock; 113 spinlock_t fs_lock;
114 struct autofs_wait_queue *queues; /* Wait queue pointer */ 114 struct autofs_wait_queue *queues; /* Wait queue pointer */
115 spinlock_t rehash_lock; 115 spinlock_t lookup_lock;
116 struct list_head rehash_list; 116 struct list_head expiring_list;
117}; 117};
118 118
119static inline struct autofs_sb_info *autofs4_sbi(struct super_block *sb) 119static inline struct autofs_sb_info *autofs4_sbi(struct super_block *sb)
diff --git a/fs/autofs4/inode.c b/fs/autofs4/inode.c
index 2fdcf5e1d236..94bfc154d7a2 100644
--- a/fs/autofs4/inode.c
+++ b/fs/autofs4/inode.c
@@ -47,7 +47,7 @@ struct autofs_info *autofs4_init_ino(struct autofs_info *ino,
47 ino->dentry = NULL; 47 ino->dentry = NULL;
48 ino->size = 0; 48 ino->size = 0;
49 49
50 INIT_LIST_HEAD(&ino->rehash); 50 INIT_LIST_HEAD(&ino->expiring);
51 51
52 ino->last_used = jiffies; 52 ino->last_used = jiffies;
53 atomic_set(&ino->count, 0); 53 atomic_set(&ino->count, 0);
@@ -338,8 +338,8 @@ int autofs4_fill_super(struct super_block *s, void *data, int silent)
338 mutex_init(&sbi->wq_mutex); 338 mutex_init(&sbi->wq_mutex);
339 spin_lock_init(&sbi->fs_lock); 339 spin_lock_init(&sbi->fs_lock);
340 sbi->queues = NULL; 340 sbi->queues = NULL;
341 spin_lock_init(&sbi->rehash_lock); 341 spin_lock_init(&sbi->lookup_lock);
342 INIT_LIST_HEAD(&sbi->rehash_list); 342 INIT_LIST_HEAD(&sbi->expiring_list);
343 s->s_blocksize = 1024; 343 s->s_blocksize = 1024;
344 s->s_blocksize_bits = 10; 344 s->s_blocksize_bits = 10;
345 s->s_magic = AUTOFS_SUPER_MAGIC; 345 s->s_magic = AUTOFS_SUPER_MAGIC;
diff --git a/fs/autofs4/root.c b/fs/autofs4/root.c
index edf5b6bddb52..9ead2279df4f 100644
--- a/fs/autofs4/root.c
+++ b/fs/autofs4/root.c
@@ -493,10 +493,10 @@ void autofs4_dentry_release(struct dentry *de)
493 struct autofs_sb_info *sbi = autofs4_sbi(de->d_sb); 493 struct autofs_sb_info *sbi = autofs4_sbi(de->d_sb);
494 494
495 if (sbi) { 495 if (sbi) {
496 spin_lock(&sbi->rehash_lock); 496 spin_lock(&sbi->lookup_lock);
497 if (!list_empty(&inf->rehash)) 497 if (!list_empty(&inf->expiring))
498 list_del(&inf->rehash); 498 list_del(&inf->expiring);
499 spin_unlock(&sbi->rehash_lock); 499 spin_unlock(&sbi->lookup_lock);
500 } 500 }
501 501
502 inf->dentry = NULL; 502 inf->dentry = NULL;
@@ -518,7 +518,7 @@ static struct dentry_operations autofs4_dentry_operations = {
518 .d_release = autofs4_dentry_release, 518 .d_release = autofs4_dentry_release,
519}; 519};
520 520
521static struct dentry *autofs4_lookup_unhashed(struct autofs_sb_info *sbi, struct dentry *parent, struct qstr *name) 521static struct dentry *autofs4_lookup_expiring(struct autofs_sb_info *sbi, struct dentry *parent, struct qstr *name)
522{ 522{
523 unsigned int len = name->len; 523 unsigned int len = name->len;
524 unsigned int hash = name->hash; 524 unsigned int hash = name->hash;
@@ -526,14 +526,14 @@ static struct dentry *autofs4_lookup_unhashed(struct autofs_sb_info *sbi, struct
526 struct list_head *p, *head; 526 struct list_head *p, *head;
527 527
528 spin_lock(&dcache_lock); 528 spin_lock(&dcache_lock);
529 spin_lock(&sbi->rehash_lock); 529 spin_lock(&sbi->lookup_lock);
530 head = &sbi->rehash_list; 530 head = &sbi->expiring_list;
531 list_for_each(p, head) { 531 list_for_each(p, head) {
532 struct autofs_info *ino; 532 struct autofs_info *ino;
533 struct dentry *dentry; 533 struct dentry *dentry;
534 struct qstr *qstr; 534 struct qstr *qstr;
535 535
536 ino = list_entry(p, struct autofs_info, rehash); 536 ino = list_entry(p, struct autofs_info, expiring);
537 dentry = ino->dentry; 537 dentry = ino->dentry;
538 538
539 spin_lock(&dentry->d_lock); 539 spin_lock(&dentry->d_lock);
@@ -555,33 +555,16 @@ static struct dentry *autofs4_lookup_unhashed(struct autofs_sb_info *sbi, struct
555 goto next; 555 goto next;
556 556
557 if (d_unhashed(dentry)) { 557 if (d_unhashed(dentry)) {
558 struct inode *inode = dentry->d_inode;
559
560 ino = autofs4_dentry_ino(dentry);
561 list_del_init(&ino->rehash);
562 dget(dentry); 558 dget(dentry);
563 /*
564 * Make the rehashed dentry negative so the VFS
565 * behaves as it should.
566 */
567 if (inode) {
568 dentry->d_inode = NULL;
569 list_del_init(&dentry->d_alias);
570 spin_unlock(&dentry->d_lock);
571 spin_unlock(&sbi->rehash_lock);
572 spin_unlock(&dcache_lock);
573 iput(inode);
574 return dentry;
575 }
576 spin_unlock(&dentry->d_lock); 559 spin_unlock(&dentry->d_lock);
577 spin_unlock(&sbi->rehash_lock); 560 spin_unlock(&sbi->lookup_lock);
578 spin_unlock(&dcache_lock); 561 spin_unlock(&dcache_lock);
579 return dentry; 562 return dentry;
580 } 563 }
581next: 564next:
582 spin_unlock(&dentry->d_lock); 565 spin_unlock(&dentry->d_lock);
583 } 566 }
584 spin_unlock(&sbi->rehash_lock); 567 spin_unlock(&sbi->lookup_lock);
585 spin_unlock(&dcache_lock); 568 spin_unlock(&dcache_lock);
586 569
587 return NULL; 570 return NULL;
@@ -591,7 +574,7 @@ next:
591static struct dentry *autofs4_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd) 574static struct dentry *autofs4_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
592{ 575{
593 struct autofs_sb_info *sbi; 576 struct autofs_sb_info *sbi;
594 struct dentry *unhashed; 577 struct dentry *expiring;
595 int oz_mode; 578 int oz_mode;
596 579
597 DPRINTK("name = %.*s", 580 DPRINTK("name = %.*s",
@@ -607,44 +590,44 @@ static struct dentry *autofs4_lookup(struct inode *dir, struct dentry *dentry, s
607 DPRINTK("pid = %u, pgrp = %u, catatonic = %d, oz_mode = %d", 590 DPRINTK("pid = %u, pgrp = %u, catatonic = %d, oz_mode = %d",
608 current->pid, task_pgrp_nr(current), sbi->catatonic, oz_mode); 591 current->pid, task_pgrp_nr(current), sbi->catatonic, oz_mode);
609 592
610 unhashed = autofs4_lookup_unhashed(sbi, dentry->d_parent, &dentry->d_name); 593 expiring = autofs4_lookup_expiring(sbi, dentry->d_parent, &dentry->d_name);
611 if (!unhashed) { 594 if (expiring) {
612 /* 595 struct autofs_info *ino = autofs4_dentry_ino(expiring);
613 * Mark the dentry incomplete but don't hash it. We do this
614 * to serialize our inode creation operations (symlink and
615 * mkdir) which prevents deadlock during the callback to
616 * the daemon. Subsequent user space lookups for the same
617 * dentry are placed on the wait queue while the daemon
618 * itself is allowed passage unresticted so the create
619 * operation itself can then hash the dentry. Finally,
620 * we check for the hashed dentry and return the newly
621 * hashed dentry.
622 */
623 dentry->d_op = &autofs4_root_dentry_operations;
624
625 dentry->d_fsdata = NULL;
626 d_instantiate(dentry, NULL);
627 } else {
628 struct autofs_info *ino = autofs4_dentry_ino(unhashed);
629 DPRINTK("rehash %p with %p", dentry, unhashed);
630 /* 596 /*
631 * If we are racing with expire the request might not 597 * If we are racing with expire the request might not
632 * be quite complete but the directory has been removed 598 * be quite complete but the directory has been removed
633 * so it must have been successful, so just wait for it. 599 * so it must have been successful, so just wait for it.
634 * We need to ensure the AUTOFS_INF_EXPIRING flag is clear
635 * before continuing as revalidate may fail when calling
636 * try_to_fill_dentry (returning EAGAIN) if we don't.
637 */ 600 */
638 while (ino && (ino->flags & AUTOFS_INF_EXPIRING)) { 601 while (ino && (ino->flags & AUTOFS_INF_EXPIRING)) {
639 DPRINTK("wait for incomplete expire %p name=%.*s", 602 DPRINTK("wait for incomplete expire %p name=%.*s",
640 unhashed, unhashed->d_name.len, 603 expiring, expiring->d_name.len,
641 unhashed->d_name.name); 604 expiring->d_name.name);
642 autofs4_wait(sbi, unhashed, NFY_NONE); 605 autofs4_wait(sbi, expiring, NFY_NONE);
643 DPRINTK("request completed"); 606 DPRINTK("request completed");
644 } 607 }
645 dentry = unhashed; 608 spin_lock(&sbi->lookup_lock);
609 if (!list_empty(&ino->expiring))
610 list_del_init(&ino->expiring);
611 spin_unlock(&sbi->lookup_lock);
612 dput(expiring);
646 } 613 }
647 614
615 /*
616 * Mark the dentry incomplete but don't hash it. We do this
617 * to serialize our inode creation operations (symlink and
618 * mkdir) which prevents deadlock during the callback to
619 * the daemon. Subsequent user space lookups for the same
620 * dentry are placed on the wait queue while the daemon
621 * itself is allowed passage unresticted so the create
622 * operation itself can then hash the dentry. Finally,
623 * we check for the hashed dentry and return the newly
624 * hashed dentry.
625 */
626 dentry->d_op = &autofs4_root_dentry_operations;
627
628 dentry->d_fsdata = NULL;
629 d_instantiate(dentry, NULL);
630
648 if (!oz_mode) { 631 if (!oz_mode) {
649 spin_lock(&dentry->d_lock); 632 spin_lock(&dentry->d_lock);
650 dentry->d_flags |= DCACHE_AUTOFS_PENDING; 633 dentry->d_flags |= DCACHE_AUTOFS_PENDING;
@@ -668,8 +651,6 @@ static struct dentry *autofs4_lookup(struct inode *dir, struct dentry *dentry, s
668 if (sigismember (sigset, SIGKILL) || 651 if (sigismember (sigset, SIGKILL) ||
669 sigismember (sigset, SIGQUIT) || 652 sigismember (sigset, SIGQUIT) ||
670 sigismember (sigset, SIGINT)) { 653 sigismember (sigset, SIGINT)) {
671 if (unhashed)
672 dput(unhashed);
673 return ERR_PTR(-ERESTARTNOINTR); 654 return ERR_PTR(-ERESTARTNOINTR);
674 } 655 }
675 } 656 }
@@ -699,15 +680,9 @@ static struct dentry *autofs4_lookup(struct inode *dir, struct dentry *dentry, s
699 else 680 else
700 dentry = ERR_PTR(-ENOENT); 681 dentry = ERR_PTR(-ENOENT);
701 682
702 if (unhashed)
703 dput(unhashed);
704
705 return dentry; 683 return dentry;
706 } 684 }
707 685
708 if (unhashed)
709 return dentry;
710
711 return NULL; 686 return NULL;
712} 687}
713 688
@@ -769,9 +744,8 @@ static int autofs4_dir_symlink(struct inode *dir,
769 * that the file no longer exists. However, doing that means that the 744 * that the file no longer exists. However, doing that means that the
770 * VFS layer can turn the dentry into a negative dentry. We don't want 745 * VFS layer can turn the dentry into a negative dentry. We don't want
771 * this, because the unlink is probably the result of an expire. 746 * this, because the unlink is probably the result of an expire.
772 * We simply d_drop it and add it to a rehash candidates list in the 747 * We simply d_drop it and add it to a expiring list in the super block,
773 * super block, which allows the dentry lookup to reuse it retaining 748 * which allows the dentry lookup to check for an incomplete expire.
774 * the flags, such as expire in progress, in case we're racing with expire.
775 * 749 *
776 * If a process is blocked on the dentry waiting for the expire to finish, 750 * If a process is blocked on the dentry waiting for the expire to finish,
777 * it will invalidate the dentry and try to mount with a new one. 751 * it will invalidate the dentry and try to mount with a new one.
@@ -801,9 +775,9 @@ static int autofs4_dir_unlink(struct inode *dir, struct dentry *dentry)
801 dir->i_mtime = CURRENT_TIME; 775 dir->i_mtime = CURRENT_TIME;
802 776
803 spin_lock(&dcache_lock); 777 spin_lock(&dcache_lock);
804 spin_lock(&sbi->rehash_lock); 778 spin_lock(&sbi->lookup_lock);
805 list_add(&ino->rehash, &sbi->rehash_list); 779 list_add(&ino->expiring, &sbi->expiring_list);
806 spin_unlock(&sbi->rehash_lock); 780 spin_unlock(&sbi->lookup_lock);
807 spin_lock(&dentry->d_lock); 781 spin_lock(&dentry->d_lock);
808 __d_drop(dentry); 782 __d_drop(dentry);
809 spin_unlock(&dentry->d_lock); 783 spin_unlock(&dentry->d_lock);
@@ -829,9 +803,9 @@ static int autofs4_dir_rmdir(struct inode *dir, struct dentry *dentry)
829 spin_unlock(&dcache_lock); 803 spin_unlock(&dcache_lock);
830 return -ENOTEMPTY; 804 return -ENOTEMPTY;
831 } 805 }
832 spin_lock(&sbi->rehash_lock); 806 spin_lock(&sbi->lookup_lock);
833 list_add(&ino->rehash, &sbi->rehash_list); 807 list_add(&ino->expiring, &sbi->expiring_list);
834 spin_unlock(&sbi->rehash_lock); 808 spin_unlock(&sbi->lookup_lock);
835 spin_lock(&dentry->d_lock); 809 spin_lock(&dentry->d_lock);
836 __d_drop(dentry); 810 __d_drop(dentry);
837 spin_unlock(&dentry->d_lock); 811 spin_unlock(&dentry->d_lock);