aboutsummaryrefslogtreecommitdiffstats
path: root/fs/autofs4/root.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/autofs4/root.c')
-rw-r--r--fs/autofs4/root.c169
1 files changed, 139 insertions, 30 deletions
diff --git a/fs/autofs4/root.c b/fs/autofs4/root.c
index 53dabe8d5b8b..dbb70d5a4882 100644
--- a/fs/autofs4/root.c
+++ b/fs/autofs4/root.c
@@ -473,6 +473,8 @@ void autofs4_dentry_release(struct dentry *de)
473 473
474 if (sbi) { 474 if (sbi) {
475 spin_lock(&sbi->lookup_lock); 475 spin_lock(&sbi->lookup_lock);
476 if (!list_empty(&inf->active))
477 list_del(&inf->active);
476 if (!list_empty(&inf->expiring)) 478 if (!list_empty(&inf->expiring))
477 list_del(&inf->expiring); 479 list_del(&inf->expiring);
478 spin_unlock(&sbi->lookup_lock); 480 spin_unlock(&sbi->lookup_lock);
@@ -497,6 +499,58 @@ static struct dentry_operations autofs4_dentry_operations = {
497 .d_release = autofs4_dentry_release, 499 .d_release = autofs4_dentry_release,
498}; 500};
499 501
502static struct dentry *autofs4_lookup_active(struct autofs_sb_info *sbi, struct dentry *parent, struct qstr *name)
503{
504 unsigned int len = name->len;
505 unsigned int hash = name->hash;
506 const unsigned char *str = name->name;
507 struct list_head *p, *head;
508
509 spin_lock(&dcache_lock);
510 spin_lock(&sbi->lookup_lock);
511 head = &sbi->active_list;
512 list_for_each(p, head) {
513 struct autofs_info *ino;
514 struct dentry *dentry;
515 struct qstr *qstr;
516
517 ino = list_entry(p, struct autofs_info, active);
518 dentry = ino->dentry;
519
520 spin_lock(&dentry->d_lock);
521
522 /* Already gone? */
523 if (atomic_read(&dentry->d_count) == 0)
524 goto next;
525
526 qstr = &dentry->d_name;
527
528 if (dentry->d_name.hash != hash)
529 goto next;
530 if (dentry->d_parent != parent)
531 goto next;
532
533 if (qstr->len != len)
534 goto next;
535 if (memcmp(qstr->name, str, len))
536 goto next;
537
538 if (d_unhashed(dentry)) {
539 dget(dentry);
540 spin_unlock(&dentry->d_lock);
541 spin_unlock(&sbi->lookup_lock);
542 spin_unlock(&dcache_lock);
543 return dentry;
544 }
545next:
546 spin_unlock(&dentry->d_lock);
547 }
548 spin_unlock(&sbi->lookup_lock);
549 spin_unlock(&dcache_lock);
550
551 return NULL;
552}
553
500static struct dentry *autofs4_lookup_expiring(struct autofs_sb_info *sbi, struct dentry *parent, struct qstr *name) 554static struct dentry *autofs4_lookup_expiring(struct autofs_sb_info *sbi, struct dentry *parent, struct qstr *name)
501{ 555{
502 unsigned int len = name->len; 556 unsigned int len = name->len;
@@ -553,7 +607,8 @@ next:
553static struct dentry *autofs4_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd) 607static struct dentry *autofs4_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
554{ 608{
555 struct autofs_sb_info *sbi; 609 struct autofs_sb_info *sbi;
556 struct dentry *expiring; 610 struct autofs_info *ino;
611 struct dentry *expiring, *unhashed;
557 int oz_mode; 612 int oz_mode;
558 613
559 DPRINTK("name = %.*s", 614 DPRINTK("name = %.*s",
@@ -571,12 +626,12 @@ static struct dentry *autofs4_lookup(struct inode *dir, struct dentry *dentry, s
571 626
572 expiring = autofs4_lookup_expiring(sbi, dentry->d_parent, &dentry->d_name); 627 expiring = autofs4_lookup_expiring(sbi, dentry->d_parent, &dentry->d_name);
573 if (expiring) { 628 if (expiring) {
574 struct autofs_info *ino = autofs4_dentry_ino(expiring);
575 /* 629 /*
576 * If we are racing with expire the request might not 630 * If we are racing with expire the request might not
577 * be quite complete but the directory has been removed 631 * be quite complete but the directory has been removed
578 * so it must have been successful, so just wait for it. 632 * so it must have been successful, so just wait for it.
579 */ 633 */
634 ino = autofs4_dentry_ino(expiring);
580 while (ino && (ino->flags & AUTOFS_INF_EXPIRING)) { 635 while (ino && (ino->flags & AUTOFS_INF_EXPIRING)) {
581 DPRINTK("wait for incomplete expire %p name=%.*s", 636 DPRINTK("wait for incomplete expire %p name=%.*s",
582 expiring, expiring->d_name.len, 637 expiring, expiring->d_name.len,
@@ -591,21 +646,41 @@ static struct dentry *autofs4_lookup(struct inode *dir, struct dentry *dentry, s
591 dput(expiring); 646 dput(expiring);
592 } 647 }
593 648
594 /* 649 unhashed = autofs4_lookup_active(sbi, dentry->d_parent, &dentry->d_name);
595 * Mark the dentry incomplete but don't hash it. We do this 650 if (unhashed)
596 * to serialize our inode creation operations (symlink and 651 dentry = unhashed;
597 * mkdir) which prevents deadlock during the callback to 652 else {
598 * the daemon. Subsequent user space lookups for the same 653 /*
599 * dentry are placed on the wait queue while the daemon 654 * Mark the dentry incomplete but don't hash it. We do this
600 * itself is allowed passage unresticted so the create 655 * to serialize our inode creation operations (symlink and
601 * operation itself can then hash the dentry. Finally, 656 * mkdir) which prevents deadlock during the callback to
602 * we check for the hashed dentry and return the newly 657 * the daemon. Subsequent user space lookups for the same
603 * hashed dentry. 658 * dentry are placed on the wait queue while the daemon
604 */ 659 * itself is allowed passage unresticted so the create
605 dentry->d_op = &autofs4_root_dentry_operations; 660 * operation itself can then hash the dentry. Finally,
661 * we check for the hashed dentry and return the newly
662 * hashed dentry.
663 */
664 dentry->d_op = &autofs4_root_dentry_operations;
665
666 /*
667 * And we need to ensure that the same dentry is used for
668 * all following lookup calls until it is hashed so that
669 * the dentry flags are persistent throughout the request.
670 */
671 ino = autofs4_init_ino(NULL, sbi, 0555);
672 if (!ino)
673 return ERR_PTR(-ENOMEM);
674
675 dentry->d_fsdata = ino;
676 ino->dentry = dentry;
677
678 spin_lock(&sbi->lookup_lock);
679 list_add(&ino->active, &sbi->active_list);
680 spin_unlock(&sbi->lookup_lock);
606 681
607 dentry->d_fsdata = NULL; 682 d_instantiate(dentry, NULL);
608 d_instantiate(dentry, NULL); 683 }
609 684
610 if (!oz_mode) { 685 if (!oz_mode) {
611 spin_lock(&dentry->d_lock); 686 spin_lock(&dentry->d_lock);
@@ -630,12 +705,16 @@ static struct dentry *autofs4_lookup(struct inode *dir, struct dentry *dentry, s
630 if (sigismember (sigset, SIGKILL) || 705 if (sigismember (sigset, SIGKILL) ||
631 sigismember (sigset, SIGQUIT) || 706 sigismember (sigset, SIGQUIT) ||
632 sigismember (sigset, SIGINT)) { 707 sigismember (sigset, SIGINT)) {
708 if (unhashed)
709 dput(unhashed);
633 return ERR_PTR(-ERESTARTNOINTR); 710 return ERR_PTR(-ERESTARTNOINTR);
634 } 711 }
635 } 712 }
636 spin_lock(&dentry->d_lock); 713 if (!oz_mode) {
637 dentry->d_flags &= ~DCACHE_AUTOFS_PENDING; 714 spin_lock(&dentry->d_lock);
638 spin_unlock(&dentry->d_lock); 715 dentry->d_flags &= ~DCACHE_AUTOFS_PENDING;
716 spin_unlock(&dentry->d_lock);
717 }
639 } 718 }
640 719
641 /* 720 /*
@@ -659,9 +738,15 @@ static struct dentry *autofs4_lookup(struct inode *dir, struct dentry *dentry, s
659 else 738 else
660 dentry = ERR_PTR(-ENOENT); 739 dentry = ERR_PTR(-ENOENT);
661 740
741 if (unhashed)
742 dput(unhashed);
743
662 return dentry; 744 return dentry;
663 } 745 }
664 746
747 if (unhashed)
748 return unhashed;
749
665 return NULL; 750 return NULL;
666} 751}
667 752
@@ -682,20 +767,30 @@ static int autofs4_dir_symlink(struct inode *dir,
682 return -EACCES; 767 return -EACCES;
683 768
684 ino = autofs4_init_ino(ino, sbi, S_IFLNK | 0555); 769 ino = autofs4_init_ino(ino, sbi, S_IFLNK | 0555);
685 if (ino == NULL) 770 if (!ino)
686 return -ENOSPC; 771 return -ENOMEM;
687 772
688 ino->size = strlen(symname); 773 spin_lock(&sbi->lookup_lock);
689 ino->u.symlink = cp = kmalloc(ino->size + 1, GFP_KERNEL); 774 if (!list_empty(&ino->active))
775 list_del_init(&ino->active);
776 spin_unlock(&sbi->lookup_lock);
690 777
691 if (cp == NULL) { 778 cp = kmalloc(ino->size + 1, GFP_KERNEL);
692 kfree(ino); 779 if (!cp) {
693 return -ENOSPC; 780 if (!dentry->d_fsdata)
781 kfree(ino);
782 return -ENOMEM;
694 } 783 }
695 784
696 strcpy(cp, symname); 785 strcpy(cp, symname);
697 786
698 inode = autofs4_get_inode(dir->i_sb, ino); 787 inode = autofs4_get_inode(dir->i_sb, ino);
788 if (!inode) {
789 kfree(cp);
790 if (!dentry->d_fsdata)
791 kfree(ino);
792 return -ENOMEM;
793 }
699 d_add(dentry, inode); 794 d_add(dentry, inode);
700 795
701 if (dir == dir->i_sb->s_root->d_inode) 796 if (dir == dir->i_sb->s_root->d_inode)
@@ -711,6 +806,8 @@ static int autofs4_dir_symlink(struct inode *dir,
711 atomic_inc(&p_ino->count); 806 atomic_inc(&p_ino->count);
712 ino->inode = inode; 807 ino->inode = inode;
713 808
809 ino->size = strlen(symname);
810 ino->u.symlink = cp;
714 dir->i_mtime = CURRENT_TIME; 811 dir->i_mtime = CURRENT_TIME;
715 812
716 return 0; 813 return 0;
@@ -755,7 +852,8 @@ static int autofs4_dir_unlink(struct inode *dir, struct dentry *dentry)
755 852
756 spin_lock(&dcache_lock); 853 spin_lock(&dcache_lock);
757 spin_lock(&sbi->lookup_lock); 854 spin_lock(&sbi->lookup_lock);
758 list_add(&ino->expiring, &sbi->expiring_list); 855 if (list_empty(&ino->expiring))
856 list_add(&ino->expiring, &sbi->expiring_list);
759 spin_unlock(&sbi->lookup_lock); 857 spin_unlock(&sbi->lookup_lock);
760 spin_lock(&dentry->d_lock); 858 spin_lock(&dentry->d_lock);
761 __d_drop(dentry); 859 __d_drop(dentry);
@@ -783,7 +881,8 @@ static int autofs4_dir_rmdir(struct inode *dir, struct dentry *dentry)
783 return -ENOTEMPTY; 881 return -ENOTEMPTY;
784 } 882 }
785 spin_lock(&sbi->lookup_lock); 883 spin_lock(&sbi->lookup_lock);
786 list_add(&ino->expiring, &sbi->expiring_list); 884 if (list_empty(&ino->expiring))
885 list_add(&ino->expiring, &sbi->expiring_list);
787 spin_unlock(&sbi->lookup_lock); 886 spin_unlock(&sbi->lookup_lock);
788 spin_lock(&dentry->d_lock); 887 spin_lock(&dentry->d_lock);
789 __d_drop(dentry); 888 __d_drop(dentry);
@@ -819,10 +918,20 @@ static int autofs4_dir_mkdir(struct inode *dir, struct dentry *dentry, int mode)
819 dentry, dentry->d_name.len, dentry->d_name.name); 918 dentry, dentry->d_name.len, dentry->d_name.name);
820 919
821 ino = autofs4_init_ino(ino, sbi, S_IFDIR | 0555); 920 ino = autofs4_init_ino(ino, sbi, S_IFDIR | 0555);
822 if (ino == NULL) 921 if (!ino)
823 return -ENOSPC; 922 return -ENOMEM;
923
924 spin_lock(&sbi->lookup_lock);
925 if (!list_empty(&ino->active))
926 list_del_init(&ino->active);
927 spin_unlock(&sbi->lookup_lock);
824 928
825 inode = autofs4_get_inode(dir->i_sb, ino); 929 inode = autofs4_get_inode(dir->i_sb, ino);
930 if (!inode) {
931 if (!dentry->d_fsdata)
932 kfree(ino);
933 return -ENOMEM;
934 }
826 d_add(dentry, inode); 935 d_add(dentry, inode);
827 936
828 if (dir == dir->i_sb->s_root->d_inode) 937 if (dir == dir->i_sb->s_root->d_inode)