aboutsummaryrefslogtreecommitdiffstats
path: root/fs/afs
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2018-06-16 03:32:04 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2018-06-16 03:32:04 -0400
commit35773c93817c5f2df264d013978e7551056a063a (patch)
tree5ca02a3f3c680091d5b1019b27ba23b5323a038a /fs/afs
parent29d6849d88b61edf130aef500acad78206bda3cd (diff)
parent47ea0f2ebffd400d36ab5946ec8d6d6e08a67d53 (diff)
Merge branch 'afs-proc' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull AFS updates from Al Viro: "Assorted AFS stuff - ended up in vfs.git since most of that consists of David's AFS-related followups to Christoph's procfs series" * 'afs-proc' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: afs: Optimise callback breaking by not repeating volume lookup afs: Display manually added cells in dynamic root mount afs: Enable IPv6 DNS lookups afs: Show all of a server's addresses in /proc/fs/afs/servers afs: Handle CONFIG_PROC_FS=n proc: Make inline name size calculation automatic afs: Implement network namespacing afs: Mark afs_net::ws_cell as __rcu and set using rcu functions afs: Fix a Sparse warning in xdr_decode_AFSFetchStatus() proc: Add a way to make network proc files writable afs: Rearrange fs/afs/proc.c to remove remaining predeclarations. afs: Rearrange fs/afs/proc.c to move the show routines up afs: Rearrange fs/afs/proc.c by moving fops and open functions down afs: Move /proc management functions to the end of the file
Diffstat (limited to 'fs/afs')
-rw-r--r--fs/afs/Makefile4
-rw-r--r--fs/afs/addr_list.c2
-rw-r--r--fs/afs/callback.c110
-rw-r--r--fs/afs/cell.c24
-rw-r--r--fs/afs/cmservice.c2
-rw-r--r--fs/afs/dynroot.c126
-rw-r--r--fs/afs/fsclient.c100
-rw-r--r--fs/afs/internal.h75
-rw-r--r--fs/afs/main.c35
-rw-r--r--fs/afs/netdevices.c6
-rw-r--r--fs/afs/proc.c793
-rw-r--r--fs/afs/rxrpc.c2
-rw-r--r--fs/afs/server.c2
-rw-r--r--fs/afs/super.c68
14 files changed, 716 insertions, 633 deletions
diff --git a/fs/afs/Makefile b/fs/afs/Makefile
index 532acae25453..546874057bd3 100644
--- a/fs/afs/Makefile
+++ b/fs/afs/Makefile
@@ -5,7 +5,7 @@
5 5
6afs-cache-$(CONFIG_AFS_FSCACHE) := cache.o 6afs-cache-$(CONFIG_AFS_FSCACHE) := cache.o
7 7
8kafs-objs := \ 8kafs-y := \
9 $(afs-cache-y) \ 9 $(afs-cache-y) \
10 addr_list.o \ 10 addr_list.o \
11 callback.o \ 11 callback.o \
@@ -21,7 +21,6 @@ kafs-objs := \
21 main.o \ 21 main.o \
22 misc.o \ 22 misc.o \
23 mntpt.o \ 23 mntpt.o \
24 proc.o \
25 rotate.o \ 24 rotate.o \
26 rxrpc.o \ 25 rxrpc.o \
27 security.o \ 26 security.o \
@@ -34,4 +33,5 @@ kafs-objs := \
34 write.o \ 33 write.o \
35 xattr.o 34 xattr.o
36 35
36kafs-$(CONFIG_PROC_FS) += proc.o
37obj-$(CONFIG_AFS_FS) := kafs.o 37obj-$(CONFIG_AFS_FS) := kafs.o
diff --git a/fs/afs/addr_list.c b/fs/afs/addr_list.c
index 2c46c46f3a6d..025a9a5e1c32 100644
--- a/fs/afs/addr_list.c
+++ b/fs/afs/addr_list.c
@@ -215,7 +215,7 @@ struct afs_addr_list *afs_dns_query(struct afs_cell *cell, time64_t *_expiry)
215 _enter("%s", cell->name); 215 _enter("%s", cell->name);
216 216
217 ret = dns_query("afsdb", cell->name, cell->name_len, 217 ret = dns_query("afsdb", cell->name, cell->name_len,
218 "ipv4", &vllist, _expiry); 218 "", &vllist, _expiry);
219 if (ret < 0) 219 if (ret < 0)
220 return ERR_PTR(ret); 220 return ERR_PTR(ret);
221 221
diff --git a/fs/afs/callback.c b/fs/afs/callback.c
index 571437dcb252..5f261fbf2182 100644
--- a/fs/afs/callback.c
+++ b/fs/afs/callback.c
@@ -21,6 +21,66 @@
21#include "internal.h" 21#include "internal.h"
22 22
23/* 23/*
24 * Create volume and callback interests on a server.
25 */
26static struct afs_cb_interest *afs_create_interest(struct afs_server *server,
27 struct afs_vnode *vnode)
28{
29 struct afs_vol_interest *new_vi, *vi;
30 struct afs_cb_interest *new;
31 struct hlist_node **pp;
32
33 new_vi = kzalloc(sizeof(struct afs_vol_interest), GFP_KERNEL);
34 if (!new_vi)
35 return NULL;
36
37 new = kzalloc(sizeof(struct afs_cb_interest), GFP_KERNEL);
38 if (!new) {
39 kfree(new_vi);
40 return NULL;
41 }
42
43 new_vi->usage = 1;
44 new_vi->vid = vnode->volume->vid;
45 INIT_HLIST_NODE(&new_vi->srv_link);
46 INIT_HLIST_HEAD(&new_vi->cb_interests);
47
48 refcount_set(&new->usage, 1);
49 new->sb = vnode->vfs_inode.i_sb;
50 new->vid = vnode->volume->vid;
51 new->server = afs_get_server(server);
52 INIT_HLIST_NODE(&new->cb_vlink);
53
54 write_lock(&server->cb_break_lock);
55
56 for (pp = &server->cb_volumes.first; *pp; pp = &(*pp)->next) {
57 vi = hlist_entry(*pp, struct afs_vol_interest, srv_link);
58 if (vi->vid < new_vi->vid)
59 continue;
60 if (vi->vid > new_vi->vid)
61 break;
62 vi->usage++;
63 goto found_vi;
64 }
65
66 new_vi->srv_link.pprev = pp;
67 new_vi->srv_link.next = *pp;
68 if (*pp)
69 (*pp)->pprev = &new_vi->srv_link.next;
70 *pp = &new_vi->srv_link;
71 vi = new_vi;
72 new_vi = NULL;
73found_vi:
74
75 new->vol_interest = vi;
76 hlist_add_head(&new->cb_vlink, &vi->cb_interests);
77
78 write_unlock(&server->cb_break_lock);
79 kfree(new_vi);
80 return new;
81}
82
83/*
24 * Set up an interest-in-callbacks record for a volume on a server and 84 * Set up an interest-in-callbacks record for a volume on a server and
25 * register it with the server. 85 * register it with the server.
26 * - Called with vnode->io_lock held. 86 * - Called with vnode->io_lock held.
@@ -77,20 +137,10 @@ again:
77 } 137 }
78 138
79 if (!cbi) { 139 if (!cbi) {
80 new = kzalloc(sizeof(struct afs_cb_interest), GFP_KERNEL); 140 new = afs_create_interest(server, vnode);
81 if (!new) 141 if (!new)
82 return -ENOMEM; 142 return -ENOMEM;
83 143
84 refcount_set(&new->usage, 1);
85 new->sb = vnode->vfs_inode.i_sb;
86 new->vid = vnode->volume->vid;
87 new->server = afs_get_server(server);
88 INIT_LIST_HEAD(&new->cb_link);
89
90 write_lock(&server->cb_break_lock);
91 list_add_tail(&new->cb_link, &server->cb_interests);
92 write_unlock(&server->cb_break_lock);
93
94 write_lock(&slist->lock); 144 write_lock(&slist->lock);
95 if (!entry->cb_interest) { 145 if (!entry->cb_interest) {
96 entry->cb_interest = afs_get_cb_interest(new); 146 entry->cb_interest = afs_get_cb_interest(new);
@@ -126,11 +176,22 @@ again:
126 */ 176 */
127void afs_put_cb_interest(struct afs_net *net, struct afs_cb_interest *cbi) 177void afs_put_cb_interest(struct afs_net *net, struct afs_cb_interest *cbi)
128{ 178{
179 struct afs_vol_interest *vi;
180
129 if (cbi && refcount_dec_and_test(&cbi->usage)) { 181 if (cbi && refcount_dec_and_test(&cbi->usage)) {
130 if (!list_empty(&cbi->cb_link)) { 182 if (!hlist_unhashed(&cbi->cb_vlink)) {
131 write_lock(&cbi->server->cb_break_lock); 183 write_lock(&cbi->server->cb_break_lock);
132 list_del_init(&cbi->cb_link); 184
185 hlist_del_init(&cbi->cb_vlink);
186 vi = cbi->vol_interest;
187 cbi->vol_interest = NULL;
188 if (--vi->usage == 0)
189 hlist_del(&vi->srv_link);
190 else
191 vi = NULL;
192
133 write_unlock(&cbi->server->cb_break_lock); 193 write_unlock(&cbi->server->cb_break_lock);
194 kfree(vi);
134 afs_put_server(net, cbi->server); 195 afs_put_server(net, cbi->server);
135 } 196 }
136 kfree(cbi); 197 kfree(cbi);
@@ -182,20 +243,34 @@ void afs_break_callback(struct afs_vnode *vnode)
182static void afs_break_one_callback(struct afs_server *server, 243static void afs_break_one_callback(struct afs_server *server,
183 struct afs_fid *fid) 244 struct afs_fid *fid)
184{ 245{
246 struct afs_vol_interest *vi;
185 struct afs_cb_interest *cbi; 247 struct afs_cb_interest *cbi;
186 struct afs_iget_data data; 248 struct afs_iget_data data;
187 struct afs_vnode *vnode; 249 struct afs_vnode *vnode;
188 struct inode *inode; 250 struct inode *inode;
189 251
190 read_lock(&server->cb_break_lock); 252 read_lock(&server->cb_break_lock);
253 hlist_for_each_entry(vi, &server->cb_volumes, srv_link) {
254 if (vi->vid < fid->vid)
255 continue;
256 if (vi->vid > fid->vid) {
257 vi = NULL;
258 break;
259 }
260 //atomic_inc(&vi->usage);
261 break;
262 }
263
264 /* TODO: Find all matching volumes if we couldn't match the server and
265 * break them anyway.
266 */
267 if (!vi)
268 goto out;
191 269
192 /* Step through all interested superblocks. There may be more than one 270 /* Step through all interested superblocks. There may be more than one
193 * because of cell aliasing. 271 * because of cell aliasing.
194 */ 272 */
195 list_for_each_entry(cbi, &server->cb_interests, cb_link) { 273 hlist_for_each_entry(cbi, &vi->cb_interests, cb_vlink) {
196 if (cbi->vid != fid->vid)
197 continue;
198
199 if (fid->vnode == 0 && fid->unique == 0) { 274 if (fid->vnode == 0 && fid->unique == 0) {
200 /* The callback break applies to an entire volume. */ 275 /* The callback break applies to an entire volume. */
201 struct afs_super_info *as = AFS_FS_S(cbi->sb); 276 struct afs_super_info *as = AFS_FS_S(cbi->sb);
@@ -217,6 +292,7 @@ static void afs_break_one_callback(struct afs_server *server,
217 } 292 }
218 } 293 }
219 294
295out:
220 read_unlock(&server->cb_break_lock); 296 read_unlock(&server->cb_break_lock);
221} 297}
222 298
diff --git a/fs/afs/cell.c b/fs/afs/cell.c
index fdf4c36cff79..f3d0bef16d78 100644
--- a/fs/afs/cell.c
+++ b/fs/afs/cell.c
@@ -15,6 +15,7 @@
15#include <linux/dns_resolver.h> 15#include <linux/dns_resolver.h>
16#include <linux/sched.h> 16#include <linux/sched.h>
17#include <linux/inet.h> 17#include <linux/inet.h>
18#include <linux/namei.h>
18#include <keys/rxrpc-type.h> 19#include <keys/rxrpc-type.h>
19#include "internal.h" 20#include "internal.h"
20 21
@@ -341,8 +342,8 @@ int afs_cell_init(struct afs_net *net, const char *rootcell)
341 342
342 /* install the new cell */ 343 /* install the new cell */
343 write_seqlock(&net->cells_lock); 344 write_seqlock(&net->cells_lock);
344 old_root = net->ws_cell; 345 old_root = rcu_access_pointer(net->ws_cell);
345 net->ws_cell = new_root; 346 rcu_assign_pointer(net->ws_cell, new_root);
346 write_sequnlock(&net->cells_lock); 347 write_sequnlock(&net->cells_lock);
347 348
348 afs_put_cell(net, old_root); 349 afs_put_cell(net, old_root);
@@ -528,12 +529,14 @@ static int afs_activate_cell(struct afs_net *net, struct afs_cell *cell)
528 NULL, 0, 529 NULL, 0,
529 cell, 0, true); 530 cell, 0, true);
530#endif 531#endif
531 ret = afs_proc_cell_setup(net, cell); 532 ret = afs_proc_cell_setup(cell);
532 if (ret < 0) 533 if (ret < 0)
533 return ret; 534 return ret;
534 spin_lock(&net->proc_cells_lock); 535
536 mutex_lock(&net->proc_cells_lock);
535 list_add_tail(&cell->proc_link, &net->proc_cells); 537 list_add_tail(&cell->proc_link, &net->proc_cells);
536 spin_unlock(&net->proc_cells_lock); 538 afs_dynroot_mkdir(net, cell);
539 mutex_unlock(&net->proc_cells_lock);
537 return 0; 540 return 0;
538} 541}
539 542
@@ -544,11 +547,12 @@ static void afs_deactivate_cell(struct afs_net *net, struct afs_cell *cell)
544{ 547{
545 _enter("%s", cell->name); 548 _enter("%s", cell->name);
546 549
547 afs_proc_cell_remove(net, cell); 550 afs_proc_cell_remove(cell);
548 551
549 spin_lock(&net->proc_cells_lock); 552 mutex_lock(&net->proc_cells_lock);
550 list_del_init(&cell->proc_link); 553 list_del_init(&cell->proc_link);
551 spin_unlock(&net->proc_cells_lock); 554 afs_dynroot_rmdir(net, cell);
555 mutex_unlock(&net->proc_cells_lock);
552 556
553#ifdef CONFIG_AFS_FSCACHE 557#ifdef CONFIG_AFS_FSCACHE
554 fscache_relinquish_cookie(cell->cache, NULL, false); 558 fscache_relinquish_cookie(cell->cache, NULL, false);
@@ -755,8 +759,8 @@ void afs_cell_purge(struct afs_net *net)
755 _enter(""); 759 _enter("");
756 760
757 write_seqlock(&net->cells_lock); 761 write_seqlock(&net->cells_lock);
758 ws = net->ws_cell; 762 ws = rcu_access_pointer(net->ws_cell);
759 net->ws_cell = NULL; 763 RCU_INIT_POINTER(net->ws_cell, NULL);
760 write_sequnlock(&net->cells_lock); 764 write_sequnlock(&net->cells_lock);
761 afs_put_cell(net, ws); 765 afs_put_cell(net, ws);
762 766
diff --git a/fs/afs/cmservice.c b/fs/afs/cmservice.c
index 238fd28cfdd2..9e51d6fe7e8f 100644
--- a/fs/afs/cmservice.c
+++ b/fs/afs/cmservice.c
@@ -526,7 +526,7 @@ static void SRXAFSCB_TellMeAboutYourself(struct work_struct *work)
526 nifs = 0; 526 nifs = 0;
527 ifs = kcalloc(32, sizeof(*ifs), GFP_KERNEL); 527 ifs = kcalloc(32, sizeof(*ifs), GFP_KERNEL);
528 if (ifs) { 528 if (ifs) {
529 nifs = afs_get_ipv4_interfaces(ifs, 32, false); 529 nifs = afs_get_ipv4_interfaces(call->net, ifs, 32, false);
530 if (nifs < 0) { 530 if (nifs < 0) {
531 kfree(ifs); 531 kfree(ifs);
532 ifs = NULL; 532 ifs = NULL;
diff --git a/fs/afs/dynroot.c b/fs/afs/dynroot.c
index 983f3946ab57..174e843f0633 100644
--- a/fs/afs/dynroot.c
+++ b/fs/afs/dynroot.c
@@ -1,4 +1,4 @@
1/* dir.c: AFS dynamic root handling 1/* AFS dynamic root handling
2 * 2 *
3 * Copyright (C) 2018 Red Hat, Inc. All Rights Reserved. 3 * Copyright (C) 2018 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com) 4 * Written by David Howells (dhowells@redhat.com)
@@ -46,7 +46,7 @@ static int afs_probe_cell_name(struct dentry *dentry)
46 return 0; 46 return 0;
47 } 47 }
48 48
49 ret = dns_query("afsdb", name, len, "ipv4", NULL, NULL); 49 ret = dns_query("afsdb", name, len, "", NULL, NULL);
50 if (ret == -ENODATA) 50 if (ret == -ENODATA)
51 ret = -EDESTADDRREQ; 51 ret = -EDESTADDRREQ;
52 return ret; 52 return ret;
@@ -207,3 +207,125 @@ const struct dentry_operations afs_dynroot_dentry_operations = {
207 .d_release = afs_d_release, 207 .d_release = afs_d_release,
208 .d_automount = afs_d_automount, 208 .d_automount = afs_d_automount,
209}; 209};
210
211/*
212 * Create a manually added cell mount directory.
213 * - The caller must hold net->proc_cells_lock
214 */
215int afs_dynroot_mkdir(struct afs_net *net, struct afs_cell *cell)
216{
217 struct super_block *sb = net->dynroot_sb;
218 struct dentry *root, *subdir;
219 int ret;
220
221 if (!sb || atomic_read(&sb->s_active) == 0)
222 return 0;
223
224 /* Let the ->lookup op do the creation */
225 root = sb->s_root;
226 inode_lock(root->d_inode);
227 subdir = lookup_one_len(cell->name, root, cell->name_len);
228 if (IS_ERR(subdir)) {
229 ret = PTR_ERR(subdir);
230 goto unlock;
231 }
232
233 /* Note that we're retaining an extra ref on the dentry */
234 subdir->d_fsdata = (void *)1UL;
235 ret = 0;
236unlock:
237 inode_unlock(root->d_inode);
238 return ret;
239}
240
241/*
242 * Remove a manually added cell mount directory.
243 * - The caller must hold net->proc_cells_lock
244 */
245void afs_dynroot_rmdir(struct afs_net *net, struct afs_cell *cell)
246{
247 struct super_block *sb = net->dynroot_sb;
248 struct dentry *root, *subdir;
249
250 if (!sb || atomic_read(&sb->s_active) == 0)
251 return;
252
253 root = sb->s_root;
254 inode_lock(root->d_inode);
255
256 /* Don't want to trigger a lookup call, which will re-add the cell */
257 subdir = try_lookup_one_len(cell->name, root, cell->name_len);
258 if (IS_ERR_OR_NULL(subdir)) {
259 _debug("lookup %ld", PTR_ERR(subdir));
260 goto no_dentry;
261 }
262
263 _debug("rmdir %pd %u", subdir, d_count(subdir));
264
265 if (subdir->d_fsdata) {
266 _debug("unpin %u", d_count(subdir));
267 subdir->d_fsdata = NULL;
268 dput(subdir);
269 }
270 dput(subdir);
271no_dentry:
272 inode_unlock(root->d_inode);
273 _leave("");
274}
275
276/*
277 * Populate a newly created dynamic root with cell names.
278 */
279int afs_dynroot_populate(struct super_block *sb)
280{
281 struct afs_cell *cell;
282 struct afs_net *net = afs_sb2net(sb);
283 int ret;
284
285 if (mutex_lock_interruptible(&net->proc_cells_lock) < 0)
286 return -ERESTARTSYS;
287
288 net->dynroot_sb = sb;
289 list_for_each_entry(cell, &net->proc_cells, proc_link) {
290 ret = afs_dynroot_mkdir(net, cell);
291 if (ret < 0)
292 goto error;
293 }
294
295 ret = 0;
296out:
297 mutex_unlock(&net->proc_cells_lock);
298 return ret;
299
300error:
301 net->dynroot_sb = NULL;
302 goto out;
303}
304
305/*
306 * When a dynamic root that's in the process of being destroyed, depopulate it
307 * of pinned directories.
308 */
309void afs_dynroot_depopulate(struct super_block *sb)
310{
311 struct afs_net *net = afs_sb2net(sb);
312 struct dentry *root = sb->s_root, *subdir, *tmp;
313
314 /* Prevent more subdirs from being created */
315 mutex_lock(&net->proc_cells_lock);
316 if (net->dynroot_sb == sb)
317 net->dynroot_sb = NULL;
318 mutex_unlock(&net->proc_cells_lock);
319
320 inode_lock(root->d_inode);
321
322 /* Remove all the pins for dirs created for manually added cells */
323 list_for_each_entry_safe(subdir, tmp, &root->d_subdirs, d_child) {
324 if (subdir->d_fsdata) {
325 subdir->d_fsdata = NULL;
326 dput(subdir);
327 }
328 }
329
330 inode_unlock(root->d_inode);
331}
diff --git a/fs/afs/fsclient.c b/fs/afs/fsclient.c
index 5907601aafd0..50929cb91732 100644
--- a/fs/afs/fsclient.c
+++ b/fs/afs/fsclient.c
@@ -138,10 +138,6 @@ static int xdr_decode_AFSFetchStatus(struct afs_call *call,
138 u64 data_version, size; 138 u64 data_version, size;
139 u32 type, abort_code; 139 u32 type, abort_code;
140 u8 flags = 0; 140 u8 flags = 0;
141 int ret;
142
143 if (vnode)
144 write_seqlock(&vnode->cb_lock);
145 141
146 abort_code = ntohl(xdr->abort_code); 142 abort_code = ntohl(xdr->abort_code);
147 143
@@ -154,8 +150,7 @@ static int xdr_decode_AFSFetchStatus(struct afs_call *call,
154 * case. 150 * case.
155 */ 151 */
156 status->abort_code = abort_code; 152 status->abort_code = abort_code;
157 ret = 0; 153 return 0;
158 goto out;
159 } 154 }
160 155
161 pr_warn("Unknown AFSFetchStatus version %u\n", ntohl(xdr->if_version)); 156 pr_warn("Unknown AFSFetchStatus version %u\n", ntohl(xdr->if_version));
@@ -164,8 +159,7 @@ static int xdr_decode_AFSFetchStatus(struct afs_call *call,
164 159
165 if (abort_code != 0 && inline_error) { 160 if (abort_code != 0 && inline_error) {
166 status->abort_code = abort_code; 161 status->abort_code = abort_code;
167 ret = 0; 162 return 0;
168 goto out;
169 } 163 }
170 164
171 type = ntohl(xdr->type); 165 type = ntohl(xdr->type);
@@ -235,17 +229,35 @@ static int xdr_decode_AFSFetchStatus(struct afs_call *call,
235 flags); 229 flags);
236 } 230 }
237 231
238 ret = 0; 232 return 0;
239
240out:
241 if (vnode)
242 write_sequnlock(&vnode->cb_lock);
243 return ret;
244 233
245bad: 234bad:
246 xdr_dump_bad(*_bp); 235 xdr_dump_bad(*_bp);
247 ret = afs_protocol_error(call, -EBADMSG); 236 return afs_protocol_error(call, -EBADMSG);
248 goto out; 237}
238
239/*
240 * Decode the file status. We need to lock the target vnode if we're going to
241 * update its status so that stat() sees the attributes update atomically.
242 */
243static int afs_decode_status(struct afs_call *call,
244 const __be32 **_bp,
245 struct afs_file_status *status,
246 struct afs_vnode *vnode,
247 const afs_dataversion_t *expected_version,
248 struct afs_read *read_req)
249{
250 int ret;
251
252 if (!vnode)
253 return xdr_decode_AFSFetchStatus(call, _bp, status, vnode,
254 expected_version, read_req);
255
256 write_seqlock(&vnode->cb_lock);
257 ret = xdr_decode_AFSFetchStatus(call, _bp, status, vnode,
258 expected_version, read_req);
259 write_sequnlock(&vnode->cb_lock);
260 return ret;
249} 261}
250 262
251/* 263/*
@@ -387,8 +399,8 @@ static int afs_deliver_fs_fetch_status_vnode(struct afs_call *call)
387 399
388 /* unmarshall the reply once we've received all of it */ 400 /* unmarshall the reply once we've received all of it */
389 bp = call->buffer; 401 bp = call->buffer;
390 if (xdr_decode_AFSFetchStatus(call, &bp, &vnode->status, vnode, 402 if (afs_decode_status(call, &bp, &vnode->status, vnode,
391 &call->expected_version, NULL) < 0) 403 &call->expected_version, NULL) < 0)
392 return afs_protocol_error(call, -EBADMSG); 404 return afs_protocol_error(call, -EBADMSG);
393 xdr_decode_AFSCallBack(call, vnode, &bp); 405 xdr_decode_AFSCallBack(call, vnode, &bp);
394 if (call->reply[1]) 406 if (call->reply[1])
@@ -568,8 +580,8 @@ static int afs_deliver_fs_fetch_data(struct afs_call *call)
568 return ret; 580 return ret;
569 581
570 bp = call->buffer; 582 bp = call->buffer;
571 if (xdr_decode_AFSFetchStatus(call, &bp, &vnode->status, vnode, 583 if (afs_decode_status(call, &bp, &vnode->status, vnode,
572 &vnode->status.data_version, req) < 0) 584 &vnode->status.data_version, req) < 0)
573 return afs_protocol_error(call, -EBADMSG); 585 return afs_protocol_error(call, -EBADMSG);
574 xdr_decode_AFSCallBack(call, vnode, &bp); 586 xdr_decode_AFSCallBack(call, vnode, &bp);
575 if (call->reply[1]) 587 if (call->reply[1])
@@ -721,9 +733,9 @@ static int afs_deliver_fs_create_vnode(struct afs_call *call)
721 /* unmarshall the reply once we've received all of it */ 733 /* unmarshall the reply once we've received all of it */
722 bp = call->buffer; 734 bp = call->buffer;
723 xdr_decode_AFSFid(&bp, call->reply[1]); 735 xdr_decode_AFSFid(&bp, call->reply[1]);
724 if (xdr_decode_AFSFetchStatus(call, &bp, call->reply[2], NULL, NULL, NULL) < 0 || 736 if (afs_decode_status(call, &bp, call->reply[2], NULL, NULL, NULL) < 0 ||
725 xdr_decode_AFSFetchStatus(call, &bp, &vnode->status, vnode, 737 afs_decode_status(call, &bp, &vnode->status, vnode,
726 &call->expected_version, NULL) < 0) 738 &call->expected_version, NULL) < 0)
727 return afs_protocol_error(call, -EBADMSG); 739 return afs_protocol_error(call, -EBADMSG);
728 xdr_decode_AFSCallBack_raw(&bp, call->reply[3]); 740 xdr_decode_AFSCallBack_raw(&bp, call->reply[3]);
729 /* xdr_decode_AFSVolSync(&bp, call->reply[X]); */ 741 /* xdr_decode_AFSVolSync(&bp, call->reply[X]); */
@@ -827,8 +839,8 @@ static int afs_deliver_fs_remove(struct afs_call *call)
827 839
828 /* unmarshall the reply once we've received all of it */ 840 /* unmarshall the reply once we've received all of it */
829 bp = call->buffer; 841 bp = call->buffer;
830 if (xdr_decode_AFSFetchStatus(call, &bp, &vnode->status, vnode, 842 if (afs_decode_status(call, &bp, &vnode->status, vnode,
831 &call->expected_version, NULL) < 0) 843 &call->expected_version, NULL) < 0)
832 return afs_protocol_error(call, -EBADMSG); 844 return afs_protocol_error(call, -EBADMSG);
833 /* xdr_decode_AFSVolSync(&bp, call->reply[X]); */ 845 /* xdr_decode_AFSVolSync(&bp, call->reply[X]); */
834 846
@@ -917,9 +929,9 @@ static int afs_deliver_fs_link(struct afs_call *call)
917 929
918 /* unmarshall the reply once we've received all of it */ 930 /* unmarshall the reply once we've received all of it */
919 bp = call->buffer; 931 bp = call->buffer;
920 if (xdr_decode_AFSFetchStatus(call, &bp, &vnode->status, vnode, NULL, NULL) < 0 || 932 if (afs_decode_status(call, &bp, &vnode->status, vnode, NULL, NULL) < 0 ||
921 xdr_decode_AFSFetchStatus(call, &bp, &dvnode->status, dvnode, 933 afs_decode_status(call, &bp, &dvnode->status, dvnode,
922 &call->expected_version, NULL) < 0) 934 &call->expected_version, NULL) < 0)
923 return afs_protocol_error(call, -EBADMSG); 935 return afs_protocol_error(call, -EBADMSG);
924 /* xdr_decode_AFSVolSync(&bp, call->reply[X]); */ 936 /* xdr_decode_AFSVolSync(&bp, call->reply[X]); */
925 937
@@ -1004,9 +1016,9 @@ static int afs_deliver_fs_symlink(struct afs_call *call)
1004 /* unmarshall the reply once we've received all of it */ 1016 /* unmarshall the reply once we've received all of it */
1005 bp = call->buffer; 1017 bp = call->buffer;
1006 xdr_decode_AFSFid(&bp, call->reply[1]); 1018 xdr_decode_AFSFid(&bp, call->reply[1]);
1007 if (xdr_decode_AFSFetchStatus(call, &bp, call->reply[2], NULL, NULL, NULL) || 1019 if (afs_decode_status(call, &bp, call->reply[2], NULL, NULL, NULL) ||
1008 xdr_decode_AFSFetchStatus(call, &bp, &vnode->status, vnode, 1020 afs_decode_status(call, &bp, &vnode->status, vnode,
1009 &call->expected_version, NULL) < 0) 1021 &call->expected_version, NULL) < 0)
1010 return afs_protocol_error(call, -EBADMSG); 1022 return afs_protocol_error(call, -EBADMSG);
1011 /* xdr_decode_AFSVolSync(&bp, call->reply[X]); */ 1023 /* xdr_decode_AFSVolSync(&bp, call->reply[X]); */
1012 1024
@@ -1110,12 +1122,12 @@ static int afs_deliver_fs_rename(struct afs_call *call)
1110 1122
1111 /* unmarshall the reply once we've received all of it */ 1123 /* unmarshall the reply once we've received all of it */
1112 bp = call->buffer; 1124 bp = call->buffer;
1113 if (xdr_decode_AFSFetchStatus(call, &bp, &orig_dvnode->status, orig_dvnode, 1125 if (afs_decode_status(call, &bp, &orig_dvnode->status, orig_dvnode,
1114 &call->expected_version, NULL) < 0) 1126 &call->expected_version, NULL) < 0)
1115 return afs_protocol_error(call, -EBADMSG); 1127 return afs_protocol_error(call, -EBADMSG);
1116 if (new_dvnode != orig_dvnode && 1128 if (new_dvnode != orig_dvnode &&
1117 xdr_decode_AFSFetchStatus(call, &bp, &new_dvnode->status, new_dvnode, 1129 afs_decode_status(call, &bp, &new_dvnode->status, new_dvnode,
1118 &call->expected_version_2, NULL) < 0) 1130 &call->expected_version_2, NULL) < 0)
1119 return afs_protocol_error(call, -EBADMSG); 1131 return afs_protocol_error(call, -EBADMSG);
1120 /* xdr_decode_AFSVolSync(&bp, call->reply[X]); */ 1132 /* xdr_decode_AFSVolSync(&bp, call->reply[X]); */
1121 1133
@@ -1219,8 +1231,8 @@ static int afs_deliver_fs_store_data(struct afs_call *call)
1219 1231
1220 /* unmarshall the reply once we've received all of it */ 1232 /* unmarshall the reply once we've received all of it */
1221 bp = call->buffer; 1233 bp = call->buffer;
1222 if (xdr_decode_AFSFetchStatus(call, &bp, &vnode->status, vnode, 1234 if (afs_decode_status(call, &bp, &vnode->status, vnode,
1223 &call->expected_version, NULL) < 0) 1235 &call->expected_version, NULL) < 0)
1224 return afs_protocol_error(call, -EBADMSG); 1236 return afs_protocol_error(call, -EBADMSG);
1225 /* xdr_decode_AFSVolSync(&bp, call->reply[X]); */ 1237 /* xdr_decode_AFSVolSync(&bp, call->reply[X]); */
1226 1238
@@ -1395,8 +1407,8 @@ static int afs_deliver_fs_store_status(struct afs_call *call)
1395 1407
1396 /* unmarshall the reply once we've received all of it */ 1408 /* unmarshall the reply once we've received all of it */
1397 bp = call->buffer; 1409 bp = call->buffer;
1398 if (xdr_decode_AFSFetchStatus(call, &bp, &vnode->status, vnode, 1410 if (afs_decode_status(call, &bp, &vnode->status, vnode,
1399 &call->expected_version, NULL) < 0) 1411 &call->expected_version, NULL) < 0)
1400 return afs_protocol_error(call, -EBADMSG); 1412 return afs_protocol_error(call, -EBADMSG);
1401 /* xdr_decode_AFSVolSync(&bp, call->reply[X]); */ 1413 /* xdr_decode_AFSVolSync(&bp, call->reply[X]); */
1402 1414
@@ -2097,8 +2109,8 @@ static int afs_deliver_fs_fetch_status(struct afs_call *call)
2097 2109
2098 /* unmarshall the reply once we've received all of it */ 2110 /* unmarshall the reply once we've received all of it */
2099 bp = call->buffer; 2111 bp = call->buffer;
2100 xdr_decode_AFSFetchStatus(call, &bp, status, vnode, 2112 afs_decode_status(call, &bp, status, vnode,
2101 &call->expected_version, NULL); 2113 &call->expected_version, NULL);
2102 callback[call->count].version = ntohl(bp[0]); 2114 callback[call->count].version = ntohl(bp[0]);
2103 callback[call->count].expiry = ntohl(bp[1]); 2115 callback[call->count].expiry = ntohl(bp[1]);
2104 callback[call->count].type = ntohl(bp[2]); 2116 callback[call->count].type = ntohl(bp[2]);
@@ -2209,9 +2221,9 @@ static int afs_deliver_fs_inline_bulk_status(struct afs_call *call)
2209 2221
2210 bp = call->buffer; 2222 bp = call->buffer;
2211 statuses = call->reply[1]; 2223 statuses = call->reply[1];
2212 if (xdr_decode_AFSFetchStatus(call, &bp, &statuses[call->count], 2224 if (afs_decode_status(call, &bp, &statuses[call->count],
2213 call->count == 0 ? vnode : NULL, 2225 call->count == 0 ? vnode : NULL,
2214 NULL, NULL) < 0) 2226 NULL, NULL) < 0)
2215 return afs_protocol_error(call, -EBADMSG); 2227 return afs_protocol_error(call, -EBADMSG);
2216 2228
2217 call->count++; 2229 call->count++;
diff --git a/fs/afs/internal.h b/fs/afs/internal.h
index e3f8a46663db..9778df135717 100644
--- a/fs/afs/internal.h
+++ b/fs/afs/internal.h
@@ -22,6 +22,8 @@
22#include <linux/backing-dev.h> 22#include <linux/backing-dev.h>
23#include <linux/uuid.h> 23#include <linux/uuid.h>
24#include <net/net_namespace.h> 24#include <net/net_namespace.h>
25#include <net/netns/generic.h>
26#include <net/sock.h>
25#include <net/af_rxrpc.h> 27#include <net/af_rxrpc.h>
26 28
27#include "afs.h" 29#include "afs.h"
@@ -40,7 +42,8 @@ struct afs_mount_params {
40 afs_voltype_t type; /* type of volume requested */ 42 afs_voltype_t type; /* type of volume requested */
41 int volnamesz; /* size of volume name */ 43 int volnamesz; /* size of volume name */
42 const char *volname; /* name of volume to mount */ 44 const char *volname; /* name of volume to mount */
43 struct afs_net *net; /* Network namespace in effect */ 45 struct net *net_ns; /* Network namespace in effect */
46 struct afs_net *net; /* the AFS net namespace stuff */
44 struct afs_cell *cell; /* cell in which to find volume */ 47 struct afs_cell *cell; /* cell in which to find volume */
45 struct afs_volume *volume; /* volume record */ 48 struct afs_volume *volume; /* volume record */
46 struct key *key; /* key to use for secure mounting */ 49 struct key *key; /* key to use for secure mounting */
@@ -189,7 +192,7 @@ struct afs_read {
189 * - there's one superblock per volume 192 * - there's one superblock per volume
190 */ 193 */
191struct afs_super_info { 194struct afs_super_info {
192 struct afs_net *net; /* Network namespace */ 195 struct net *net_ns; /* Network namespace */
193 struct afs_cell *cell; /* The cell in which the volume resides */ 196 struct afs_cell *cell; /* The cell in which the volume resides */
194 struct afs_volume *volume; /* volume record */ 197 struct afs_volume *volume; /* volume record */
195 bool dyn_root; /* True if dynamic root */ 198 bool dyn_root; /* True if dynamic root */
@@ -210,7 +213,6 @@ struct afs_sysnames {
210 char *subs[AFS_NR_SYSNAME]; 213 char *subs[AFS_NR_SYSNAME];
211 refcount_t usage; 214 refcount_t usage;
212 unsigned short nr; 215 unsigned short nr;
213 short error;
214 char blank[1]; 216 char blank[1];
215}; 217};
216 218
@@ -218,6 +220,7 @@ struct afs_sysnames {
218 * AFS network namespace record. 220 * AFS network namespace record.
219 */ 221 */
220struct afs_net { 222struct afs_net {
223 struct net *net; /* Backpointer to the owning net namespace */
221 struct afs_uuid uuid; 224 struct afs_uuid uuid;
222 bool live; /* F if this namespace is being removed */ 225 bool live; /* F if this namespace is being removed */
223 226
@@ -231,13 +234,13 @@ struct afs_net {
231 234
232 /* Cell database */ 235 /* Cell database */
233 struct rb_root cells; 236 struct rb_root cells;
234 struct afs_cell *ws_cell; 237 struct afs_cell __rcu *ws_cell;
235 struct work_struct cells_manager; 238 struct work_struct cells_manager;
236 struct timer_list cells_timer; 239 struct timer_list cells_timer;
237 atomic_t cells_outstanding; 240 atomic_t cells_outstanding;
238 seqlock_t cells_lock; 241 seqlock_t cells_lock;
239 242
240 spinlock_t proc_cells_lock; 243 struct mutex proc_cells_lock;
241 struct list_head proc_cells; 244 struct list_head proc_cells;
242 245
243 /* Known servers. Theoretically each fileserver can only be in one 246 /* Known servers. Theoretically each fileserver can only be in one
@@ -261,6 +264,7 @@ struct afs_net {
261 struct mutex lock_manager_mutex; 264 struct mutex lock_manager_mutex;
262 265
263 /* Misc */ 266 /* Misc */
267 struct super_block *dynroot_sb; /* Dynamic root mount superblock */
264 struct proc_dir_entry *proc_afs; /* /proc/net/afs directory */ 268 struct proc_dir_entry *proc_afs; /* /proc/net/afs directory */
265 struct afs_sysnames *sysnames; 269 struct afs_sysnames *sysnames;
266 rwlock_t sysnames_lock; 270 rwlock_t sysnames_lock;
@@ -280,7 +284,6 @@ struct afs_net {
280}; 284};
281 285
282extern const char afs_init_sysname[]; 286extern const char afs_init_sysname[];
283extern struct afs_net __afs_net;// Dummy AFS network namespace; TODO: replace with real netns
284 287
285enum afs_cell_state { 288enum afs_cell_state {
286 AFS_CELL_UNSET, 289 AFS_CELL_UNSET,
@@ -404,16 +407,27 @@ struct afs_server {
404 rwlock_t fs_lock; /* access lock */ 407 rwlock_t fs_lock; /* access lock */
405 408
406 /* callback promise management */ 409 /* callback promise management */
407 struct list_head cb_interests; /* List of superblocks using this server */ 410 struct hlist_head cb_volumes; /* List of volume interests on this server */
408 unsigned cb_s_break; /* Break-everything counter. */ 411 unsigned cb_s_break; /* Break-everything counter. */
409 rwlock_t cb_break_lock; /* Volume finding lock */ 412 rwlock_t cb_break_lock; /* Volume finding lock */
410}; 413};
411 414
412/* 415/*
416 * Volume collation in the server's callback interest list.
417 */
418struct afs_vol_interest {
419 struct hlist_node srv_link; /* Link in server->cb_volumes */
420 struct hlist_head cb_interests; /* List of callback interests on the server */
421 afs_volid_t vid; /* Volume ID to match */
422 unsigned int usage;
423};
424
425/*
413 * Interest by a superblock on a server. 426 * Interest by a superblock on a server.
414 */ 427 */
415struct afs_cb_interest { 428struct afs_cb_interest {
416 struct list_head cb_link; /* Link in server->cb_interests */ 429 struct hlist_node cb_vlink; /* Link in vol_interest->cb_interests */
430 struct afs_vol_interest *vol_interest;
417 struct afs_server *server; /* Server on which this interest resides */ 431 struct afs_server *server; /* Server on which this interest resides */
418 struct super_block *sb; /* Superblock on which inodes reside */ 432 struct super_block *sb; /* Superblock on which inodes reside */
419 afs_volid_t vid; /* Volume ID to match */ 433 afs_volid_t vid; /* Volume ID to match */
@@ -720,6 +734,10 @@ extern const struct inode_operations afs_dynroot_inode_operations;
720extern const struct dentry_operations afs_dynroot_dentry_operations; 734extern const struct dentry_operations afs_dynroot_dentry_operations;
721 735
722extern struct inode *afs_try_auto_mntpt(struct dentry *, struct inode *); 736extern struct inode *afs_try_auto_mntpt(struct dentry *, struct inode *);
737extern int afs_dynroot_mkdir(struct afs_net *, struct afs_cell *);
738extern void afs_dynroot_rmdir(struct afs_net *, struct afs_cell *);
739extern int afs_dynroot_populate(struct super_block *);
740extern void afs_dynroot_depopulate(struct super_block *);
723 741
724/* 742/*
725 * file.c 743 * file.c
@@ -806,34 +824,36 @@ extern int afs_drop_inode(struct inode *);
806 * main.c 824 * main.c
807 */ 825 */
808extern struct workqueue_struct *afs_wq; 826extern struct workqueue_struct *afs_wq;
827extern int afs_net_id;
809 828
810static inline struct afs_net *afs_d2net(struct dentry *dentry) 829static inline struct afs_net *afs_net(struct net *net)
811{ 830{
812 return &__afs_net; 831 return net_generic(net, afs_net_id);
813} 832}
814 833
815static inline struct afs_net *afs_i2net(struct inode *inode) 834static inline struct afs_net *afs_sb2net(struct super_block *sb)
816{ 835{
817 return &__afs_net; 836 return afs_net(AFS_FS_S(sb)->net_ns);
818} 837}
819 838
820static inline struct afs_net *afs_v2net(struct afs_vnode *vnode) 839static inline struct afs_net *afs_d2net(struct dentry *dentry)
821{ 840{
822 return &__afs_net; 841 return afs_sb2net(dentry->d_sb);
823} 842}
824 843
825static inline struct afs_net *afs_sock2net(struct sock *sk) 844static inline struct afs_net *afs_i2net(struct inode *inode)
826{ 845{
827 return &__afs_net; 846 return afs_sb2net(inode->i_sb);
828} 847}
829 848
830static inline struct afs_net *afs_get_net(struct afs_net *net) 849static inline struct afs_net *afs_v2net(struct afs_vnode *vnode)
831{ 850{
832 return net; 851 return afs_i2net(&vnode->vfs_inode);
833} 852}
834 853
835static inline void afs_put_net(struct afs_net *net) 854static inline struct afs_net *afs_sock2net(struct sock *sk)
836{ 855{
856 return net_generic(sock_net(sk), afs_net_id);
837} 857}
838 858
839static inline void __afs_stat(atomic_t *s) 859static inline void __afs_stat(atomic_t *s)
@@ -861,16 +881,25 @@ extern void afs_mntpt_kill_timer(void);
861/* 881/*
862 * netdevices.c 882 * netdevices.c
863 */ 883 */
864extern int afs_get_ipv4_interfaces(struct afs_interface *, size_t, bool); 884extern int afs_get_ipv4_interfaces(struct afs_net *, struct afs_interface *,
885 size_t, bool);
865 886
866/* 887/*
867 * proc.c 888 * proc.c
868 */ 889 */
890#ifdef CONFIG_PROC_FS
869extern int __net_init afs_proc_init(struct afs_net *); 891extern int __net_init afs_proc_init(struct afs_net *);
870extern void __net_exit afs_proc_cleanup(struct afs_net *); 892extern void __net_exit afs_proc_cleanup(struct afs_net *);
871extern int afs_proc_cell_setup(struct afs_net *, struct afs_cell *); 893extern int afs_proc_cell_setup(struct afs_cell *);
872extern void afs_proc_cell_remove(struct afs_net *, struct afs_cell *); 894extern void afs_proc_cell_remove(struct afs_cell *);
873extern void afs_put_sysnames(struct afs_sysnames *); 895extern void afs_put_sysnames(struct afs_sysnames *);
896#else
897static inline int afs_proc_init(struct afs_net *net) { return 0; }
898static inline void afs_proc_cleanup(struct afs_net *net) {}
899static inline int afs_proc_cell_setup(struct afs_cell *cell) { return 0; }
900static inline void afs_proc_cell_remove(struct afs_cell *cell) {}
901static inline void afs_put_sysnames(struct afs_sysnames *sysnames) {}
902#endif
874 903
875/* 904/*
876 * rotate.c 905 * rotate.c
@@ -1002,7 +1031,7 @@ extern bool afs_annotate_server_list(struct afs_server_list *, struct afs_server
1002 * super.c 1031 * super.c
1003 */ 1032 */
1004extern int __init afs_fs_init(void); 1033extern int __init afs_fs_init(void);
1005extern void __exit afs_fs_exit(void); 1034extern void afs_fs_exit(void);
1006 1035
1007/* 1036/*
1008 * vlclient.c 1037 * vlclient.c
diff --git a/fs/afs/main.c b/fs/afs/main.c
index d7560168b3bf..e84fe822a960 100644
--- a/fs/afs/main.c
+++ b/fs/afs/main.c
@@ -15,6 +15,7 @@
15#include <linux/completion.h> 15#include <linux/completion.h>
16#include <linux/sched.h> 16#include <linux/sched.h>
17#include <linux/random.h> 17#include <linux/random.h>
18#include <linux/proc_fs.h>
18#define CREATE_TRACE_POINTS 19#define CREATE_TRACE_POINTS
19#include "internal.h" 20#include "internal.h"
20 21
@@ -32,7 +33,7 @@ module_param(rootcell, charp, 0);
32MODULE_PARM_DESC(rootcell, "root AFS cell name and VL server IP addr list"); 33MODULE_PARM_DESC(rootcell, "root AFS cell name and VL server IP addr list");
33 34
34struct workqueue_struct *afs_wq; 35struct workqueue_struct *afs_wq;
35struct afs_net __afs_net; 36static struct proc_dir_entry *afs_proc_symlink;
36 37
37#if defined(CONFIG_ALPHA) 38#if defined(CONFIG_ALPHA)
38const char afs_init_sysname[] = "alpha_linux26"; 39const char afs_init_sysname[] = "alpha_linux26";
@@ -67,11 +68,13 @@ const char afs_init_sysname[] = "unknown_linux26";
67/* 68/*
68 * Initialise an AFS network namespace record. 69 * Initialise an AFS network namespace record.
69 */ 70 */
70static int __net_init afs_net_init(struct afs_net *net) 71static int __net_init afs_net_init(struct net *net_ns)
71{ 72{
72 struct afs_sysnames *sysnames; 73 struct afs_sysnames *sysnames;
74 struct afs_net *net = afs_net(net_ns);
73 int ret; 75 int ret;
74 76
77 net->net = net_ns;
75 net->live = true; 78 net->live = true;
76 generate_random_uuid((unsigned char *)&net->uuid); 79 generate_random_uuid((unsigned char *)&net->uuid);
77 80
@@ -83,7 +86,7 @@ static int __net_init afs_net_init(struct afs_net *net)
83 INIT_WORK(&net->cells_manager, afs_manage_cells); 86 INIT_WORK(&net->cells_manager, afs_manage_cells);
84 timer_setup(&net->cells_timer, afs_cells_timer, 0); 87 timer_setup(&net->cells_timer, afs_cells_timer, 0);
85 88
86 spin_lock_init(&net->proc_cells_lock); 89 mutex_init(&net->proc_cells_lock);
87 INIT_LIST_HEAD(&net->proc_cells); 90 INIT_LIST_HEAD(&net->proc_cells);
88 91
89 seqlock_init(&net->fs_lock); 92 seqlock_init(&net->fs_lock);
@@ -142,8 +145,10 @@ error_sysnames:
142/* 145/*
143 * Clean up and destroy an AFS network namespace record. 146 * Clean up and destroy an AFS network namespace record.
144 */ 147 */
145static void __net_exit afs_net_exit(struct afs_net *net) 148static void __net_exit afs_net_exit(struct net *net_ns)
146{ 149{
150 struct afs_net *net = afs_net(net_ns);
151
147 net->live = false; 152 net->live = false;
148 afs_cell_purge(net); 153 afs_cell_purge(net);
149 afs_purge_servers(net); 154 afs_purge_servers(net);
@@ -152,6 +157,13 @@ static void __net_exit afs_net_exit(struct afs_net *net)
152 afs_put_sysnames(net->sysnames); 157 afs_put_sysnames(net->sysnames);
153} 158}
154 159
160static struct pernet_operations afs_net_ops = {
161 .init = afs_net_init,
162 .exit = afs_net_exit,
163 .id = &afs_net_id,
164 .size = sizeof(struct afs_net),
165};
166
155/* 167/*
156 * initialise the AFS client FS module 168 * initialise the AFS client FS module
157 */ 169 */
@@ -178,7 +190,7 @@ static int __init afs_init(void)
178 goto error_cache; 190 goto error_cache;
179#endif 191#endif
180 192
181 ret = afs_net_init(&__afs_net); 193 ret = register_pernet_subsys(&afs_net_ops);
182 if (ret < 0) 194 if (ret < 0)
183 goto error_net; 195 goto error_net;
184 196
@@ -187,10 +199,18 @@ static int __init afs_init(void)
187 if (ret < 0) 199 if (ret < 0)
188 goto error_fs; 200 goto error_fs;
189 201
202 afs_proc_symlink = proc_symlink("fs/afs", NULL, "../self/net/afs");
203 if (IS_ERR(afs_proc_symlink)) {
204 ret = PTR_ERR(afs_proc_symlink);
205 goto error_proc;
206 }
207
190 return ret; 208 return ret;
191 209
210error_proc:
211 afs_fs_exit();
192error_fs: 212error_fs:
193 afs_net_exit(&__afs_net); 213 unregister_pernet_subsys(&afs_net_ops);
194error_net: 214error_net:
195#ifdef CONFIG_AFS_FSCACHE 215#ifdef CONFIG_AFS_FSCACHE
196 fscache_unregister_netfs(&afs_cache_netfs); 216 fscache_unregister_netfs(&afs_cache_netfs);
@@ -219,8 +239,9 @@ static void __exit afs_exit(void)
219{ 239{
220 printk(KERN_INFO "kAFS: Red Hat AFS client v0.1 unregistering.\n"); 240 printk(KERN_INFO "kAFS: Red Hat AFS client v0.1 unregistering.\n");
221 241
242 proc_remove(afs_proc_symlink);
222 afs_fs_exit(); 243 afs_fs_exit();
223 afs_net_exit(&__afs_net); 244 unregister_pernet_subsys(&afs_net_ops);
224#ifdef CONFIG_AFS_FSCACHE 245#ifdef CONFIG_AFS_FSCACHE
225 fscache_unregister_netfs(&afs_cache_netfs); 246 fscache_unregister_netfs(&afs_cache_netfs);
226#endif 247#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 @@
17 * - maxbufs must be at least 1 17 * - maxbufs must be at least 1
18 * - returns the number of interface records in the buffer 18 * - returns the number of interface records in the buffer
19 */ 19 */
20int afs_get_ipv4_interfaces(struct afs_interface *bufs, size_t maxbufs, 20int afs_get_ipv4_interfaces(struct afs_net *net, struct afs_interface *bufs,
21 bool wantloopback) 21 size_t maxbufs, bool wantloopback)
22{ 22{
23 struct net_device *dev; 23 struct net_device *dev;
24 struct in_device *idev; 24 struct in_device *idev;
@@ -27,7 +27,7 @@ int afs_get_ipv4_interfaces(struct afs_interface *bufs, size_t maxbufs,
27 ASSERT(maxbufs > 0); 27 ASSERT(maxbufs > 0);
28 28
29 rtnl_lock(); 29 rtnl_lock();
30 for_each_netdev(&init_net, dev) { 30 for_each_netdev(net->net, dev) {
31 if (dev->type == ARPHRD_LOOPBACK && !wantloopback) 31 if (dev->type == ARPHRD_LOOPBACK && !wantloopback)
32 continue; 32 continue;
33 idev = __in_dev_get_rtnl(dev); 33 idev = __in_dev_get_rtnl(dev);
diff --git a/fs/afs/proc.c b/fs/afs/proc.c
index 3aad32762989..0c3285c8db95 100644
--- a/fs/afs/proc.c
+++ b/fs/afs/proc.c
@@ -17,240 +17,78 @@
17#include <linux/uaccess.h> 17#include <linux/uaccess.h>
18#include "internal.h" 18#include "internal.h"
19 19
20static inline struct afs_net *afs_proc2net(struct file *f) 20static inline struct afs_net *afs_seq2net(struct seq_file *m)
21{ 21{
22 return &__afs_net; 22 return afs_net(seq_file_net(m));
23} 23}
24 24
25static inline struct afs_net *afs_seq2net(struct seq_file *m) 25static inline struct afs_net *afs_seq2net_single(struct seq_file *m)
26{ 26{
27 return &__afs_net; // TODO: use seq_file_net(m) 27 return afs_net(seq_file_single_net(m));
28} 28}
29 29
30static int afs_proc_cells_open(struct inode *inode, struct file *file);
31static void *afs_proc_cells_start(struct seq_file *p, loff_t *pos);
32static void *afs_proc_cells_next(struct seq_file *p, void *v, loff_t *pos);
33static void afs_proc_cells_stop(struct seq_file *p, void *v);
34static int afs_proc_cells_show(struct seq_file *m, void *v);
35static ssize_t afs_proc_cells_write(struct file *file, const char __user *buf,
36 size_t size, loff_t *_pos);
37
38static const struct seq_operations afs_proc_cells_ops = {
39 .start = afs_proc_cells_start,
40 .next = afs_proc_cells_next,
41 .stop = afs_proc_cells_stop,
42 .show = afs_proc_cells_show,
43};
44
45static const struct file_operations afs_proc_cells_fops = {
46 .open = afs_proc_cells_open,
47 .read = seq_read,
48 .write = afs_proc_cells_write,
49 .llseek = seq_lseek,
50 .release = seq_release,
51};
52
53static ssize_t afs_proc_rootcell_read(struct file *file, char __user *buf,
54 size_t size, loff_t *_pos);
55static ssize_t afs_proc_rootcell_write(struct file *file,
56 const char __user *buf,
57 size_t size, loff_t *_pos);
58
59static const struct file_operations afs_proc_rootcell_fops = {
60 .read = afs_proc_rootcell_read,
61 .write = afs_proc_rootcell_write,
62 .llseek = no_llseek,
63};
64
65static void *afs_proc_cell_volumes_start(struct seq_file *p, loff_t *pos);
66static void *afs_proc_cell_volumes_next(struct seq_file *p, void *v,
67 loff_t *pos);
68static void afs_proc_cell_volumes_stop(struct seq_file *p, void *v);
69static int afs_proc_cell_volumes_show(struct seq_file *m, void *v);
70
71static const struct seq_operations afs_proc_cell_volumes_ops = {
72 .start = afs_proc_cell_volumes_start,
73 .next = afs_proc_cell_volumes_next,
74 .stop = afs_proc_cell_volumes_stop,
75 .show = afs_proc_cell_volumes_show,
76};
77
78static void *afs_proc_cell_vlservers_start(struct seq_file *p, loff_t *pos);
79static void *afs_proc_cell_vlservers_next(struct seq_file *p, void *v,
80 loff_t *pos);
81static void afs_proc_cell_vlservers_stop(struct seq_file *p, void *v);
82static int afs_proc_cell_vlservers_show(struct seq_file *m, void *v);
83
84static const struct seq_operations afs_proc_cell_vlservers_ops = {
85 .start = afs_proc_cell_vlservers_start,
86 .next = afs_proc_cell_vlservers_next,
87 .stop = afs_proc_cell_vlservers_stop,
88 .show = afs_proc_cell_vlservers_show,
89};
90
91static void *afs_proc_servers_start(struct seq_file *p, loff_t *pos);
92static void *afs_proc_servers_next(struct seq_file *p, void *v,
93 loff_t *pos);
94static void afs_proc_servers_stop(struct seq_file *p, void *v);
95static int afs_proc_servers_show(struct seq_file *m, void *v);
96
97static const struct seq_operations afs_proc_servers_ops = {
98 .start = afs_proc_servers_start,
99 .next = afs_proc_servers_next,
100 .stop = afs_proc_servers_stop,
101 .show = afs_proc_servers_show,
102};
103
104static int afs_proc_sysname_open(struct inode *inode, struct file *file);
105static int afs_proc_sysname_release(struct inode *inode, struct file *file);
106static void *afs_proc_sysname_start(struct seq_file *p, loff_t *pos);
107static void *afs_proc_sysname_next(struct seq_file *p, void *v,
108 loff_t *pos);
109static void afs_proc_sysname_stop(struct seq_file *p, void *v);
110static int afs_proc_sysname_show(struct seq_file *m, void *v);
111static ssize_t afs_proc_sysname_write(struct file *file,
112 const char __user *buf,
113 size_t size, loff_t *_pos);
114
115static const struct seq_operations afs_proc_sysname_ops = {
116 .start = afs_proc_sysname_start,
117 .next = afs_proc_sysname_next,
118 .stop = afs_proc_sysname_stop,
119 .show = afs_proc_sysname_show,
120};
121
122static const struct file_operations afs_proc_sysname_fops = {
123 .open = afs_proc_sysname_open,
124 .read = seq_read,
125 .llseek = seq_lseek,
126 .release = afs_proc_sysname_release,
127 .write = afs_proc_sysname_write,
128};
129
130static int afs_proc_stats_show(struct seq_file *m, void *v);
131
132/* 30/*
133 * initialise the /proc/fs/afs/ directory 31 * Display the list of cells known to the namespace.
134 */ 32 */
135int afs_proc_init(struct afs_net *net) 33static int afs_proc_cells_show(struct seq_file *m, void *v)
136{ 34{
137 _enter(""); 35 struct afs_cell *cell = list_entry(v, struct afs_cell, proc_link);
138 36 struct afs_net *net = afs_seq2net(m);
139 net->proc_afs = proc_mkdir("fs/afs", NULL);
140 if (!net->proc_afs)
141 goto error_dir;
142 37
143 if (!proc_create("cells", 0644, net->proc_afs, &afs_proc_cells_fops) || 38 if (v == &net->proc_cells) {
144 !proc_create("rootcell", 0644, net->proc_afs, &afs_proc_rootcell_fops) || 39 /* display header on line 1 */
145 !proc_create_seq("servers", 0644, net->proc_afs, &afs_proc_servers_ops) || 40 seq_puts(m, "USE NAME\n");
146 !proc_create_single("stats", 0644, net->proc_afs, afs_proc_stats_show) || 41 return 0;
147 !proc_create("sysname", 0644, net->proc_afs, &afs_proc_sysname_fops)) 42 }
148 goto error_tree;
149 43
150 _leave(" = 0"); 44 /* display one cell per line on subsequent lines */
45 seq_printf(m, "%3u %s\n", atomic_read(&cell->usage), cell->name);
151 return 0; 46 return 0;
152
153error_tree:
154 proc_remove(net->proc_afs);
155error_dir:
156 _leave(" = -ENOMEM");
157 return -ENOMEM;
158}
159
160/*
161 * clean up the /proc/fs/afs/ directory
162 */
163void afs_proc_cleanup(struct afs_net *net)
164{
165 proc_remove(net->proc_afs);
166 net->proc_afs = NULL;
167}
168
169/*
170 * open "/proc/fs/afs/cells" which provides a summary of extant cells
171 */
172static int afs_proc_cells_open(struct inode *inode, struct file *file)
173{
174 return seq_open(file, &afs_proc_cells_ops);
175} 47}
176 48
177/*
178 * set up the iterator to start reading from the cells list and return the
179 * first item
180 */
181static void *afs_proc_cells_start(struct seq_file *m, loff_t *_pos) 49static void *afs_proc_cells_start(struct seq_file *m, loff_t *_pos)
182 __acquires(rcu) 50 __acquires(rcu)
183{ 51{
184 struct afs_net *net = afs_seq2net(m);
185
186 rcu_read_lock(); 52 rcu_read_lock();
187 return seq_list_start_head(&net->proc_cells, *_pos); 53 return seq_list_start_head(&afs_seq2net(m)->proc_cells, *_pos);
188} 54}
189 55
190/*
191 * move to next cell in cells list
192 */
193static void *afs_proc_cells_next(struct seq_file *m, void *v, loff_t *pos) 56static void *afs_proc_cells_next(struct seq_file *m, void *v, loff_t *pos)
194{ 57{
195 struct afs_net *net = afs_seq2net(m); 58 return seq_list_next(v, &afs_seq2net(m)->proc_cells, pos);
196
197 return seq_list_next(v, &net->proc_cells, pos);
198} 59}
199 60
200/*
201 * clean up after reading from the cells list
202 */
203static void afs_proc_cells_stop(struct seq_file *m, void *v) 61static void afs_proc_cells_stop(struct seq_file *m, void *v)
204 __releases(rcu) 62 __releases(rcu)
205{ 63{
206 rcu_read_unlock(); 64 rcu_read_unlock();
207} 65}
208 66
209/* 67static const struct seq_operations afs_proc_cells_ops = {
210 * display a header line followed by a load of cell lines 68 .start = afs_proc_cells_start,
211 */ 69 .next = afs_proc_cells_next,
212static int afs_proc_cells_show(struct seq_file *m, void *v) 70 .stop = afs_proc_cells_stop,
213{ 71 .show = afs_proc_cells_show,
214 struct afs_cell *cell = list_entry(v, struct afs_cell, proc_link); 72};
215 struct afs_net *net = afs_seq2net(m);
216
217 if (v == &net->proc_cells) {
218 /* display header on line 1 */
219 seq_puts(m, "USE NAME\n");
220 return 0;
221 }
222
223 /* display one cell per line on subsequent lines */
224 seq_printf(m, "%3u %s\n", atomic_read(&cell->usage), cell->name);
225 return 0;
226}
227 73
228/* 74/*
229 * handle writes to /proc/fs/afs/cells 75 * handle writes to /proc/fs/afs/cells
230 * - to add cells: echo "add <cellname> <IP>[:<IP>][:<IP>]" 76 * - to add cells: echo "add <cellname> <IP>[:<IP>][:<IP>]"
231 */ 77 */
232static ssize_t afs_proc_cells_write(struct file *file, const char __user *buf, 78static int afs_proc_cells_write(struct file *file, char *buf, size_t size)
233 size_t size, loff_t *_pos)
234{ 79{
235 struct afs_net *net = afs_proc2net(file); 80 struct seq_file *m = file->private_data;
236 char *kbuf, *name, *args; 81 struct afs_net *net = afs_seq2net(m);
82 char *name, *args;
237 int ret; 83 int ret;
238 84
239 /* start by dragging the command into memory */
240 if (size <= 1 || size >= PAGE_SIZE)
241 return -EINVAL;
242
243 kbuf = memdup_user_nul(buf, size);
244 if (IS_ERR(kbuf))
245 return PTR_ERR(kbuf);
246
247 /* trim to first NL */ 85 /* trim to first NL */
248 name = memchr(kbuf, '\n', size); 86 name = memchr(buf, '\n', size);
249 if (name) 87 if (name)
250 *name = 0; 88 *name = 0;
251 89
252 /* split into command, name and argslist */ 90 /* split into command, name and argslist */
253 name = strchr(kbuf, ' '); 91 name = strchr(buf, ' ');
254 if (!name) 92 if (!name)
255 goto inval; 93 goto inval;
256 do { 94 do {
@@ -269,9 +107,9 @@ static ssize_t afs_proc_cells_write(struct file *file, const char __user *buf,
269 goto inval; 107 goto inval;
270 108
271 /* determine command to perform */ 109 /* determine command to perform */
272 _debug("cmd=%s name=%s args=%s", kbuf, name, args); 110 _debug("cmd=%s name=%s args=%s", buf, name, args);
273 111
274 if (strcmp(kbuf, "add") == 0) { 112 if (strcmp(buf, "add") == 0) {
275 struct afs_cell *cell; 113 struct afs_cell *cell;
276 114
277 cell = afs_lookup_cell(net, name, strlen(name), args, true); 115 cell = afs_lookup_cell(net, name, strlen(name), args, true);
@@ -287,10 +125,9 @@ static ssize_t afs_proc_cells_write(struct file *file, const char __user *buf,
287 goto inval; 125 goto inval;
288 } 126 }
289 127
290 ret = size; 128 ret = 0;
291 129
292done: 130done:
293 kfree(kbuf);
294 _leave(" = %d", ret); 131 _leave(" = %d", ret);
295 return ret; 132 return ret;
296 133
@@ -300,200 +137,136 @@ inval:
300 goto done; 137 goto done;
301} 138}
302 139
303static ssize_t afs_proc_rootcell_read(struct file *file, char __user *buf, 140/*
304 size_t size, loff_t *_pos) 141 * Display the name of the current workstation cell.
142 */
143static int afs_proc_rootcell_show(struct seq_file *m, void *v)
305{ 144{
306 struct afs_cell *cell; 145 struct afs_cell *cell;
307 struct afs_net *net = afs_proc2net(file); 146 struct afs_net *net;
308 unsigned int seq = 0; 147
309 char name[AFS_MAXCELLNAME + 1]; 148 net = afs_seq2net_single(m);
310 int len; 149 if (rcu_access_pointer(net->ws_cell)) {
311 150 rcu_read_lock();
312 if (*_pos > 0) 151 cell = rcu_dereference(net->ws_cell);
313 return 0; 152 if (cell)
314 if (!net->ws_cell) 153 seq_printf(m, "%s\n", cell->name);
315 return 0; 154 rcu_read_unlock();
316 155 }
317 rcu_read_lock(); 156 return 0;
318 do {
319 read_seqbegin_or_lock(&net->cells_lock, &seq);
320 len = 0;
321 cell = rcu_dereference_raw(net->ws_cell);
322 if (cell) {
323 len = cell->name_len;
324 memcpy(name, cell->name, len);
325 }
326 } while (need_seqretry(&net->cells_lock, seq));
327 done_seqretry(&net->cells_lock, seq);
328 rcu_read_unlock();
329
330 if (!len)
331 return 0;
332
333 name[len++] = '\n';
334 if (len > size)
335 len = size;
336 if (copy_to_user(buf, name, len) != 0)
337 return -EFAULT;
338 *_pos = 1;
339 return len;
340} 157}
341 158
342/* 159/*
343 * handle writes to /proc/fs/afs/rootcell 160 * Set the current workstation cell and optionally supply its list of volume
344 * - to initialize rootcell: echo "cell.name:192.168.231.14" 161 * location servers.
162 *
163 * echo "cell.name:192.168.231.14" >/proc/fs/afs/rootcell
345 */ 164 */
346static ssize_t afs_proc_rootcell_write(struct file *file, 165static int afs_proc_rootcell_write(struct file *file, char *buf, size_t size)
347 const char __user *buf,
348 size_t size, loff_t *_pos)
349{ 166{
350 struct afs_net *net = afs_proc2net(file); 167 struct seq_file *m = file->private_data;
351 char *kbuf, *s; 168 struct afs_net *net = afs_seq2net_single(m);
169 char *s;
352 int ret; 170 int ret;
353 171
354 /* start by dragging the command into memory */
355 if (size <= 1 || size >= PAGE_SIZE)
356 return -EINVAL;
357
358 kbuf = memdup_user_nul(buf, size);
359 if (IS_ERR(kbuf))
360 return PTR_ERR(kbuf);
361
362 ret = -EINVAL; 172 ret = -EINVAL;
363 if (kbuf[0] == '.') 173 if (buf[0] == '.')
364 goto out; 174 goto out;
365 if (memchr(kbuf, '/', size)) 175 if (memchr(buf, '/', size))
366 goto out; 176 goto out;
367 177
368 /* trim to first NL */ 178 /* trim to first NL */
369 s = memchr(kbuf, '\n', size); 179 s = memchr(buf, '\n', size);
370 if (s) 180 if (s)
371 *s = 0; 181 *s = 0;
372 182
373 /* determine command to perform */ 183 /* determine command to perform */
374 _debug("rootcell=%s", kbuf); 184 _debug("rootcell=%s", buf);
375 185
376 ret = afs_cell_init(net, kbuf); 186 ret = afs_cell_init(net, buf);
377 if (ret >= 0)
378 ret = size; /* consume everything, always */
379 187
380out: 188out:
381 kfree(kbuf);
382 _leave(" = %d", ret); 189 _leave(" = %d", ret);
383 return ret; 190 return ret;
384} 191}
385 192
193static const char afs_vol_types[3][3] = {
194 [AFSVL_RWVOL] = "RW",
195 [AFSVL_ROVOL] = "RO",
196 [AFSVL_BACKVOL] = "BK",
197};
198
386/* 199/*
387 * initialise /proc/fs/afs/<cell>/ 200 * Display the list of volumes known to a cell.
388 */ 201 */
389int afs_proc_cell_setup(struct afs_net *net, struct afs_cell *cell) 202static int afs_proc_cell_volumes_show(struct seq_file *m, void *v)
390{ 203{
391 struct proc_dir_entry *dir; 204 struct afs_cell *cell = PDE_DATA(file_inode(m->file));
392 205 struct afs_volume *vol = list_entry(v, struct afs_volume, proc_link);
393 _enter("%p{%s},%p", cell, cell->name, net->proc_afs);
394 206
395 dir = proc_mkdir(cell->name, net->proc_afs); 207 /* Display header on line 1 */
396 if (!dir) 208 if (v == &cell->proc_volumes) {
397 goto error_dir; 209 seq_puts(m, "USE VID TY\n");
210 return 0;
211 }
398 212
399 if (!proc_create_seq_data("vlservers", 0, dir, 213 seq_printf(m, "%3d %08x %s\n",
400 &afs_proc_cell_vlservers_ops, cell)) 214 atomic_read(&vol->usage), vol->vid,
401 goto error_tree; 215 afs_vol_types[vol->type]);
402 if (!proc_create_seq_data("volumes", 0, dir, &afs_proc_cell_volumes_ops,
403 cell))
404 goto error_tree;
405 216
406 _leave(" = 0");
407 return 0; 217 return 0;
408
409error_tree:
410 remove_proc_subtree(cell->name, net->proc_afs);
411error_dir:
412 _leave(" = -ENOMEM");
413 return -ENOMEM;
414} 218}
415 219
416/*
417 * remove /proc/fs/afs/<cell>/
418 */
419void afs_proc_cell_remove(struct afs_net *net, struct afs_cell *cell)
420{
421 _enter("");
422
423 remove_proc_subtree(cell->name, net->proc_afs);
424
425 _leave("");
426}
427
428/*
429 * set up the iterator to start reading from the cells list and return the
430 * first item
431 */
432static void *afs_proc_cell_volumes_start(struct seq_file *m, loff_t *_pos) 220static void *afs_proc_cell_volumes_start(struct seq_file *m, loff_t *_pos)
433 __acquires(cell->proc_lock) 221 __acquires(cell->proc_lock)
434{ 222{
435 struct afs_cell *cell = PDE_DATA(file_inode(m->file)); 223 struct afs_cell *cell = PDE_DATA(file_inode(m->file));
436 224
437 _enter("cell=%p pos=%Ld", cell, *_pos);
438
439 read_lock(&cell->proc_lock); 225 read_lock(&cell->proc_lock);
440 return seq_list_start_head(&cell->proc_volumes, *_pos); 226 return seq_list_start_head(&cell->proc_volumes, *_pos);
441} 227}
442 228
443/* 229static void *afs_proc_cell_volumes_next(struct seq_file *m, void *v,
444 * move to next cell in cells list
445 */
446static void *afs_proc_cell_volumes_next(struct seq_file *p, void *v,
447 loff_t *_pos) 230 loff_t *_pos)
448{ 231{
449 struct afs_cell *cell = PDE_DATA(file_inode(p->file)); 232 struct afs_cell *cell = PDE_DATA(file_inode(m->file));
450 233
451 _enter("cell=%p pos=%Ld", cell, *_pos);
452 return seq_list_next(v, &cell->proc_volumes, _pos); 234 return seq_list_next(v, &cell->proc_volumes, _pos);
453} 235}
454 236
455/* 237static void afs_proc_cell_volumes_stop(struct seq_file *m, void *v)
456 * clean up after reading from the cells list
457 */
458static void afs_proc_cell_volumes_stop(struct seq_file *p, void *v)
459 __releases(cell->proc_lock) 238 __releases(cell->proc_lock)
460{ 239{
461 struct afs_cell *cell = PDE_DATA(file_inode(p->file)); 240 struct afs_cell *cell = PDE_DATA(file_inode(m->file));
462 241
463 read_unlock(&cell->proc_lock); 242 read_unlock(&cell->proc_lock);
464} 243}
465 244
466static const char afs_vol_types[3][3] = { 245static const struct seq_operations afs_proc_cell_volumes_ops = {
467 [AFSVL_RWVOL] = "RW", 246 .start = afs_proc_cell_volumes_start,
468 [AFSVL_ROVOL] = "RO", 247 .next = afs_proc_cell_volumes_next,
469 [AFSVL_BACKVOL] = "BK", 248 .stop = afs_proc_cell_volumes_stop,
249 .show = afs_proc_cell_volumes_show,
470}; 250};
471 251
472/* 252/*
473 * display a header line followed by a load of volume lines 253 * Display the list of Volume Location servers we're using for a cell.
474 */ 254 */
475static int afs_proc_cell_volumes_show(struct seq_file *m, void *v) 255static int afs_proc_cell_vlservers_show(struct seq_file *m, void *v)
476{ 256{
477 struct afs_cell *cell = PDE_DATA(file_inode(m->file)); 257 struct sockaddr_rxrpc *addr = v;
478 struct afs_volume *vol = list_entry(v, struct afs_volume, proc_link);
479 258
480 /* Display header on line 1 */ 259 /* display header on line 1 */
481 if (v == &cell->proc_volumes) { 260 if (v == (void *)1) {
482 seq_puts(m, "USE VID TY\n"); 261 seq_puts(m, "ADDRESS\n");
483 return 0; 262 return 0;
484 } 263 }
485 264
486 seq_printf(m, "%3d %08x %s\n", 265 /* display one cell per line on subsequent lines */
487 atomic_read(&vol->usage), vol->vid, 266 seq_printf(m, "%pISp\n", &addr->transport);
488 afs_vol_types[vol->type]);
489
490 return 0; 267 return 0;
491} 268}
492 269
493/*
494 * set up the iterator to start reading from the cells list and return the
495 * first item
496 */
497static void *afs_proc_cell_vlservers_start(struct seq_file *m, loff_t *_pos) 270static void *afs_proc_cell_vlservers_start(struct seq_file *m, loff_t *_pos)
498 __acquires(rcu) 271 __acquires(rcu)
499{ 272{
@@ -516,14 +289,11 @@ static void *afs_proc_cell_vlservers_start(struct seq_file *m, loff_t *_pos)
516 return alist->addrs + pos; 289 return alist->addrs + pos;
517} 290}
518 291
519/* 292static void *afs_proc_cell_vlservers_next(struct seq_file *m, void *v,
520 * move to next cell in cells list
521 */
522static void *afs_proc_cell_vlservers_next(struct seq_file *p, void *v,
523 loff_t *_pos) 293 loff_t *_pos)
524{ 294{
525 struct afs_addr_list *alist; 295 struct afs_addr_list *alist;
526 struct afs_cell *cell = PDE_DATA(file_inode(p->file)); 296 struct afs_cell *cell = PDE_DATA(file_inode(m->file));
527 loff_t pos; 297 loff_t pos;
528 298
529 alist = rcu_dereference(cell->vl_addrs); 299 alist = rcu_dereference(cell->vl_addrs);
@@ -536,161 +306,145 @@ static void *afs_proc_cell_vlservers_next(struct seq_file *p, void *v,
536 return alist->addrs + pos; 306 return alist->addrs + pos;
537} 307}
538 308
539/* 309static void afs_proc_cell_vlservers_stop(struct seq_file *m, void *v)
540 * clean up after reading from the cells list
541 */
542static void afs_proc_cell_vlservers_stop(struct seq_file *p, void *v)
543 __releases(rcu) 310 __releases(rcu)
544{ 311{
545 rcu_read_unlock(); 312 rcu_read_unlock();
546} 313}
547 314
315static const struct seq_operations afs_proc_cell_vlservers_ops = {
316 .start = afs_proc_cell_vlservers_start,
317 .next = afs_proc_cell_vlservers_next,
318 .stop = afs_proc_cell_vlservers_stop,
319 .show = afs_proc_cell_vlservers_show,
320};
321
548/* 322/*
549 * display a header line followed by a load of volume lines 323 * Display the list of fileservers we're using within a namespace.
550 */ 324 */
551static int afs_proc_cell_vlservers_show(struct seq_file *m, void *v) 325static int afs_proc_servers_show(struct seq_file *m, void *v)
552{ 326{
553 struct sockaddr_rxrpc *addr = v; 327 struct afs_server *server;
328 struct afs_addr_list *alist;
329 int i;
554 330
555 /* display header on line 1 */ 331 if (v == SEQ_START_TOKEN) {
556 if (v == (void *)1) { 332 seq_puts(m, "UUID USE ADDR\n");
557 seq_puts(m, "ADDRESS\n");
558 return 0; 333 return 0;
559 } 334 }
560 335
561 /* display one cell per line on subsequent lines */ 336 server = list_entry(v, struct afs_server, proc_link);
562 seq_printf(m, "%pISp\n", &addr->transport); 337 alist = rcu_dereference(server->addresses);
338 seq_printf(m, "%pU %3d %pISpc%s\n",
339 &server->uuid,
340 atomic_read(&server->usage),
341 &alist->addrs[0].transport,
342 alist->index == 0 ? "*" : "");
343 for (i = 1; i < alist->nr_addrs; i++)
344 seq_printf(m, " %pISpc%s\n",
345 &alist->addrs[i].transport,
346 alist->index == i ? "*" : "");
563 return 0; 347 return 0;
564} 348}
565 349
566/*
567 * Set up the iterator to start reading from the server list and return the
568 * first item.
569 */
570static void *afs_proc_servers_start(struct seq_file *m, loff_t *_pos) 350static void *afs_proc_servers_start(struct seq_file *m, loff_t *_pos)
571 __acquires(rcu) 351 __acquires(rcu)
572{ 352{
573 struct afs_net *net = afs_seq2net(m);
574
575 rcu_read_lock(); 353 rcu_read_lock();
576 return seq_hlist_start_head_rcu(&net->fs_proc, *_pos); 354 return seq_hlist_start_head_rcu(&afs_seq2net(m)->fs_proc, *_pos);
577} 355}
578 356
579/*
580 * move to next cell in cells list
581 */
582static void *afs_proc_servers_next(struct seq_file *m, void *v, loff_t *_pos) 357static void *afs_proc_servers_next(struct seq_file *m, void *v, loff_t *_pos)
583{ 358{
584 struct afs_net *net = afs_seq2net(m); 359 return seq_hlist_next_rcu(v, &afs_seq2net(m)->fs_proc, _pos);
585
586 return seq_hlist_next_rcu(v, &net->fs_proc, _pos);
587} 360}
588 361
589/* 362static void afs_proc_servers_stop(struct seq_file *m, void *v)
590 * clean up after reading from the cells list
591 */
592static void afs_proc_servers_stop(struct seq_file *p, void *v)
593 __releases(rcu) 363 __releases(rcu)
594{ 364{
595 rcu_read_unlock(); 365 rcu_read_unlock();
596} 366}
597 367
368static const struct seq_operations afs_proc_servers_ops = {
369 .start = afs_proc_servers_start,
370 .next = afs_proc_servers_next,
371 .stop = afs_proc_servers_stop,
372 .show = afs_proc_servers_show,
373};
374
598/* 375/*
599 * display a header line followed by a load of volume lines 376 * Display the list of strings that may be substituted for the @sys pathname
377 * macro.
600 */ 378 */
601static int afs_proc_servers_show(struct seq_file *m, void *v) 379static int afs_proc_sysname_show(struct seq_file *m, void *v)
602{ 380{
603 struct afs_server *server; 381 struct afs_net *net = afs_seq2net(m);
604 struct afs_addr_list *alist; 382 struct afs_sysnames *sysnames = net->sysnames;
605 383 unsigned int i = (unsigned long)v - 1;
606 if (v == SEQ_START_TOKEN) {
607 seq_puts(m, "UUID USE ADDR\n");
608 return 0;
609 }
610 384
611 server = list_entry(v, struct afs_server, proc_link); 385 if (i < sysnames->nr)
612 alist = rcu_dereference(server->addresses); 386 seq_printf(m, "%s\n", sysnames->subs[i]);
613 seq_printf(m, "%pU %3d %pISp\n",
614 &server->uuid,
615 atomic_read(&server->usage),
616 &alist->addrs[alist->index].transport);
617 return 0; 387 return 0;
618} 388}
619 389
620void afs_put_sysnames(struct afs_sysnames *sysnames) 390static void *afs_proc_sysname_start(struct seq_file *m, loff_t *pos)
391 __acquires(&net->sysnames_lock)
621{ 392{
622 int i; 393 struct afs_net *net = afs_seq2net(m);
394 struct afs_sysnames *names;
623 395
624 if (sysnames && refcount_dec_and_test(&sysnames->usage)) { 396 read_lock(&net->sysnames_lock);
625 for (i = 0; i < sysnames->nr; i++) 397
626 if (sysnames->subs[i] != afs_init_sysname && 398 names = net->sysnames;
627 sysnames->subs[i] != sysnames->blank) 399 if (*pos >= names->nr)
628 kfree(sysnames->subs[i]); 400 return NULL;
629 } 401 return (void *)(unsigned long)(*pos + 1);
630} 402}
631 403
632/* 404static void *afs_proc_sysname_next(struct seq_file *m, void *v, loff_t *pos)
633 * Handle opening of /proc/fs/afs/sysname. If it is opened for writing, we
634 * assume the caller wants to change the substitution list and we allocate a
635 * buffer to hold the list.
636 */
637static int afs_proc_sysname_open(struct inode *inode, struct file *file)
638{ 405{
639 struct afs_sysnames *sysnames; 406 struct afs_net *net = afs_seq2net(m);
640 struct seq_file *m; 407 struct afs_sysnames *names = net->sysnames;
641 int ret;
642
643 ret = seq_open(file, &afs_proc_sysname_ops);
644 if (ret < 0)
645 return ret;
646 408
647 if (file->f_mode & FMODE_WRITE) { 409 *pos += 1;
648 sysnames = kzalloc(sizeof(*sysnames), GFP_KERNEL); 410 if (*pos >= names->nr)
649 if (!sysnames) { 411 return NULL;
650 seq_release(inode, file); 412 return (void *)(unsigned long)(*pos + 1);
651 return -ENOMEM; 413}
652 }
653 414
654 refcount_set(&sysnames->usage, 1); 415static void afs_proc_sysname_stop(struct seq_file *m, void *v)
655 m = file->private_data; 416 __releases(&net->sysnames_lock)
656 m->private = sysnames; 417{
657 } 418 struct afs_net *net = afs_seq2net(m);
658 419
659 return 0; 420 read_unlock(&net->sysnames_lock);
660} 421}
661 422
423static const struct seq_operations afs_proc_sysname_ops = {
424 .start = afs_proc_sysname_start,
425 .next = afs_proc_sysname_next,
426 .stop = afs_proc_sysname_stop,
427 .show = afs_proc_sysname_show,
428};
429
662/* 430/*
663 * Handle writes to /proc/fs/afs/sysname to set the @sys substitution. 431 * Allow the @sys substitution to be configured.
664 */ 432 */
665static ssize_t afs_proc_sysname_write(struct file *file, 433static int afs_proc_sysname_write(struct file *file, char *buf, size_t size)
666 const char __user *buf,
667 size_t size, loff_t *_pos)
668{ 434{
669 struct afs_sysnames *sysnames; 435 struct afs_sysnames *sysnames, *kill;
670 struct seq_file *m = file->private_data; 436 struct seq_file *m = file->private_data;
671 char *kbuf = NULL, *s, *p, *sub; 437 struct afs_net *net = afs_seq2net(m);
438 char *s, *p, *sub;
672 int ret, len; 439 int ret, len;
673 440
674 sysnames = m->private; 441 sysnames = kzalloc(sizeof(*sysnames), GFP_KERNEL);
675 if (!sysnames) 442 if (!sysnames)
676 return -EINVAL; 443 return -ENOMEM;
677 if (sysnames->error) 444 refcount_set(&sysnames->usage, 1);
678 return sysnames->error; 445 kill = sysnames;
679
680 if (size >= PAGE_SIZE - 1) {
681 sysnames->error = -EINVAL;
682 return -EINVAL;
683 }
684 if (size == 0)
685 return 0;
686
687 kbuf = memdup_user_nul(buf, size);
688 if (IS_ERR(kbuf))
689 return PTR_ERR(kbuf);
690
691 inode_lock(file_inode(file));
692 446
693 p = kbuf; 447 p = buf;
694 while ((s = strsep(&p, " \t\n"))) { 448 while ((s = strsep(&p, " \t\n"))) {
695 len = strlen(s); 449 len = strlen(s);
696 if (len == 0) 450 if (len == 0)
@@ -731,85 +485,36 @@ static ssize_t afs_proc_sysname_write(struct file *file,
731 sysnames->nr++; 485 sysnames->nr++;
732 } 486 }
733 487
734 ret = size; /* consume everything, always */ 488 if (sysnames->nr == 0) {
489 sysnames->subs[0] = sysnames->blank;
490 sysnames->nr++;
491 }
492
493 write_lock(&net->sysnames_lock);
494 kill = net->sysnames;
495 net->sysnames = sysnames;
496 write_unlock(&net->sysnames_lock);
497 ret = 0;
735out: 498out:
736 inode_unlock(file_inode(file)); 499 afs_put_sysnames(kill);
737 kfree(kbuf);
738 return ret; 500 return ret;
739 501
740invalid: 502invalid:
741 ret = -EINVAL; 503 ret = -EINVAL;
742error: 504error:
743 sysnames->error = ret;
744 goto out; 505 goto out;
745} 506}
746 507
747static int afs_proc_sysname_release(struct inode *inode, struct file *file) 508void afs_put_sysnames(struct afs_sysnames *sysnames)
748{ 509{
749 struct afs_sysnames *sysnames, *kill = NULL; 510 int i;
750 struct seq_file *m = file->private_data;
751 struct afs_net *net = afs_seq2net(m);
752 511
753 sysnames = m->private; 512 if (sysnames && refcount_dec_and_test(&sysnames->usage)) {
754 if (sysnames) { 513 for (i = 0; i < sysnames->nr; i++)
755 if (!sysnames->error) { 514 if (sysnames->subs[i] != afs_init_sysname &&
756 kill = sysnames; 515 sysnames->subs[i] != sysnames->blank)
757 if (sysnames->nr == 0) { 516 kfree(sysnames->subs[i]);
758 sysnames->subs[0] = sysnames->blank;
759 sysnames->nr++;
760 }
761 write_lock(&net->sysnames_lock);
762 kill = net->sysnames;
763 net->sysnames = sysnames;
764 write_unlock(&net->sysnames_lock);
765 }
766 afs_put_sysnames(kill);
767 } 517 }
768
769 return seq_release(inode, file);
770}
771
772static void *afs_proc_sysname_start(struct seq_file *m, loff_t *pos)
773 __acquires(&net->sysnames_lock)
774{
775 struct afs_net *net = afs_seq2net(m);
776 struct afs_sysnames *names = net->sysnames;
777
778 read_lock(&net->sysnames_lock);
779
780 if (*pos >= names->nr)
781 return NULL;
782 return (void *)(unsigned long)(*pos + 1);
783}
784
785static void *afs_proc_sysname_next(struct seq_file *m, void *v, loff_t *pos)
786{
787 struct afs_net *net = afs_seq2net(m);
788 struct afs_sysnames *names = net->sysnames;
789
790 *pos += 1;
791 if (*pos >= names->nr)
792 return NULL;
793 return (void *)(unsigned long)(*pos + 1);
794}
795
796static void afs_proc_sysname_stop(struct seq_file *m, void *v)
797 __releases(&net->sysnames_lock)
798{
799 struct afs_net *net = afs_seq2net(m);
800
801 read_unlock(&net->sysnames_lock);
802}
803
804static int afs_proc_sysname_show(struct seq_file *m, void *v)
805{
806 struct afs_net *net = afs_seq2net(m);
807 struct afs_sysnames *sysnames = net->sysnames;
808 unsigned int i = (unsigned long)v - 1;
809
810 if (i < sysnames->nr)
811 seq_printf(m, "%s\n", sysnames->subs[i]);
812 return 0;
813} 518}
814 519
815/* 520/*
@@ -817,7 +522,7 @@ static int afs_proc_sysname_show(struct seq_file *m, void *v)
817 */ 522 */
818static int afs_proc_stats_show(struct seq_file *m, void *v) 523static int afs_proc_stats_show(struct seq_file *m, void *v)
819{ 524{
820 struct afs_net *net = afs_seq2net(m); 525 struct afs_net *net = afs_seq2net_single(m);
821 526
822 seq_puts(m, "kAFS statistics\n"); 527 seq_puts(m, "kAFS statistics\n");
823 528
@@ -842,3 +547,101 @@ static int afs_proc_stats_show(struct seq_file *m, void *v)
842 atomic_long_read(&net->n_store_bytes)); 547 atomic_long_read(&net->n_store_bytes));
843 return 0; 548 return 0;
844} 549}
550
551/*
552 * initialise /proc/fs/afs/<cell>/
553 */
554int afs_proc_cell_setup(struct afs_cell *cell)
555{
556 struct proc_dir_entry *dir;
557 struct afs_net *net = cell->net;
558
559 _enter("%p{%s},%p", cell, cell->name, net->proc_afs);
560
561 dir = proc_net_mkdir(net->net, cell->name, net->proc_afs);
562 if (!dir)
563 goto error_dir;
564
565 if (!proc_create_net_data("vlservers", 0444, dir,
566 &afs_proc_cell_vlservers_ops,
567 sizeof(struct seq_net_private),
568 cell) ||
569 !proc_create_net_data("volumes", 0444, dir,
570 &afs_proc_cell_volumes_ops,
571 sizeof(struct seq_net_private),
572 cell))
573 goto error_tree;
574
575 _leave(" = 0");
576 return 0;
577
578error_tree:
579 remove_proc_subtree(cell->name, net->proc_afs);
580error_dir:
581 _leave(" = -ENOMEM");
582 return -ENOMEM;
583}
584
585/*
586 * remove /proc/fs/afs/<cell>/
587 */
588void afs_proc_cell_remove(struct afs_cell *cell)
589{
590 struct afs_net *net = cell->net;
591
592 _enter("");
593 remove_proc_subtree(cell->name, net->proc_afs);
594 _leave("");
595}
596
597/*
598 * initialise the /proc/fs/afs/ directory
599 */
600int afs_proc_init(struct afs_net *net)
601{
602 struct proc_dir_entry *p;
603
604 _enter("");
605
606 p = proc_net_mkdir(net->net, "afs", net->net->proc_net);
607 if (!p)
608 goto error_dir;
609
610 if (!proc_create_net_data_write("cells", 0644, p,
611 &afs_proc_cells_ops,
612 afs_proc_cells_write,
613 sizeof(struct seq_net_private),
614 NULL) ||
615 !proc_create_net_single_write("rootcell", 0644, p,
616 afs_proc_rootcell_show,
617 afs_proc_rootcell_write,
618 NULL) ||
619 !proc_create_net("servers", 0444, p, &afs_proc_servers_ops,
620 sizeof(struct seq_net_private)) ||
621 !proc_create_net_single("stats", 0444, p, afs_proc_stats_show, NULL) ||
622 !proc_create_net_data_write("sysname", 0644, p,
623 &afs_proc_sysname_ops,
624 afs_proc_sysname_write,
625 sizeof(struct seq_net_private),
626 NULL))
627 goto error_tree;
628
629 net->proc_afs = p;
630 _leave(" = 0");
631 return 0;
632
633error_tree:
634 proc_remove(p);
635error_dir:
636 _leave(" = -ENOMEM");
637 return -ENOMEM;
638}
639
640/*
641 * clean up the /proc/fs/afs/ directory
642 */
643void afs_proc_cleanup(struct afs_net *net)
644{
645 proc_remove(net->proc_afs);
646 net->proc_afs = NULL;
647}
diff --git a/fs/afs/rxrpc.c b/fs/afs/rxrpc.c
index 08735948f15d..a1b18082991b 100644
--- a/fs/afs/rxrpc.c
+++ b/fs/afs/rxrpc.c
@@ -46,7 +46,7 @@ int afs_open_socket(struct afs_net *net)
46 46
47 _enter(""); 47 _enter("");
48 48
49 ret = sock_create_kern(&init_net, AF_RXRPC, SOCK_DGRAM, PF_INET6, &socket); 49 ret = sock_create_kern(net->net, AF_RXRPC, SOCK_DGRAM, PF_INET6, &socket);
50 if (ret < 0) 50 if (ret < 0)
51 goto error_1; 51 goto error_1;
52 52
diff --git a/fs/afs/server.c b/fs/afs/server.c
index 3af4625e2f8c..1d329e6981d5 100644
--- a/fs/afs/server.c
+++ b/fs/afs/server.c
@@ -228,7 +228,7 @@ static struct afs_server *afs_alloc_server(struct afs_net *net,
228 server->flags = (1UL << AFS_SERVER_FL_NEW); 228 server->flags = (1UL << AFS_SERVER_FL_NEW);
229 server->update_at = ktime_get_real_seconds() + afs_server_update_delay; 229 server->update_at = ktime_get_real_seconds() + afs_server_update_delay;
230 rwlock_init(&server->fs_lock); 230 rwlock_init(&server->fs_lock);
231 INIT_LIST_HEAD(&server->cb_interests); 231 INIT_HLIST_HEAD(&server->cb_volumes);
232 rwlock_init(&server->cb_break_lock); 232 rwlock_init(&server->cb_break_lock);
233 233
234 afs_inc_servers_outstanding(net); 234 afs_inc_servers_outstanding(net);
diff --git a/fs/afs/super.c b/fs/afs/super.c
index 9e5d7966621c..4d3e274207fb 100644
--- a/fs/afs/super.c
+++ b/fs/afs/super.c
@@ -48,6 +48,8 @@ struct file_system_type afs_fs_type = {
48}; 48};
49MODULE_ALIAS_FS("afs"); 49MODULE_ALIAS_FS("afs");
50 50
51int afs_net_id;
52
51static const struct super_operations afs_super_ops = { 53static const struct super_operations afs_super_ops = {
52 .statfs = afs_statfs, 54 .statfs = afs_statfs,
53 .alloc_inode = afs_alloc_inode, 55 .alloc_inode = afs_alloc_inode,
@@ -117,7 +119,7 @@ int __init afs_fs_init(void)
117/* 119/*
118 * clean up the filesystem 120 * clean up the filesystem
119 */ 121 */
120void __exit afs_fs_exit(void) 122void afs_fs_exit(void)
121{ 123{
122 _enter(""); 124 _enter("");
123 125
@@ -351,14 +353,19 @@ static int afs_test_super(struct super_block *sb, void *data)
351 struct afs_super_info *as1 = data; 353 struct afs_super_info *as1 = data;
352 struct afs_super_info *as = AFS_FS_S(sb); 354 struct afs_super_info *as = AFS_FS_S(sb);
353 355
354 return (as->net == as1->net && 356 return (as->net_ns == as1->net_ns &&
355 as->volume && 357 as->volume &&
356 as->volume->vid == as1->volume->vid); 358 as->volume->vid == as1->volume->vid &&
359 !as->dyn_root);
357} 360}
358 361
359static int afs_dynroot_test_super(struct super_block *sb, void *data) 362static int afs_dynroot_test_super(struct super_block *sb, void *data)
360{ 363{
361 return false; 364 struct afs_super_info *as1 = data;
365 struct afs_super_info *as = AFS_FS_S(sb);
366
367 return (as->net_ns == as1->net_ns &&
368 as->dyn_root);
362} 369}
363 370
364static int afs_set_super(struct super_block *sb, void *data) 371static int afs_set_super(struct super_block *sb, void *data)
@@ -418,10 +425,14 @@ static int afs_fill_super(struct super_block *sb,
418 if (!sb->s_root) 425 if (!sb->s_root)
419 goto error; 426 goto error;
420 427
421 if (params->dyn_root) 428 if (as->dyn_root) {
422 sb->s_d_op = &afs_dynroot_dentry_operations; 429 sb->s_d_op = &afs_dynroot_dentry_operations;
423 else 430 ret = afs_dynroot_populate(sb);
431 if (ret < 0)
432 goto error;
433 } else {
424 sb->s_d_op = &afs_fs_dentry_operations; 434 sb->s_d_op = &afs_fs_dentry_operations;
435 }
425 436
426 _leave(" = 0"); 437 _leave(" = 0");
427 return 0; 438 return 0;
@@ -437,7 +448,7 @@ static struct afs_super_info *afs_alloc_sbi(struct afs_mount_params *params)
437 448
438 as = kzalloc(sizeof(struct afs_super_info), GFP_KERNEL); 449 as = kzalloc(sizeof(struct afs_super_info), GFP_KERNEL);
439 if (as) { 450 if (as) {
440 as->net = afs_get_net(params->net); 451 as->net_ns = get_net(params->net_ns);
441 if (params->dyn_root) 452 if (params->dyn_root)
442 as->dyn_root = true; 453 as->dyn_root = true;
443 else 454 else
@@ -450,12 +461,31 @@ static void afs_destroy_sbi(struct afs_super_info *as)
450{ 461{
451 if (as) { 462 if (as) {
452 afs_put_volume(as->cell, as->volume); 463 afs_put_volume(as->cell, as->volume);
453 afs_put_cell(as->net, as->cell); 464 afs_put_cell(afs_net(as->net_ns), as->cell);
454 afs_put_net(as->net); 465 put_net(as->net_ns);
455 kfree(as); 466 kfree(as);
456 } 467 }
457} 468}
458 469
470static void afs_kill_super(struct super_block *sb)
471{
472 struct afs_super_info *as = AFS_FS_S(sb);
473 struct afs_net *net = afs_net(as->net_ns);
474
475 if (as->dyn_root)
476 afs_dynroot_depopulate(sb);
477
478 /* Clear the callback interests (which will do ilookup5) before
479 * deactivating the superblock.
480 */
481 if (as->volume)
482 afs_clear_callback_interests(net, as->volume->servers);
483 kill_anon_super(sb);
484 if (as->volume)
485 afs_deactivate_volume(as->volume);
486 afs_destroy_sbi(as);
487}
488
459/* 489/*
460 * get an AFS superblock 490 * get an AFS superblock
461 */ 491 */
@@ -472,12 +502,13 @@ static struct dentry *afs_mount(struct file_system_type *fs_type,
472 _enter(",,%s,%p", dev_name, options); 502 _enter(",,%s,%p", dev_name, options);
473 503
474 memset(&params, 0, sizeof(params)); 504 memset(&params, 0, sizeof(params));
475 params.net = &__afs_net;
476 505
477 ret = -EINVAL; 506 ret = -EINVAL;
478 if (current->nsproxy->net_ns != &init_net) 507 if (current->nsproxy->net_ns != &init_net)
479 goto error; 508 goto error;
480 509 params.net_ns = current->nsproxy->net_ns;
510 params.net = afs_net(params.net_ns);
511
481 /* parse the options and device name */ 512 /* parse the options and device name */
482 if (options) { 513 if (options) {
483 ret = afs_parse_options(&params, options, &dev_name); 514 ret = afs_parse_options(&params, options, &dev_name);
@@ -563,21 +594,6 @@ error:
563 return ERR_PTR(ret); 594 return ERR_PTR(ret);
564} 595}
565 596
566static void afs_kill_super(struct super_block *sb)
567{
568 struct afs_super_info *as = AFS_FS_S(sb);
569
570 /* Clear the callback interests (which will do ilookup5) before
571 * deactivating the superblock.
572 */
573 if (as->volume)
574 afs_clear_callback_interests(as->net, as->volume->servers);
575 kill_anon_super(sb);
576 if (as->volume)
577 afs_deactivate_volume(as->volume);
578 afs_destroy_sbi(as);
579}
580
581/* 597/*
582 * Initialise an inode cache slab element prior to any use. Note that 598 * Initialise an inode cache slab element prior to any use. Note that
583 * afs_alloc_inode() *must* reset anything that could incorrectly leak from one 599 * afs_alloc_inode() *must* reset anything that could incorrectly leak from one