diff options
Diffstat (limited to 'fs/autofs4')
-rw-r--r-- | fs/autofs4/autofs_i.h | 2 | ||||
-rw-r--r-- | fs/autofs4/inode.c | 1 | ||||
-rw-r--r-- | fs/autofs4/root.c | 46 |
3 files changed, 38 insertions, 11 deletions
diff --git a/fs/autofs4/autofs_i.h b/fs/autofs4/autofs_i.h index 8f7cdde41733..f3cf151a59e3 100644 --- a/fs/autofs4/autofs_i.h +++ b/fs/autofs4/autofs_i.h | |||
@@ -75,6 +75,8 @@ struct autofs_info { | |||
75 | struct completion expire_complete; | 75 | struct completion expire_complete; |
76 | 76 | ||
77 | struct list_head active; | 77 | struct list_head active; |
78 | int active_count; | ||
79 | |||
78 | struct list_head expiring; | 80 | struct list_head expiring; |
79 | 81 | ||
80 | struct autofs_sb_info *sbi; | 82 | struct autofs_sb_info *sbi; |
diff --git a/fs/autofs4/inode.c b/fs/autofs4/inode.c index 69c8142da838..4670a7818eac 100644 --- a/fs/autofs4/inode.c +++ b/fs/autofs4/inode.c | |||
@@ -49,6 +49,7 @@ struct autofs_info *autofs4_init_ino(struct autofs_info *ino, | |||
49 | ino->dentry = NULL; | 49 | ino->dentry = NULL; |
50 | ino->size = 0; | 50 | ino->size = 0; |
51 | INIT_LIST_HEAD(&ino->active); | 51 | INIT_LIST_HEAD(&ino->active); |
52 | ino->active_count = 0; | ||
52 | INIT_LIST_HEAD(&ino->expiring); | 53 | INIT_LIST_HEAD(&ino->expiring); |
53 | atomic_set(&ino->count, 0); | 54 | atomic_set(&ino->count, 0); |
54 | } | 55 | } |
diff --git a/fs/autofs4/root.c b/fs/autofs4/root.c index b96a3c57359d..67d8d962168d 100644 --- a/fs/autofs4/root.c +++ b/fs/autofs4/root.c | |||
@@ -72,6 +72,38 @@ const struct inode_operations autofs4_dir_inode_operations = { | |||
72 | .rmdir = autofs4_dir_rmdir, | 72 | .rmdir = autofs4_dir_rmdir, |
73 | }; | 73 | }; |
74 | 74 | ||
75 | static void autofs4_add_active(struct dentry *dentry) | ||
76 | { | ||
77 | struct autofs_sb_info *sbi = autofs4_sbi(dentry->d_sb); | ||
78 | struct autofs_info *ino = autofs4_dentry_ino(dentry); | ||
79 | if (ino) { | ||
80 | spin_lock(&sbi->lookup_lock); | ||
81 | if (!ino->active_count) { | ||
82 | if (list_empty(&ino->active)) | ||
83 | list_add(&ino->active, &sbi->active_list); | ||
84 | } | ||
85 | ino->active_count++; | ||
86 | spin_unlock(&sbi->lookup_lock); | ||
87 | } | ||
88 | return; | ||
89 | } | ||
90 | |||
91 | static void autofs4_del_active(struct dentry *dentry) | ||
92 | { | ||
93 | struct autofs_sb_info *sbi = autofs4_sbi(dentry->d_sb); | ||
94 | struct autofs_info *ino = autofs4_dentry_ino(dentry); | ||
95 | if (ino) { | ||
96 | spin_lock(&sbi->lookup_lock); | ||
97 | ino->active_count--; | ||
98 | if (!ino->active_count) { | ||
99 | if (!list_empty(&ino->active)) | ||
100 | list_del_init(&ino->active); | ||
101 | } | ||
102 | spin_unlock(&sbi->lookup_lock); | ||
103 | } | ||
104 | return; | ||
105 | } | ||
106 | |||
75 | static int autofs4_dir_open(struct inode *inode, struct file *file) | 107 | static int autofs4_dir_open(struct inode *inode, struct file *file) |
76 | { | 108 | { |
77 | struct dentry *dentry = file->f_path.dentry; | 109 | struct dentry *dentry = file->f_path.dentry; |
@@ -513,9 +545,7 @@ static struct dentry *autofs4_lookup(struct inode *dir, struct dentry *dentry, s | |||
513 | dentry->d_fsdata = ino; | 545 | dentry->d_fsdata = ino; |
514 | ino->dentry = dentry; | 546 | ino->dentry = dentry; |
515 | 547 | ||
516 | spin_lock(&sbi->lookup_lock); | 548 | autofs4_add_active(dentry); |
517 | list_add(&ino->active, &sbi->active_list); | ||
518 | spin_unlock(&sbi->lookup_lock); | ||
519 | 549 | ||
520 | d_instantiate(dentry, NULL); | 550 | d_instantiate(dentry, NULL); |
521 | } | 551 | } |
@@ -624,10 +654,7 @@ static int autofs4_dir_symlink(struct inode *dir, | |||
624 | if (!ino) | 654 | if (!ino) |
625 | return -ENOMEM; | 655 | return -ENOMEM; |
626 | 656 | ||
627 | spin_lock(&sbi->lookup_lock); | 657 | autofs4_del_active(dentry); |
628 | if (!list_empty(&ino->active)) | ||
629 | list_del_init(&ino->active); | ||
630 | spin_unlock(&sbi->lookup_lock); | ||
631 | 658 | ||
632 | ino->size = strlen(symname); | 659 | ino->size = strlen(symname); |
633 | cp = kmalloc(ino->size + 1, GFP_KERNEL); | 660 | cp = kmalloc(ino->size + 1, GFP_KERNEL); |
@@ -775,10 +802,7 @@ static int autofs4_dir_mkdir(struct inode *dir, struct dentry *dentry, int mode) | |||
775 | if (!ino) | 802 | if (!ino) |
776 | return -ENOMEM; | 803 | return -ENOMEM; |
777 | 804 | ||
778 | spin_lock(&sbi->lookup_lock); | 805 | autofs4_del_active(dentry); |
779 | if (!list_empty(&ino->active)) | ||
780 | list_del_init(&ino->active); | ||
781 | spin_unlock(&sbi->lookup_lock); | ||
782 | 806 | ||
783 | inode = autofs4_get_inode(dir->i_sb, ino); | 807 | inode = autofs4_get_inode(dir->i_sb, ino); |
784 | if (!inode) { | 808 | if (!inode) { |