diff options
Diffstat (limited to 'fs/autofs4/inode.c')
-rw-r--r-- | fs/autofs4/inode.c | 39 |
1 files changed, 20 insertions, 19 deletions
diff --git a/fs/autofs4/inode.c b/fs/autofs4/inode.c index 800ce876caec..ce7c0f1dd529 100644 --- a/fs/autofs4/inode.c +++ b/fs/autofs4/inode.c | |||
@@ -96,9 +96,12 @@ void autofs4_free_ino(struct autofs_info *ino) | |||
96 | */ | 96 | */ |
97 | static void autofs4_force_release(struct autofs_sb_info *sbi) | 97 | static void autofs4_force_release(struct autofs_sb_info *sbi) |
98 | { | 98 | { |
99 | struct dentry *this_parent = sbi->root; | 99 | struct dentry *this_parent = sbi->sb->s_root; |
100 | struct list_head *next; | 100 | struct list_head *next; |
101 | 101 | ||
102 | if (!sbi->sb->s_root) | ||
103 | return; | ||
104 | |||
102 | spin_lock(&dcache_lock); | 105 | spin_lock(&dcache_lock); |
103 | repeat: | 106 | repeat: |
104 | next = this_parent->d_subdirs.next; | 107 | next = this_parent->d_subdirs.next; |
@@ -127,7 +130,7 @@ resume: | |||
127 | spin_lock(&dcache_lock); | 130 | spin_lock(&dcache_lock); |
128 | } | 131 | } |
129 | 132 | ||
130 | if (this_parent != sbi->root) { | 133 | if (this_parent != sbi->sb->s_root) { |
131 | struct dentry *dentry = this_parent; | 134 | struct dentry *dentry = this_parent; |
132 | 135 | ||
133 | next = this_parent->d_u.d_child.next; | 136 | next = this_parent->d_u.d_child.next; |
@@ -140,18 +143,20 @@ resume: | |||
140 | goto resume; | 143 | goto resume; |
141 | } | 144 | } |
142 | spin_unlock(&dcache_lock); | 145 | spin_unlock(&dcache_lock); |
143 | |||
144 | dput(sbi->root); | ||
145 | sbi->root = NULL; | ||
146 | shrink_dcache_sb(sbi->sb); | ||
147 | |||
148 | return; | ||
149 | } | 146 | } |
150 | 147 | ||
151 | static void autofs4_put_super(struct super_block *sb) | 148 | void autofs4_kill_sb(struct super_block *sb) |
152 | { | 149 | { |
153 | struct autofs_sb_info *sbi = autofs4_sbi(sb); | 150 | struct autofs_sb_info *sbi = autofs4_sbi(sb); |
154 | 151 | ||
152 | /* | ||
153 | * In the event of a failure in get_sb_nodev the superblock | ||
154 | * info is not present so nothing else has been setup, so | ||
155 | * just exit when we are called from deactivate_super. | ||
156 | */ | ||
157 | if (!sbi) | ||
158 | return; | ||
159 | |||
155 | sb->s_fs_info = NULL; | 160 | sb->s_fs_info = NULL; |
156 | 161 | ||
157 | if ( !sbi->catatonic ) | 162 | if ( !sbi->catatonic ) |
@@ -163,6 +168,7 @@ static void autofs4_put_super(struct super_block *sb) | |||
163 | kfree(sbi); | 168 | kfree(sbi); |
164 | 169 | ||
165 | DPRINTK("shutting down"); | 170 | DPRINTK("shutting down"); |
171 | kill_anon_super(sb); | ||
166 | } | 172 | } |
167 | 173 | ||
168 | static int autofs4_show_options(struct seq_file *m, struct vfsmount *mnt) | 174 | static int autofs4_show_options(struct seq_file *m, struct vfsmount *mnt) |
@@ -189,7 +195,6 @@ static int autofs4_show_options(struct seq_file *m, struct vfsmount *mnt) | |||
189 | } | 195 | } |
190 | 196 | ||
191 | static struct super_operations autofs4_sops = { | 197 | static struct super_operations autofs4_sops = { |
192 | .put_super = autofs4_put_super, | ||
193 | .statfs = simple_statfs, | 198 | .statfs = simple_statfs, |
194 | .show_options = autofs4_show_options, | 199 | .show_options = autofs4_show_options, |
195 | }; | 200 | }; |
@@ -315,9 +320,9 @@ int autofs4_fill_super(struct super_block *s, void *data, int silent) | |||
315 | 320 | ||
316 | s->s_fs_info = sbi; | 321 | s->s_fs_info = sbi; |
317 | sbi->magic = AUTOFS_SBI_MAGIC; | 322 | sbi->magic = AUTOFS_SBI_MAGIC; |
318 | sbi->root = NULL; | ||
319 | sbi->pipefd = -1; | 323 | sbi->pipefd = -1; |
320 | sbi->catatonic = 0; | 324 | sbi->pipe = NULL; |
325 | sbi->catatonic = 1; | ||
321 | sbi->exp_timeout = 0; | 326 | sbi->exp_timeout = 0; |
322 | sbi->oz_pgrp = process_group(current); | 327 | sbi->oz_pgrp = process_group(current); |
323 | sbi->sb = s; | 328 | sbi->sb = s; |
@@ -395,13 +400,7 @@ int autofs4_fill_super(struct super_block *s, void *data, int silent) | |||
395 | goto fail_fput; | 400 | goto fail_fput; |
396 | sbi->pipe = pipe; | 401 | sbi->pipe = pipe; |
397 | sbi->pipefd = pipefd; | 402 | sbi->pipefd = pipefd; |
398 | 403 | sbi->catatonic = 0; | |
399 | /* | ||
400 | * Take a reference to the root dentry so we get a chance to | ||
401 | * clean up the dentry tree on umount. | ||
402 | * See autofs4_force_release. | ||
403 | */ | ||
404 | sbi->root = dget(root); | ||
405 | 404 | ||
406 | /* | 405 | /* |
407 | * Success! Install the root dentry now to indicate completion. | 406 | * Success! Install the root dentry now to indicate completion. |
@@ -426,6 +425,8 @@ fail_ino: | |||
426 | kfree(ino); | 425 | kfree(ino); |
427 | fail_free: | 426 | fail_free: |
428 | kfree(sbi); | 427 | kfree(sbi); |
428 | s->s_fs_info = NULL; | ||
429 | kill_anon_super(s); | ||
429 | fail_unlock: | 430 | fail_unlock: |
430 | return -EINVAL; | 431 | return -EINVAL; |
431 | } | 432 | } |