diff options
Diffstat (limited to 'fs/afs/super.c')
-rw-r--r-- | fs/afs/super.c | 106 |
1 files changed, 50 insertions, 56 deletions
diff --git a/fs/afs/super.c b/fs/afs/super.c index 0470a5c0b8a1..efc4fe69f4f0 100644 --- a/fs/afs/super.c +++ b/fs/afs/super.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* AFS superblock handling | 1 | /* AFS superblock handling |
2 | * | 2 | * |
3 | * Copyright (c) 2002 Red Hat, Inc. All rights reserved. | 3 | * Copyright (c) 2002, 2007 Red Hat, Inc. All rights reserved. |
4 | * | 4 | * |
5 | * This software may be freely redistributed under the terms of the | 5 | * This software may be freely redistributed under the terms of the |
6 | * GNU General Public License. | 6 | * GNU General Public License. |
@@ -20,12 +20,6 @@ | |||
20 | #include <linux/slab.h> | 20 | #include <linux/slab.h> |
21 | #include <linux/fs.h> | 21 | #include <linux/fs.h> |
22 | #include <linux/pagemap.h> | 22 | #include <linux/pagemap.h> |
23 | #include "vnode.h" | ||
24 | #include "volume.h" | ||
25 | #include "cell.h" | ||
26 | #include "cmservice.h" | ||
27 | #include "fsclient.h" | ||
28 | #include "super.h" | ||
29 | #include "internal.h" | 23 | #include "internal.h" |
30 | 24 | ||
31 | #define AFS_FS_MAGIC 0x6B414653 /* 'kAFS' */ | 25 | #define AFS_FS_MAGIC 0x6B414653 /* 'kAFS' */ |
@@ -63,6 +57,7 @@ static const struct super_operations afs_super_ops = { | |||
63 | .drop_inode = generic_delete_inode, | 57 | .drop_inode = generic_delete_inode, |
64 | .destroy_inode = afs_destroy_inode, | 58 | .destroy_inode = afs_destroy_inode, |
65 | .clear_inode = afs_clear_inode, | 59 | .clear_inode = afs_clear_inode, |
60 | .umount_begin = afs_umount_begin, | ||
66 | .put_super = afs_put_super, | 61 | .put_super = afs_put_super, |
67 | }; | 62 | }; |
68 | 63 | ||
@@ -78,8 +73,6 @@ int __init afs_fs_init(void) | |||
78 | 73 | ||
79 | _enter(""); | 74 | _enter(""); |
80 | 75 | ||
81 | afs_timer_init(&afs_mntpt_expiry_timer, &afs_mntpt_expiry_timer_ops); | ||
82 | |||
83 | /* create ourselves an inode cache */ | 76 | /* create ourselves an inode cache */ |
84 | atomic_set(&afs_count_active_inodes, 0); | 77 | atomic_set(&afs_count_active_inodes, 0); |
85 | 78 | ||
@@ -99,11 +92,11 @@ int __init afs_fs_init(void) | |||
99 | ret = register_filesystem(&afs_fs_type); | 92 | ret = register_filesystem(&afs_fs_type); |
100 | if (ret < 0) { | 93 | if (ret < 0) { |
101 | kmem_cache_destroy(afs_inode_cachep); | 94 | kmem_cache_destroy(afs_inode_cachep); |
102 | kleave(" = %d", ret); | 95 | _leave(" = %d", ret); |
103 | return ret; | 96 | return ret; |
104 | } | 97 | } |
105 | 98 | ||
106 | kleave(" = 0"); | 99 | _leave(" = 0"); |
107 | return 0; | 100 | return 0; |
108 | } | 101 | } |
109 | 102 | ||
@@ -112,6 +105,9 @@ int __init afs_fs_init(void) | |||
112 | */ | 105 | */ |
113 | void __exit afs_fs_exit(void) | 106 | void __exit afs_fs_exit(void) |
114 | { | 107 | { |
108 | _enter(""); | ||
109 | |||
110 | afs_mntpt_kill_timer(); | ||
115 | unregister_filesystem(&afs_fs_type); | 111 | unregister_filesystem(&afs_fs_type); |
116 | 112 | ||
117 | if (atomic_read(&afs_count_active_inodes) != 0) { | 113 | if (atomic_read(&afs_count_active_inodes) != 0) { |
@@ -121,6 +117,7 @@ void __exit afs_fs_exit(void) | |||
121 | } | 117 | } |
122 | 118 | ||
123 | kmem_cache_destroy(afs_inode_cachep); | 119 | kmem_cache_destroy(afs_inode_cachep); |
120 | _leave(""); | ||
124 | } | 121 | } |
125 | 122 | ||
126 | /* | 123 | /* |
@@ -154,9 +151,9 @@ static int want_no_value(char *const *_value, const char *option) | |||
154 | * shamelessly adapted it from the msdos fs | 151 | * shamelessly adapted it from the msdos fs |
155 | */ | 152 | */ |
156 | static int afs_super_parse_options(struct afs_mount_params *params, | 153 | static int afs_super_parse_options(struct afs_mount_params *params, |
157 | char *options, | 154 | char *options, const char **devname) |
158 | const char **devname) | ||
159 | { | 155 | { |
156 | struct afs_cell *cell; | ||
160 | char *key, *value; | 157 | char *key, *value; |
161 | int ret; | 158 | int ret; |
162 | 159 | ||
@@ -165,43 +162,37 @@ static int afs_super_parse_options(struct afs_mount_params *params, | |||
165 | options[PAGE_SIZE - 1] = 0; | 162 | options[PAGE_SIZE - 1] = 0; |
166 | 163 | ||
167 | ret = 0; | 164 | ret = 0; |
168 | while ((key = strsep(&options, ",")) != 0) | 165 | while ((key = strsep(&options, ","))) { |
169 | { | ||
170 | value = strchr(key, '='); | 166 | value = strchr(key, '='); |
171 | if (value) | 167 | if (value) |
172 | *value++ = 0; | 168 | *value++ = 0; |
173 | 169 | ||
174 | printk("kAFS: KEY: %s, VAL:%s\n", key, value ?: "-"); | 170 | _debug("kAFS: KEY: %s, VAL:%s", key, value ?: "-"); |
175 | 171 | ||
176 | if (strcmp(key, "rwpath") == 0) { | 172 | if (strcmp(key, "rwpath") == 0) { |
177 | if (!want_no_value(&value, "rwpath")) | 173 | if (!want_no_value(&value, "rwpath")) |
178 | return -EINVAL; | 174 | return -EINVAL; |
179 | params->rwpath = 1; | 175 | params->rwpath = 1; |
180 | continue; | ||
181 | } else if (strcmp(key, "vol") == 0) { | 176 | } else if (strcmp(key, "vol") == 0) { |
182 | if (!want_arg(&value, "vol")) | 177 | if (!want_arg(&value, "vol")) |
183 | return -EINVAL; | 178 | return -EINVAL; |
184 | *devname = value; | 179 | *devname = value; |
185 | continue; | ||
186 | } else if (strcmp(key, "cell") == 0) { | 180 | } else if (strcmp(key, "cell") == 0) { |
187 | if (!want_arg(&value, "cell")) | 181 | if (!want_arg(&value, "cell")) |
188 | return -EINVAL; | 182 | return -EINVAL; |
183 | cell = afs_cell_lookup(value, strlen(value)); | ||
184 | if (IS_ERR(cell)) | ||
185 | return PTR_ERR(cell); | ||
189 | afs_put_cell(params->default_cell); | 186 | afs_put_cell(params->default_cell); |
190 | ret = afs_cell_lookup(value, | 187 | params->default_cell = cell; |
191 | strlen(value), | 188 | } else { |
192 | ¶ms->default_cell); | 189 | printk("kAFS: Unknown mount option: '%s'\n", key); |
193 | if (ret < 0) | 190 | ret = -EINVAL; |
194 | return -EINVAL; | 191 | goto error; |
195 | continue; | ||
196 | } | 192 | } |
197 | |||
198 | printk("kAFS: Unknown mount option: '%s'\n", key); | ||
199 | ret = -EINVAL; | ||
200 | goto error; | ||
201 | } | 193 | } |
202 | 194 | ||
203 | ret = 0; | 195 | ret = 0; |
204 | |||
205 | error: | 196 | error: |
206 | _leave(" = %d", ret); | 197 | _leave(" = %d", ret); |
207 | return ret; | 198 | return ret; |
@@ -230,7 +221,7 @@ static int afs_fill_super(struct super_block *sb, void *data, int silent) | |||
230 | struct inode *inode = NULL; | 221 | struct inode *inode = NULL; |
231 | int ret; | 222 | int ret; |
232 | 223 | ||
233 | kenter(""); | 224 | _enter(""); |
234 | 225 | ||
235 | /* allocate a superblock info record */ | 226 | /* allocate a superblock info record */ |
236 | as = kzalloc(sizeof(struct afs_super_info), GFP_KERNEL); | 227 | as = kzalloc(sizeof(struct afs_super_info), GFP_KERNEL); |
@@ -253,9 +244,9 @@ static int afs_fill_super(struct super_block *sb, void *data, int silent) | |||
253 | fid.vid = as->volume->vid; | 244 | fid.vid = as->volume->vid; |
254 | fid.vnode = 1; | 245 | fid.vnode = 1; |
255 | fid.unique = 1; | 246 | fid.unique = 1; |
256 | ret = afs_iget(sb, &fid, &inode); | 247 | inode = afs_iget(sb, &fid); |
257 | if (ret < 0) | 248 | if (IS_ERR(inode)) |
258 | goto error; | 249 | goto error_inode; |
259 | 250 | ||
260 | ret = -ENOMEM; | 251 | ret = -ENOMEM; |
261 | root = d_alloc_root(inode); | 252 | root = d_alloc_root(inode); |
@@ -264,9 +255,12 @@ static int afs_fill_super(struct super_block *sb, void *data, int silent) | |||
264 | 255 | ||
265 | sb->s_root = root; | 256 | sb->s_root = root; |
266 | 257 | ||
267 | kleave(" = 0"); | 258 | _leave(" = 0"); |
268 | return 0; | 259 | return 0; |
269 | 260 | ||
261 | error_inode: | ||
262 | ret = PTR_ERR(inode); | ||
263 | inode = NULL; | ||
270 | error: | 264 | error: |
271 | iput(inode); | 265 | iput(inode); |
272 | afs_put_volume(as->volume); | 266 | afs_put_volume(as->volume); |
@@ -274,7 +268,7 @@ error: | |||
274 | 268 | ||
275 | sb->s_fs_info = NULL; | 269 | sb->s_fs_info = NULL; |
276 | 270 | ||
277 | kleave(" = %d", ret); | 271 | _leave(" = %d", ret); |
278 | return ret; | 272 | return ret; |
279 | } | 273 | } |
280 | 274 | ||
@@ -290,19 +284,13 @@ static int afs_get_sb(struct file_system_type *fs_type, | |||
290 | { | 284 | { |
291 | struct afs_mount_params params; | 285 | struct afs_mount_params params; |
292 | struct super_block *sb; | 286 | struct super_block *sb; |
287 | struct afs_volume *vol; | ||
293 | int ret; | 288 | int ret; |
294 | 289 | ||
295 | _enter(",,%s,%p", dev_name, options); | 290 | _enter(",,%s,%p", dev_name, options); |
296 | 291 | ||
297 | memset(¶ms, 0, sizeof(params)); | 292 | memset(¶ms, 0, sizeof(params)); |
298 | 293 | ||
299 | /* start the cache manager */ | ||
300 | ret = afscm_start(); | ||
301 | if (ret < 0) { | ||
302 | _leave(" = %d", ret); | ||
303 | return ret; | ||
304 | } | ||
305 | |||
306 | /* parse the options */ | 294 | /* parse the options */ |
307 | if (options) { | 295 | if (options) { |
308 | ret = afs_super_parse_options(¶ms, options, &dev_name); | 296 | ret = afs_super_parse_options(¶ms, options, &dev_name); |
@@ -316,17 +304,20 @@ static int afs_get_sb(struct file_system_type *fs_type, | |||
316 | } | 304 | } |
317 | 305 | ||
318 | /* parse the device name */ | 306 | /* parse the device name */ |
319 | ret = afs_volume_lookup(dev_name, | 307 | vol = afs_volume_lookup(dev_name, params.default_cell, params.rwpath); |
320 | params.default_cell, | 308 | if (IS_ERR(vol)) { |
321 | params.rwpath, | 309 | ret = PTR_ERR(vol); |
322 | ¶ms.volume); | ||
323 | if (ret < 0) | ||
324 | goto error; | 310 | goto error; |
311 | } | ||
312 | |||
313 | params.volume = vol; | ||
325 | 314 | ||
326 | /* allocate a deviceless superblock */ | 315 | /* allocate a deviceless superblock */ |
327 | sb = sget(fs_type, afs_test_super, set_anon_super, ¶ms); | 316 | sb = sget(fs_type, afs_test_super, set_anon_super, ¶ms); |
328 | if (IS_ERR(sb)) | 317 | if (IS_ERR(sb)) { |
318 | ret = PTR_ERR(sb); | ||
329 | goto error; | 319 | goto error; |
320 | } | ||
330 | 321 | ||
331 | sb->s_flags = flags; | 322 | sb->s_flags = flags; |
332 | 323 | ||
@@ -341,13 +332,12 @@ static int afs_get_sb(struct file_system_type *fs_type, | |||
341 | 332 | ||
342 | afs_put_volume(params.volume); | 333 | afs_put_volume(params.volume); |
343 | afs_put_cell(params.default_cell); | 334 | afs_put_cell(params.default_cell); |
344 | _leave(" = 0 [%p]", 0, sb); | 335 | _leave(" = 0 [%p]", sb); |
345 | return 0; | 336 | return 0; |
346 | 337 | ||
347 | error: | 338 | error: |
348 | afs_put_volume(params.volume); | 339 | afs_put_volume(params.volume); |
349 | afs_put_cell(params.default_cell); | 340 | afs_put_cell(params.default_cell); |
350 | afscm_stop(); | ||
351 | _leave(" = %d", ret); | 341 | _leave(" = %d", ret); |
352 | return ret; | 342 | return ret; |
353 | } | 343 | } |
@@ -362,7 +352,6 @@ static void afs_put_super(struct super_block *sb) | |||
362 | _enter(""); | 352 | _enter(""); |
363 | 353 | ||
364 | afs_put_volume(as->volume); | 354 | afs_put_volume(as->volume); |
365 | afscm_stop(); | ||
366 | 355 | ||
367 | _leave(""); | 356 | _leave(""); |
368 | } | 357 | } |
@@ -381,10 +370,8 @@ static void afs_i_init_once(void *_vnode, struct kmem_cache *cachep, | |||
381 | inode_init_once(&vnode->vfs_inode); | 370 | inode_init_once(&vnode->vfs_inode); |
382 | init_waitqueue_head(&vnode->update_waitq); | 371 | init_waitqueue_head(&vnode->update_waitq); |
383 | spin_lock_init(&vnode->lock); | 372 | spin_lock_init(&vnode->lock); |
384 | INIT_LIST_HEAD(&vnode->cb_link); | 373 | INIT_WORK(&vnode->cb_broken_work, afs_broken_callback_work); |
385 | INIT_LIST_HEAD(&vnode->cb_hash_link); | 374 | mutex_init(&vnode->cb_broken_lock); |
386 | afs_timer_init(&vnode->cb_timeout, | ||
387 | &afs_vnode_cb_timed_out_ops); | ||
388 | } | 375 | } |
389 | } | 376 | } |
390 | 377 | ||
@@ -407,6 +394,7 @@ static struct inode *afs_alloc_inode(struct super_block *sb) | |||
407 | vnode->volume = NULL; | 394 | vnode->volume = NULL; |
408 | vnode->update_cnt = 0; | 395 | vnode->update_cnt = 0; |
409 | vnode->flags = 0; | 396 | vnode->flags = 0; |
397 | vnode->cb_promised = false; | ||
410 | 398 | ||
411 | return &vnode->vfs_inode; | 399 | return &vnode->vfs_inode; |
412 | } | 400 | } |
@@ -416,8 +404,14 @@ static struct inode *afs_alloc_inode(struct super_block *sb) | |||
416 | */ | 404 | */ |
417 | static void afs_destroy_inode(struct inode *inode) | 405 | static void afs_destroy_inode(struct inode *inode) |
418 | { | 406 | { |
407 | struct afs_vnode *vnode = AFS_FS_I(inode); | ||
408 | |||
419 | _enter("{%lu}", inode->i_ino); | 409 | _enter("{%lu}", inode->i_ino); |
420 | 410 | ||
421 | kmem_cache_free(afs_inode_cachep, AFS_FS_I(inode)); | 411 | _debug("DESTROY INODE %p", inode); |
412 | |||
413 | ASSERTCMP(vnode->server, ==, NULL); | ||
414 | |||
415 | kmem_cache_free(afs_inode_cachep, vnode); | ||
422 | atomic_dec(&afs_count_active_inodes); | 416 | atomic_dec(&afs_count_active_inodes); |
423 | } | 417 | } |