diff --git a/fs/afs/cell.c b/fs/afs/cell.c index 80fd127239ce..bb92b54d2a4a 100644 --- a/fs/afs/cell.c +++ b/fs/afs/cell.c @@ -528,7 +528,7 @@ static int afs_activate_cell(struct afs_net *net, struct afs_cell *cell) NULL, 0, cell, 0, true); #endif - ret = afs_proc_cell_setup(net, cell); + ret = afs_proc_cell_setup(cell); if (ret < 0) return ret; spin_lock(&net->proc_cells_lock); @@ -544,7 +544,7 @@ static void afs_deactivate_cell(struct afs_net *net, struct afs_cell *cell) { _enter("%s", cell->name); - afs_proc_cell_remove(net, cell); + afs_proc_cell_remove(cell); spin_lock(&net->proc_cells_lock); list_del_init(&cell->proc_link); diff --git a/fs/afs/cmservice.c b/fs/afs/cmservice.c index 357de908df3a..4c89b1f4c02b 100644 --- a/fs/afs/cmservice.c +++ b/fs/afs/cmservice.c @@ -550,7 +550,7 @@ static void SRXAFSCB_TellMeAboutYourself(struct work_struct *work) nifs = 0; ifs = kcalloc(32, sizeof(*ifs), GFP_KERNEL); if (ifs) { - nifs = afs_get_ipv4_interfaces(ifs, 32, false); + nifs = afs_get_ipv4_interfaces(call->net, ifs, 32, false); if (nifs < 0) { kfree(ifs); ifs = NULL; diff --git a/fs/afs/internal.h b/fs/afs/internal.h index 5d922ad148a8..e6cef5702ae2 100644 --- a/fs/afs/internal.h +++ b/fs/afs/internal.h @@ -22,6 +22,8 @@ #include #include #include +#include +#include #include #include "afs.h" @@ -40,7 +42,8 @@ struct afs_mount_params { afs_voltype_t type; /* type of volume requested */ int volnamesz; /* size of volume name */ const char *volname; /* name of volume to mount */ - struct afs_net *net; /* Network namespace in effect */ + struct net *net_ns; /* Network namespace in effect */ + struct afs_net *net; /* the AFS net namespace stuff */ struct afs_cell *cell; /* cell in which to find volume */ struct afs_volume *volume; /* volume record */ struct key *key; /* key to use for secure mounting */ @@ -189,7 +192,7 @@ struct afs_read { * - there's one superblock per volume */ struct afs_super_info { - struct afs_net *net; /* Network namespace */ + struct net *net_ns; /* Network namespace */ struct afs_cell *cell; /* The cell in which the volume resides */ struct afs_volume *volume; /* volume record */ bool dyn_root; /* True if dynamic root */ @@ -210,7 +213,6 @@ struct afs_sysnames { char *subs[AFS_NR_SYSNAME]; refcount_t usage; unsigned short nr; - short error; char blank[1]; }; @@ -218,6 +220,7 @@ struct afs_sysnames { * AFS network namespace record. */ struct afs_net { + struct net *net; /* Backpointer to the owning net namespace */ struct afs_uuid uuid; bool live; /* F if this namespace is being removed */ @@ -280,7 +283,6 @@ struct afs_net { }; extern const char afs_init_sysname[]; -extern struct afs_net __afs_net;// Dummy AFS network namespace; TODO: replace with real netns enum afs_cell_state { AFS_CELL_UNSET, @@ -787,34 +789,36 @@ extern int afs_drop_inode(struct inode *); * main.c */ extern struct workqueue_struct *afs_wq; +extern int afs_net_id; + +static inline struct afs_net *afs_net(struct net *net) +{ + return net_generic(net, afs_net_id); +} + +static inline struct afs_net *afs_sb2net(struct super_block *sb) +{ + return afs_net(AFS_FS_S(sb)->net_ns); +} static inline struct afs_net *afs_d2net(struct dentry *dentry) { - return &__afs_net; + return afs_sb2net(dentry->d_sb); } static inline struct afs_net *afs_i2net(struct inode *inode) { - return &__afs_net; + return afs_sb2net(inode->i_sb); } static inline struct afs_net *afs_v2net(struct afs_vnode *vnode) { - return &__afs_net; + return afs_i2net(&vnode->vfs_inode); } static inline struct afs_net *afs_sock2net(struct sock *sk) { - return &__afs_net; -} - -static inline struct afs_net *afs_get_net(struct afs_net *net) -{ - return net; -} - -static inline void afs_put_net(struct afs_net *net) -{ + return net_generic(sock_net(sk), afs_net_id); } static inline void __afs_stat(atomic_t *s) @@ -842,15 +846,16 @@ extern void afs_mntpt_kill_timer(void); /* * netdevices.c */ -extern int afs_get_ipv4_interfaces(struct afs_interface *, size_t, bool); +extern int afs_get_ipv4_interfaces(struct afs_net *, struct afs_interface *, + size_t, bool); /* * proc.c */ extern int __net_init afs_proc_init(struct afs_net *); extern void __net_exit afs_proc_cleanup(struct afs_net *); -extern int afs_proc_cell_setup(struct afs_net *, struct afs_cell *); -extern void afs_proc_cell_remove(struct afs_net *, struct afs_cell *); +extern int afs_proc_cell_setup(struct afs_cell *); +extern void afs_proc_cell_remove(struct afs_cell *); extern void afs_put_sysnames(struct afs_sysnames *); /* @@ -983,7 +988,7 @@ extern bool afs_annotate_server_list(struct afs_server_list *, struct afs_server * super.c */ extern int __init afs_fs_init(void); -extern void __exit afs_fs_exit(void); +extern void afs_fs_exit(void); /* * vlclient.c diff --git a/fs/afs/main.c b/fs/afs/main.c index d7560168b3bf..7d2c1354e2ca 100644 --- a/fs/afs/main.c +++ b/fs/afs/main.c @@ -15,6 +15,7 @@ #include #include #include +#include #define CREATE_TRACE_POINTS #include "internal.h" @@ -32,7 +33,7 @@ module_param(rootcell, charp, 0); MODULE_PARM_DESC(rootcell, "root AFS cell name and VL server IP addr list"); struct workqueue_struct *afs_wq; -struct afs_net __afs_net; +static struct proc_dir_entry *afs_proc_symlink; #if defined(CONFIG_ALPHA) const char afs_init_sysname[] = "alpha_linux26"; @@ -67,11 +68,13 @@ const char afs_init_sysname[] = "unknown_linux26"; /* * Initialise an AFS network namespace record. */ -static int __net_init afs_net_init(struct afs_net *net) +static int __net_init afs_net_init(struct net *net_ns) { struct afs_sysnames *sysnames; + struct afs_net *net = afs_net(net_ns); int ret; + net->net = net_ns; net->live = true; generate_random_uuid((unsigned char *)&net->uuid); @@ -142,8 +145,10 @@ error_sysnames: /* * Clean up and destroy an AFS network namespace record. */ -static void __net_exit afs_net_exit(struct afs_net *net) +static void __net_exit afs_net_exit(struct net *net_ns) { + struct afs_net *net = afs_net(net_ns); + net->live = false; afs_cell_purge(net); afs_purge_servers(net); @@ -152,6 +157,13 @@ static void __net_exit afs_net_exit(struct afs_net *net) afs_put_sysnames(net->sysnames); } +static struct pernet_operations afs_net_ops = { + .init = afs_net_init, + .exit = afs_net_exit, + .id = &afs_net_id, + .size = sizeof(struct afs_net), +}; + /* * initialise the AFS client FS module */ @@ -178,7 +190,7 @@ static int __init afs_init(void) goto error_cache; #endif - ret = afs_net_init(&__afs_net); + ret = register_pernet_subsys(&afs_net_ops); if (ret < 0) goto error_net; @@ -187,10 +199,18 @@ static int __init afs_init(void) if (ret < 0) goto error_fs; + afs_proc_symlink = proc_symlink("fs/afs", NULL, "../self/net/afs"); + if (IS_ERR(afs_proc_symlink)) { + ret = PTR_ERR(afs_proc_symlink); + goto error_proc; + } + return ret; +error_proc: + afs_fs_exit(); error_fs: - afs_net_exit(&__afs_net); + unregister_pernet_subsys(&afs_net_ops); error_net: #ifdef CONFIG_AFS_FSCACHE fscache_unregister_netfs(&afs_cache_netfs); @@ -219,8 +239,9 @@ static void __exit afs_exit(void) { printk(KERN_INFO "kAFS: Red Hat AFS client v0.1 unregistering.\n"); + proc_remove(afs_proc_symlink); afs_fs_exit(); - afs_net_exit(&__afs_net); + unregister_pernet_subsys(&afs_net_ops); #ifdef CONFIG_AFS_FSCACHE fscache_unregister_netfs(&afs_cache_netfs); #endif diff --git a/fs/afs/netdevices.c b/fs/afs/netdevices.c index 50bd5bb1c4fb..2a009d1939d7 100644 --- a/fs/afs/netdevices.c +++ b/fs/afs/netdevices.c @@ -17,8 +17,8 @@ * - maxbufs must be at least 1 * - returns the number of interface records in the buffer */ -int afs_get_ipv4_interfaces(struct afs_interface *bufs, size_t maxbufs, - bool wantloopback) +int afs_get_ipv4_interfaces(struct afs_net *net, struct afs_interface *bufs, + size_t maxbufs, bool wantloopback) { struct net_device *dev; struct in_device *idev; @@ -27,7 +27,7 @@ int afs_get_ipv4_interfaces(struct afs_interface *bufs, size_t maxbufs, ASSERT(maxbufs > 0); rtnl_lock(); - for_each_netdev(&init_net, dev) { + for_each_netdev(net->net, dev) { if (dev->type == ARPHRD_LOOPBACK && !wantloopback) continue; idev = __in_dev_get_rtnl(dev); diff --git a/fs/afs/proc.c b/fs/afs/proc.c index 362f281b1b16..3512b9b66caf 100644 --- a/fs/afs/proc.c +++ b/fs/afs/proc.c @@ -17,14 +17,14 @@ #include #include "internal.h" -static inline struct afs_net *afs_proc2net(struct file *f) -{ - return &__afs_net; -} - static inline struct afs_net *afs_seq2net(struct seq_file *m) { - return &__afs_net; // TODO: use seq_file_net(m) + return afs_net(seq_file_net(m)); +} + +static inline struct afs_net *afs_seq2net_single(struct seq_file *m) +{ + return afs_net(seq_file_single_net(m)); } /* @@ -75,28 +75,20 @@ static const struct seq_operations afs_proc_cells_ops = { * handle writes to /proc/fs/afs/cells * - to add cells: echo "add [:][:]" */ -static ssize_t afs_proc_cells_write(struct file *file, const char __user *buf, - size_t size, loff_t *_pos) +static int afs_proc_cells_write(struct file *file, char *buf, size_t size) { - struct afs_net *net = afs_proc2net(file); - char *kbuf, *name, *args; + struct seq_file *m = file->private_data; + struct afs_net *net = afs_seq2net(m); + char *name, *args; int ret; - /* start by dragging the command into memory */ - if (size <= 1 || size >= PAGE_SIZE) - return -EINVAL; - - kbuf = memdup_user_nul(buf, size); - if (IS_ERR(kbuf)) - return PTR_ERR(kbuf); - /* trim to first NL */ - name = memchr(kbuf, '\n', size); + name = memchr(buf, '\n', size); if (name) *name = 0; /* split into command, name and argslist */ - name = strchr(kbuf, ' '); + name = strchr(buf, ' '); if (!name) goto inval; do { @@ -115,9 +107,9 @@ static ssize_t afs_proc_cells_write(struct file *file, const char __user *buf, goto inval; /* determine command to perform */ - _debug("cmd=%s name=%s args=%s", kbuf, name, args); + _debug("cmd=%s name=%s args=%s", buf, name, args); - if (strcmp(kbuf, "add") == 0) { + if (strcmp(buf, "add") == 0) { struct afs_cell *cell; cell = afs_lookup_cell(net, name, strlen(name), args, true); @@ -133,10 +125,9 @@ static ssize_t afs_proc_cells_write(struct file *file, const char __user *buf, goto inval; } - ret = size; + ret = 0; done: - kfree(kbuf); _leave(" = %d", ret); return ret; @@ -146,59 +137,23 @@ inval: goto done; } -static int afs_proc_cells_open(struct inode *inode, struct file *file) -{ - return seq_open(file, &afs_proc_cells_ops); -} - -static const struct file_operations afs_proc_cells_fops = { - .open = afs_proc_cells_open, - .read = seq_read, - .write = afs_proc_cells_write, - .llseek = seq_lseek, - .release = seq_release, -}; - /* - * Read the name of the current workstation cell. + * Display the name of the current workstation cell. */ -static ssize_t afs_proc_rootcell_read(struct file *file, char __user *buf, - size_t size, loff_t *_pos) +static int afs_proc_rootcell_show(struct seq_file *m, void *v) { struct afs_cell *cell; - struct afs_net *net = afs_proc2net(file); - unsigned int seq = 0; - char name[AFS_MAXCELLNAME + 1]; - int len; + struct afs_net *net; - if (*_pos > 0) - return 0; - if (!rcu_access_pointer(net->ws_cell)) - return 0; - - rcu_read_lock(); - do { - read_seqbegin_or_lock(&net->cells_lock, &seq); - len = 0; - cell = rcu_dereference_raw(net->ws_cell); - if (cell) { - len = cell->name_len; - memcpy(name, cell->name, len); - } - } while (need_seqretry(&net->cells_lock, seq)); - done_seqretry(&net->cells_lock, seq); - rcu_read_unlock(); - - if (!len) - return 0; - - name[len++] = '\n'; - if (len > size) - len = size; - if (copy_to_user(buf, name, len) != 0) - return -EFAULT; - *_pos = 1; - return len; + net = afs_seq2net_single(m); + if (rcu_access_pointer(net->ws_cell)) { + rcu_read_lock(); + cell = rcu_dereference(net->ws_cell); + if (cell) + seq_printf(m, "%s\n", cell->name); + rcu_read_unlock(); + } + return 0; } /* @@ -207,52 +162,34 @@ static ssize_t afs_proc_rootcell_read(struct file *file, char __user *buf, * * echo "cell.name:192.168.231.14" >/proc/fs/afs/rootcell */ -static ssize_t afs_proc_rootcell_write(struct file *file, - const char __user *buf, - size_t size, loff_t *_pos) +static int afs_proc_rootcell_write(struct file *file, char *buf, size_t size) { - struct afs_net *net = afs_proc2net(file); - char *kbuf, *s; + struct seq_file *m = file->private_data; + struct afs_net *net = afs_seq2net_single(m); + char *s; int ret; - /* start by dragging the command into memory */ - if (size <= 1 || size >= PAGE_SIZE) - return -EINVAL; - - kbuf = memdup_user_nul(buf, size); - if (IS_ERR(kbuf)) - return PTR_ERR(kbuf); - ret = -EINVAL; - if (kbuf[0] == '.') + if (buf[0] == '.') goto out; - if (memchr(kbuf, '/', size)) + if (memchr(buf, '/', size)) goto out; /* trim to first NL */ - s = memchr(kbuf, '\n', size); + s = memchr(buf, '\n', size); if (s) *s = 0; /* determine command to perform */ - _debug("rootcell=%s", kbuf); + _debug("rootcell=%s", buf); - ret = afs_cell_init(net, kbuf); - if (ret >= 0) - ret = size; /* consume everything, always */ + ret = afs_cell_init(net, buf); out: - kfree(kbuf); _leave(" = %d", ret); return ret; } -static const struct file_operations afs_proc_rootcell_fops = { - .read = afs_proc_rootcell_read, - .write = afs_proc_rootcell_write, - .llseek = no_llseek, -}; - static const char afs_vol_types[3][3] = { [AFSVL_RWVOL] = "RW", [AFSVL_ROVOL] = "RO", @@ -289,18 +226,18 @@ static void *afs_proc_cell_volumes_start(struct seq_file *m, loff_t *_pos) return seq_list_start_head(&cell->proc_volumes, *_pos); } -static void *afs_proc_cell_volumes_next(struct seq_file *p, void *v, +static void *afs_proc_cell_volumes_next(struct seq_file *m, void *v, loff_t *_pos) { - struct afs_cell *cell = PDE_DATA(file_inode(p->file)); + struct afs_cell *cell = PDE_DATA(file_inode(m->file)); return seq_list_next(v, &cell->proc_volumes, _pos); } -static void afs_proc_cell_volumes_stop(struct seq_file *p, void *v) +static void afs_proc_cell_volumes_stop(struct seq_file *m, void *v) __releases(cell->proc_lock) { - struct afs_cell *cell = PDE_DATA(file_inode(p->file)); + struct afs_cell *cell = PDE_DATA(file_inode(m->file)); read_unlock(&cell->proc_lock); } @@ -352,11 +289,11 @@ static void *afs_proc_cell_vlservers_start(struct seq_file *m, loff_t *_pos) return alist->addrs + pos; } -static void *afs_proc_cell_vlservers_next(struct seq_file *p, void *v, +static void *afs_proc_cell_vlservers_next(struct seq_file *m, void *v, loff_t *_pos) { struct afs_addr_list *alist; - struct afs_cell *cell = PDE_DATA(file_inode(p->file)); + struct afs_cell *cell = PDE_DATA(file_inode(m->file)); loff_t pos; alist = rcu_dereference(cell->vl_addrs); @@ -369,7 +306,7 @@ static void *afs_proc_cell_vlservers_next(struct seq_file *p, void *v, return alist->addrs + pos; } -static void afs_proc_cell_vlservers_stop(struct seq_file *p, void *v) +static void afs_proc_cell_vlservers_stop(struct seq_file *m, void *v) __releases(rcu) { rcu_read_unlock(); @@ -382,33 +319,6 @@ static const struct seq_operations afs_proc_cell_vlservers_ops = { .show = afs_proc_cell_vlservers_show, }; -static int afs_proc_cell_vlservers_open(struct inode *inode, struct file *file) -{ - struct afs_cell *cell; - struct seq_file *m; - int ret; - - cell = PDE_DATA(inode); - if (!cell) - return -ENOENT; - - ret = seq_open(file, &afs_proc_cell_vlservers_ops); - if (ret<0) - return ret; - - m = file->private_data; - m->private = cell; - - return 0; -} - -static const struct file_operations afs_proc_cell_vlservers_fops = { - .open = afs_proc_cell_vlservers_open, - .read = seq_read, - .llseek = seq_lseek, - .release = seq_release, -}; - /* * Display the list of fileservers we're using within a namespace. */ @@ -443,7 +353,7 @@ static void *afs_proc_servers_next(struct seq_file *m, void *v, loff_t *_pos) return seq_hlist_next_rcu(v, &afs_seq2net(m)->fs_proc, _pos); } -static void afs_proc_servers_stop(struct seq_file *p, void *v) +static void afs_proc_servers_stop(struct seq_file *m, void *v) __releases(rcu) { rcu_read_unlock(); @@ -456,18 +366,6 @@ static const struct seq_operations afs_proc_servers_ops = { .show = afs_proc_servers_show, }; -static int afs_proc_servers_open(struct inode *inode, struct file *file) -{ - return seq_open(file, &afs_proc_servers_ops); -} - -static const struct file_operations afs_proc_servers_fops = { - .open = afs_proc_servers_open, - .read = seq_read, - .llseek = seq_lseek, - .release = seq_release, -}; - /* * Display the list of strings that may be substituted for the @sys pathname * macro. @@ -487,10 +385,11 @@ static void *afs_proc_sysname_start(struct seq_file *m, loff_t *pos) __acquires(&net->sysnames_lock) { struct afs_net *net = afs_seq2net(m); - struct afs_sysnames *names = net->sysnames; + struct afs_sysnames *names; read_lock(&net->sysnames_lock); + names = net->sysnames; if (*pos >= names->nr) return NULL; return (void *)(unsigned long)(*pos + 1); @@ -525,35 +424,21 @@ static const struct seq_operations afs_proc_sysname_ops = { /* * Allow the @sys substitution to be configured. */ -static ssize_t afs_proc_sysname_write(struct file *file, - const char __user *buf, - size_t size, loff_t *_pos) +static int afs_proc_sysname_write(struct file *file, char *buf, size_t size) { - struct afs_sysnames *sysnames; + struct afs_sysnames *sysnames, *kill; struct seq_file *m = file->private_data; - char *kbuf = NULL, *s, *p, *sub; + struct afs_net *net = afs_seq2net(m); + char *s, *p, *sub; int ret, len; - sysnames = m->private; + sysnames = kzalloc(sizeof(*sysnames), GFP_KERNEL); if (!sysnames) - return -EINVAL; - if (sysnames->error) - return sysnames->error; + return -ENOMEM; + refcount_set(&sysnames->usage, 1); + kill = sysnames; - if (size >= PAGE_SIZE - 1) { - sysnames->error = -EINVAL; - return -EINVAL; - } - if (size == 0) - return 0; - - kbuf = memdup_user_nul(buf, size); - if (IS_ERR(kbuf)) - return PTR_ERR(kbuf); - - inode_lock(file_inode(file)); - - p = kbuf; + p = buf; while ((s = strsep(&p, " \t\n"))) { len = strlen(s); if (len == 0) @@ -594,16 +479,23 @@ static ssize_t afs_proc_sysname_write(struct file *file, sysnames->nr++; } - ret = size; /* consume everything, always */ + if (sysnames->nr == 0) { + sysnames->subs[0] = sysnames->blank; + sysnames->nr++; + } + + write_lock(&net->sysnames_lock); + kill = net->sysnames; + net->sysnames = sysnames; + write_unlock(&net->sysnames_lock); + ret = 0; out: - inode_unlock(file_inode(file)); - kfree(kbuf); + afs_put_sysnames(kill); return ret; invalid: ret = -EINVAL; error: - sysnames->error = ret; goto out; } @@ -619,75 +511,12 @@ void afs_put_sysnames(struct afs_sysnames *sysnames) } } -static int afs_proc_sysname_release(struct inode *inode, struct file *file) -{ - struct afs_sysnames *sysnames, *kill = NULL; - struct seq_file *m = file->private_data; - struct afs_net *net = afs_seq2net(m); - - sysnames = m->private; - if (sysnames) { - if (!sysnames->error) { - kill = sysnames; - if (sysnames->nr == 0) { - sysnames->subs[0] = sysnames->blank; - sysnames->nr++; - } - write_lock(&net->sysnames_lock); - kill = net->sysnames; - net->sysnames = sysnames; - write_unlock(&net->sysnames_lock); - } - afs_put_sysnames(kill); - } - - return seq_release(inode, file); -} - -/* - * Handle opening of /proc/fs/afs/sysname. If it is opened for writing, we - * assume the caller wants to change the substitution list and we allocate a - * buffer to hold the list. - */ -static int afs_proc_sysname_open(struct inode *inode, struct file *file) -{ - struct afs_sysnames *sysnames; - struct seq_file *m; - int ret; - - ret = seq_open(file, &afs_proc_sysname_ops); - if (ret < 0) - return ret; - - if (file->f_mode & FMODE_WRITE) { - sysnames = kzalloc(sizeof(*sysnames), GFP_KERNEL); - if (!sysnames) { - seq_release(inode, file); - return -ENOMEM; - } - - refcount_set(&sysnames->usage, 1); - m = file->private_data; - m->private = sysnames; - } - - return 0; -} - -static const struct file_operations afs_proc_sysname_fops = { - .open = afs_proc_sysname_open, - .read = seq_read, - .llseek = seq_lseek, - .release = afs_proc_sysname_release, - .write = afs_proc_sysname_write, -}; - /* * Display general per-net namespace statistics */ static int afs_proc_stats_show(struct seq_file *m, void *v) { - struct afs_net *net = afs_seq2net(m); + struct afs_net *net = afs_seq2net_single(m); seq_puts(m, "kAFS statistics\n"); @@ -716,21 +545,25 @@ static int afs_proc_stats_show(struct seq_file *m, void *v) /* * initialise /proc/fs/afs// */ -int afs_proc_cell_setup(struct afs_net *net, struct afs_cell *cell) +int afs_proc_cell_setup(struct afs_cell *cell) { struct proc_dir_entry *dir; + struct afs_net *net = cell->net; _enter("%p{%s},%p", cell, cell->name, net->proc_afs); - dir = proc_mkdir(cell->name, net->proc_afs); + dir = proc_net_mkdir(net->net, cell->name, net->proc_afs); if (!dir) goto error_dir; - if (!proc_create_seq_data("vlservers", 0, dir, - &afs_proc_cell_vlservers_ops, cell)) - goto error_tree; - if (!proc_create_seq_data("volumes", 0, dir, - &afs_proc_cell_volumes_ops, cell)) + if (!proc_create_net_data("vlservers", 0444, dir, + &afs_proc_cell_vlservers_ops, + sizeof(struct seq_net_private), + cell) || + !proc_create_net_data("volumes", 0444, dir, + &afs_proc_cell_volumes_ops, + sizeof(struct seq_net_private), + cell)) goto error_tree; _leave(" = 0"); @@ -746,12 +579,12 @@ error_dir: /* * remove /proc/fs/afs// */ -void afs_proc_cell_remove(struct afs_net *net, struct afs_cell *cell) +void afs_proc_cell_remove(struct afs_cell *cell) { + struct afs_net *net = cell->net; + _enter(""); - remove_proc_subtree(cell->name, net->proc_afs); - _leave(""); } @@ -760,24 +593,39 @@ void afs_proc_cell_remove(struct afs_net *net, struct afs_cell *cell) */ int afs_proc_init(struct afs_net *net) { + struct proc_dir_entry *p; + _enter(""); - net->proc_afs = proc_mkdir("fs/afs", NULL); - if (!net->proc_afs) + p = proc_net_mkdir(net->net, "afs", net->net->proc_net); + if (!p) goto error_dir; - if (!proc_create("cells", 0644, net->proc_afs, &afs_proc_cells_fops) || - !proc_create("rootcell", 0644, net->proc_afs, &afs_proc_rootcell_fops) || - !proc_create_seq("servers", 0644, net->proc_afs, &afs_proc_servers_ops) || - !proc_create_single("stats", 0644, net->proc_afs, afs_proc_stats_show) || - !proc_create("sysname", 0644, net->proc_afs, &afs_proc_sysname_fops)) + if (!proc_create_net_data_write("cells", 0644, p, + &afs_proc_cells_ops, + afs_proc_cells_write, + sizeof(struct seq_net_private), + NULL) || + !proc_create_net_single_write("rootcell", 0644, p, + afs_proc_rootcell_show, + afs_proc_rootcell_write, + NULL) || + !proc_create_net("servers", 0444, p, &afs_proc_servers_ops, + sizeof(struct seq_net_private)) || + !proc_create_net_single("stats", 0444, p, afs_proc_stats_show, NULL) || + !proc_create_net_data_write("sysname", 0644, p, + &afs_proc_sysname_ops, + afs_proc_sysname_write, + sizeof(struct seq_net_private), + NULL)) goto error_tree; + net->proc_afs = p; _leave(" = 0"); return 0; error_tree: - proc_remove(net->proc_afs); + proc_remove(p); error_dir: _leave(" = -ENOMEM"); return -ENOMEM; diff --git a/fs/afs/rxrpc.c b/fs/afs/rxrpc.c index 5c6263972ec9..e58fa0e15798 100644 --- a/fs/afs/rxrpc.c +++ b/fs/afs/rxrpc.c @@ -45,7 +45,7 @@ int afs_open_socket(struct afs_net *net) _enter(""); - ret = sock_create_kern(&init_net, AF_RXRPC, SOCK_DGRAM, PF_INET6, &socket); + ret = sock_create_kern(net->net, AF_RXRPC, SOCK_DGRAM, PF_INET6, &socket); if (ret < 0) goto error_1; diff --git a/fs/afs/super.c b/fs/afs/super.c index 65081ec3c36e..593820372848 100644 --- a/fs/afs/super.c +++ b/fs/afs/super.c @@ -48,6 +48,8 @@ struct file_system_type afs_fs_type = { }; MODULE_ALIAS_FS("afs"); +int afs_net_id; + static const struct super_operations afs_super_ops = { .statfs = afs_statfs, .alloc_inode = afs_alloc_inode, @@ -117,7 +119,7 @@ int __init afs_fs_init(void) /* * clean up the filesystem */ -void __exit afs_fs_exit(void) +void afs_fs_exit(void) { _enter(""); @@ -351,7 +353,7 @@ static int afs_test_super(struct super_block *sb, void *data) 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); } @@ -437,7 +439,7 @@ static struct afs_super_info *afs_alloc_sbi(struct afs_mount_params *params) 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 @@ -450,8 +452,8 @@ static void afs_destroy_sbi(struct afs_super_info *as) { 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); } } @@ -472,12 +474,13 @@ static struct dentry *afs_mount(struct file_system_type *fs_type, _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); @@ -571,7 +574,8 @@ static void afs_kill_super(struct super_block *sb) * deactivating the superblock. */ if (as->volume) - afs_clear_callback_interests(as->net, as->volume->servers); + afs_clear_callback_interests(afs_net(as->net_ns), + as->volume->servers); kill_anon_super(sb); if (as->volume) afs_deactivate_volume(as->volume);