Blame view
fs/afs/super.c
13.6 KB
ec26815ad [AFS]: Clean up t... |
1 2 |
/* AFS superblock handling * |
08e0e7c82 [AF_RXRPC]: Make ... |
3 |
* Copyright (c) 2002, 2007 Red Hat, Inc. All rights reserved. |
1da177e4c Linux-2.6.12-rc2 |
4 5 6 7 8 9 10 11 12 |
* * This software may be freely redistributed under the terms of the * GNU General Public License. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * Authors: David Howells <dhowells@redhat.com> |
44d1b980c Fix various old e... |
13 |
* David Woodhouse <dwmw2@infradead.org> |
1da177e4c Linux-2.6.12-rc2 |
14 15 16 17 18 |
* */ #include <linux/kernel.h> #include <linux/module.h> |
bec5eb614 AFS: Implement an... |
19 |
#include <linux/mount.h> |
1da177e4c Linux-2.6.12-rc2 |
20 21 22 23 |
#include <linux/init.h> #include <linux/slab.h> #include <linux/fs.h> #include <linux/pagemap.h> |
80c72fe41 [AFS/AF_RXRPC]: M... |
24 |
#include <linux/parser.h> |
45222b9e0 AFS: implement st... |
25 |
#include <linux/statfs.h> |
e8edc6e03 Detach sched.h fr... |
26 |
#include <linux/sched.h> |
f74f70f8b afs: Only allow m... |
27 28 |
#include <linux/nsproxy.h> #include <net/net_namespace.h> |
1da177e4c Linux-2.6.12-rc2 |
29 30 31 |
#include "internal.h" #define AFS_FS_MAGIC 0x6B414653 /* 'kAFS' */ |
51cc50685 SL*B: drop kmem c... |
32 |
static void afs_i_init_once(void *foo); |
f7442b3be convert afs |
33 34 |
static struct dentry *afs_mount(struct file_system_type *fs_type, int flags, const char *dev_name, void *data); |
dde194a64 afs: fix sget() r... |
35 |
static void afs_kill_super(struct super_block *sb); |
1da177e4c Linux-2.6.12-rc2 |
36 |
static struct inode *afs_alloc_inode(struct super_block *sb); |
1da177e4c Linux-2.6.12-rc2 |
37 |
static void afs_destroy_inode(struct inode *inode); |
45222b9e0 AFS: implement st... |
38 |
static int afs_statfs(struct dentry *dentry, struct kstatfs *buf); |
677018a6c afs: Implement sh... |
39 40 |
static int afs_show_devname(struct seq_file *m, struct dentry *root); static int afs_show_options(struct seq_file *m, struct dentry *root); |
1da177e4c Linux-2.6.12-rc2 |
41 |
|
1f5ce9e93 VFS: Unexport do_... |
42 |
struct file_system_type afs_fs_type = { |
1da177e4c Linux-2.6.12-rc2 |
43 44 |
.owner = THIS_MODULE, .name = "afs", |
f7442b3be convert afs |
45 |
.mount = afs_mount, |
dde194a64 afs: fix sget() r... |
46 |
.kill_sb = afs_kill_super, |
80c72fe41 [AFS/AF_RXRPC]: M... |
47 |
.fs_flags = 0, |
1da177e4c Linux-2.6.12-rc2 |
48 |
}; |
7f78e0351 fs: Limit sys_mou... |
49 |
MODULE_ALIAS_FS("afs"); |
1da177e4c Linux-2.6.12-rc2 |
50 |
|
ee9b6d61a [PATCH] Mark stru... |
51 |
static const struct super_operations afs_super_ops = { |
45222b9e0 AFS: implement st... |
52 |
.statfs = afs_statfs, |
1da177e4c Linux-2.6.12-rc2 |
53 |
.alloc_inode = afs_alloc_inode, |
bec5eb614 AFS: Implement an... |
54 |
.drop_inode = afs_drop_inode, |
1da177e4c Linux-2.6.12-rc2 |
55 |
.destroy_inode = afs_destroy_inode, |
b57922d97 convert remaining... |
56 |
.evict_inode = afs_evict_inode, |
677018a6c afs: Implement sh... |
57 58 |
.show_devname = afs_show_devname, .show_options = afs_show_options, |
1da177e4c Linux-2.6.12-rc2 |
59 |
}; |
e18b890bb [PATCH] slab: rem... |
60 |
static struct kmem_cache *afs_inode_cachep; |
1da177e4c Linux-2.6.12-rc2 |
61 |
static atomic_t afs_count_active_inodes; |
80c72fe41 [AFS/AF_RXRPC]: M... |
62 63 64 65 66 |
enum { afs_no_opt, afs_opt_cell, afs_opt_rwpath, afs_opt_vol, |
bec5eb614 AFS: Implement an... |
67 |
afs_opt_autocell, |
80c72fe41 [AFS/AF_RXRPC]: M... |
68 |
}; |
a447c0932 vfs: Use const fo... |
69 |
static const match_table_t afs_options_list = { |
80c72fe41 [AFS/AF_RXRPC]: M... |
70 71 72 |
{ afs_opt_cell, "cell=%s" }, { afs_opt_rwpath, "rwpath" }, { afs_opt_vol, "vol=%s" }, |
bec5eb614 AFS: Implement an... |
73 |
{ afs_opt_autocell, "autocell" }, |
80c72fe41 [AFS/AF_RXRPC]: M... |
74 75 |
{ afs_no_opt, NULL }, }; |
1da177e4c Linux-2.6.12-rc2 |
76 77 78 79 80 81 82 83 |
/* * initialise the filesystem */ int __init afs_fs_init(void) { int ret; _enter(""); |
1da177e4c Linux-2.6.12-rc2 |
84 85 86 87 88 89 90 |
/* create ourselves an inode cache */ atomic_set(&afs_count_active_inodes, 0); ret = -ENOMEM; afs_inode_cachep = kmem_cache_create("afs_inode_cache", sizeof(struct afs_vnode), 0, |
5d097056c kmemcg: account c... |
91 |
SLAB_HWCACHE_ALIGN|SLAB_ACCOUNT, |
20c2df83d mm: Remove slab d... |
92 |
afs_i_init_once); |
1da177e4c Linux-2.6.12-rc2 |
93 94 95 96 97 98 99 100 101 102 |
if (!afs_inode_cachep) { printk(KERN_NOTICE "kAFS: Failed to allocate inode cache "); return ret; } /* now export our filesystem to lesser mortals */ ret = register_filesystem(&afs_fs_type); if (ret < 0) { kmem_cache_destroy(afs_inode_cachep); |
08e0e7c82 [AF_RXRPC]: Make ... |
103 |
_leave(" = %d", ret); |
1da177e4c Linux-2.6.12-rc2 |
104 105 |
return ret; } |
08e0e7c82 [AF_RXRPC]: Make ... |
106 |
_leave(" = 0"); |
1da177e4c Linux-2.6.12-rc2 |
107 |
return 0; |
ec26815ad [AFS]: Clean up t... |
108 |
} |
1da177e4c Linux-2.6.12-rc2 |
109 |
|
1da177e4c Linux-2.6.12-rc2 |
110 111 112 113 114 |
/* * clean up the filesystem */ void __exit afs_fs_exit(void) { |
08e0e7c82 [AF_RXRPC]: Make ... |
115 116 117 |
_enter(""); afs_mntpt_kill_timer(); |
1da177e4c Linux-2.6.12-rc2 |
118 119 120 121 122 123 124 125 |
unregister_filesystem(&afs_fs_type); if (atomic_read(&afs_count_active_inodes) != 0) { printk("kAFS: %d active inode objects still present ", atomic_read(&afs_count_active_inodes)); BUG(); } |
8c0a85377 fs: push rcu_barr... |
126 127 128 129 130 |
/* * Make sure all delayed rcu free inodes are flushed before we * destroy cache. */ rcu_barrier(); |
1da177e4c Linux-2.6.12-rc2 |
131 |
kmem_cache_destroy(afs_inode_cachep); |
08e0e7c82 [AF_RXRPC]: Make ... |
132 |
_leave(""); |
ec26815ad [AFS]: Clean up t... |
133 |
} |
1da177e4c Linux-2.6.12-rc2 |
134 |
|
1da177e4c Linux-2.6.12-rc2 |
135 |
/* |
677018a6c afs: Implement sh... |
136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 |
* Display the mount device name in /proc/mounts. */ static int afs_show_devname(struct seq_file *m, struct dentry *root) { struct afs_super_info *as = root->d_sb->s_fs_info; struct afs_volume *volume = as->volume; struct afs_cell *cell = volume->cell; const char *suf = ""; char pref = '%'; switch (volume->type) { case AFSVL_RWVOL: break; case AFSVL_ROVOL: pref = '#'; if (volume->type_force) suf = ".readonly"; break; case AFSVL_BACKVOL: pref = '#'; suf = ".backup"; break; } seq_printf(m, "%c%s:%s%s", pref, cell->name, volume->vlocation->vldb.name, suf); return 0; } /* * Display the mount options in /proc/mounts. */ static int afs_show_options(struct seq_file *m, struct dentry *root) { if (test_bit(AFS_VNODE_AUTOCELL, &AFS_FS_I(d_inode(root))->flags)) seq_puts(m, "autocell"); return 0; } /* |
1da177e4c Linux-2.6.12-rc2 |
175 176 177 178 |
* parse the mount options * - this function has been shamelessly adapted from the ext3 fs which * shamelessly adapted it from the msdos fs */ |
00d3b7a45 [AFS]: Add securi... |
179 180 |
static int afs_parse_options(struct afs_mount_params *params, char *options, const char **devname) |
1da177e4c Linux-2.6.12-rc2 |
181 |
{ |
08e0e7c82 [AF_RXRPC]: Make ... |
182 |
struct afs_cell *cell; |
80c72fe41 [AFS/AF_RXRPC]: M... |
183 184 185 |
substring_t args[MAX_OPT_ARGS]; char *p; int token; |
1da177e4c Linux-2.6.12-rc2 |
186 187 188 189 |
_enter("%s", options); options[PAGE_SIZE - 1] = 0; |
80c72fe41 [AFS/AF_RXRPC]: M... |
190 191 192 |
while ((p = strsep(&options, ","))) { if (!*p) continue; |
1da177e4c Linux-2.6.12-rc2 |
193 |
|
80c72fe41 [AFS/AF_RXRPC]: M... |
194 195 196 197 |
token = match_token(p, afs_options_list, args); switch (token) { case afs_opt_cell: cell = afs_cell_lookup(args[0].from, |
bec5eb614 AFS: Implement an... |
198 199 |
args[0].to - args[0].from, false); |
08e0e7c82 [AF_RXRPC]: Make ... |
200 201 |
if (IS_ERR(cell)) return PTR_ERR(cell); |
00d3b7a45 [AFS]: Add securi... |
202 203 |
afs_put_cell(params->cell); params->cell = cell; |
80c72fe41 [AFS/AF_RXRPC]: M... |
204 205 206 207 208 209 210 211 212 |
break; case afs_opt_rwpath: params->rwpath = 1; break; case afs_opt_vol: *devname = args[0].from; break; |
bec5eb614 AFS: Implement an... |
213 214 215 |
case afs_opt_autocell: params->autocell = 1; break; |
80c72fe41 [AFS/AF_RXRPC]: M... |
216 217 218 219 220 |
default: printk(KERN_ERR "kAFS:" " Unknown or invalid mount option: '%s' ", p); return -EINVAL; |
1da177e4c Linux-2.6.12-rc2 |
221 |
} |
1da177e4c Linux-2.6.12-rc2 |
222 |
} |
80c72fe41 [AFS/AF_RXRPC]: M... |
223 224 |
_leave(" = 0"); return 0; |
ec26815ad [AFS]: Clean up t... |
225 |
} |
1da177e4c Linux-2.6.12-rc2 |
226 |
|
1da177e4c Linux-2.6.12-rc2 |
227 |
/* |
00d3b7a45 [AFS]: Add securi... |
228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 |
* parse a device name to get cell name, volume name, volume type and R/W * selector * - this can be one of the following: * "%[cell:]volume[.]" R/W volume * "#[cell:]volume[.]" R/O or R/W volume (rwpath=0), * or R/W (rwpath=1) volume * "%[cell:]volume.readonly" R/O volume * "#[cell:]volume.readonly" R/O volume * "%[cell:]volume.backup" Backup volume * "#[cell:]volume.backup" Backup volume */ static int afs_parse_device_name(struct afs_mount_params *params, const char *name) { struct afs_cell *cell; const char *cellname, *suffix; int cellnamesz; _enter(",%s", name); if (!name) { printk(KERN_ERR "kAFS: no volume name specified "); return -EINVAL; } if ((name[0] != '%' && name[0] != '#') || !name[1]) { printk(KERN_ERR "kAFS: unparsable volume name "); return -EINVAL; } /* determine the type of volume we're looking for */ params->type = AFSVL_ROVOL; params->force = false; if (params->rwpath || name[0] == '%') { params->type = AFSVL_RWVOL; params->force = true; } name++; /* split the cell name out if there is one */ params->volname = strchr(name, ':'); if (params->volname) { cellname = name; cellnamesz = params->volname - name; params->volname++; } else { params->volname = name; cellname = NULL; cellnamesz = 0; } /* the volume type is further affected by a possible suffix */ suffix = strrchr(params->volname, '.'); if (suffix) { if (strcmp(suffix, ".readonly") == 0) { params->type = AFSVL_ROVOL; params->force = true; } else if (strcmp(suffix, ".backup") == 0) { params->type = AFSVL_BACKVOL; params->force = true; } else if (suffix[1] == 0) { } else { suffix = NULL; } } params->volnamesz = suffix ? suffix - params->volname : strlen(params->volname); _debug("cell %*.*s [%p]", cellnamesz, cellnamesz, cellname ?: "", params->cell); /* lookup the cell record */ if (cellname || !params->cell) { |
bec5eb614 AFS: Implement an... |
304 |
cell = afs_cell_lookup(cellname, cellnamesz, true); |
00d3b7a45 [AFS]: Add securi... |
305 |
if (IS_ERR(cell)) { |
bec5eb614 AFS: Implement an... |
306 307 308 |
printk(KERN_ERR "kAFS: unable to lookup cell '%*.*s' ", cellnamesz, cellnamesz, cellname ?: ""); |
00d3b7a45 [AFS]: Add securi... |
309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 |
return PTR_ERR(cell); } afs_put_cell(params->cell); params->cell = cell; } _debug("CELL:%s [%p] VOLUME:%*.*s SUFFIX:%s TYPE:%d%s", params->cell->name, params->cell, params->volnamesz, params->volnamesz, params->volname, suffix ?: "-", params->type, params->force ? " FORCE" : ""); return 0; } /* |
1da177e4c Linux-2.6.12-rc2 |
324 325 326 327 |
* check a superblock to see if it's the one we're looking for */ static int afs_test_super(struct super_block *sb, void *data) { |
dde194a64 afs: fix sget() r... |
328 |
struct afs_super_info *as1 = data; |
1da177e4c Linux-2.6.12-rc2 |
329 |
struct afs_super_info *as = sb->s_fs_info; |
dde194a64 afs: fix sget() r... |
330 331 332 333 334 335 336 |
return as->volume == as1->volume; } static int afs_set_super(struct super_block *sb, void *data) { sb->s_fs_info = data; return set_anon_super(sb, NULL); |
ec26815ad [AFS]: Clean up t... |
337 |
} |
1da177e4c Linux-2.6.12-rc2 |
338 |
|
1da177e4c Linux-2.6.12-rc2 |
339 340 341 |
/* * fill in the superblock */ |
dde194a64 afs: fix sget() r... |
342 343 |
static int afs_fill_super(struct super_block *sb, struct afs_mount_params *params) |
1da177e4c Linux-2.6.12-rc2 |
344 |
{ |
dde194a64 afs: fix sget() r... |
345 |
struct afs_super_info *as = sb->s_fs_info; |
1da177e4c Linux-2.6.12-rc2 |
346 |
struct afs_fid fid; |
1da177e4c Linux-2.6.12-rc2 |
347 348 |
struct inode *inode = NULL; int ret; |
08e0e7c82 [AF_RXRPC]: Make ... |
349 |
_enter(""); |
1da177e4c Linux-2.6.12-rc2 |
350 |
|
1da177e4c Linux-2.6.12-rc2 |
351 |
/* fill in the superblock */ |
09cbfeaf1 mm, fs: get rid o... |
352 353 |
sb->s_blocksize = PAGE_SIZE; sb->s_blocksize_bits = PAGE_SHIFT; |
1da177e4c Linux-2.6.12-rc2 |
354 355 |
sb->s_magic = AFS_FS_MAGIC; sb->s_op = &afs_super_ops; |
d3e3b7eac afs: Add metadata... |
356 |
sb->s_xattr = afs_xattr_handlers; |
edd3ba94c afs: Convert to s... |
357 358 359 360 |
ret = super_setup_bdi(sb); if (ret) return ret; sb->s_bdi->ra_pages = VM_MAX_READAHEAD * 1024 / PAGE_SIZE; |
2e41ae225 AFS: Set s_id in ... |
361 |
strlcpy(sb->s_id, as->volume->vlocation->vldb.name, sizeof(sb->s_id)); |
1da177e4c Linux-2.6.12-rc2 |
362 363 364 365 366 |
/* allocate the root inode and dentry */ fid.vid = as->volume->vid; fid.vnode = 1; fid.unique = 1; |
260a98031 [AFS]: Add "direc... |
367 |
inode = afs_iget(sb, params->key, &fid, NULL, NULL); |
08e0e7c82 [AF_RXRPC]: Make ... |
368 |
if (IS_ERR(inode)) |
dde194a64 afs: fix sget() r... |
369 |
return PTR_ERR(inode); |
1da177e4c Linux-2.6.12-rc2 |
370 |
|
bec5eb614 AFS: Implement an... |
371 372 |
if (params->autocell) set_bit(AFS_VNODE_AUTOCELL, &AFS_FS_I(inode)->flags); |
1da177e4c Linux-2.6.12-rc2 |
373 |
ret = -ENOMEM; |
48fde701a switch open-coded... |
374 375 |
sb->s_root = d_make_root(inode); if (!sb->s_root) |
1da177e4c Linux-2.6.12-rc2 |
376 |
goto error; |
d61dcce29 switch afs |
377 |
sb->s_d_op = &afs_fs_dentry_operations; |
1da177e4c Linux-2.6.12-rc2 |
378 |
|
08e0e7c82 [AF_RXRPC]: Make ... |
379 |
_leave(" = 0"); |
1da177e4c Linux-2.6.12-rc2 |
380 |
return 0; |
ec26815ad [AFS]: Clean up t... |
381 |
error: |
08e0e7c82 [AF_RXRPC]: Make ... |
382 |
_leave(" = %d", ret); |
1da177e4c Linux-2.6.12-rc2 |
383 |
return ret; |
ec26815ad [AFS]: Clean up t... |
384 |
} |
1da177e4c Linux-2.6.12-rc2 |
385 |
|
1da177e4c Linux-2.6.12-rc2 |
386 387 |
/* * get an AFS superblock |
1da177e4c Linux-2.6.12-rc2 |
388 |
*/ |
f7442b3be convert afs |
389 390 |
static struct dentry *afs_mount(struct file_system_type *fs_type, int flags, const char *dev_name, void *options) |
1da177e4c Linux-2.6.12-rc2 |
391 392 393 |
{ struct afs_mount_params params; struct super_block *sb; |
08e0e7c82 [AF_RXRPC]: Make ... |
394 |
struct afs_volume *vol; |
00d3b7a45 [AFS]: Add securi... |
395 |
struct key *key; |
969729d56 mount options: fi... |
396 |
char *new_opts = kstrdup(options, GFP_KERNEL); |
dde194a64 afs: fix sget() r... |
397 |
struct afs_super_info *as; |
1da177e4c Linux-2.6.12-rc2 |
398 399 400 401 402 |
int ret; _enter(",,%s,%p", dev_name, options); memset(¶ms, 0, sizeof(params)); |
f74f70f8b afs: Only allow m... |
403 404 405 |
ret = -EINVAL; if (current->nsproxy->net_ns != &init_net) goto error; |
00d3b7a45 [AFS]: Add securi... |
406 |
/* parse the options and device name */ |
1da177e4c Linux-2.6.12-rc2 |
407 |
if (options) { |
00d3b7a45 [AFS]: Add securi... |
408 |
ret = afs_parse_options(¶ms, options, &dev_name); |
1da177e4c Linux-2.6.12-rc2 |
409 410 |
if (ret < 0) goto error; |
1da177e4c Linux-2.6.12-rc2 |
411 |
} |
00d3b7a45 [AFS]: Add securi... |
412 413 414 415 416 417 418 419 420 421 422 423 |
ret = afs_parse_device_name(¶ms, dev_name); if (ret < 0) goto error; /* try and do the mount securely */ key = afs_request_key(params.cell); if (IS_ERR(key)) { _leave(" = %ld [key]", PTR_ERR(key)); ret = PTR_ERR(key); goto error; } params.key = key; |
1da177e4c Linux-2.6.12-rc2 |
424 |
/* parse the device name */ |
00d3b7a45 [AFS]: Add securi... |
425 |
vol = afs_volume_lookup(¶ms); |
08e0e7c82 [AF_RXRPC]: Make ... |
426 427 |
if (IS_ERR(vol)) { ret = PTR_ERR(vol); |
1da177e4c Linux-2.6.12-rc2 |
428 |
goto error; |
08e0e7c82 [AF_RXRPC]: Make ... |
429 |
} |
dde194a64 afs: fix sget() r... |
430 431 432 433 434 435 436 437 438 |
/* allocate a superblock info record */ as = kzalloc(sizeof(struct afs_super_info), GFP_KERNEL); if (!as) { ret = -ENOMEM; afs_put_volume(vol); goto error; } as->volume = vol; |
1da177e4c Linux-2.6.12-rc2 |
439 440 |
/* allocate a deviceless superblock */ |
9249e17fe VFS: Pass mount f... |
441 |
sb = sget(fs_type, afs_test_super, afs_set_super, flags, as); |
08e0e7c82 [AF_RXRPC]: Make ... |
442 443 |
if (IS_ERR(sb)) { ret = PTR_ERR(sb); |
dde194a64 afs: fix sget() r... |
444 445 |
afs_put_volume(vol); kfree(as); |
1da177e4c Linux-2.6.12-rc2 |
446 |
goto error; |
08e0e7c82 [AF_RXRPC]: Make ... |
447 |
} |
1da177e4c Linux-2.6.12-rc2 |
448 |
|
436058a49 [AFS]: Handle mul... |
449 450 451 |
if (!sb->s_root) { /* initial superblock/root creation */ _debug("create"); |
436058a49 [AFS]: Handle mul... |
452 453 |
ret = afs_fill_super(sb, ¶ms); if (ret < 0) { |
6f5bbff9a Convert obvious p... |
454 |
deactivate_locked_super(sb); |
436058a49 [AFS]: Handle mul... |
455 456 457 458 459 460 |
goto error; } sb->s_flags |= MS_ACTIVE; } else { _debug("reuse"); ASSERTCMP(sb->s_flags, &, MS_ACTIVE); |
dde194a64 afs: fix sget() r... |
461 462 |
afs_put_volume(vol); kfree(as); |
1da177e4c Linux-2.6.12-rc2 |
463 |
} |
1da177e4c Linux-2.6.12-rc2 |
464 |
|
00d3b7a45 [AFS]: Add securi... |
465 |
afs_put_cell(params.cell); |
2a32cebd6 Fix races around ... |
466 |
kfree(new_opts); |
08e0e7c82 [AF_RXRPC]: Make ... |
467 |
_leave(" = 0 [%p]", sb); |
f7442b3be convert afs |
468 |
return dget(sb->s_root); |
1da177e4c Linux-2.6.12-rc2 |
469 |
|
ec26815ad [AFS]: Clean up t... |
470 |
error: |
00d3b7a45 [AFS]: Add securi... |
471 472 |
afs_put_cell(params.cell); key_put(params.key); |
969729d56 mount options: fi... |
473 |
kfree(new_opts); |
1da177e4c Linux-2.6.12-rc2 |
474 |
_leave(" = %d", ret); |
f7442b3be convert afs |
475 |
return ERR_PTR(ret); |
ec26815ad [AFS]: Clean up t... |
476 |
} |
1da177e4c Linux-2.6.12-rc2 |
477 |
|
dde194a64 afs: fix sget() r... |
478 |
static void afs_kill_super(struct super_block *sb) |
1da177e4c Linux-2.6.12-rc2 |
479 480 |
{ struct afs_super_info *as = sb->s_fs_info; |
dde194a64 afs: fix sget() r... |
481 |
kill_anon_super(sb); |
1da177e4c Linux-2.6.12-rc2 |
482 |
afs_put_volume(as->volume); |
dde194a64 afs: fix sget() r... |
483 |
kfree(as); |
ec26815ad [AFS]: Clean up t... |
484 |
} |
1da177e4c Linux-2.6.12-rc2 |
485 |
|
1da177e4c Linux-2.6.12-rc2 |
486 487 488 |
/* * initialise an inode cache slab element prior to any use */ |
51cc50685 SL*B: drop kmem c... |
489 |
static void afs_i_init_once(void *_vnode) |
1da177e4c Linux-2.6.12-rc2 |
490 |
{ |
ec26815ad [AFS]: Clean up t... |
491 |
struct afs_vnode *vnode = _vnode; |
1da177e4c Linux-2.6.12-rc2 |
492 |
|
a35afb830 Remove SLAB_CTOR_... |
493 494 495 496 497 498 499 500 |
memset(vnode, 0, sizeof(*vnode)); inode_init_once(&vnode->vfs_inode); init_waitqueue_head(&vnode->update_waitq); mutex_init(&vnode->permits_lock); mutex_init(&vnode->validate_lock); spin_lock_init(&vnode->writeback_lock); spin_lock_init(&vnode->lock); INIT_LIST_HEAD(&vnode->writebacks); |
e8d6c5541 AFS: implement fi... |
501 502 503 |
INIT_LIST_HEAD(&vnode->pending_locks); INIT_LIST_HEAD(&vnode->granted_locks); INIT_DELAYED_WORK(&vnode->lock_work, afs_lock_work); |
a35afb830 Remove SLAB_CTOR_... |
504 |
INIT_WORK(&vnode->cb_broken_work, afs_broken_callback_work); |
ec26815ad [AFS]: Clean up t... |
505 |
} |
1da177e4c Linux-2.6.12-rc2 |
506 |
|
1da177e4c Linux-2.6.12-rc2 |
507 508 509 510 511 512 |
/* * allocate an AFS inode struct from our slab cache */ static struct inode *afs_alloc_inode(struct super_block *sb) { struct afs_vnode *vnode; |
ec26815ad [AFS]: Clean up t... |
513 |
vnode = kmem_cache_alloc(afs_inode_cachep, GFP_KERNEL); |
1da177e4c Linux-2.6.12-rc2 |
514 515 516 517 518 519 520 521 522 523 |
if (!vnode) return NULL; atomic_inc(&afs_count_active_inodes); memset(&vnode->fid, 0, sizeof(vnode->fid)); memset(&vnode->status, 0, sizeof(vnode->status)); vnode->volume = NULL; vnode->update_cnt = 0; |
260a98031 [AFS]: Add "direc... |
524 |
vnode->flags = 1 << AFS_VNODE_UNSET; |
08e0e7c82 [AF_RXRPC]: Make ... |
525 |
vnode->cb_promised = false; |
1da177e4c Linux-2.6.12-rc2 |
526 |
|
0f300ca92 AFS: fix a couple... |
527 |
_leave(" = %p", &vnode->vfs_inode); |
1da177e4c Linux-2.6.12-rc2 |
528 |
return &vnode->vfs_inode; |
ec26815ad [AFS]: Clean up t... |
529 |
} |
1da177e4c Linux-2.6.12-rc2 |
530 |
|
fa0d7e3de fs: icache RCU fr... |
531 532 533 534 |
static void afs_i_callback(struct rcu_head *head) { struct inode *inode = container_of(head, struct inode, i_rcu); struct afs_vnode *vnode = AFS_FS_I(inode); |
fa0d7e3de fs: icache RCU fr... |
535 536 |
kmem_cache_free(afs_inode_cachep, vnode); } |
1da177e4c Linux-2.6.12-rc2 |
537 538 539 540 541 |
/* * destroy an AFS inode struct */ static void afs_destroy_inode(struct inode *inode) { |
08e0e7c82 [AF_RXRPC]: Make ... |
542 |
struct afs_vnode *vnode = AFS_FS_I(inode); |
0f300ca92 AFS: fix a couple... |
543 |
_enter("%p{%x:%u}", inode, vnode->fid.vid, vnode->fid.vnode); |
1da177e4c Linux-2.6.12-rc2 |
544 |
|
08e0e7c82 [AF_RXRPC]: Make ... |
545 546 547 |
_debug("DESTROY INODE %p", inode); ASSERTCMP(vnode->server, ==, NULL); |
fa0d7e3de fs: icache RCU fr... |
548 |
call_rcu(&inode->i_rcu, afs_i_callback); |
1da177e4c Linux-2.6.12-rc2 |
549 |
atomic_dec(&afs_count_active_inodes); |
ec26815ad [AFS]: Clean up t... |
550 |
} |
45222b9e0 AFS: implement st... |
551 552 553 554 555 556 557 |
/* * return information about an AFS volume */ static int afs_statfs(struct dentry *dentry, struct kstatfs *buf) { struct afs_volume_status vs; |
2b0143b5c VFS: normal files... |
558 |
struct afs_vnode *vnode = AFS_FS_I(d_inode(dentry)); |
45222b9e0 AFS: implement st... |
559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 |
struct key *key; int ret; key = afs_request_key(vnode->volume->cell); if (IS_ERR(key)) return PTR_ERR(key); ret = afs_vnode_get_volume_status(vnode, key, &vs); key_put(key); if (ret < 0) { _leave(" = %d", ret); return ret; } buf->f_type = dentry->d_sb->s_magic; buf->f_bsize = AFS_BLOCK_SIZE; buf->f_namelen = AFSNAMEMAX - 1; if (vs.max_quota == 0) buf->f_blocks = vs.part_max_blocks; else buf->f_blocks = vs.max_quota; buf->f_bavail = buf->f_bfree = buf->f_blocks - vs.blocks_in_use; return 0; } |