aboutsummaryrefslogtreecommitdiffstats
path: root/fs/afs/super.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/afs/super.c')
-rw-r--r--fs/afs/super.c106
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 */
113void __exit afs_fs_exit(void) 106void __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 */
156static int afs_super_parse_options(struct afs_mount_params *params, 153static 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 &params->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
205error: 196error:
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
261error_inode:
262 ret = PTR_ERR(inode);
263 inode = NULL;
270error: 264error:
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(&params, 0, sizeof(params)); 292 memset(&params, 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(&params, options, &dev_name); 296 ret = afs_super_parse_options(&params, 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 &params.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, &params); 316 sb = sget(fs_type, afs_test_super, set_anon_super, &params);
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
347error: 338error:
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 */
417static void afs_destroy_inode(struct inode *inode) 405static 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}