aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/autofs4/autofs_i.h2
-rw-r--r--fs/autofs4/inode.c25
-rw-r--r--fs/autofs4/root.c169
3 files changed, 156 insertions, 40 deletions
diff --git a/fs/autofs4/autofs_i.h b/fs/autofs4/autofs_i.h
index 69b1497b0029..2dce2334737d 100644
--- a/fs/autofs4/autofs_i.h
+++ b/fs/autofs4/autofs_i.h
@@ -52,6 +52,7 @@ struct autofs_info {
52 52
53 int flags; 53 int flags;
54 54
55 struct list_head active;
55 struct list_head expiring; 56 struct list_head expiring;
56 57
57 struct autofs_sb_info *sbi; 58 struct autofs_sb_info *sbi;
@@ -113,6 +114,7 @@ struct autofs_sb_info {
113 spinlock_t fs_lock; 114 spinlock_t fs_lock;
114 struct autofs_wait_queue *queues; /* Wait queue pointer */ 115 struct autofs_wait_queue *queues; /* Wait queue pointer */
115 spinlock_t lookup_lock; 116 spinlock_t lookup_lock;
117 struct list_head active_list;
116 struct list_head expiring_list; 118 struct list_head expiring_list;
117}; 119};
118 120
diff --git a/fs/autofs4/inode.c b/fs/autofs4/inode.c
index 94bfc154d7a2..e3e70994ab46 100644
--- a/fs/autofs4/inode.c
+++ b/fs/autofs4/inode.c
@@ -24,8 +24,10 @@
24 24
25static void ino_lnkfree(struct autofs_info *ino) 25static void ino_lnkfree(struct autofs_info *ino)
26{ 26{
27 kfree(ino->u.symlink); 27 if (ino->u.symlink) {
28 ino->u.symlink = NULL; 28 kfree(ino->u.symlink);
29 ino->u.symlink = NULL;
30 }
29} 31}
30 32
31struct autofs_info *autofs4_init_ino(struct autofs_info *ino, 33struct autofs_info *autofs4_init_ino(struct autofs_info *ino,
@@ -41,16 +43,18 @@ struct autofs_info *autofs4_init_ino(struct autofs_info *ino,
41 if (ino == NULL) 43 if (ino == NULL)
42 return NULL; 44 return NULL;
43 45
44 ino->flags = 0; 46 if (!reinit) {
45 ino->mode = mode; 47 ino->flags = 0;
46 ino->inode = NULL; 48 ino->inode = NULL;
47 ino->dentry = NULL; 49 ino->dentry = NULL;
48 ino->size = 0; 50 ino->size = 0;
49 51 INIT_LIST_HEAD(&ino->active);
50 INIT_LIST_HEAD(&ino->expiring); 52 INIT_LIST_HEAD(&ino->expiring);
53 atomic_set(&ino->count, 0);
54 }
51 55
56 ino->mode = mode;
52 ino->last_used = jiffies; 57 ino->last_used = jiffies;
53 atomic_set(&ino->count, 0);
54 58
55 ino->sbi = sbi; 59 ino->sbi = sbi;
56 60
@@ -339,6 +343,7 @@ int autofs4_fill_super(struct super_block *s, void *data, int silent)
339 spin_lock_init(&sbi->fs_lock); 343 spin_lock_init(&sbi->fs_lock);
340 sbi->queues = NULL; 344 sbi->queues = NULL;
341 spin_lock_init(&sbi->lookup_lock); 345 spin_lock_init(&sbi->lookup_lock);
346 INIT_LIST_HEAD(&sbi->active_list);
342 INIT_LIST_HEAD(&sbi->expiring_list); 347 INIT_LIST_HEAD(&sbi->expiring_list);
343 s->s_blocksize = 1024; 348 s->s_blocksize = 1024;
344 s->s_blocksize_bits = 10; 349 s->s_blocksize_bits = 10;
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)