[AF_RXRPC]: Make the in-kernel AFS filesystem use AF_RXRPC.
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / fs / afs / super.c
blobefc4fe69f4f010693c0ff54607d1639d398dd7cd
1 /* AFS superblock handling
3 * Copyright (c) 2002, 2007 Red Hat, Inc. All rights reserved.
5 * This software may be freely redistributed under the terms of the
6 * GNU General Public License.
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.
12 * Authors: David Howells <dhowells@redhat.com>
13 * David Woodhouse <dwmw2@redhat.com>
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>
23 #include "internal.h"
25 #define AFS_FS_MAGIC 0x6B414653 /* 'kAFS' */
27 struct afs_mount_params {
28 int rwpath;
29 struct afs_cell *default_cell;
30 struct afs_volume *volume;
33 static void afs_i_init_once(void *foo, struct kmem_cache *cachep,
34 unsigned long flags);
36 static int afs_get_sb(struct file_system_type *fs_type,
37 int flags, const char *dev_name,
38 void *data, struct vfsmount *mnt);
40 static struct inode *afs_alloc_inode(struct super_block *sb);
42 static void afs_put_super(struct super_block *sb);
44 static void afs_destroy_inode(struct inode *inode);
46 struct file_system_type afs_fs_type = {
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,
54 static const struct super_operations afs_super_ops = {
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,
60 .umount_begin = afs_umount_begin,
61 .put_super = afs_put_super,
64 static struct kmem_cache *afs_inode_cachep;
65 static atomic_t afs_count_active_inodes;
68 * initialise the filesystem
70 int __init afs_fs_init(void)
72 int ret;
74 _enter("");
76 /* create ourselves an inode cache */
77 atomic_set(&afs_count_active_inodes, 0);
79 ret = -ENOMEM;
80 afs_inode_cachep = kmem_cache_create("afs_inode_cache",
81 sizeof(struct afs_vnode),
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;
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);
95 _leave(" = %d", ret);
96 return ret;
99 _leave(" = 0");
100 return 0;
104 * clean up the filesystem
106 void __exit afs_fs_exit(void)
108 _enter("");
110 afs_mntpt_kill_timer();
111 unregister_filesystem(&afs_fs_type);
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();
119 kmem_cache_destroy(afs_inode_cachep);
120 _leave("");
124 * check that an argument has a value
126 static int want_arg(char **_value, const char *option)
128 if (!_value || !*_value || !**_value) {
129 printk(KERN_NOTICE "kAFS: %s: argument missing\n", option);
130 return 0;
132 return 1;
136 * check that there's no subsequent value
138 static int want_no_value(char *const *_value, const char *option)
140 if (*_value && **_value) {
141 printk(KERN_NOTICE "kAFS: %s: Invalid argument: %s\n",
142 option, *_value);
143 return 0;
145 return 1;
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
153 static int afs_super_parse_options(struct afs_mount_params *params,
154 char *options, const char **devname)
156 struct afs_cell *cell;
157 char *key, *value;
158 int ret;
160 _enter("%s", options);
162 options[PAGE_SIZE - 1] = 0;
164 ret = 0;
165 while ((key = strsep(&options, ","))) {
166 value = strchr(key, '=');
167 if (value)
168 *value++ = 0;
170 _debug("kAFS: KEY: %s, VAL:%s", key, value ?: "-");
172 if (strcmp(key, "rwpath") == 0) {
173 if (!want_no_value(&value, "rwpath"))
174 return -EINVAL;
175 params->rwpath = 1;
176 } else if (strcmp(key, "vol") == 0) {
177 if (!want_arg(&value, "vol"))
178 return -EINVAL;
179 *devname = value;
180 } else if (strcmp(key, "cell") == 0) {
181 if (!want_arg(&value, "cell"))
182 return -EINVAL;
183 cell = afs_cell_lookup(value, strlen(value));
184 if (IS_ERR(cell))
185 return PTR_ERR(cell);
186 afs_put_cell(params->default_cell);
187 params->default_cell = cell;
188 } else {
189 printk("kAFS: Unknown mount option: '%s'\n", key);
190 ret = -EINVAL;
191 goto error;
195 ret = 0;
196 error:
197 _leave(" = %d", ret);
198 return ret;
202 * check a superblock to see if it's the one we're looking for
204 static int afs_test_super(struct super_block *sb, void *data)
206 struct afs_mount_params *params = data;
207 struct afs_super_info *as = sb->s_fs_info;
209 return as->volume == params->volume;
213 * fill in the superblock
215 static int afs_fill_super(struct super_block *sb, void *data, int silent)
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;
224 _enter("");
226 /* allocate a superblock info record */
227 as = kzalloc(sizeof(struct afs_super_info), GFP_KERNEL);
228 if (!as) {
229 _leave(" = -ENOMEM");
230 return -ENOMEM;
233 afs_get_volume(params->volume);
234 as->volume = params->volume;
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;
243 /* allocate the root inode and dentry */
244 fid.vid = as->volume->vid;
245 fid.vnode = 1;
246 fid.unique = 1;
247 inode = afs_iget(sb, &fid);
248 if (IS_ERR(inode))
249 goto error_inode;
251 ret = -ENOMEM;
252 root = d_alloc_root(inode);
253 if (!root)
254 goto error;
256 sb->s_root = root;
258 _leave(" = 0");
259 return 0;
261 error_inode:
262 ret = PTR_ERR(inode);
263 inode = NULL;
264 error:
265 iput(inode);
266 afs_put_volume(as->volume);
267 kfree(as);
269 sb->s_fs_info = NULL;
271 _leave(" = %d", ret);
272 return ret;
276 * get an AFS superblock
277 * - TODO: don't use get_sb_nodev(), but rather call sget() directly
279 static 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)
285 struct afs_mount_params params;
286 struct super_block *sb;
287 struct afs_volume *vol;
288 int ret;
290 _enter(",,%s,%p", dev_name, options);
292 memset(&params, 0, sizeof(params));
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;
306 /* parse the device name */
307 vol = afs_volume_lookup(dev_name, params.default_cell, params.rwpath);
308 if (IS_ERR(vol)) {
309 ret = PTR_ERR(vol);
310 goto error;
313 params.volume = vol;
315 /* allocate a deviceless superblock */
316 sb = sget(fs_type, afs_test_super, set_anon_super, &params);
317 if (IS_ERR(sb)) {
318 ret = PTR_ERR(sb);
319 goto error;
322 sb->s_flags = flags;
324 ret = afs_fill_super(sb, &params, flags & MS_SILENT ? 1 : 0);
325 if (ret < 0) {
326 up_write(&sb->s_umount);
327 deactivate_super(sb);
328 goto error;
330 sb->s_flags |= MS_ACTIVE;
331 simple_set_mnt(mnt, sb);
333 afs_put_volume(params.volume);
334 afs_put_cell(params.default_cell);
335 _leave(" = 0 [%p]", sb);
336 return 0;
338 error:
339 afs_put_volume(params.volume);
340 afs_put_cell(params.default_cell);
341 _leave(" = %d", ret);
342 return ret;
346 * finish the unmounting process on the superblock
348 static void afs_put_super(struct super_block *sb)
350 struct afs_super_info *as = sb->s_fs_info;
352 _enter("");
354 afs_put_volume(as->volume);
356 _leave("");
360 * initialise an inode cache slab element prior to any use
362 static void afs_i_init_once(void *_vnode, struct kmem_cache *cachep,
363 unsigned long flags)
365 struct afs_vnode *vnode = _vnode;
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);
373 INIT_WORK(&vnode->cb_broken_work, afs_broken_callback_work);
374 mutex_init(&vnode->cb_broken_lock);
379 * allocate an AFS inode struct from our slab cache
381 static struct inode *afs_alloc_inode(struct super_block *sb)
383 struct afs_vnode *vnode;
385 vnode = kmem_cache_alloc(afs_inode_cachep, GFP_KERNEL);
386 if (!vnode)
387 return NULL;
389 atomic_inc(&afs_count_active_inodes);
391 memset(&vnode->fid, 0, sizeof(vnode->fid));
392 memset(&vnode->status, 0, sizeof(vnode->status));
394 vnode->volume = NULL;
395 vnode->update_cnt = 0;
396 vnode->flags = 0;
397 vnode->cb_promised = false;
399 return &vnode->vfs_inode;
403 * destroy an AFS inode struct
405 static void afs_destroy_inode(struct inode *inode)
407 struct afs_vnode *vnode = AFS_FS_I(inode);
409 _enter("{%lu}", inode->i_ino);
411 _debug("DESTROY INODE %p", inode);
413 ASSERTCMP(vnode->server, ==, NULL);
415 kmem_cache_free(afs_inode_cachep, vnode);
416 atomic_dec(&afs_count_active_inodes);