};
MODULE_ALIAS_FS("afs");
+int afs_net_id;
+
static const struct super_operations afs_super_ops = {
.statfs = afs_statfs,
.alloc_inode = afs_alloc_inode,
/*
* clean up the filesystem
*/
-void __exit afs_fs_exit(void)
+void afs_fs_exit(void)
{
_enter("");
struct afs_super_info *as1 = data;
struct afs_super_info *as = AFS_FS_S(sb);
- return (as->net == as1->net &&
+ return (as->net_ns == as1->net_ns &&
as->volume &&
- as->volume->vid == as1->volume->vid);
+ as->volume->vid == as1->volume->vid &&
+ !as->dyn_root);
}
static int afs_dynroot_test_super(struct super_block *sb, void *data)
{
- return false;
+ struct afs_super_info *as1 = data;
+ struct afs_super_info *as = AFS_FS_S(sb);
+
+ return (as->net_ns == as1->net_ns &&
+ as->dyn_root);
}
static int afs_set_super(struct super_block *sb, void *data)
if (!sb->s_root)
goto error;
- if (params->dyn_root)
+ if (as->dyn_root) {
sb->s_d_op = &afs_dynroot_dentry_operations;
- else
+ ret = afs_dynroot_populate(sb);
+ if (ret < 0)
+ goto error;
+ } else {
sb->s_d_op = &afs_fs_dentry_operations;
+ }
_leave(" = 0");
return 0;
as = kzalloc(sizeof(struct afs_super_info), GFP_KERNEL);
if (as) {
- as->net = afs_get_net(params->net);
+ as->net_ns = get_net(params->net_ns);
if (params->dyn_root)
as->dyn_root = true;
else
{
if (as) {
afs_put_volume(as->cell, as->volume);
- afs_put_cell(as->net, as->cell);
- afs_put_net(as->net);
+ afs_put_cell(afs_net(as->net_ns), as->cell);
+ put_net(as->net_ns);
kfree(as);
}
}
+static void afs_kill_super(struct super_block *sb)
+{
+ struct afs_super_info *as = AFS_FS_S(sb);
+ struct afs_net *net = afs_net(as->net_ns);
+
+ if (as->dyn_root)
+ afs_dynroot_depopulate(sb);
+
+ /* Clear the callback interests (which will do ilookup5) before
+ * deactivating the superblock.
+ */
+ if (as->volume)
+ afs_clear_callback_interests(net, as->volume->servers);
+ kill_anon_super(sb);
+ if (as->volume)
+ afs_deactivate_volume(as->volume);
+ afs_destroy_sbi(as);
+}
+
/*
* get an AFS superblock
*/
_enter(",,%s,%p", dev_name, options);
memset(¶ms, 0, sizeof(params));
- params.net = &__afs_net;
ret = -EINVAL;
if (current->nsproxy->net_ns != &init_net)
goto error;
-
+ params.net_ns = current->nsproxy->net_ns;
+ params.net = afs_net(params.net_ns);
+
/* parse the options and device name */
if (options) {
ret = afs_parse_options(¶ms, options, &dev_name);
return ERR_PTR(ret);
}
-static void afs_kill_super(struct super_block *sb)
-{
- struct afs_super_info *as = AFS_FS_S(sb);
-
- /* Clear the callback interests (which will do ilookup5) before
- * deactivating the superblock.
- */
- if (as->volume)
- afs_clear_callback_interests(as->net, as->volume->servers);
- kill_anon_super(sb);
- if (as->volume)
- afs_deactivate_volume(as->volume);
- afs_destroy_sbi(as);
-}
-
/*
* Initialise an inode cache slab element prior to any use. Note that
* afs_alloc_inode() *must* reset anything that could incorrectly leak from one