[AF_RXRPC]: Delete the old RxRPC code.
[deliverable/linux.git] / fs / afs / super.c
CommitLineData
ec26815a
DH
1/* AFS superblock handling
2 *
08e0e7c8 3 * Copyright (c) 2002, 2007 Red Hat, Inc. All rights reserved.
1da177e4
LT
4 *
5 * This software may be freely redistributed under the terms of the
6 * GNU General Public License.
7 *
8 * You should have received a copy of the GNU General Public License
9 * along with this program; if not, write to the Free Software
10 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
11 *
12 * Authors: David Howells <dhowells@redhat.com>
ec26815a 13 * David Woodhouse <dwmw2@redhat.com>
1da177e4
LT
14 *
15 */
16
17#include <linux/kernel.h>
18#include <linux/module.h>
19#include <linux/init.h>
20#include <linux/slab.h>
21#include <linux/fs.h>
22#include <linux/pagemap.h>
1da177e4
LT
23#include "internal.h"
24
25#define AFS_FS_MAGIC 0x6B414653 /* 'kAFS' */
26
27struct afs_mount_params {
28 int rwpath;
29 struct afs_cell *default_cell;
30 struct afs_volume *volume;
31};
32
e18b890b 33static void afs_i_init_once(void *foo, struct kmem_cache *cachep,
1da177e4
LT
34 unsigned long flags);
35
454e2398
DH
36static int afs_get_sb(struct file_system_type *fs_type,
37 int flags, const char *dev_name,
38 void *data, struct vfsmount *mnt);
1da177e4
LT
39
40static struct inode *afs_alloc_inode(struct super_block *sb);
41
42static void afs_put_super(struct super_block *sb);
43
44static void afs_destroy_inode(struct inode *inode);
45
1f5ce9e9 46struct file_system_type afs_fs_type = {
1da177e4
LT
47 .owner = THIS_MODULE,
48 .name = "afs",
49 .get_sb = afs_get_sb,
50 .kill_sb = kill_anon_super,
51 .fs_flags = FS_BINARY_MOUNTDATA,
52};
53
ee9b6d61 54static const struct super_operations afs_super_ops = {
1da177e4
LT
55 .statfs = simple_statfs,
56 .alloc_inode = afs_alloc_inode,
57 .drop_inode = generic_delete_inode,
58 .destroy_inode = afs_destroy_inode,
59 .clear_inode = afs_clear_inode,
08e0e7c8 60 .umount_begin = afs_umount_begin,
1da177e4
LT
61 .put_super = afs_put_super,
62};
63
e18b890b 64static struct kmem_cache *afs_inode_cachep;
1da177e4
LT
65static atomic_t afs_count_active_inodes;
66
1da177e4
LT
67/*
68 * initialise the filesystem
69 */
70int __init afs_fs_init(void)
71{
72 int ret;
73
74 _enter("");
75
1da177e4
LT
76 /* create ourselves an inode cache */
77 atomic_set(&afs_count_active_inodes, 0);
78
79 ret = -ENOMEM;
80 afs_inode_cachep = kmem_cache_create("afs_inode_cache",
81 sizeof(struct afs_vnode),
82 0,
83 SLAB_HWCACHE_ALIGN,
84 afs_i_init_once,
85 NULL);
86 if (!afs_inode_cachep) {
87 printk(KERN_NOTICE "kAFS: Failed to allocate inode cache\n");
88 return ret;
89 }
90
91 /* now export our filesystem to lesser mortals */
92 ret = register_filesystem(&afs_fs_type);
93 if (ret < 0) {
94 kmem_cache_destroy(afs_inode_cachep);
08e0e7c8 95 _leave(" = %d", ret);
1da177e4
LT
96 return ret;
97 }
98
08e0e7c8 99 _leave(" = 0");
1da177e4 100 return 0;
ec26815a 101}
1da177e4 102
1da177e4
LT
103/*
104 * clean up the filesystem
105 */
106void __exit afs_fs_exit(void)
107{
08e0e7c8
DH
108 _enter("");
109
110 afs_mntpt_kill_timer();
1da177e4
LT
111 unregister_filesystem(&afs_fs_type);
112
113 if (atomic_read(&afs_count_active_inodes) != 0) {
114 printk("kAFS: %d active inode objects still present\n",
115 atomic_read(&afs_count_active_inodes));
116 BUG();
117 }
118
119 kmem_cache_destroy(afs_inode_cachep);
08e0e7c8 120 _leave("");
ec26815a 121}
1da177e4 122
1da177e4
LT
123/*
124 * check that an argument has a value
125 */
126static int want_arg(char **_value, const char *option)
127{
128 if (!_value || !*_value || !**_value) {
129 printk(KERN_NOTICE "kAFS: %s: argument missing\n", option);
130 return 0;
131 }
132 return 1;
ec26815a 133}
1da177e4 134
1da177e4
LT
135/*
136 * check that there's no subsequent value
137 */
138static int want_no_value(char *const *_value, const char *option)
139{
140 if (*_value && **_value) {
141 printk(KERN_NOTICE "kAFS: %s: Invalid argument: %s\n",
142 option, *_value);
143 return 0;
144 }
145 return 1;
ec26815a 146}
1da177e4 147
1da177e4
LT
148/*
149 * parse the mount options
150 * - this function has been shamelessly adapted from the ext3 fs which
151 * shamelessly adapted it from the msdos fs
152 */
153static int afs_super_parse_options(struct afs_mount_params *params,
08e0e7c8 154 char *options, const char **devname)
1da177e4 155{
08e0e7c8 156 struct afs_cell *cell;
1da177e4
LT
157 char *key, *value;
158 int ret;
159
160 _enter("%s", options);
161
162 options[PAGE_SIZE - 1] = 0;
163
164 ret = 0;
08e0e7c8 165 while ((key = strsep(&options, ","))) {
1da177e4
LT
166 value = strchr(key, '=');
167 if (value)
168 *value++ = 0;
169
08e0e7c8 170 _debug("kAFS: KEY: %s, VAL:%s", key, value ?: "-");
1da177e4
LT
171
172 if (strcmp(key, "rwpath") == 0) {
173 if (!want_no_value(&value, "rwpath"))
174 return -EINVAL;
175 params->rwpath = 1;
ec26815a 176 } else if (strcmp(key, "vol") == 0) {
1da177e4
LT
177 if (!want_arg(&value, "vol"))
178 return -EINVAL;
179 *devname = value;
ec26815a 180 } else if (strcmp(key, "cell") == 0) {
1da177e4
LT
181 if (!want_arg(&value, "cell"))
182 return -EINVAL;
08e0e7c8
DH
183 cell = afs_cell_lookup(value, strlen(value));
184 if (IS_ERR(cell))
185 return PTR_ERR(cell);
1da177e4 186 afs_put_cell(params->default_cell);
08e0e7c8
DH
187 params->default_cell = cell;
188 } else {
189 printk("kAFS: Unknown mount option: '%s'\n", key);
190 ret = -EINVAL;
191 goto error;
1da177e4 192 }
1da177e4
LT
193 }
194
195 ret = 0;
ec26815a 196error:
1da177e4
LT
197 _leave(" = %d", ret);
198 return ret;
ec26815a 199}
1da177e4 200
1da177e4
LT
201/*
202 * check a superblock to see if it's the one we're looking for
203 */
204static int afs_test_super(struct super_block *sb, void *data)
205{
206 struct afs_mount_params *params = data;
207 struct afs_super_info *as = sb->s_fs_info;
208
209 return as->volume == params->volume;
ec26815a 210}
1da177e4 211
1da177e4
LT
212/*
213 * fill in the superblock
214 */
215static int afs_fill_super(struct super_block *sb, void *data, int silent)
216{
217 struct afs_mount_params *params = data;
218 struct afs_super_info *as = NULL;
219 struct afs_fid fid;
220 struct dentry *root = NULL;
221 struct inode *inode = NULL;
222 int ret;
223
08e0e7c8 224 _enter("");
1da177e4
LT
225
226 /* allocate a superblock info record */
b593e48d 227 as = kzalloc(sizeof(struct afs_super_info), GFP_KERNEL);
1da177e4
LT
228 if (!as) {
229 _leave(" = -ENOMEM");
230 return -ENOMEM;
231 }
232
1da177e4
LT
233 afs_get_volume(params->volume);
234 as->volume = params->volume;
235
236 /* fill in the superblock */
237 sb->s_blocksize = PAGE_CACHE_SIZE;
238 sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
239 sb->s_magic = AFS_FS_MAGIC;
240 sb->s_op = &afs_super_ops;
241 sb->s_fs_info = as;
242
243 /* allocate the root inode and dentry */
244 fid.vid = as->volume->vid;
245 fid.vnode = 1;
246 fid.unique = 1;
08e0e7c8
DH
247 inode = afs_iget(sb, &fid);
248 if (IS_ERR(inode))
249 goto error_inode;
1da177e4
LT
250
251 ret = -ENOMEM;
252 root = d_alloc_root(inode);
253 if (!root)
254 goto error;
255
256 sb->s_root = root;
257
08e0e7c8 258 _leave(" = 0");
1da177e4
LT
259 return 0;
260
08e0e7c8
DH
261error_inode:
262 ret = PTR_ERR(inode);
263 inode = NULL;
ec26815a 264error:
1da177e4
LT
265 iput(inode);
266 afs_put_volume(as->volume);
267 kfree(as);
268
269 sb->s_fs_info = NULL;
270
08e0e7c8 271 _leave(" = %d", ret);
1da177e4 272 return ret;
ec26815a 273}
1da177e4 274
1da177e4
LT
275/*
276 * get an AFS superblock
277 * - TODO: don't use get_sb_nodev(), but rather call sget() directly
278 */
454e2398
DH
279static int afs_get_sb(struct file_system_type *fs_type,
280 int flags,
281 const char *dev_name,
282 void *options,
283 struct vfsmount *mnt)
1da177e4
LT
284{
285 struct afs_mount_params params;
286 struct super_block *sb;
08e0e7c8 287 struct afs_volume *vol;
1da177e4
LT
288 int ret;
289
290 _enter(",,%s,%p", dev_name, options);
291
292 memset(&params, 0, sizeof(params));
293
1da177e4
LT
294 /* parse the options */
295 if (options) {
296 ret = afs_super_parse_options(&params, options, &dev_name);
297 if (ret < 0)
298 goto error;
299 if (!dev_name) {
300 printk("kAFS: no volume name specified\n");
301 ret = -EINVAL;
302 goto error;
303 }
304 }
305
306 /* parse the device name */
08e0e7c8
DH
307 vol = afs_volume_lookup(dev_name, params.default_cell, params.rwpath);
308 if (IS_ERR(vol)) {
309 ret = PTR_ERR(vol);
1da177e4 310 goto error;
08e0e7c8
DH
311 }
312
313 params.volume = vol;
1da177e4
LT
314
315 /* allocate a deviceless superblock */
316 sb = sget(fs_type, afs_test_super, set_anon_super, &params);
08e0e7c8
DH
317 if (IS_ERR(sb)) {
318 ret = PTR_ERR(sb);
1da177e4 319 goto error;
08e0e7c8 320 }
1da177e4
LT
321
322 sb->s_flags = flags;
323
9b04c997 324 ret = afs_fill_super(sb, &params, flags & MS_SILENT ? 1 : 0);
1da177e4
LT
325 if (ret < 0) {
326 up_write(&sb->s_umount);
327 deactivate_super(sb);
328 goto error;
329 }
330 sb->s_flags |= MS_ACTIVE;
454e2398 331 simple_set_mnt(mnt, sb);
1da177e4
LT
332
333 afs_put_volume(params.volume);
334 afs_put_cell(params.default_cell);
08e0e7c8 335 _leave(" = 0 [%p]", sb);
454e2398 336 return 0;
1da177e4 337
ec26815a 338error:
1da177e4
LT
339 afs_put_volume(params.volume);
340 afs_put_cell(params.default_cell);
1da177e4 341 _leave(" = %d", ret);
454e2398 342 return ret;
ec26815a 343}
1da177e4 344
1da177e4
LT
345/*
346 * finish the unmounting process on the superblock
347 */
348static void afs_put_super(struct super_block *sb)
349{
350 struct afs_super_info *as = sb->s_fs_info;
351
352 _enter("");
353
354 afs_put_volume(as->volume);
1da177e4
LT
355
356 _leave("");
ec26815a 357}
1da177e4 358
1da177e4
LT
359/*
360 * initialise an inode cache slab element prior to any use
361 */
e18b890b 362static void afs_i_init_once(void *_vnode, struct kmem_cache *cachep,
1da177e4
LT
363 unsigned long flags)
364{
ec26815a 365 struct afs_vnode *vnode = _vnode;
1da177e4
LT
366
367 if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
368 SLAB_CTOR_CONSTRUCTOR) {
369 memset(vnode, 0, sizeof(*vnode));
370 inode_init_once(&vnode->vfs_inode);
371 init_waitqueue_head(&vnode->update_waitq);
372 spin_lock_init(&vnode->lock);
08e0e7c8
DH
373 INIT_WORK(&vnode->cb_broken_work, afs_broken_callback_work);
374 mutex_init(&vnode->cb_broken_lock);
1da177e4 375 }
ec26815a 376}
1da177e4 377
1da177e4
LT
378/*
379 * allocate an AFS inode struct from our slab cache
380 */
381static struct inode *afs_alloc_inode(struct super_block *sb)
382{
383 struct afs_vnode *vnode;
384
ec26815a 385 vnode = kmem_cache_alloc(afs_inode_cachep, GFP_KERNEL);
1da177e4
LT
386 if (!vnode)
387 return NULL;
388
389 atomic_inc(&afs_count_active_inodes);
390
391 memset(&vnode->fid, 0, sizeof(vnode->fid));
392 memset(&vnode->status, 0, sizeof(vnode->status));
393
394 vnode->volume = NULL;
395 vnode->update_cnt = 0;
396 vnode->flags = 0;
08e0e7c8 397 vnode->cb_promised = false;
1da177e4
LT
398
399 return &vnode->vfs_inode;
ec26815a 400}
1da177e4 401
1da177e4
LT
402/*
403 * destroy an AFS inode struct
404 */
405static void afs_destroy_inode(struct inode *inode)
406{
08e0e7c8
DH
407 struct afs_vnode *vnode = AFS_FS_I(inode);
408
1da177e4
LT
409 _enter("{%lu}", inode->i_ino);
410
08e0e7c8
DH
411 _debug("DESTROY INODE %p", inode);
412
413 ASSERTCMP(vnode->server, ==, NULL);
414
415 kmem_cache_free(afs_inode_cachep, vnode);
1da177e4 416 atomic_dec(&afs_count_active_inodes);
ec26815a 417}
This page took 0.234197 seconds and 5 git commands to generate.