History

afs: Lay the groundwork for supporting network namespaces

Lay the groundwork for supporting network namespaces (netns) to the AFS filesystem by moving various global features to a network-namespace struct (afs_net) and providing an instance of this as a temporary global variable that everything uses via accessor functions for the moment. The following changes have been made: (1) Store the netns in the superblock info. This will be obtained from the mounter's nsproxy on a manual mount and inherited from the parent superblock on an automount. (2) The cell list is made per-netns. It can be viewed through /proc/net/afs/cells and also be modified by writing commands to that file. (3) The local workstation cell is set per-ns in /proc/net/afs/rootcell. This is unset by default. (4) The 'rootcell' module parameter, which sets a cell and VL server list modifies the init net namespace, thereby allowing an AFS root fs to be theoretically used. (5) The volume location lists and the file lock manager are made per-netns. (6) The AF_RXRPC socket and associated I/O bits are made per-ns. The various workqueues remain global for the moment. Changes still to be made: (1) /proc/fs/afs/ should be moved to /proc/net/afs/ and a symlink emplaced from the old name. (2) A per-netns subsys needs to be registered for AFS into which it can store its per-netns data. (3) Rather than the AF_RXRPC socket being opened on module init, it needs to be opened on the creation of a superblock in that netns. (4) The socket needs to be closed when the last superblock using it is destroyed and all outstanding client calls on it have been completed. This prevents a reference loop on the namespace. (5) It is possible that several namespaces will want to use AFS, in which case each one will need its own UDP port. These can either be set through /proc/net/afs/cm_port or the kernel can pick one at random. The init_ns gets 7001 by default. Other issues that need resolving: (1) The DNS keyring needs net-namespacing. (2) Where do upcalls go (eg. DNS request-key upcall)? (3) Need something like open_socket_in_file_ns() syscall so that AFS command line tools attempting to operate on an AFS file/volume have their RPC calls go to the right place.

David Howells committed 9 years ago

Commit f044c881 parent 5e4def216 files · +603 −492Browse files

Unified · Split

16 files
  1. fs/afs/afs.h +9 −0
  2. fs/afs/callback.c +2 −22
  3. fs/afs/cell.c +63 −67
  4. fs/afs/cmservice.c +13 −13
  5. fs/afs/flock.c +2 −37
  6. fs/afs/fsclient.c +37 −19
  7. fs/afs/internal.h +122 −41
  8. fs/afs/main.c +105 −48
  9. fs/afs/proc.c +40 −24
  10. fs/afs/rxrpc.c +65 −67
  11. fs/afs/server.c +39 −43
  12. fs/afs/super.c +26 −19
  13. fs/afs/vlclient.c +6 −4
  14. fs/afs/vlocation.c +68 −83
  15. fs/afs/volume.c +5 −5
  16. include/uapi/linux/magic.h +1 −0
fs/afs/afs.h+9−0
@@ -72,6 +72,15 @@ struct afs_callback { · 71 unmodified lines
72 72
73#define AFSCBMAX 50 /* maximum callbacks transferred per bulk op */73#define AFSCBMAX 50 /* maximum callbacks transferred per bulk op */
74 74
75struct afs_uuid {
76 __be32 time_low; /* low part of timestamp */
77 __be16 time_mid; /* mid part of timestamp */
78 __be16 time_hi_and_version; /* high part of timestamp and version */
79 __u8 clock_seq_hi_and_reserved; /* clock seq hi and variant */
80 __u8 clock_seq_low; /* clock seq low */
81 __u8 node[6]; /* spatially unique node ID (MAC addr) */
82};
83
75/*84/*
76 * AFS volume information85 * AFS volume information
77 */86 */
fs/afs/callback.c+2−22
@@ -28,9 +28,7 @@ unsigned afs_vnode_update_timeout = 10; · 27 unmodified lines
28 CIRC_SPACE((server)->cb_break_head, (server)->cb_break_tail, \28 CIRC_SPACE((server)->cb_break_head, (server)->cb_break_tail, \
29 ARRAY_SIZE((server)->cb_break))29 ARRAY_SIZE((server)->cb_break))
30 30
31//static void afs_callback_updater(struct work_struct *);31struct workqueue_struct *afs_callback_update_worker;
32
33static struct workqueue_struct *afs_callback_update_worker;
34 32
35/*33/*
36 * allow the fileserver to request callback state (re-)initialisation34 * allow the fileserver to request callback state (re-)initialisation
@@ -343,7 +341,7 @@ void afs_dispatch_give_up_callbacks(struct work_struct *work) · 306 unmodified lines
343 * had callbacks entirely, and the server will call us later to break341 * had callbacks entirely, and the server will call us later to break
344 * them342 * them
345 */343 */
346 afs_fs_give_up_callbacks(server, true);344 afs_fs_give_up_callbacks(server->cell->net, server, true);
347}345}
348 346
349/*347/*
@@ -456,21 +454,3 @@ static void afs_callback_updater(struct work_struct *work) · 106 unmodified lines
456 afs_put_vnode(vl);454 afs_put_vnode(vl);
457}455}
458#endif456#endif
459
460/*
461 * initialise the callback update process
462 */
463int __init afs_callback_update_init(void)
464{
465 afs_callback_update_worker = alloc_ordered_workqueue("kafs_callbackd",
466 WQ_MEM_RECLAIM);
467 return afs_callback_update_worker ? 0 : -ENOMEM;
468}
469
470/*
471 * shut down the callback update process
472 */
473void afs_callback_update_kill(void)
474{
475 destroy_workqueue(afs_callback_update_worker);
476}
fs/afs/cell.c+63−67
@@ -18,20 +18,12 @@ · 17 unmodified lines
18#include <keys/rxrpc-type.h>18#include <keys/rxrpc-type.h>
19#include "internal.h"19#include "internal.h"
20 20
21DECLARE_RWSEM(afs_proc_cells_sem);
22LIST_HEAD(afs_proc_cells);
23
24static LIST_HEAD(afs_cells);
25static DEFINE_RWLOCK(afs_cells_lock);
26static DECLARE_RWSEM(afs_cells_sem); /* add/remove serialisation */
27static DECLARE_WAIT_QUEUE_HEAD(afs_cells_freeable_wq);
28static struct afs_cell *afs_cell_root;
29
30/*21/*
31 * allocate a cell record and fill in its name, VL server address list and22 * allocate a cell record and fill in its name, VL server address list and
32 * allocate an anonymous key23 * allocate an anonymous key
33 */24 */
34static struct afs_cell *afs_cell_alloc(const char *name, unsigned namelen,25static struct afs_cell *afs_cell_alloc(struct afs_net *net,
26 const char *name, unsigned namelen,
35 char *vllist)27 char *vllist)
36{28{
37 struct afs_cell *cell;29 struct afs_cell *cell;
@@ -62,6 +54,7 @@ static struct afs_cell *afs_cell_alloc(const char *name, unsigned namelen, · 24 unmodified lines
62 54
63 atomic_set(&cell->usage, 1);55 atomic_set(&cell->usage, 1);
64 INIT_LIST_HEAD(&cell->link);56 INIT_LIST_HEAD(&cell->link);
57 cell->net = net;
65 rwlock_init(&cell->servers_lock);58 rwlock_init(&cell->servers_lock);
66 INIT_LIST_HEAD(&cell->servers);59 INIT_LIST_HEAD(&cell->servers);
67 init_rwsem(&cell->vl_sem);60 init_rwsem(&cell->vl_sem);
@@ -142,12 +135,14 @@ error: · 74 unmodified lines
142 135
143/*136/*
144 * afs_cell_crate() - create a cell record137 * afs_cell_crate() - create a cell record
138 * @net: The network namespace
145 * @name: is the name of the cell.139 * @name: is the name of the cell.
146 * @namsesz: is the strlen of the cell name.140 * @namsesz: is the strlen of the cell name.
147 * @vllist: is a colon separated list of IP addresses in "a.b.c.d" format.141 * @vllist: is a colon separated list of IP addresses in "a.b.c.d" format.
148 * @retref: is T to return the cell reference when the cell exists.142 * @retref: is T to return the cell reference when the cell exists.
149 */143 */
150struct afs_cell *afs_cell_create(const char *name, unsigned namesz,144struct afs_cell *afs_cell_create(struct afs_net *net,
145 const char *name, unsigned namesz,
151 char *vllist, bool retref)146 char *vllist, bool retref)
152{147{
153 struct afs_cell *cell;148 struct afs_cell *cell;
@@ -155,23 +150,23 @@ struct afs_cell *afs_cell_create(const char *name, unsigned namesz, · 1 unmodified line
155 150
156 _enter("%*.*s,%s", namesz, namesz, name ?: "", vllist);151 _enter("%*.*s,%s", namesz, namesz, name ?: "", vllist);
157 152
158 down_write(&afs_cells_sem);153 down_write(&net->cells_sem);
159 read_lock(&afs_cells_lock);154 read_lock(&net->cells_lock);
160 list_for_each_entry(cell, &afs_cells, link) {155 list_for_each_entry(cell, &net->cells, link) {
161 if (strncasecmp(cell->name, name, namesz) == 0)156 if (strncasecmp(cell->name, name, namesz) == 0)
162 goto duplicate_name;157 goto duplicate_name;
163 }158 }
164 read_unlock(&afs_cells_lock);159 read_unlock(&net->cells_lock);
165 160
166 cell = afs_cell_alloc(name, namesz, vllist);161 cell = afs_cell_alloc(net, name, namesz, vllist);
167 if (IS_ERR(cell)) {162 if (IS_ERR(cell)) {
168 _leave(" = %ld", PTR_ERR(cell));163 _leave(" = %ld", PTR_ERR(cell));
169 up_write(&afs_cells_sem);164 up_write(&net->cells_sem);
170 return cell;165 return cell;
171 }166 }
172 167
173 /* add a proc directory for this cell */168 /* add a proc directory for this cell */
174 ret = afs_proc_cell_setup(cell);169 ret = afs_proc_cell_setup(net, cell);
175 if (ret < 0)170 if (ret < 0)
176 goto error;171 goto error;
177 172
@@ -183,20 +178,20 @@ struct afs_cell *afs_cell_create(const char *name, unsigned namesz, · 5 unmodified lines
183#endif178#endif
184 179
185 /* add to the cell lists */180 /* add to the cell lists */
186 write_lock(&afs_cells_lock);181 write_lock(&net->cells_lock);
187 list_add_tail(&cell->link, &afs_cells);182 list_add_tail(&cell->link, &net->cells);
188 write_unlock(&afs_cells_lock);183 write_unlock(&net->cells_lock);
189 184
190 down_write(&afs_proc_cells_sem);185 down_write(&net->proc_cells_sem);
191 list_add_tail(&cell->proc_link, &afs_proc_cells);186 list_add_tail(&cell->proc_link, &net->proc_cells);
192 up_write(&afs_proc_cells_sem);187 up_write(&net->proc_cells_sem);
193 up_write(&afs_cells_sem);188 up_write(&net->cells_sem);
194 189
195 _leave(" = %p", cell);190 _leave(" = %p", cell);
196 return cell;191 return cell;
197 192
198error:193error:
199 up_write(&afs_cells_sem);194 up_write(&net->cells_sem);
200 key_put(cell->anonymous_key);195 key_put(cell->anonymous_key);
201 kfree(cell);196 kfree(cell);
202 _leave(" = %d", ret);197 _leave(" = %d", ret);
@@ -206,8 +201,8 @@ duplicate_name: · 3 unmodified lines
206 if (retref && !IS_ERR(cell))201 if (retref && !IS_ERR(cell))
207 afs_get_cell(cell);202 afs_get_cell(cell);
208 203
209 read_unlock(&afs_cells_lock);204 read_unlock(&net->cells_lock);
210 up_write(&afs_cells_sem);205 up_write(&net->cells_sem);
211 206
212 if (retref) {207 if (retref) {
213 _leave(" = %p", cell);208 _leave(" = %p", cell);
@@ -223,7 +218,7 @@ duplicate_name: · 9 unmodified lines
223 * - can be called with a module parameter string218 * - can be called with a module parameter string
224 * - can be called from a write to /proc/fs/afs/rootcell219 * - can be called from a write to /proc/fs/afs/rootcell
225 */220 */
226int afs_cell_init(char *rootcell)221int afs_cell_init(struct afs_net *net, char *rootcell)
227{222{
228 struct afs_cell *old_root, *new_root;223 struct afs_cell *old_root, *new_root;
229 char *cp;224 char *cp;
@@ -245,17 +240,17 @@ int afs_cell_init(char *rootcell) · 15 unmodified lines
245 *cp++ = 0;240 *cp++ = 0;
246 241
247 /* allocate a cell record for the root cell */242 /* allocate a cell record for the root cell */
248 new_root = afs_cell_create(rootcell, strlen(rootcell), cp, false);243 new_root = afs_cell_create(net, rootcell, strlen(rootcell), cp, false);
249 if (IS_ERR(new_root)) {244 if (IS_ERR(new_root)) {
250 _leave(" = %ld", PTR_ERR(new_root));245 _leave(" = %ld", PTR_ERR(new_root));
251 return PTR_ERR(new_root);246 return PTR_ERR(new_root);
252 }247 }
253 248
254 /* install the new cell */249 /* install the new cell */
255 write_lock(&afs_cells_lock);250 write_lock(&net->cells_lock);
256 old_root = afs_cell_root;251 old_root = net->ws_cell;
257 afs_cell_root = new_root;252 net->ws_cell = new_root;
258 write_unlock(&afs_cells_lock);253 write_unlock(&net->cells_lock);
259 afs_put_cell(old_root);254 afs_put_cell(old_root);
260 255
261 _leave(" = 0");256 _leave(" = 0");
@@ -265,19 +260,20 @@ int afs_cell_init(char *rootcell) · 3 unmodified lines
265/*260/*
266 * lookup a cell record261 * lookup a cell record
267 */262 */
268struct afs_cell *afs_cell_lookup(const char *name, unsigned namesz,263struct afs_cell *afs_cell_lookup(struct afs_net *net,
264 const char *name, unsigned namesz,
269 bool dns_cell)265 bool dns_cell)
270{266{
271 struct afs_cell *cell;267 struct afs_cell *cell;
272 268
273 _enter("\"%*.*s\",", namesz, namesz, name ?: "");269 _enter("\"%*.*s\",", namesz, namesz, name ?: "");
274 270
275 down_read(&afs_cells_sem);271 down_read(&net->cells_sem);
276 read_lock(&afs_cells_lock);272 read_lock(&net->cells_lock);
277 273
278 if (name) {274 if (name) {
279 /* if the cell was named, look for it in the cell record list */275 /* if the cell was named, look for it in the cell record list */
280 list_for_each_entry(cell, &afs_cells, link) {276 list_for_each_entry(cell, &net->cells, link) {
281 if (strncmp(cell->name, name, namesz) == 0) {277 if (strncmp(cell->name, name, namesz) == 0) {
282 afs_get_cell(cell);278 afs_get_cell(cell);
283 goto found;279 goto found;
@@ -289,7 +285,7 @@ struct afs_cell *afs_cell_lookup(const char *name, unsigned namesz, · 5 unmodified lines
289 found:285 found:
290 ;286 ;
291 } else {287 } else {
292 cell = afs_cell_root;288 cell = net->ws_cell;
293 if (!cell) {289 if (!cell) {
294 /* this should not happen unless user tries to mount290 /* this should not happen unless user tries to mount
295 * when root cell is not set. Return an impossibly291 * when root cell is not set. Return an impossibly
@@ -304,16 +300,16 @@ struct afs_cell *afs_cell_lookup(const char *name, unsigned namesz, · 8 unmodified lines
304 300
305 }301 }
306 302
307 read_unlock(&afs_cells_lock);303 read_unlock(&net->cells_lock);
308 up_read(&afs_cells_sem);304 up_read(&net->cells_sem);
309 _leave(" = %p", cell);305 _leave(" = %p", cell);
310 return cell;306 return cell;
311 307
312create_cell:308create_cell:
313 read_unlock(&afs_cells_lock);309 read_unlock(&net->cells_lock);
314 up_read(&afs_cells_sem);310 up_read(&net->cells_sem);
315 311
316 cell = afs_cell_create(name, namesz, NULL, true);312 cell = afs_cell_create(net, name, namesz, NULL, true);
317 313
318 _leave(" = %p", cell);314 _leave(" = %p", cell);
319 return cell;315 return cell;
@@ -325,14 +321,14 @@ create_cell: · 5 unmodified lines
325 */321 */
326struct afs_cell *afs_get_cell_maybe(struct afs_cell *cell)322struct afs_cell *afs_get_cell_maybe(struct afs_cell *cell)
327{323{
328 write_lock(&afs_cells_lock);324 write_lock(&net->cells_lock);
329 325
330 if (cell && !list_empty(&cell->link))326 if (cell && !list_empty(&cell->link))
331 afs_get_cell(cell);327 afs_get_cell(cell);
332 else328 else
333 cell = NULL;329 cell = NULL;
334 330
335 write_unlock(&afs_cells_lock);331 write_unlock(&net->cells_lock);
336 return cell;332 return cell;
337}333}
338#endif /* 0 */334#endif /* 0 */
@@ -351,10 +347,10 @@ void afs_put_cell(struct afs_cell *cell) · 12 unmodified lines
351 347
352 /* to prevent a race, the decrement and the dequeue must be effectively348 /* to prevent a race, the decrement and the dequeue must be effectively
353 * atomic */349 * atomic */
354 write_lock(&afs_cells_lock);350 write_lock(&cell->net->cells_lock);
355 351
356 if (likely(!atomic_dec_and_test(&cell->usage))) {352 if (likely(!atomic_dec_and_test(&cell->usage))) {
357 write_unlock(&afs_cells_lock);353 write_unlock(&cell->net->cells_lock);
358 _leave("");354 _leave("");
359 return;355 return;
360 }356 }
@@ -362,19 +358,19 @@ void afs_put_cell(struct afs_cell *cell) · 1 unmodified line
362 ASSERT(list_empty(&cell->servers));358 ASSERT(list_empty(&cell->servers));
363 ASSERT(list_empty(&cell->vl_list));359 ASSERT(list_empty(&cell->vl_list));
364 360
365 write_unlock(&afs_cells_lock);361 wake_up(&cell->net->cells_freeable_wq);
366 362
367 wake_up(&afs_cells_freeable_wq);363 write_unlock(&cell->net->cells_lock);
368 364
369 _leave(" [unused]");365 _leave(" [unused]");
370}366}
371 367
372/*368/*
373 * destroy a cell record369 * destroy a cell record
374 * - must be called with the afs_cells_sem write-locked370 * - must be called with the net->cells_sem write-locked
375 * - cell->link should have been broken by the caller371 * - cell->link should have been broken by the caller
376 */372 */
377static void afs_cell_destroy(struct afs_cell *cell)373static void afs_cell_destroy(struct afs_net *net, struct afs_cell *cell)
378{374{
379 _enter("%p{%d,%s}", cell, atomic_read(&cell->usage), cell->name);375 _enter("%p{%d,%s}", cell, atomic_read(&cell->usage), cell->name);
380 376
@@ -387,14 +383,14 @@ static void afs_cell_destroy(struct afs_cell *cell) · 6 unmodified lines
387 383
388 _debug("wait for cell %s", cell->name);384 _debug("wait for cell %s", cell->name);
389 set_current_state(TASK_UNINTERRUPTIBLE);385 set_current_state(TASK_UNINTERRUPTIBLE);
390 add_wait_queue(&afs_cells_freeable_wq, &myself);386 add_wait_queue(&net->cells_freeable_wq, &myself);
391 387
392 while (atomic_read(&cell->usage) > 0) {388 while (atomic_read(&cell->usage) > 0) {
393 schedule();389 schedule();
394 set_current_state(TASK_UNINTERRUPTIBLE);390 set_current_state(TASK_UNINTERRUPTIBLE);
395 }391 }
396 392
397 remove_wait_queue(&afs_cells_freeable_wq, &myself);393 remove_wait_queue(&net->cells_freeable_wq, &myself);
398 set_current_state(TASK_RUNNING);394 set_current_state(TASK_RUNNING);
399 }395 }
400 396
@@ -403,11 +399,11 @@ static void afs_cell_destroy(struct afs_cell *cell) · 2 unmodified lines
403 ASSERT(list_empty(&cell->servers));399 ASSERT(list_empty(&cell->servers));
404 ASSERT(list_empty(&cell->vl_list));400 ASSERT(list_empty(&cell->vl_list));
405 401
406 afs_proc_cell_remove(cell);402 afs_proc_cell_remove(net, cell);
407 403
408 down_write(&afs_proc_cells_sem);404 down_write(&net->proc_cells_sem);
409 list_del_init(&cell->proc_link);405 list_del_init(&cell->proc_link);
410 up_write(&afs_proc_cells_sem);406 up_write(&net->proc_cells_sem);
411 407
412#ifdef CONFIG_AFS_FSCACHE408#ifdef CONFIG_AFS_FSCACHE
413 fscache_relinquish_cookie(cell->cache, 0);409 fscache_relinquish_cookie(cell->cache, 0);
@@ -422,39 +418,39 @@ static void afs_cell_destroy(struct afs_cell *cell) · 8 unmodified lines
422 * purge in-memory cell database on module unload or afs_init() failure418 * purge in-memory cell database on module unload or afs_init() failure
423 * - the timeout daemon is stopped before calling this419 * - the timeout daemon is stopped before calling this
424 */420 */
425void afs_cell_purge(void)421void afs_cell_purge(struct afs_net *net)
426{422{
427 struct afs_cell *cell;423 struct afs_cell *cell;
428 424
429 _enter("");425 _enter("");
430 426
431 afs_put_cell(afs_cell_root);427 afs_put_cell(net->ws_cell);
432 428
433 down_write(&afs_cells_sem);429 down_write(&net->cells_sem);
434 430
435 while (!list_empty(&afs_cells)) {431 while (!list_empty(&net->cells)) {
436 cell = NULL;432 cell = NULL;
437 433
438 /* remove the next cell from the front of the list */434 /* remove the next cell from the front of the list */
439 write_lock(&afs_cells_lock);435 write_lock(&net->cells_lock);
440 436
441 if (!list_empty(&afs_cells)) {437 if (!list_empty(&net->cells)) {
442 cell = list_entry(afs_cells.next,438 cell = list_entry(net->cells.next,
443 struct afs_cell, link);439 struct afs_cell, link);
444 list_del_init(&cell->link);440 list_del_init(&cell->link);
445 }441 }
446 442
447 write_unlock(&afs_cells_lock);443 write_unlock(&net->cells_lock);
448 444
449 if (cell) {445 if (cell) {
450 _debug("PURGING CELL %s (%d)",446 _debug("PURGING CELL %s (%d)",
451 cell->name, atomic_read(&cell->usage));447 cell->name, atomic_read(&cell->usage));
452 448
453 /* now the cell should be left with no references */449 /* now the cell should be left with no references */
454 afs_cell_destroy(cell);450 afs_cell_destroy(net, cell);
455 }451 }
456 }452 }
457 453
458 up_write(&afs_cells_sem);454 up_write(&net->cells_sem);
459 _leave("");455 _leave("");
460}456}
fs/afs/cmservice.c+13−13
@@ -193,7 +193,7 @@ static int afs_deliver_cb_callback(struct afs_call *call) · 192 unmodified lines
193 193
194 switch (call->unmarshall) {194 switch (call->unmarshall) {
195 case 0:195 case 0:
196 rxrpc_kernel_get_peer(afs_socket, call->rxcall, &srx);196 rxrpc_kernel_get_peer(call->net->socket, call->rxcall, &srx);
197 call->offset = 0;197 call->offset = 0;
198 call->unmarshall++;198 call->unmarshall++;
199 199
@@ -290,7 +290,7 @@ static int afs_deliver_cb_callback(struct afs_call *call) · 90 unmodified lines
290 290
291 /* we'll need the file server record as that tells us which set of291 /* we'll need the file server record as that tells us which set of
292 * vnodes to operate upon */292 * vnodes to operate upon */
293 server = afs_find_server(&srx);293 server = afs_find_server(call->net, &srx);
294 if (!server)294 if (!server)
295 return -ENOTCONN;295 return -ENOTCONN;
296 call->server = server;296 call->server = server;
@@ -324,7 +324,7 @@ static int afs_deliver_cb_init_call_back_state(struct afs_call *call) · 27 unmodified lines
324 324
325 _enter("");325 _enter("");
326 326
327 rxrpc_kernel_get_peer(afs_socket, call->rxcall, &srx);327 rxrpc_kernel_get_peer(call->net->socket, call->rxcall, &srx);
328 328
329 ret = afs_extract_data(call, NULL, 0, false);329 ret = afs_extract_data(call, NULL, 0, false);
330 if (ret < 0)330 if (ret < 0)
@@ -335,7 +335,7 @@ static int afs_deliver_cb_init_call_back_state(struct afs_call *call) · 4 unmodified lines
335 335
336 /* we'll need the file server record as that tells us which set of336 /* we'll need the file server record as that tells us which set of
337 * vnodes to operate upon */337 * vnodes to operate upon */
338 server = afs_find_server(&srx);338 server = afs_find_server(call->net, &srx);
339 if (!server)339 if (!server)
340 return -ENOTCONN;340 return -ENOTCONN;
341 call->server = server;341 call->server = server;
@@ -357,7 +357,7 @@ static int afs_deliver_cb_init_call_back_state3(struct afs_call *call) · 15 unmodified lines
357 357
358 _enter("");358 _enter("");
359 359
360 rxrpc_kernel_get_peer(afs_socket, call->rxcall, &srx);360 rxrpc_kernel_get_peer(call->net->socket, call->rxcall, &srx);
361 361
362 _enter("{%u}", call->unmarshall);362 _enter("{%u}", call->unmarshall);
363 363
@@ -407,7 +407,7 @@ static int afs_deliver_cb_init_call_back_state3(struct afs_call *call) · 43 unmodified lines
407 407
408 /* we'll need the file server record as that tells us which set of408 /* we'll need the file server record as that tells us which set of
409 * vnodes to operate upon */409 * vnodes to operate upon */
410 server = afs_find_server(&srx);410 server = afs_find_server(call->net, &srx);
411 if (!server)411 if (!server)
412 return -ENOTCONN;412 return -ENOTCONN;
413 call->server = server;413 call->server = server;
@@ -461,7 +461,7 @@ static void SRXAFSCB_ProbeUuid(struct work_struct *work) · 47 unmodified lines
461 461
462 _enter("");462 _enter("");
463 463
464 if (memcmp(r, &afs_uuid, sizeof(afs_uuid)) == 0)464 if (memcmp(r, &call->net->uuid, sizeof(call->net->uuid)) == 0)
465 reply.match = htonl(0);465 reply.match = htonl(0);
466 else466 else
467 reply.match = htonl(1);467 reply.match = htonl(1);
@@ -568,13 +568,13 @@ static void SRXAFSCB_TellMeAboutYourself(struct work_struct *work) · 100 unmodified lines
568 memset(&reply, 0, sizeof(reply));568 memset(&reply, 0, sizeof(reply));
569 reply.ia.nifs = htonl(nifs);569 reply.ia.nifs = htonl(nifs);
570 570
571 reply.ia.uuid[0] = afs_uuid.time_low;571 reply.ia.uuid[0] = call->net->uuid.time_low;
572 reply.ia.uuid[1] = htonl(ntohs(afs_uuid.time_mid));572 reply.ia.uuid[1] = htonl(ntohs(call->net->uuid.time_mid));
573 reply.ia.uuid[2] = htonl(ntohs(afs_uuid.time_hi_and_version));573 reply.ia.uuid[2] = htonl(ntohs(call->net->uuid.time_hi_and_version));
574 reply.ia.uuid[3] = htonl((s8) afs_uuid.clock_seq_hi_and_reserved);574 reply.ia.uuid[3] = htonl((s8) call->net->uuid.clock_seq_hi_and_reserved);
575 reply.ia.uuid[4] = htonl((s8) afs_uuid.clock_seq_low);575 reply.ia.uuid[4] = htonl((s8) call->net->uuid.clock_seq_low);
576 for (loop = 0; loop < 6; loop++)576 for (loop = 0; loop < 6; loop++)
577 reply.ia.uuid[loop + 5] = htonl((s8) afs_uuid.node[loop]);577 reply.ia.uuid[loop + 5] = htonl((s8) call->net->uuid.node[loop]);
578 578
579 if (ifs) {579 if (ifs) {
580 for (loop = 0; loop < nifs; loop++) {580 for (loop = 0; loop < nifs; loop++) {
fs/afs/flock.c+2−37
@@ -14,47 +14,16 @@ · 13 unmodified lines
14#define AFS_LOCK_GRANTED 014#define AFS_LOCK_GRANTED 0
15#define AFS_LOCK_PENDING 115#define AFS_LOCK_PENDING 1
16 16
17struct workqueue_struct *afs_lock_manager;
18
17static void afs_fl_copy_lock(struct file_lock *new, struct file_lock *fl);19static void afs_fl_copy_lock(struct file_lock *new, struct file_lock *fl);
18static void afs_fl_release_private(struct file_lock *fl);20static void afs_fl_release_private(struct file_lock *fl);
19 21
20static struct workqueue_struct *afs_lock_manager;
21static DEFINE_MUTEX(afs_lock_manager_mutex);
22
23static const struct file_lock_operations afs_lock_ops = {22static const struct file_lock_operations afs_lock_ops = {
24 .fl_copy_lock = afs_fl_copy_lock,23 .fl_copy_lock = afs_fl_copy_lock,
25 .fl_release_private = afs_fl_release_private,24 .fl_release_private = afs_fl_release_private,
26};25};
27 26
28/*
29 * initialise the lock manager thread if it isn't already running
30 */
31static int afs_init_lock_manager(void)
32{
33 int ret;
34
35 ret = 0;
36 if (!afs_lock_manager) {
37 mutex_lock(&afs_lock_manager_mutex);
38 if (!afs_lock_manager) {
39 afs_lock_manager = alloc_workqueue("kafs_lockd",
40 WQ_MEM_RECLAIM, 0);
41 if (!afs_lock_manager)
42 ret = -ENOMEM;
43 }
44 mutex_unlock(&afs_lock_manager_mutex);
45 }
46 return ret;
47}
48
49/*
50 * destroy the lock manager thread if it's running
51 */
52void __exit afs_kill_lock_manager(void)
53{
54 if (afs_lock_manager)
55 destroy_workqueue(afs_lock_manager);
56}
57
58/*27/*
59 * if the callback is broken on this vnode, then the lock may now be available28 * if the callback is broken on this vnode, then the lock may now be available
60 */29 */
@@ -264,10 +233,6 @@ static int afs_do_setlk(struct file *file, struct file_lock *fl) · 203 unmodified lines
264 if (fl->fl_start != 0 || fl->fl_end != OFFSET_MAX)233 if (fl->fl_start != 0 || fl->fl_end != OFFSET_MAX)
265 return -EINVAL;234 return -EINVAL;
266 235
267 ret = afs_init_lock_manager();
268 if (ret < 0)
269 return ret;
270
271 fl->fl_ops = &afs_lock_ops;236 fl->fl_ops = &afs_lock_ops;
272 INIT_LIST_HEAD(&fl->fl_u.afs.link);237 INIT_LIST_HEAD(&fl->fl_u.afs.link);
273 fl->fl_u.afs.state = AFS_LOCK_PENDING;238 fl->fl_u.afs.state = AFS_LOCK_PENDING;
fs/afs/fsclient.c+37−19
@@ -284,12 +284,13 @@ int afs_fs_fetch_file_status(struct afs_server *server, · 283 unmodified lines
284 bool async)284 bool async)
285{285{
286 struct afs_call *call;286 struct afs_call *call;
287 struct afs_net *net = afs_v2net(vnode);
287 __be32 *bp;288 __be32 *bp;
288 289
289 _enter(",%x,{%x:%u},,",290 _enter(",%x,{%x:%u},,",
290 key_serial(key), vnode->fid.vid, vnode->fid.vnode);291 key_serial(key), vnode->fid.vid, vnode->fid.vnode);
291 292
292 call = afs_alloc_flat_call(&afs_RXFSFetchStatus, 16, (21 + 3 + 6) * 4);293 call = afs_alloc_flat_call(net, &afs_RXFSFetchStatus, 16, (21 + 3 + 6) * 4);
293 if (!call)294 if (!call)
294 return -ENOMEM;295 return -ENOMEM;
295 296
@@ -490,11 +491,12 @@ static int afs_fs_fetch_data64(struct afs_server *server, · 194 unmodified lines
490 bool async)491 bool async)
491{492{
492 struct afs_call *call;493 struct afs_call *call;
494 struct afs_net *net = afs_v2net(vnode);
493 __be32 *bp;495 __be32 *bp;
494 496
495 _enter("");497 _enter("");
496 498
497 call = afs_alloc_flat_call(&afs_RXFSFetchData64, 32, (21 + 3 + 6) * 4);499 call = afs_alloc_flat_call(net, &afs_RXFSFetchData64, 32, (21 + 3 + 6) * 4);
498 if (!call)500 if (!call)
499 return -ENOMEM;501 return -ENOMEM;
500 502
@@ -531,6 +533,7 @@ int afs_fs_fetch_data(struct afs_server *server, · 30 unmodified lines
531 bool async)533 bool async)
532{534{
533 struct afs_call *call;535 struct afs_call *call;
536 struct afs_net *net = afs_v2net(vnode);
534 __be32 *bp;537 __be32 *bp;
535 538
536 if (upper_32_bits(req->pos) ||539 if (upper_32_bits(req->pos) ||
@@ -540,7 +543,7 @@ int afs_fs_fetch_data(struct afs_server *server, · 3 unmodified lines
540 543
541 _enter("");544 _enter("");
542 545
543 call = afs_alloc_flat_call(&afs_RXFSFetchData, 24, (21 + 3 + 6) * 4);546 call = afs_alloc_flat_call(net, &afs_RXFSFetchData, 24, (21 + 3 + 6) * 4);
544 if (!call)547 if (!call)
545 return -ENOMEM;548 return -ENOMEM;
546 549
@@ -590,7 +593,8 @@ static const struct afs_call_type afs_RXFSGiveUpCallBacks = { · 43 unmodified lines
590 * give up a set of callbacks593 * give up a set of callbacks
591 * - the callbacks are held in the server->cb_break ring594 * - the callbacks are held in the server->cb_break ring
592 */595 */
593int afs_fs_give_up_callbacks(struct afs_server *server,596int afs_fs_give_up_callbacks(struct afs_net *net,
597 struct afs_server *server,
594 bool async)598 bool async)
595{599{
596 struct afs_call *call;600 struct afs_call *call;
@@ -610,7 +614,7 @@ int afs_fs_give_up_callbacks(struct afs_server *server, · 13 unmodified lines
610 614
611 _debug("break %zu callbacks", ncallbacks);615 _debug("break %zu callbacks", ncallbacks);
612 616
613 call = afs_alloc_flat_call(&afs_RXFSGiveUpCallBacks,617 call = afs_alloc_flat_call(net, &afs_RXFSGiveUpCallBacks,
614 12 + ncallbacks * 6 * 4, 0);618 12 + ncallbacks * 6 * 4, 0);
615 if (!call)619 if (!call)
616 return -ENOMEM;620 return -ENOMEM;
@@ -699,6 +703,7 @@ int afs_fs_create(struct afs_server *server, · 82 unmodified lines
699 bool async)703 bool async)
700{704{
701 struct afs_call *call;705 struct afs_call *call;
706 struct afs_net *net = afs_v2net(vnode);
702 size_t namesz, reqsz, padsz;707 size_t namesz, reqsz, padsz;
703 __be32 *bp;708 __be32 *bp;
704 709
@@ -708,7 +713,7 @@ int afs_fs_create(struct afs_server *server, · 3 unmodified lines
708 padsz = (4 - (namesz & 3)) & 3;713 padsz = (4 - (namesz & 3)) & 3;
709 reqsz = (5 * 4) + namesz + padsz + (6 * 4);714 reqsz = (5 * 4) + namesz + padsz + (6 * 4);
710 715
711 call = afs_alloc_flat_call(&afs_RXFSCreateXXXX, reqsz,716 call = afs_alloc_flat_call(net, &afs_RXFSCreateXXXX, reqsz,
712 (3 + 21 + 21 + 3 + 6) * 4);717 (3 + 21 + 21 + 3 + 6) * 4);
713 if (!call)718 if (!call)
714 return -ENOMEM;719 return -ENOMEM;
@@ -789,6 +794,7 @@ int afs_fs_remove(struct afs_server *server, · 74 unmodified lines
789 bool async)794 bool async)
790{795{
791 struct afs_call *call;796 struct afs_call *call;
797 struct afs_net *net = afs_v2net(vnode);
792 size_t namesz, reqsz, padsz;798 size_t namesz, reqsz, padsz;
793 __be32 *bp;799 __be32 *bp;
794 800
@@ -798,7 +804,7 @@ int afs_fs_remove(struct afs_server *server, · 3 unmodified lines
798 padsz = (4 - (namesz & 3)) & 3;804 padsz = (4 - (namesz & 3)) & 3;
799 reqsz = (5 * 4) + namesz + padsz;805 reqsz = (5 * 4) + namesz + padsz;
800 806
801 call = afs_alloc_flat_call(&afs_RXFSRemoveXXXX, reqsz, (21 + 6) * 4);807 call = afs_alloc_flat_call(net, &afs_RXFSRemoveXXXX, reqsz, (21 + 6) * 4);
802 if (!call)808 if (!call)
803 return -ENOMEM;809 return -ENOMEM;
804 810
@@ -870,6 +876,7 @@ int afs_fs_link(struct afs_server *server, · 65 unmodified lines
870 bool async)876 bool async)
871{877{
872 struct afs_call *call;878 struct afs_call *call;
879 struct afs_net *net = afs_v2net(vnode);
873 size_t namesz, reqsz, padsz;880 size_t namesz, reqsz, padsz;
874 __be32 *bp;881 __be32 *bp;
875 882
@@ -879,7 +886,7 @@ int afs_fs_link(struct afs_server *server, · 3 unmodified lines
879 padsz = (4 - (namesz & 3)) & 3;886 padsz = (4 - (namesz & 3)) & 3;
880 reqsz = (5 * 4) + namesz + padsz + (3 * 4);887 reqsz = (5 * 4) + namesz + padsz + (3 * 4);
881 888
882 call = afs_alloc_flat_call(&afs_RXFSLink, reqsz, (21 + 21 + 6) * 4);889 call = afs_alloc_flat_call(net, &afs_RXFSLink, reqsz, (21 + 21 + 6) * 4);
883 if (!call)890 if (!call)
884 return -ENOMEM;891 return -ENOMEM;
885 892
@@ -958,6 +965,7 @@ int afs_fs_symlink(struct afs_server *server, · 72 unmodified lines
958 bool async)965 bool async)
959{966{
960 struct afs_call *call;967 struct afs_call *call;
968 struct afs_net *net = afs_v2net(vnode);
961 size_t namesz, reqsz, padsz, c_namesz, c_padsz;969 size_t namesz, reqsz, padsz, c_namesz, c_padsz;
962 __be32 *bp;970 __be32 *bp;
963 971
@@ -971,7 +979,7 @@ int afs_fs_symlink(struct afs_server *server, · 7 unmodified lines
971 979
972 reqsz = (6 * 4) + namesz + padsz + c_namesz + c_padsz + (6 * 4);980 reqsz = (6 * 4) + namesz + padsz + c_namesz + c_padsz + (6 * 4);
973 981
974 call = afs_alloc_flat_call(&afs_RXFSSymlink, reqsz,982 call = afs_alloc_flat_call(net, &afs_RXFSSymlink, reqsz,
975 (3 + 21 + 21 + 6) * 4);983 (3 + 21 + 21 + 6) * 4);
976 if (!call)984 if (!call)
977 return -ENOMEM;985 return -ENOMEM;
@@ -1062,6 +1070,7 @@ int afs_fs_rename(struct afs_server *server, · 84 unmodified lines
1062 bool async)1070 bool async)
1063{1071{
1064 struct afs_call *call;1072 struct afs_call *call;
1073 struct afs_net *net = afs_v2net(orig_dvnode);
1065 size_t reqsz, o_namesz, o_padsz, n_namesz, n_padsz;1074 size_t reqsz, o_namesz, o_padsz, n_namesz, n_padsz;
1066 __be32 *bp;1075 __be32 *bp;
1067 1076
@@ -1078,7 +1087,7 @@ int afs_fs_rename(struct afs_server *server, · 10 unmodified lines
1078 (3 * 4) +1087 (3 * 4) +
1079 4 + n_namesz + n_padsz;1088 4 + n_namesz + n_padsz;
1080 1089
1081 call = afs_alloc_flat_call(&afs_RXFSRename, reqsz, (21 + 21 + 6) * 4);1090 call = afs_alloc_flat_call(net, &afs_RXFSRename, reqsz, (21 + 21 + 6) * 4);
1082 if (!call)1091 if (!call)
1083 return -ENOMEM;1092 return -ENOMEM;
1084 1093
@@ -1172,12 +1181,13 @@ static int afs_fs_store_data64(struct afs_server *server, · 87 unmodified lines
1172{1181{
1173 struct afs_vnode *vnode = wb->vnode;1182 struct afs_vnode *vnode = wb->vnode;
1174 struct afs_call *call;1183 struct afs_call *call;
1184 struct afs_net *net = afs_v2net(vnode);
1175 __be32 *bp;1185 __be32 *bp;
1176 1186
1177 _enter(",%x,{%x:%u},,",1187 _enter(",%x,{%x:%u},,",
1178 key_serial(wb->key), vnode->fid.vid, vnode->fid.vnode);1188 key_serial(wb->key), vnode->fid.vid, vnode->fid.vnode);
1179 1189
1180 call = afs_alloc_flat_call(&afs_RXFSStoreData64,1190 call = afs_alloc_flat_call(net, &afs_RXFSStoreData64,
1181 (4 + 6 + 3 * 2) * 4,1191 (4 + 6 + 3 * 2) * 4,
1182 (21 + 6) * 4);1192 (21 + 6) * 4);
1183 if (!call)1193 if (!call)
@@ -1230,6 +1240,7 @@ int afs_fs_store_data(struct afs_server *server, struct afs_writeback *wb, · 46 unmodified lines
1230{1240{
1231 struct afs_vnode *vnode = wb->vnode;1241 struct afs_vnode *vnode = wb->vnode;
1232 struct afs_call *call;1242 struct afs_call *call;
1243 struct afs_net *net = afs_v2net(vnode);
1233 loff_t size, pos, i_size;1244 loff_t size, pos, i_size;
1234 __be32 *bp;1245 __be32 *bp;
1235 1246
@@ -1254,7 +1265,7 @@ int afs_fs_store_data(struct afs_server *server, struct afs_writeback *wb, · 18 unmodified lines
1254 return afs_fs_store_data64(server, wb, first, last, offset, to,1265 return afs_fs_store_data64(server, wb, first, last, offset, to,
1255 size, pos, i_size, async);1266 size, pos, i_size, async);
1256 1267
1257 call = afs_alloc_flat_call(&afs_RXFSStoreData,1268 call = afs_alloc_flat_call(net, &afs_RXFSStoreData,
1258 (4 + 6 + 3) * 4,1269 (4 + 6 + 3) * 4,
1259 (21 + 6) * 4);1270 (21 + 6) * 4);
1260 if (!call)1271 if (!call)
@@ -1356,6 +1367,7 @@ static int afs_fs_setattr_size64(struct afs_server *server, struct key *key, · 95 unmodified lines
1356 bool async)1367 bool async)
1357{1368{
1358 struct afs_call *call;1369 struct afs_call *call;
1370 struct afs_net *net = afs_v2net(vnode);
1359 __be32 *bp;1371 __be32 *bp;
1360 1372
1361 _enter(",%x,{%x:%u},,",1373 _enter(",%x,{%x:%u},,",
@@ -1363,7 +1375,7 @@ static int afs_fs_setattr_size64(struct afs_server *server, struct key *key, · 1 unmodified line
1363 1375
1364 ASSERT(attr->ia_valid & ATTR_SIZE);1376 ASSERT(attr->ia_valid & ATTR_SIZE);
1365 1377
1366 call = afs_alloc_flat_call(&afs_RXFSStoreData64_as_Status,1378 call = afs_alloc_flat_call(net, &afs_RXFSStoreData64_as_Status,
1367 (4 + 6 + 3 * 2) * 4,1379 (4 + 6 + 3 * 2) * 4,
1368 (21 + 6) * 4);1380 (21 + 6) * 4);
1369 if (!call)1381 if (!call)
@@ -1404,6 +1416,7 @@ static int afs_fs_setattr_size(struct afs_server *server, struct key *key, · 34 unmodified lines
1404 bool async)1416 bool async)
1405{1417{
1406 struct afs_call *call;1418 struct afs_call *call;
1419 struct afs_net *net = afs_v2net(vnode);
1407 __be32 *bp;1420 __be32 *bp;
1408 1421
1409 _enter(",%x,{%x:%u},,",1422 _enter(",%x,{%x:%u},,",
@@ -1414,7 +1427,7 @@ static int afs_fs_setattr_size(struct afs_server *server, struct key *key, · 4 unmodified lines
1414 return afs_fs_setattr_size64(server, key, vnode, attr,1427 return afs_fs_setattr_size64(server, key, vnode, attr,
1415 async);1428 async);
1416 1429
1417 call = afs_alloc_flat_call(&afs_RXFSStoreData_as_Status,1430 call = afs_alloc_flat_call(net, &afs_RXFSStoreData_as_Status,
1418 (4 + 6 + 3) * 4,1431 (4 + 6 + 3) * 4,
1419 (21 + 6) * 4);1432 (21 + 6) * 4);
1420 if (!call)1433 if (!call)
@@ -1452,6 +1465,7 @@ int afs_fs_setattr(struct afs_server *server, struct key *key, · 31 unmodified lines
1452 bool async)1465 bool async)
1453{1466{
1454 struct afs_call *call;1467 struct afs_call *call;
1468 struct afs_net *net = afs_v2net(vnode);
1455 __be32 *bp;1469 __be32 *bp;
1456 1470
1457 if (attr->ia_valid & ATTR_SIZE)1471 if (attr->ia_valid & ATTR_SIZE)
@@ -1461,7 +1475,7 @@ int afs_fs_setattr(struct afs_server *server, struct key *key, · 3 unmodified lines
1461 _enter(",%x,{%x:%u},,",1475 _enter(",%x,{%x:%u},,",
1462 key_serial(key), vnode->fid.vid, vnode->fid.vnode);1476 key_serial(key), vnode->fid.vid, vnode->fid.vnode);
1463 1477
1464 call = afs_alloc_flat_call(&afs_RXFSStoreStatus,1478 call = afs_alloc_flat_call(net, &afs_RXFSStoreStatus,
1465 (4 + 6) * 4,1479 (4 + 6) * 4,
1466 (21 + 6) * 4);1480 (21 + 6) * 4);
1467 if (!call)1481 if (!call)
@@ -1687,6 +1701,7 @@ int afs_fs_get_volume_status(struct afs_server *server, · 219 unmodified lines
1687 bool async)1701 bool async)
1688{1702{
1689 struct afs_call *call;1703 struct afs_call *call;
1704 struct afs_net *net = afs_v2net(vnode);
1690 __be32 *bp;1705 __be32 *bp;
1691 void *tmpbuf;1706 void *tmpbuf;
1692 1707
@@ -1696,7 +1711,7 @@ int afs_fs_get_volume_status(struct afs_server *server, · 3 unmodified lines
1696 if (!tmpbuf)1711 if (!tmpbuf)
1697 return -ENOMEM;1712 return -ENOMEM;
1698 1713
1699 call = afs_alloc_flat_call(&afs_RXFSGetVolumeStatus, 2 * 4, 12 * 4);1714 call = afs_alloc_flat_call(net, &afs_RXFSGetVolumeStatus, 2 * 4, 12 * 4);
1700 if (!call) {1715 if (!call) {
1701 kfree(tmpbuf);1716 kfree(tmpbuf);
1702 return -ENOMEM;1717 return -ENOMEM;
@@ -1779,11 +1794,12 @@ int afs_fs_set_lock(struct afs_server *server, · 76 unmodified lines
1779 bool async)1794 bool async)
1780{1795{
1781 struct afs_call *call;1796 struct afs_call *call;
1797 struct afs_net *net = afs_v2net(vnode);
1782 __be32 *bp;1798 __be32 *bp;
1783 1799
1784 _enter("");1800 _enter("");
1785 1801
1786 call = afs_alloc_flat_call(&afs_RXFSSetLock, 5 * 4, 6 * 4);1802 call = afs_alloc_flat_call(net, &afs_RXFSSetLock, 5 * 4, 6 * 4);
1787 if (!call)1803 if (!call)
1788 return -ENOMEM;1804 return -ENOMEM;
1789 1805
@@ -1812,11 +1828,12 @@ int afs_fs_extend_lock(struct afs_server *server, · 22 unmodified lines
1812 bool async)1828 bool async)
1813{1829{
1814 struct afs_call *call;1830 struct afs_call *call;
1831 struct afs_net *net = afs_v2net(vnode);
1815 __be32 *bp;1832 __be32 *bp;
1816 1833
1817 _enter("");1834 _enter("");
1818 1835
1819 call = afs_alloc_flat_call(&afs_RXFSExtendLock, 4 * 4, 6 * 4);1836 call = afs_alloc_flat_call(net, &afs_RXFSExtendLock, 4 * 4, 6 * 4);
1820 if (!call)1837 if (!call)
1821 return -ENOMEM;1838 return -ENOMEM;
1822 1839
@@ -1844,11 +1861,12 @@ int afs_fs_release_lock(struct afs_server *server, · 21 unmodified lines
1844 bool async)1861 bool async)
1845{1862{
1846 struct afs_call *call;1863 struct afs_call *call;
1864 struct afs_net *net = afs_v2net(vnode);
1847 __be32 *bp;1865 __be32 *bp;
1848 1866
1849 _enter("");1867 _enter("");
1850 1868
1851 call = afs_alloc_flat_call(&afs_RXFSReleaseLock, 4 * 4, 6 * 4);1869 call = afs_alloc_flat_call(net, &afs_RXFSReleaseLock, 4 * 4, 6 * 4);
1852 if (!call)1870 if (!call)
1853 return -ENOMEM;1871 return -ENOMEM;
1854 1872
fs/afs/internal.h+122−41
@@ -21,6 +21,7 @@ · 20 unmodified lines
21#include <linux/fscache.h>21#include <linux/fscache.h>
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/af_rxrpc.h>25#include <net/af_rxrpc.h>
25 26
26#include "afs.h"27#include "afs.h"
@@ -48,6 +49,7 @@ struct afs_mount_params { · 21 unmodified lines
48 afs_voltype_t type; /* type of volume requested */49 afs_voltype_t type; /* type of volume requested */
49 int volnamesz; /* size of volume name */50 int volnamesz; /* size of volume name */
50 const char *volname; /* name of volume to mount */51 const char *volname; /* name of volume to mount */
52 struct afs_net *net; /* Network namespace in effect */
51 struct afs_cell *cell; /* cell in which to find volume */53 struct afs_cell *cell; /* cell in which to find volume */
52 struct afs_volume *volume; /* volume record */54 struct afs_volume *volume; /* volume record */
53 struct key *key; /* key to use for secure mounting */55 struct key *key; /* key to use for secure mounting */
@@ -62,6 +64,7 @@ enum afs_call_state { · 8 unmodified lines
62 AFS_CALL_AWAIT_ACK, /* awaiting final ACK of incoming call */64 AFS_CALL_AWAIT_ACK, /* awaiting final ACK of incoming call */
63 AFS_CALL_COMPLETE, /* Completed or failed */65 AFS_CALL_COMPLETE, /* Completed or failed */
64};66};
67
65/*68/*
66 * a record of an in-progress RxRPC call69 * a record of an in-progress RxRPC call
67 */70 */
@@ -72,6 +75,7 @@ struct afs_call { · 4 unmodified lines
72 struct work_struct work; /* actual work processor */75 struct work_struct work; /* actual work processor */
73 struct rxrpc_call *rxcall; /* RxRPC call handle */76 struct rxrpc_call *rxcall; /* RxRPC call handle */
74 struct key *key; /* security for this call */77 struct key *key; /* security for this call */
78 struct afs_net *net; /* The network namespace */
75 struct afs_server *server; /* server affected by incoming CM call */79 struct afs_server *server; /* server affected by incoming CM call */
76 void *request; /* request data (first part) */80 void *request; /* request data (first part) */
77 struct address_space *mapping; /* page set */81 struct address_space *mapping; /* page set */
@@ -173,6 +177,7 @@ struct afs_writeback { · 95 unmodified lines
173 * - there's one superblock per volume177 * - there's one superblock per volume
174 */178 */
175struct afs_super_info {179struct afs_super_info {
180 struct afs_net *net; /* Network namespace */
176 struct afs_volume *volume; /* volume record */181 struct afs_volume *volume; /* volume record */
177 char rwparent; /* T if parent is R/W AFS volume */182 char rwparent; /* T if parent is R/W AFS volume */
178};183};
@@ -192,12 +197,62 @@ struct afs_cache_cell { · 13 unmodified lines
192 struct in_addr vl_servers[15]; /* cached cell VL servers */197 struct in_addr vl_servers[15]; /* cached cell VL servers */
193};198};
194 199
200/*
201 * AFS network namespace record.
202 */
203struct afs_net {
204 struct afs_uuid uuid;
205 bool live; /* F if this namespace is being removed */
206
207 /* AF_RXRPC I/O stuff */
208 struct socket *socket;
209 struct afs_call *spare_incoming_call;
210 struct work_struct charge_preallocation_work;
211 struct mutex socket_mutex;
212 atomic_t nr_outstanding_calls;
213 atomic_t nr_superblocks;
214
215 /* Cell database */
216 struct list_head cells;
217 struct afs_cell *ws_cell;
218 rwlock_t cells_lock;
219 struct rw_semaphore cells_sem;
220 wait_queue_head_t cells_freeable_wq;
221
222 struct rw_semaphore proc_cells_sem;
223 struct list_head proc_cells;
224
225 /* Volume location database */
226 struct list_head vl_updates; /* VL records in need-update order */
227 struct list_head vl_graveyard; /* Inactive VL records */
228 struct delayed_work vl_reaper;
229 struct delayed_work vl_updater;
230 spinlock_t vl_updates_lock;
231 spinlock_t vl_graveyard_lock;
232
233 /* File locking renewal management */
234 struct mutex lock_manager_mutex;
235
236 /* Server database */
237 struct rb_root servers; /* Active servers */
238 rwlock_t servers_lock;
239 struct list_head server_graveyard; /* Inactive server LRU list */
240 spinlock_t server_graveyard_lock;
241 struct delayed_work server_reaper;
242
243 /* Misc */
244 struct proc_dir_entry *proc_afs; /* /proc/net/afs directory */
245};
246
247extern struct afs_net __afs_net;// Dummy AFS network namespace; TODO: replace with real netns
248
195/*249/*
196 * AFS cell record250 * AFS cell record
197 */251 */
198struct afs_cell {252struct afs_cell {
199 atomic_t usage;253 atomic_t usage;
200 struct list_head link; /* main cell list link */254 struct list_head link; /* main cell list link */
255 struct afs_net *net; /* The network namespace */
201 struct key *anonymous_key; /* anonymous user key for this cell */256 struct key *anonymous_key; /* anonymous user key for this cell */
202 struct list_head proc_link; /* /proc cell list link */257 struct list_head proc_link; /* /proc cell list link */
203#ifdef CONFIG_AFS_FSCACHE258#ifdef CONFIG_AFS_FSCACHE
@@ -411,15 +466,6 @@ struct afs_interface { · 207 unmodified lines
411 unsigned mtu; /* MTU of interface */466 unsigned mtu; /* MTU of interface */
412};467};
413 468
414struct afs_uuid {
415 __be32 time_low; /* low part of timestamp */
416 __be16 time_mid; /* mid part of timestamp */
417 __be16 time_hi_and_version; /* high part of timestamp and version */
418 __u8 clock_seq_hi_and_reserved; /* clock seq hi and variant */
419 __u8 clock_seq_low; /* clock seq low */
420 __u8 node[6]; /* spatially unique node ID (MAC addr) */
421};
422
423/*****************************************************************************/469/*****************************************************************************/
424/*470/*
425 * cache.c471 * cache.c
@@ -440,6 +486,8 @@ extern struct fscache_cookie_def afs_vnode_cache_index_def; · 14 unmodified lines
440/*486/*
441 * callback.c487 * callback.c
442 */488 */
489extern struct workqueue_struct *afs_callback_update_worker;
490
443extern void afs_init_callback_state(struct afs_server *);491extern void afs_init_callback_state(struct afs_server *);
444extern void afs_broken_callback_work(struct work_struct *);492extern void afs_broken_callback_work(struct work_struct *);
445extern void afs_break_callbacks(struct afs_server *, size_t,493extern void afs_break_callbacks(struct afs_server *, size_t,
@@ -448,22 +496,17 @@ extern void afs_discard_callback_on_delete(struct afs_vnode *); · 2 unmodified lines
448extern void afs_give_up_callback(struct afs_vnode *);496extern void afs_give_up_callback(struct afs_vnode *);
449extern void afs_dispatch_give_up_callbacks(struct work_struct *);497extern void afs_dispatch_give_up_callbacks(struct work_struct *);
450extern void afs_flush_callback_breaks(struct afs_server *);498extern void afs_flush_callback_breaks(struct afs_server *);
451extern int __init afs_callback_update_init(void);
452extern void afs_callback_update_kill(void);
453 499
454/*500/*
455 * cell.c501 * cell.c
456 */502 */
457extern struct rw_semaphore afs_proc_cells_sem;
458extern struct list_head afs_proc_cells;
459
460#define afs_get_cell(C) do { atomic_inc(&(C)->usage); } while(0)503#define afs_get_cell(C) do { atomic_inc(&(C)->usage); } while(0)
461extern int afs_cell_init(char *);504extern int afs_cell_init(struct afs_net *, char *);
462extern struct afs_cell *afs_cell_create(const char *, unsigned, char *, bool);505extern struct afs_cell *afs_cell_create(struct afs_net *, const char *, unsigned, char *, bool);
463extern struct afs_cell *afs_cell_lookup(const char *, unsigned, bool);506extern struct afs_cell *afs_cell_lookup(struct afs_net *, const char *, unsigned, bool);
464extern struct afs_cell *afs_grab_cell(struct afs_cell *);507extern struct afs_cell *afs_grab_cell(struct afs_cell *);
465extern void afs_put_cell(struct afs_cell *);508extern void afs_put_cell(struct afs_cell *);
466extern void afs_cell_purge(void);509extern void __net_exit afs_cell_purge(struct afs_net *);
467 510
468/*511/*
469 * cmservice.c512 * cmservice.c
@@ -492,7 +535,8 @@ extern void afs_put_read(struct afs_read *); · 22 unmodified lines
492/*535/*
493 * flock.c536 * flock.c
494 */537 */
495extern void __exit afs_kill_lock_manager(void);538extern struct workqueue_struct *afs_lock_manager;
539
496extern void afs_lock_work(struct work_struct *);540extern void afs_lock_work(struct work_struct *);
497extern void afs_lock_may_be_available(struct afs_vnode *);541extern void afs_lock_may_be_available(struct afs_vnode *);
498extern int afs_lock(struct file *, int, struct file_lock *);542extern int afs_lock(struct file *, int, struct file_lock *);
@@ -504,7 +548,7 @@ extern int afs_flock(struct file *, int, struct file_lock *); · 5 unmodified lines
504extern int afs_fs_fetch_file_status(struct afs_server *, struct key *,548extern int afs_fs_fetch_file_status(struct afs_server *, struct key *,
505 struct afs_vnode *, struct afs_volsync *,549 struct afs_vnode *, struct afs_volsync *,
506 bool);550 bool);
507extern int afs_fs_give_up_callbacks(struct afs_server *, bool);551extern int afs_fs_give_up_callbacks(struct afs_net *, struct afs_server *, bool);
508extern int afs_fs_fetch_data(struct afs_server *, struct key *,552extern int afs_fs_fetch_data(struct afs_server *, struct key *,
509 struct afs_vnode *, struct afs_read *, bool);553 struct afs_vnode *, struct afs_read *, bool);
510extern int afs_fs_create(struct afs_server *, struct key *,554extern int afs_fs_create(struct afs_server *, struct key *,
@@ -554,7 +598,35 @@ extern int afs_drop_inode(struct inode *); · 43 unmodified lines
554 * main.c598 * main.c
555 */599 */
556extern struct workqueue_struct *afs_wq;600extern struct workqueue_struct *afs_wq;
557extern struct afs_uuid afs_uuid;601
602static inline struct afs_net *afs_d2net(struct dentry *dentry)
603{
604 return &__afs_net;
605}
606
607static inline struct afs_net *afs_i2net(struct inode *inode)
608{
609 return &__afs_net;
610}
611
612static inline struct afs_net *afs_v2net(struct afs_vnode *vnode)
613{
614 return &__afs_net;
615}
616
617static inline struct afs_net *afs_sock2net(struct sock *sk)
618{
619 return &__afs_net;
620}
621
622static inline struct afs_net *afs_get_net(struct afs_net *net)
623{
624 return net;
625}
626
627static inline void afs_put_net(struct afs_net *net)
628{
629}
558 630
559/*631/*
560 * misc.c632 * misc.c
@@ -579,23 +651,24 @@ extern int afs_get_ipv4_interfaces(struct afs_interface *, size_t, bool); · 18 unmodified lines
579/*651/*
580 * proc.c652 * proc.c
581 */653 */
582extern int afs_proc_init(void);654extern int __net_init afs_proc_init(struct afs_net *);
583extern void afs_proc_cleanup(void);655extern void __net_exit afs_proc_cleanup(struct afs_net *);
584extern int afs_proc_cell_setup(struct afs_cell *);656extern int afs_proc_cell_setup(struct afs_net *, struct afs_cell *);
585extern void afs_proc_cell_remove(struct afs_cell *);657extern void afs_proc_cell_remove(struct afs_net *, struct afs_cell *);
586 658
587/*659/*
588 * rxrpc.c660 * rxrpc.c
589 */661 */
590extern struct socket *afs_socket;662extern struct workqueue_struct *afs_async_calls;
591extern atomic_t afs_outstanding_calls;
592 663
593extern int afs_open_socket(void);664extern int __net_init afs_open_socket(struct afs_net *);
594extern void afs_close_socket(void);665extern void __net_exit afs_close_socket(struct afs_net *);
666extern void afs_charge_preallocation(struct work_struct *);
595extern void afs_put_call(struct afs_call *);667extern void afs_put_call(struct afs_call *);
596extern int afs_queue_call_work(struct afs_call *);668extern int afs_queue_call_work(struct afs_call *);
597extern int afs_make_call(struct in_addr *, struct afs_call *, gfp_t, bool);669extern int afs_make_call(struct in_addr *, struct afs_call *, gfp_t, bool);
598extern struct afs_call *afs_alloc_flat_call(const struct afs_call_type *,670extern struct afs_call *afs_alloc_flat_call(struct afs_net *,
671 const struct afs_call_type *,
599 size_t, size_t);672 size_t, size_t);
600extern void afs_flat_call_destructor(struct afs_call *);673extern void afs_flat_call_destructor(struct afs_call *);
601extern void afs_send_empty_reply(struct afs_call *);674extern void afs_send_empty_reply(struct afs_call *);
@@ -629,37 +702,45 @@ do { \ · 27 unmodified lines
629 702
630extern struct afs_server *afs_lookup_server(struct afs_cell *,703extern struct afs_server *afs_lookup_server(struct afs_cell *,
631 const struct in_addr *);704 const struct in_addr *);
632extern struct afs_server *afs_find_server(const struct sockaddr_rxrpc *);705extern struct afs_server *afs_find_server(struct afs_net *,
706 const struct sockaddr_rxrpc *);
633extern void afs_put_server(struct afs_server *);707extern void afs_put_server(struct afs_server *);
634extern void __exit afs_purge_servers(void);708extern void afs_reap_server(struct work_struct *);
709extern void __net_exit afs_purge_servers(struct afs_net *);
635 710
636/*711/*
637 * super.c712 * super.c
638 */713 */
639extern int afs_fs_init(void);714extern int __init afs_fs_init(void);
640extern void afs_fs_exit(void);715extern void __exit afs_fs_exit(void);
641 716
642/*717/*
643 * vlclient.c718 * vlclient.c
644 */719 */
645extern int afs_vl_get_entry_by_name(struct in_addr *, struct key *,720extern int afs_vl_get_entry_by_name(struct afs_net *,
721 struct in_addr *, struct key *,
646 const char *, struct afs_cache_vlocation *,722 const char *, struct afs_cache_vlocation *,
647 bool);723 bool);
648extern int afs_vl_get_entry_by_id(struct in_addr *, struct key *,724extern int afs_vl_get_entry_by_id(struct afs_net *,
725 struct in_addr *, struct key *,
649 afs_volid_t, afs_voltype_t,726 afs_volid_t, afs_voltype_t,
650 struct afs_cache_vlocation *, bool);727 struct afs_cache_vlocation *, bool);
651 728
652/*729/*
653 * vlocation.c730 * vlocation.c
654 */731 */
732extern struct workqueue_struct *afs_vlocation_update_worker;
733
655#define afs_get_vlocation(V) do { atomic_inc(&(V)->usage); } while(0)734#define afs_get_vlocation(V) do { atomic_inc(&(V)->usage); } while(0)
656 735
657extern int __init afs_vlocation_update_init(void);736extern struct afs_vlocation *afs_vlocation_lookup(struct afs_net *,
658extern struct afs_vlocation *afs_vlocation_lookup(struct afs_cell *,737 struct afs_cell *,
659 struct key *,738 struct key *,
660 const char *, size_t);739 const char *, size_t);
661extern void afs_put_vlocation(struct afs_vlocation *);740extern void afs_put_vlocation(struct afs_net *, struct afs_vlocation *);
662extern void afs_vlocation_purge(void);741extern void afs_vlocation_updater(struct work_struct *);
742extern void afs_vlocation_reaper(struct work_struct *);
743extern void __net_exit afs_vlocation_purge(struct afs_net *);
663 744
664/*745/*
665 * vnode.c746 * vnode.c
@@ -707,7 +788,7 @@ extern int afs_vnode_release_lock(struct afs_vnode *, struct key *); · 41 unmodified lines
707 */788 */
708#define afs_get_volume(V) do { atomic_inc(&(V)->usage); } while(0)789#define afs_get_volume(V) do { atomic_inc(&(V)->usage); } while(0)
709 790
710extern void afs_put_volume(struct afs_volume *);791extern void afs_put_volume(struct afs_net *, struct afs_volume *);
711extern struct afs_volume *afs_volume_lookup(struct afs_mount_params *);792extern struct afs_volume *afs_volume_lookup(struct afs_mount_params *);
712extern struct afs_server *afs_volume_pick_fileserver(struct afs_vnode *);793extern struct afs_server *afs_volume_pick_fileserver(struct afs_vnode *);
713extern int afs_volume_release_fileserver(struct afs_vnode *,794extern int afs_volume_release_fileserver(struct afs_vnode *,
fs/afs/main.c+105−48
@@ -31,30 +31,104 @@ static char *rootcell; · 30 unmodified lines
31module_param(rootcell, charp, 0);31module_param(rootcell, charp, 0);
32MODULE_PARM_DESC(rootcell, "root AFS cell name and VL server IP addr list");32MODULE_PARM_DESC(rootcell, "root AFS cell name and VL server IP addr list");
33 33
34struct afs_uuid afs_uuid;
35struct workqueue_struct *afs_wq;34struct workqueue_struct *afs_wq;
35struct afs_net __afs_net;
36
37/*
38 * Initialise an AFS network namespace record.
39 */
40static int __net_init afs_net_init(struct afs_net *net)
41{
42 int ret;
43
44 net->live = true;
45 generate_random_uuid((unsigned char *)&net->uuid);
46
47 INIT_WORK(&net->charge_preallocation_work, afs_charge_preallocation);
48 mutex_init(&net->socket_mutex);
49 INIT_LIST_HEAD(&net->cells);
50 rwlock_init(&net->cells_lock);
51 init_rwsem(&net->cells_sem);
52 init_waitqueue_head(&net->cells_freeable_wq);
53 init_rwsem(&net->proc_cells_sem);
54 INIT_LIST_HEAD(&net->proc_cells);
55 INIT_LIST_HEAD(&net->vl_updates);
56 INIT_LIST_HEAD(&net->vl_graveyard);
57 INIT_DELAYED_WORK(&net->vl_reaper, afs_vlocation_reaper);
58 INIT_DELAYED_WORK(&net->vl_updater, afs_vlocation_updater);
59 spin_lock_init(&net->vl_updates_lock);
60 spin_lock_init(&net->vl_graveyard_lock);
61 net->servers = RB_ROOT;
62 rwlock_init(&net->servers_lock);
63 INIT_LIST_HEAD(&net->server_graveyard);
64 spin_lock_init(&net->server_graveyard_lock);
65 INIT_DELAYED_WORK(&net->server_reaper, afs_reap_server);
66
67 /* Register the /proc stuff */
68 ret = afs_proc_init(net);
69 if (ret < 0)
70 goto error_proc;
71
72 /* Initialise the cell DB */
73 ret = afs_cell_init(net, rootcell);
74 if (ret < 0)
75 goto error_cell_init;
76
77 /* Create the RxRPC transport */
78 ret = afs_open_socket(net);
79 if (ret < 0)
80 goto error_open_socket;
81
82 return 0;
83
84error_open_socket:
85 afs_vlocation_purge(net);
86 afs_cell_purge(net);
87error_cell_init:
88 afs_proc_cleanup(net);
89error_proc:
90 return ret;
91}
92
93/*
94 * Clean up and destroy an AFS network namespace record.
95 */
96static void __net_exit afs_net_exit(struct afs_net *net)
97{
98 net->live = false;
99 afs_close_socket(net);
100 afs_purge_servers(net);
101 afs_vlocation_purge(net);
102 afs_cell_purge(net);
103 afs_proc_cleanup(net);
104}
36 105
37/*106/*
38 * initialise the AFS client FS module107 * initialise the AFS client FS module
39 */108 */
40static int __init afs_init(void)109static int __init afs_init(void)
41{110{
42 int ret;111 int ret = -ENOMEM;
43 112
44 printk(KERN_INFO "kAFS: Red Hat AFS client v0.1 registering.\n");113 printk(KERN_INFO "kAFS: Red Hat AFS client v0.1 registering.\n");
45 114
46 generate_random_uuid((unsigned char *)&afs_uuid);
47
48 /* create workqueue */
49 ret = -ENOMEM;
50 afs_wq = alloc_workqueue("afs", 0, 0);115 afs_wq = alloc_workqueue("afs", 0, 0);
51 if (!afs_wq)116 if (!afs_wq)
52 return ret;117 goto error_afs_wq;
53 118 afs_async_calls = alloc_workqueue("kafsd", WQ_MEM_RECLAIM, 0);
54 /* register the /proc stuff */119 if (!afs_async_calls)
55 ret = afs_proc_init();120 goto error_async;
56 if (ret < 0)121 afs_vlocation_update_worker =
57 goto error_proc;122 alloc_workqueue("kafs_vlupdated", WQ_MEM_RECLAIM, 0);
123 if (!afs_vlocation_update_worker)
124 goto error_vl_up;
125 afs_callback_update_worker =
126 alloc_ordered_workqueue("kafs_callbackd", WQ_MEM_RECLAIM);
127 if (!afs_callback_update_worker)
128 goto error_callback;
129 afs_lock_manager = alloc_workqueue("kafs_lockd", WQ_MEM_RECLAIM, 0);
130 if (!afs_lock_manager)
131 goto error_lockmgr;
58 132
59#ifdef CONFIG_AFS_FSCACHE133#ifdef CONFIG_AFS_FSCACHE
60 /* we want to be able to cache */134 /* we want to be able to cache */
@@ -63,25 +137,9 @@ static int __init afs_init(void) · 2 unmodified lines
63 goto error_cache;137 goto error_cache;
64#endif138#endif
65 139
66 /* initialise the cell DB */140 ret = afs_net_init(&__afs_net);
67 ret = afs_cell_init(rootcell);
68 if (ret < 0)
69 goto error_cell_init;
70
71 /* initialise the VL update process */
72 ret = afs_vlocation_update_init();
73 if (ret < 0)
74 goto error_vl_update_init;
75
76 /* initialise the callback update process */
77 ret = afs_callback_update_init();
78 if (ret < 0)141 if (ret < 0)
79 goto error_callback_update_init;142 goto error_net;
80
81 /* create the RxRPC transport */
82 ret = afs_open_socket();
83 if (ret < 0)
84 goto error_open_socket;
85 143
86 /* register the filesystems */144 /* register the filesystems */
87 ret = afs_fs_init();145 ret = afs_fs_init();
@@ -91,21 +149,22 @@ static int __init afs_init(void) · 3 unmodified lines
91 return ret;149 return ret;
92 150
93error_fs:151error_fs:
94 afs_close_socket();152 afs_net_exit(&__afs_net);
95error_open_socket:153error_net:
96 afs_callback_update_kill();
97error_callback_update_init:
98 afs_vlocation_purge();
99error_vl_update_init:
100 afs_cell_purge();
101error_cell_init:
102#ifdef CONFIG_AFS_FSCACHE154#ifdef CONFIG_AFS_FSCACHE
103 fscache_unregister_netfs(&afs_cache_netfs);155 fscache_unregister_netfs(&afs_cache_netfs);
104error_cache:156error_cache:
105#endif157#endif
106 afs_proc_cleanup();158 destroy_workqueue(afs_lock_manager);
107error_proc:159error_lockmgr:
160 destroy_workqueue(afs_callback_update_worker);
161error_callback:
162 destroy_workqueue(afs_vlocation_update_worker);
163error_vl_up:
164 destroy_workqueue(afs_async_calls);
165error_async:
108 destroy_workqueue(afs_wq);166 destroy_workqueue(afs_wq);
167error_afs_wq:
109 rcu_barrier();168 rcu_barrier();
110 printk(KERN_ERR "kAFS: failed to register: %d\n", ret);169 printk(KERN_ERR "kAFS: failed to register: %d\n", ret);
111 return ret;170 return ret;
@@ -124,17 +183,15 @@ static void __exit afs_exit(void) · 12 unmodified lines
124 printk(KERN_INFO "kAFS: Red Hat AFS client v0.1 unregistering.\n");183 printk(KERN_INFO "kAFS: Red Hat AFS client v0.1 unregistering.\n");
125 184
126 afs_fs_exit();185 afs_fs_exit();
127 afs_kill_lock_manager();186 afs_net_exit(&__afs_net);
128 afs_close_socket();
129 afs_purge_servers();
130 afs_callback_update_kill();
131 afs_vlocation_purge();
132 destroy_workqueue(afs_wq);
133 afs_cell_purge();
134#ifdef CONFIG_AFS_FSCACHE187#ifdef CONFIG_AFS_FSCACHE
135 fscache_unregister_netfs(&afs_cache_netfs);188 fscache_unregister_netfs(&afs_cache_netfs);
136#endif189#endif
137 afs_proc_cleanup();190 destroy_workqueue(afs_lock_manager);
191 destroy_workqueue(afs_callback_update_worker);
192 destroy_workqueue(afs_vlocation_update_worker);
193 destroy_workqueue(afs_async_calls);
194 destroy_workqueue(afs_wq);
138 rcu_barrier();195 rcu_barrier();
139}196}
140 197
fs/afs/proc.c+40−24
@@ -17,8 +17,15 @@ · 16 unmodified lines
17#include <linux/uaccess.h>17#include <linux/uaccess.h>
18#include "internal.h"18#include "internal.h"
19 19
20static struct proc_dir_entry *proc_afs;20static inline struct afs_net *afs_proc2net(struct file *f)
21{
22 return &__afs_net;
23}
21 24
25static inline struct afs_net *afs_seq2net(struct seq_file *m)
26{
27 return &__afs_net; // TODO: use seq_file_net(m)
28}
22 29
23static int afs_proc_cells_open(struct inode *inode, struct file *file);30static int afs_proc_cells_open(struct inode *inode, struct file *file);
24static void *afs_proc_cells_start(struct seq_file *p, loff_t *pos);31static void *afs_proc_cells_start(struct seq_file *p, loff_t *pos);
@@ -122,23 +129,23 @@ static const struct file_operations afs_proc_cell_servers_fops = { · 97 unmodified lines
122/*129/*
123 * initialise the /proc/fs/afs/ directory130 * initialise the /proc/fs/afs/ directory
124 */131 */
125int afs_proc_init(void)132int afs_proc_init(struct afs_net *net)
126{133{
127 _enter("");134 _enter("");
128 135
129 proc_afs = proc_mkdir("fs/afs", NULL);136 net->proc_afs = proc_mkdir("fs/afs", NULL);
130 if (!proc_afs)137 if (!net->proc_afs)
131 goto error_dir;138 goto error_dir;
132 139
133 if (!proc_create("cells", 0644, proc_afs, &afs_proc_cells_fops) ||140 if (!proc_create("cells", 0644, net->proc_afs, &afs_proc_cells_fops) ||
134 !proc_create("rootcell", 0644, proc_afs, &afs_proc_rootcell_fops))141 !proc_create("rootcell", 0644, net->proc_afs, &afs_proc_rootcell_fops))
135 goto error_tree;142 goto error_tree;
136 143
137 _leave(" = 0");144 _leave(" = 0");
138 return 0;145 return 0;
139 146
140error_tree:147error_tree:
141 remove_proc_subtree("fs/afs", NULL);148 proc_remove(net->proc_afs);
142error_dir:149error_dir:
143 _leave(" = -ENOMEM");150 _leave(" = -ENOMEM");
144 return -ENOMEM;151 return -ENOMEM;
@@ -147,9 +154,10 @@ error_dir: · 2 unmodified lines
147/*154/*
148 * clean up the /proc/fs/afs/ directory155 * clean up the /proc/fs/afs/ directory
149 */156 */
150void afs_proc_cleanup(void)157void afs_proc_cleanup(struct afs_net *net)
151{158{
152 remove_proc_subtree("fs/afs", NULL);159 proc_remove(net->proc_afs);
160 net->proc_afs = NULL;
153}161}
154 162
155/*163/*
@@ -176,25 +184,30 @@ static int afs_proc_cells_open(struct inode *inode, struct file *file) · 20 unmodified lines
176 */184 */
177static void *afs_proc_cells_start(struct seq_file *m, loff_t *_pos)185static void *afs_proc_cells_start(struct seq_file *m, loff_t *_pos)
178{186{
179 /* lock the list against modification */187 struct afs_net *net = afs_seq2net(m);
180 down_read(&afs_proc_cells_sem);188
181 return seq_list_start_head(&afs_proc_cells, *_pos);189 down_read(&net->proc_cells_sem);
190 return seq_list_start_head(&net->proc_cells, *_pos);
182}191}
183 192
184/*193/*
185 * move to next cell in cells list194 * move to next cell in cells list
186 */195 */
187static void *afs_proc_cells_next(struct seq_file *p, void *v, loff_t *pos)196static void *afs_proc_cells_next(struct seq_file *m, void *v, loff_t *pos)
188{197{
189 return seq_list_next(v, &afs_proc_cells, pos);198 struct afs_net *net = afs_seq2net(m);
199
200 return seq_list_next(v, &net->proc_cells, pos);
190}201}
191 202
192/*203/*
193 * clean up after reading from the cells list204 * clean up after reading from the cells list
194 */205 */
195static void afs_proc_cells_stop(struct seq_file *p, void *v)206static void afs_proc_cells_stop(struct seq_file *m, void *v)
196{207{
197 up_read(&afs_proc_cells_sem);208 struct afs_net *net = afs_seq2net(m);
209
210 up_read(&net->proc_cells_sem);
198}211}
199 212
200/*213/*
@@ -203,8 +216,9 @@ static void afs_proc_cells_stop(struct seq_file *p, void *v) · 2 unmodified lines
203static int afs_proc_cells_show(struct seq_file *m, void *v)216static int afs_proc_cells_show(struct seq_file *m, void *v)
204{217{
205 struct afs_cell *cell = list_entry(v, struct afs_cell, proc_link);218 struct afs_cell *cell = list_entry(v, struct afs_cell, proc_link);
219 struct afs_net *net = afs_seq2net(m);
206 220
207 if (v == &afs_proc_cells) {221 if (v == &net->proc_cells) {
208 /* display header on line 1 */222 /* display header on line 1 */
209 seq_puts(m, "USE NAME\n");223 seq_puts(m, "USE NAME\n");
210 return 0;224 return 0;
@@ -223,6 +237,7 @@ static int afs_proc_cells_show(struct seq_file *m, void *v) · 12 unmodified lines
223static ssize_t afs_proc_cells_write(struct file *file, const char __user *buf,237static ssize_t afs_proc_cells_write(struct file *file, const char __user *buf,
224 size_t size, loff_t *_pos)238 size_t size, loff_t *_pos)
225{239{
240 struct afs_net *net = afs_proc2net(file);
226 char *kbuf, *name, *args;241 char *kbuf, *name, *args;
227 int ret;242 int ret;
228 243
@@ -264,7 +279,7 @@ static ssize_t afs_proc_cells_write(struct file *file, const char __user *buf, · 35 unmodified lines
264 if (strcmp(kbuf, "add") == 0) {279 if (strcmp(kbuf, "add") == 0) {
265 struct afs_cell *cell;280 struct afs_cell *cell;
266 281
267 cell = afs_cell_create(name, strlen(name), args, false);282 cell = afs_cell_create(net, name, strlen(name), args, false);
268 if (IS_ERR(cell)) {283 if (IS_ERR(cell)) {
269 ret = PTR_ERR(cell);284 ret = PTR_ERR(cell);
270 goto done;285 goto done;
@@ -303,6 +318,7 @@ static ssize_t afs_proc_rootcell_write(struct file *file, · 32 unmodified lines
303 const char __user *buf,318 const char __user *buf,
304 size_t size, loff_t *_pos)319 size_t size, loff_t *_pos)
305{320{
321 struct afs_net *net = afs_proc2net(file);
306 char *kbuf, *s;322 char *kbuf, *s;
307 int ret;323 int ret;
308 324
@@ -322,7 +338,7 @@ static ssize_t afs_proc_rootcell_write(struct file *file, · 13 unmodified lines
322 /* determine command to perform */338 /* determine command to perform */
323 _debug("rootcell=%s", kbuf);339 _debug("rootcell=%s", kbuf);
324 340
325 ret = afs_cell_init(kbuf);341 ret = afs_cell_init(net, kbuf);
326 if (ret >= 0)342 if (ret >= 0)
327 ret = size; /* consume everything, always */343 ret = size; /* consume everything, always */
328 344
@@ -334,13 +350,13 @@ static ssize_t afs_proc_rootcell_write(struct file *file, · 5 unmodified lines
334/*350/*
335 * initialise /proc/fs/afs/<cell>/351 * initialise /proc/fs/afs/<cell>/
336 */352 */
337int afs_proc_cell_setup(struct afs_cell *cell)353int afs_proc_cell_setup(struct afs_net *net, struct afs_cell *cell)
338{354{
339 struct proc_dir_entry *dir;355 struct proc_dir_entry *dir;
340 356
341 _enter("%p{%s}", cell, cell->name);357 _enter("%p{%s}", cell, cell->name);
342 358
343 dir = proc_mkdir(cell->name, proc_afs);359 dir = proc_mkdir(cell->name, net->proc_afs);
344 if (!dir)360 if (!dir)
345 goto error_dir;361 goto error_dir;
346 362
@@ -356,7 +372,7 @@ int afs_proc_cell_setup(struct afs_cell *cell) · 9 unmodified lines
356 return 0;372 return 0;
357 373
358error_tree:374error_tree:
359 remove_proc_subtree(cell->name, proc_afs);375 remove_proc_subtree(cell->name, net->proc_afs);
360error_dir:376error_dir:
361 _leave(" = -ENOMEM");377 _leave(" = -ENOMEM");
362 return -ENOMEM;378 return -ENOMEM;
@@ -365,11 +381,11 @@ error_dir: · 2 unmodified lines
365/*381/*
366 * remove /proc/fs/afs/<cell>/382 * remove /proc/fs/afs/<cell>/
367 */383 */
368void afs_proc_cell_remove(struct afs_cell *cell)384void afs_proc_cell_remove(struct afs_net *net, struct afs_cell *cell)
369{385{
370 _enter("");386 _enter("");
371 387
372 remove_proc_subtree(cell->name, proc_afs);388 remove_proc_subtree(cell->name, net->proc_afs);
373 389
374 _leave("");390 _leave("");
375}391}
fs/afs/rxrpc.c+65−67
@@ -17,10 +17,7 @@ · 16 unmodified lines
17#include "internal.h"17#include "internal.h"
18#include "afs_cm.h"18#include "afs_cm.h"
19 19
20struct socket *afs_socket; /* my RxRPC socket */20struct workqueue_struct *afs_async_calls;
21static struct workqueue_struct *afs_async_calls;
22static struct afs_call *afs_spare_incoming_call;
23atomic_t afs_outstanding_calls;
24 21
25static void afs_wake_up_call_waiter(struct sock *, struct rxrpc_call *, unsigned long);22static void afs_wake_up_call_waiter(struct sock *, struct rxrpc_call *, unsigned long);
26static int afs_wait_for_call_to_complete(struct afs_call *);23static int afs_wait_for_call_to_complete(struct afs_call *);
@@ -37,15 +34,11 @@ static const struct afs_call_type afs_RXCMxxxx = { · 10 unmodified lines
37 .abort_to_error = afs_abort_to_error,34 .abort_to_error = afs_abort_to_error,
38};35};
39 36
40static void afs_charge_preallocation(struct work_struct *);
41
42static DECLARE_WORK(afs_charge_preallocation_work, afs_charge_preallocation);
43
44/*37/*
45 * open an RxRPC socket and bind it to be a server for callback notifications38 * open an RxRPC socket and bind it to be a server for callback notifications
46 * - the socket is left in blocking mode and non-blocking ops use MSG_DONTWAIT39 * - the socket is left in blocking mode and non-blocking ops use MSG_DONTWAIT
47 */40 */
48int afs_open_socket(void)41int afs_open_socket(struct afs_net *net)
49{42{
50 struct sockaddr_rxrpc srx;43 struct sockaddr_rxrpc srx;
51 struct socket *socket;44 struct socket *socket;
@@ -53,11 +46,6 @@ int afs_open_socket(void) · 1 unmodified line
53 46
54 _enter("");47 _enter("");
55 48
56 ret = -ENOMEM;
57 afs_async_calls = alloc_workqueue("kafsd", WQ_MEM_RECLAIM, 0);
58 if (!afs_async_calls)
59 goto error_0;
60
61 ret = sock_create_kern(&init_net, AF_RXRPC, SOCK_DGRAM, PF_INET, &socket);49 ret = sock_create_kern(&init_net, AF_RXRPC, SOCK_DGRAM, PF_INET, &socket);
62 if (ret < 0)50 if (ret < 0)
63 goto error_1;51 goto error_1;
@@ -85,16 +73,14 @@ int afs_open_socket(void) · 21 unmodified lines
85 if (ret < 0)73 if (ret < 0)
86 goto error_2;74 goto error_2;
87 75
88 afs_socket = socket;76 net->socket = socket;
89 afs_charge_preallocation(NULL);77 afs_charge_preallocation(&net->charge_preallocation_work);
90 _leave(" = 0");78 _leave(" = 0");
91 return 0;79 return 0;
92 80
93error_2:81error_2:
94 sock_release(socket);82 sock_release(socket);
95error_1:83error_1:
96 destroy_workqueue(afs_async_calls);
97error_0:
98 _leave(" = %d", ret);84 _leave(" = %d", ret);
99 return ret;85 return ret;
100}86}
@@ -102,36 +88,36 @@ error_0: · 1 unmodified line
102/*88/*
103 * close the RxRPC socket AFS was using89 * close the RxRPC socket AFS was using
104 */90 */
105void afs_close_socket(void)91void afs_close_socket(struct afs_net *net)
106{92{
107 _enter("");93 _enter("");
108 94
109 kernel_listen(afs_socket, 0);95 kernel_listen(net->socket, 0);
110 flush_workqueue(afs_async_calls);96 flush_workqueue(afs_async_calls);
111 97
112 if (afs_spare_incoming_call) {98 if (net->spare_incoming_call) {
113 afs_put_call(afs_spare_incoming_call);99 afs_put_call(net->spare_incoming_call);
114 afs_spare_incoming_call = NULL;100 net->spare_incoming_call = NULL;
115 }101 }
116 102
117 _debug("outstanding %u", atomic_read(&afs_outstanding_calls));103 _debug("outstanding %u", atomic_read(&net->nr_outstanding_calls));
118 wait_on_atomic_t(&afs_outstanding_calls, atomic_t_wait,104 wait_on_atomic_t(&net->nr_outstanding_calls, atomic_t_wait,
119 TASK_UNINTERRUPTIBLE);105 TASK_UNINTERRUPTIBLE);
120 _debug("no outstanding calls");106 _debug("no outstanding calls");
121 107
122 kernel_sock_shutdown(afs_socket, SHUT_RDWR);108 kernel_sock_shutdown(net->socket, SHUT_RDWR);
123 flush_workqueue(afs_async_calls);109 flush_workqueue(afs_async_calls);
124 sock_release(afs_socket);110 sock_release(net->socket);
125 111
126 _debug("dework");112 _debug("dework");
127 destroy_workqueue(afs_async_calls);
128 _leave("");113 _leave("");
129}114}
130 115
131/*116/*
132 * Allocate a call.117 * Allocate a call.
133 */118 */
134static struct afs_call *afs_alloc_call(const struct afs_call_type *type,119static struct afs_call *afs_alloc_call(struct afs_net *net,
120 const struct afs_call_type *type,
135 gfp_t gfp)121 gfp_t gfp)
136{122{
137 struct afs_call *call;123 struct afs_call *call;
@@ -142,11 +128,12 @@ static struct afs_call *afs_alloc_call(const struct afs_call_type *type, · 4 unmodified lines
142 return NULL;128 return NULL;
143 129
144 call->type = type;130 call->type = type;
131 call->net = net;
145 atomic_set(&call->usage, 1);132 atomic_set(&call->usage, 1);
146 INIT_WORK(&call->async_work, afs_process_async_call);133 INIT_WORK(&call->async_work, afs_process_async_call);
147 init_waitqueue_head(&call->waitq);134 init_waitqueue_head(&call->waitq);
148 135
149 o = atomic_inc_return(&afs_outstanding_calls);136 o = atomic_inc_return(&net->nr_outstanding_calls);
150 trace_afs_call(call, afs_call_trace_alloc, 1, o,137 trace_afs_call(call, afs_call_trace_alloc, 1, o,
151 __builtin_return_address(0));138 __builtin_return_address(0));
152 return call;139 return call;
@@ -157,8 +144,9 @@ static struct afs_call *afs_alloc_call(const struct afs_call_type *type, · 4 unmodified lines
157 */144 */
158void afs_put_call(struct afs_call *call)145void afs_put_call(struct afs_call *call)
159{146{
147 struct afs_net *net = call->net;
160 int n = atomic_dec_return(&call->usage);148 int n = atomic_dec_return(&call->usage);
161 int o = atomic_read(&afs_outstanding_calls);149 int o = atomic_read(&net->nr_outstanding_calls);
162 150
163 trace_afs_call(call, afs_call_trace_put, n + 1, o,151 trace_afs_call(call, afs_call_trace_put, n + 1, o,
164 __builtin_return_address(0));152 __builtin_return_address(0));
@@ -169,7 +157,7 @@ void afs_put_call(struct afs_call *call) · 4 unmodified lines
169 ASSERT(call->type->name != NULL);157 ASSERT(call->type->name != NULL);
170 158
171 if (call->rxcall) {159 if (call->rxcall) {
172 rxrpc_kernel_end_call(afs_socket, call->rxcall);160 rxrpc_kernel_end_call(net->socket, call->rxcall);
173 call->rxcall = NULL;161 call->rxcall = NULL;
174 }162 }
175 if (call->type->destructor)163 if (call->type->destructor)
@@ -178,11 +166,11 @@ void afs_put_call(struct afs_call *call) · 2 unmodified lines
178 kfree(call->request);166 kfree(call->request);
179 kfree(call);167 kfree(call);
180 168
181 o = atomic_dec_return(&afs_outstanding_calls);169 o = atomic_dec_return(&net->nr_outstanding_calls);
182 trace_afs_call(call, afs_call_trace_free, 0, o,170 trace_afs_call(call, afs_call_trace_free, 0, o,
183 __builtin_return_address(0));171 __builtin_return_address(0));
184 if (o == 0)172 if (o == 0)
185 wake_up_atomic_t(&afs_outstanding_calls);173 wake_up_atomic_t(&net->nr_outstanding_calls);
186 }174 }
187}175}
188 176
@@ -194,7 +182,7 @@ int afs_queue_call_work(struct afs_call *call) · 5 unmodified lines
194 int u = atomic_inc_return(&call->usage);182 int u = atomic_inc_return(&call->usage);
195 183
196 trace_afs_call(call, afs_call_trace_work, u,184 trace_afs_call(call, afs_call_trace_work, u,
197 atomic_read(&afs_outstanding_calls),185 atomic_read(&call->net->nr_outstanding_calls),
198 __builtin_return_address(0));186 __builtin_return_address(0));
199 187
200 INIT_WORK(&call->work, call->type->work);188 INIT_WORK(&call->work, call->type->work);
@@ -207,12 +195,13 @@ int afs_queue_call_work(struct afs_call *call) · 6 unmodified lines
207/*195/*
208 * allocate a call with flat request and reply buffers196 * allocate a call with flat request and reply buffers
209 */197 */
210struct afs_call *afs_alloc_flat_call(const struct afs_call_type *type,198struct afs_call *afs_alloc_flat_call(struct afs_net *net,
199 const struct afs_call_type *type,
211 size_t request_size, size_t reply_max)200 size_t request_size, size_t reply_max)
212{201{
213 struct afs_call *call;202 struct afs_call *call;
214 203
215 call = afs_alloc_call(type, GFP_NOFS);204 call = afs_alloc_call(net, type, GFP_NOFS);
216 if (!call)205 if (!call)
217 goto nomem_call;206 goto nomem_call;
218 207
@@ -317,7 +306,7 @@ static int afs_send_pages(struct afs_call *call, struct msghdr *msg) · 98 unmodified lines
317 bytes = msg->msg_iter.count;306 bytes = msg->msg_iter.count;
318 nr = msg->msg_iter.nr_segs;307 nr = msg->msg_iter.nr_segs;
319 308
320 ret = rxrpc_kernel_send_data(afs_socket, call->rxcall, msg,309 ret = rxrpc_kernel_send_data(call->net->socket, call->rxcall, msg,
321 bytes, afs_notify_end_request_tx);310 bytes, afs_notify_end_request_tx);
322 for (loop = 0; loop < nr; loop++)311 for (loop = 0; loop < nr; loop++)
323 put_page(bv[loop].bv_page);312 put_page(bv[loop].bv_page);
@@ -352,7 +341,7 @@ int afs_make_call(struct in_addr *addr, struct afs_call *call, gfp_t gfp, · 28 unmodified lines
352 341
353 _debug("____MAKE %p{%s,%x} [%d]____",342 _debug("____MAKE %p{%s,%x} [%d]____",
354 call, call->type->name, key_serial(call->key),343 call, call->type->name, key_serial(call->key),
355 atomic_read(&afs_outstanding_calls));344 atomic_read(&call->net->nr_outstanding_calls));
356 345
357 call->async = async;346 call->async = async;
358 347
@@ -376,7 +365,7 @@ int afs_make_call(struct in_addr *addr, struct afs_call *call, gfp_t gfp, · 17 unmodified lines
376 }365 }
377 366
378 /* create a call */367 /* create a call */
379 rxcall = rxrpc_kernel_begin_call(afs_socket, &srx, call->key,368 rxcall = rxrpc_kernel_begin_call(call->net->socket, &srx, call->key,
380 (unsigned long)call,369 (unsigned long)call,
381 tx_total_len, gfp,370 tx_total_len, gfp,
382 (async ?371 (async ?
@@ -410,7 +399,7 @@ int afs_make_call(struct in_addr *addr, struct afs_call *call, gfp_t gfp, · 27 unmodified lines
410 */399 */
411 if (!call->send_pages)400 if (!call->send_pages)
412 call->state = AFS_CALL_AWAIT_REPLY;401 call->state = AFS_CALL_AWAIT_REPLY;
413 ret = rxrpc_kernel_send_data(afs_socket, rxcall,402 ret = rxrpc_kernel_send_data(call->net->socket, rxcall,
414 &msg, call->request_size,403 &msg, call->request_size,
415 afs_notify_end_request_tx);404 afs_notify_end_request_tx);
416 if (ret < 0)405 if (ret < 0)
@@ -432,13 +421,14 @@ int afs_make_call(struct in_addr *addr, struct afs_call *call, gfp_t gfp, · 15 unmodified lines
432error_do_abort:421error_do_abort:
433 call->state = AFS_CALL_COMPLETE;422 call->state = AFS_CALL_COMPLETE;
434 if (ret != -ECONNABORTED) {423 if (ret != -ECONNABORTED) {
435 rxrpc_kernel_abort_call(afs_socket, rxcall, RX_USER_ABORT,424 rxrpc_kernel_abort_call(call->net->socket, rxcall,
436 ret, "KSD");425 RX_USER_ABORT, ret, "KSD");
437 } else {426 } else {
438 abort_code = 0;427 abort_code = 0;
439 offset = 0;428 offset = 0;
440 rxrpc_kernel_recv_data(afs_socket, rxcall, NULL, 0, &offset,429 rxrpc_kernel_recv_data(call->net->socket, rxcall, NULL,
441 false, &abort_code, &call->service_id);430 0, &offset, false, &abort_code,
431 &call->service_id);
442 ret = call->type->abort_to_error(abort_code);432 ret = call->type->abort_to_error(abort_code);
443 }433 }
444error_kill_call:434error_kill_call:
@@ -464,7 +454,8 @@ static void afs_deliver_to_call(struct afs_call *call) · 19 unmodified lines
464 ) {454 ) {
465 if (call->state == AFS_CALL_AWAIT_ACK) {455 if (call->state == AFS_CALL_AWAIT_ACK) {
466 size_t offset = 0;456 size_t offset = 0;
467 ret = rxrpc_kernel_recv_data(afs_socket, call->rxcall,457 ret = rxrpc_kernel_recv_data(call->net->socket,
458 call->rxcall,
468 NULL, 0, &offset, false,459 NULL, 0, &offset, false,
469 &call->abort_code,460 &call->abort_code,
470 &call->service_id);461 &call->service_id);
@@ -492,12 +483,12 @@ static void afs_deliver_to_call(struct afs_call *call) · 21 unmodified lines
492 goto call_complete;483 goto call_complete;
493 case -ENOTCONN:484 case -ENOTCONN:
494 abort_code = RX_CALL_DEAD;485 abort_code = RX_CALL_DEAD;
495 rxrpc_kernel_abort_call(afs_socket, call->rxcall,486 rxrpc_kernel_abort_call(call->net->socket, call->rxcall,
496 abort_code, ret, "KNC");487 abort_code, ret, "KNC");
497 goto save_error;488 goto save_error;
498 case -ENOTSUPP:489 case -ENOTSUPP:
499 abort_code = RXGEN_OPCODE;490 abort_code = RXGEN_OPCODE;
500 rxrpc_kernel_abort_call(afs_socket, call->rxcall,491 rxrpc_kernel_abort_call(call->net->socket, call->rxcall,
501 abort_code, ret, "KIV");492 abort_code, ret, "KIV");
502 goto save_error;493 goto save_error;
503 case -ENODATA:494 case -ENODATA:
@@ -507,7 +498,7 @@ static void afs_deliver_to_call(struct afs_call *call) · 3 unmodified lines
507 abort_code = RXGEN_CC_UNMARSHAL;498 abort_code = RXGEN_CC_UNMARSHAL;
508 if (call->state != AFS_CALL_AWAIT_REPLY)499 if (call->state != AFS_CALL_AWAIT_REPLY)
509 abort_code = RXGEN_SS_UNMARSHAL;500 abort_code = RXGEN_SS_UNMARSHAL;
510 rxrpc_kernel_abort_call(afs_socket, call->rxcall,501 rxrpc_kernel_abort_call(call->net->socket, call->rxcall,
511 abort_code, -EBADMSG, "KUM");502 abort_code, -EBADMSG, "KUM");
512 goto save_error;503 goto save_error;
513 }504 }
@@ -541,13 +532,13 @@ static int afs_wait_for_call_to_complete(struct afs_call *call) · 27 unmodified lines
541 532
542 _enter("");533 _enter("");
543 534
544 rtt = rxrpc_kernel_get_rtt(afs_socket, call->rxcall);535 rtt = rxrpc_kernel_get_rtt(call->net->socket, call->rxcall);
545 rtt2 = nsecs_to_jiffies64(rtt) * 2;536 rtt2 = nsecs_to_jiffies64(rtt) * 2;
546 if (rtt2 < 2)537 if (rtt2 < 2)
547 rtt2 = 2;538 rtt2 = 2;
548 539
549 timeout = rtt2;540 timeout = rtt2;
550 last_life = rxrpc_kernel_check_life(afs_socket, call->rxcall);541 last_life = rxrpc_kernel_check_life(call->net->socket, call->rxcall);
551 542
552 add_wait_queue(&call->waitq, &myself);543 add_wait_queue(&call->waitq, &myself);
553 for (;;) {544 for (;;) {
@@ -564,7 +555,7 @@ static int afs_wait_for_call_to_complete(struct afs_call *call) · 10 unmodified lines
564 if (call->state == AFS_CALL_COMPLETE)555 if (call->state == AFS_CALL_COMPLETE)
565 break;556 break;
566 557
567 life = rxrpc_kernel_check_life(afs_socket, call->rxcall);558 life = rxrpc_kernel_check_life(call->net->socket, call->rxcall);
568 if (timeout == 0 &&559 if (timeout == 0 &&
569 life == last_life && signal_pending(current))560 life == last_life && signal_pending(current))
570 break;561 break;
@@ -583,7 +574,7 @@ static int afs_wait_for_call_to_complete(struct afs_call *call) · 12 unmodified lines
583 /* Kill off the call if it's still live. */574 /* Kill off the call if it's still live. */
584 if (call->state < AFS_CALL_COMPLETE) {575 if (call->state < AFS_CALL_COMPLETE) {
585 _debug("call interrupted");576 _debug("call interrupted");
586 rxrpc_kernel_abort_call(afs_socket, call->rxcall,577 rxrpc_kernel_abort_call(call->net->socket, call->rxcall,
587 RX_USER_ABORT, -EINTR, "KWI");578 RX_USER_ABORT, -EINTR, "KWI");
588 }579 }
589 580
@@ -621,7 +612,7 @@ static void afs_wake_up_async_call(struct sock *sk, struct rxrpc_call *rxcall, · 31 unmodified lines
621 u = __atomic_add_unless(&call->usage, 1, 0);612 u = __atomic_add_unless(&call->usage, 1, 0);
622 if (u != 0) {613 if (u != 0) {
623 trace_afs_call(call, afs_call_trace_wake, u,614 trace_afs_call(call, afs_call_trace_wake, u,
624 atomic_read(&afs_outstanding_calls),615 atomic_read(&call->net->nr_outstanding_calls),
625 __builtin_return_address(0));616 __builtin_return_address(0));
626 617
627 if (!queue_work(afs_async_calls, &call->async_work))618 if (!queue_work(afs_async_calls, &call->async_work))
@@ -685,13 +676,15 @@ static void afs_rx_attach(struct rxrpc_call *rxcall, unsigned long user_call_ID) · 57 unmodified lines
685/*676/*
686 * Charge the incoming call preallocation.677 * Charge the incoming call preallocation.
687 */678 */
688static void afs_charge_preallocation(struct work_struct *work)679void afs_charge_preallocation(struct work_struct *work)
689{680{
690 struct afs_call *call = afs_spare_incoming_call;681 struct afs_net *net =
682 container_of(work, struct afs_net, charge_preallocation_work);
683 struct afs_call *call = net->spare_incoming_call;
691 684
692 for (;;) {685 for (;;) {
693 if (!call) {686 if (!call) {
694 call = afs_alloc_call(&afs_RXCMxxxx, GFP_KERNEL);687 call = afs_alloc_call(net, &afs_RXCMxxxx, GFP_KERNEL);
695 if (!call)688 if (!call)
696 break;689 break;
697 690
@@ -700,7 +693,7 @@ static void afs_charge_preallocation(struct work_struct *work) · 2 unmodified lines
700 init_waitqueue_head(&call->waitq);693 init_waitqueue_head(&call->waitq);
701 }694 }
702 695
703 if (rxrpc_kernel_charge_accept(afs_socket,696 if (rxrpc_kernel_charge_accept(net->socket,
704 afs_wake_up_async_call,697 afs_wake_up_async_call,
705 afs_rx_attach,698 afs_rx_attach,
706 (unsigned long)call,699 (unsigned long)call,
@@ -708,7 +701,7 @@ static void afs_charge_preallocation(struct work_struct *work) · 1 unmodified line
708 break;701 break;
709 call = NULL;702 call = NULL;
710 }703 }
711 afs_spare_incoming_call = call;704 net->spare_incoming_call = call;
712}705}
713 706
714/*707/*
@@ -729,7 +722,9 @@ static void afs_rx_discard_new_call(struct rxrpc_call *rxcall, · 14 unmodified lines
729static void afs_rx_new_call(struct sock *sk, struct rxrpc_call *rxcall,722static void afs_rx_new_call(struct sock *sk, struct rxrpc_call *rxcall,
730 unsigned long user_call_ID)723 unsigned long user_call_ID)
731{724{
732 queue_work(afs_wq, &afs_charge_preallocation_work);725 struct afs_net *net = afs_sock2net(sk);
726
727 queue_work(afs_wq, &net->charge_preallocation_work);
733}728}
734 729
735/*730/*
@@ -784,11 +779,12 @@ static void afs_notify_end_reply_tx(struct sock *sock, · 48 unmodified lines
784 */779 */
785void afs_send_empty_reply(struct afs_call *call)780void afs_send_empty_reply(struct afs_call *call)
786{781{
782 struct afs_net *net = call->net;
787 struct msghdr msg;783 struct msghdr msg;
788 784
789 _enter("");785 _enter("");
790 786
791 rxrpc_kernel_set_tx_length(afs_socket, call->rxcall, 0);787 rxrpc_kernel_set_tx_length(net->socket, call->rxcall, 0);
792 788
793 msg.msg_name = NULL;789 msg.msg_name = NULL;
794 msg.msg_namelen = 0;790 msg.msg_namelen = 0;
@@ -798,7 +794,7 @@ void afs_send_empty_reply(struct afs_call *call) · 3 unmodified lines
798 msg.msg_flags = 0;794 msg.msg_flags = 0;
799 795
800 call->state = AFS_CALL_AWAIT_ACK;796 call->state = AFS_CALL_AWAIT_ACK;
801 switch (rxrpc_kernel_send_data(afs_socket, call->rxcall, &msg, 0,797 switch (rxrpc_kernel_send_data(net->socket, call->rxcall, &msg, 0,
802 afs_notify_end_reply_tx)) {798 afs_notify_end_reply_tx)) {
803 case 0:799 case 0:
804 _leave(" [replied]");800 _leave(" [replied]");
@@ -806,7 +802,7 @@ void afs_send_empty_reply(struct afs_call *call) · 1 unmodified line
806 802
807 case -ENOMEM:803 case -ENOMEM:
808 _debug("oom");804 _debug("oom");
809 rxrpc_kernel_abort_call(afs_socket, call->rxcall,805 rxrpc_kernel_abort_call(net->socket, call->rxcall,
810 RX_USER_ABORT, -ENOMEM, "KOO");806 RX_USER_ABORT, -ENOMEM, "KOO");
811 default:807 default:
812 _leave(" [error]");808 _leave(" [error]");
@@ -819,13 +815,14 @@ void afs_send_empty_reply(struct afs_call *call) · 6 unmodified lines
819 */815 */
820void afs_send_simple_reply(struct afs_call *call, const void *buf, size_t len)816void afs_send_simple_reply(struct afs_call *call, const void *buf, size_t len)
821{817{
818 struct afs_net *net = call->net;
822 struct msghdr msg;819 struct msghdr msg;
823 struct kvec iov[1];820 struct kvec iov[1];
824 int n;821 int n;
825 822
826 _enter("");823 _enter("");
827 824
828 rxrpc_kernel_set_tx_length(afs_socket, call->rxcall, len);825 rxrpc_kernel_set_tx_length(net->socket, call->rxcall, len);
829 826
830 iov[0].iov_base = (void *) buf;827 iov[0].iov_base = (void *) buf;
831 iov[0].iov_len = len;828 iov[0].iov_len = len;
@@ -837,7 +834,7 @@ void afs_send_simple_reply(struct afs_call *call, const void *buf, size_t len) · 5 unmodified lines
837 msg.msg_flags = 0;834 msg.msg_flags = 0;
838 835
839 call->state = AFS_CALL_AWAIT_ACK;836 call->state = AFS_CALL_AWAIT_ACK;
840 n = rxrpc_kernel_send_data(afs_socket, call->rxcall, &msg, len,837 n = rxrpc_kernel_send_data(net->socket, call->rxcall, &msg, len,
841 afs_notify_end_reply_tx);838 afs_notify_end_reply_tx);
842 if (n >= 0) {839 if (n >= 0) {
843 /* Success */840 /* Success */
@@ -847,7 +844,7 @@ void afs_send_simple_reply(struct afs_call *call, const void *buf, size_t len) · 3 unmodified lines
847 844
848 if (n == -ENOMEM) {845 if (n == -ENOMEM) {
849 _debug("oom");846 _debug("oom");
850 rxrpc_kernel_abort_call(afs_socket, call->rxcall,847 rxrpc_kernel_abort_call(net->socket, call->rxcall,
851 RX_USER_ABORT, -ENOMEM, "KOO");848 RX_USER_ABORT, -ENOMEM, "KOO");
852 }849 }
853 _leave(" [error]");850 _leave(" [error]");
@@ -859,6 +856,7 @@ void afs_send_simple_reply(struct afs_call *call, const void *buf, size_t len) · 5 unmodified lines
859int afs_extract_data(struct afs_call *call, void *buf, size_t count,856int afs_extract_data(struct afs_call *call, void *buf, size_t count,
860 bool want_more)857 bool want_more)
861{858{
859 struct afs_net *net = call->net;
862 int ret;860 int ret;
863 861
864 _enter("{%s,%zu},,%zu,%d",862 _enter("{%s,%zu},,%zu,%d",
@@ -866,7 +864,7 @@ int afs_extract_data(struct afs_call *call, void *buf, size_t count, · 1 unmodified line
866 864
867 ASSERTCMP(call->offset, <=, count);865 ASSERTCMP(call->offset, <=, count);
868 866
869 ret = rxrpc_kernel_recv_data(afs_socket, call->rxcall,867 ret = rxrpc_kernel_recv_data(net->socket, call->rxcall,
870 buf, count, &call->offset,868 buf, count, &call->offset,
871 want_more, &call->abort_code,869 want_more, &call->abort_code,
872 &call->service_id);870 &call->service_id);
fs/afs/server.c+39−43
@@ -15,32 +15,22 @@ · 14 unmodified lines
15 15
16static unsigned afs_server_timeout = 10; /* server timeout in seconds */16static unsigned afs_server_timeout = 10; /* server timeout in seconds */
17 17
18static void afs_reap_server(struct work_struct *);
19
20/* tree of all the servers, indexed by IP address */
21static struct rb_root afs_servers = RB_ROOT;
22static DEFINE_RWLOCK(afs_servers_lock);
23
24/* LRU list of all the servers not currently in use */
25static LIST_HEAD(afs_server_graveyard);
26static DEFINE_SPINLOCK(afs_server_graveyard_lock);
27static DECLARE_DELAYED_WORK(afs_server_reaper, afs_reap_server);
28
29/*18/*
30 * install a server record in the master tree19 * install a server record in the master tree
31 */20 */
32static int afs_install_server(struct afs_server *server)21static int afs_install_server(struct afs_server *server)
33{22{
34 struct afs_server *xserver;23 struct afs_server *xserver;
24 struct afs_net *net = server->cell->net;
35 struct rb_node **pp, *p;25 struct rb_node **pp, *p;
36 int ret;26 int ret;
37 27
38 _enter("%p", server);28 _enter("%p", server);
39 29
40 write_lock(&afs_servers_lock);30 write_lock(&net->servers_lock);
41 31
42 ret = -EEXIST;32 ret = -EEXIST;
43 pp = &afs_servers.rb_node;33 pp = &net->servers.rb_node;
44 p = NULL;34 p = NULL;
45 while (*pp) {35 while (*pp) {
46 p = *pp;36 p = *pp;
@@ -55,11 +45,11 @@ static int afs_install_server(struct afs_server *server) · 8 unmodified lines
55 }45 }
56 46
57 rb_link_node(&server->master_rb, p, pp);47 rb_link_node(&server->master_rb, p, pp);
58 rb_insert_color(&server->master_rb, &afs_servers);48 rb_insert_color(&server->master_rb, &net->servers);
59 ret = 0;49 ret = 0;
60 50
61error:51error:
62 write_unlock(&afs_servers_lock);52 write_unlock(&net->servers_lock);
63 return ret;53 return ret;
64}54}
65 55
@@ -150,9 +140,9 @@ found_server_quickly: · 84 unmodified lines
150 read_unlock(&cell->servers_lock);140 read_unlock(&cell->servers_lock);
151no_longer_unused:141no_longer_unused:
152 if (!list_empty(&server->grave)) {142 if (!list_empty(&server->grave)) {
153 spin_lock(&afs_server_graveyard_lock);143 spin_lock(&cell->net->server_graveyard_lock);
154 list_del_init(&server->grave);144 list_del_init(&server->grave);
155 spin_unlock(&afs_server_graveyard_lock);145 spin_unlock(&cell->net->server_graveyard_lock);
156 }146 }
157 _leave(" = %p{%d}", server, atomic_read(&server->usage));147 _leave(" = %p{%d}", server, atomic_read(&server->usage));
158 return server;148 return server;
@@ -178,7 +168,8 @@ server_in_two_cells: · 19 unmodified lines
178/*168/*
179 * look up a server by its IP address169 * look up a server by its IP address
180 */170 */
181struct afs_server *afs_find_server(const struct sockaddr_rxrpc *srx)171struct afs_server *afs_find_server(struct afs_net *net,
172 const struct sockaddr_rxrpc *srx)
182{173{
183 struct afs_server *server = NULL;174 struct afs_server *server = NULL;
184 struct rb_node *p;175 struct rb_node *p;
@@ -191,9 +182,9 @@ struct afs_server *afs_find_server(const struct sockaddr_rxrpc *srx) · 6 unmodified lines
191 return NULL;182 return NULL;
192 }183 }
193 184
194 read_lock(&afs_servers_lock);185 read_lock(&net->servers_lock);
195 186
196 p = afs_servers.rb_node;187 p = net->servers.rb_node;
197 while (p) {188 while (p) {
198 server = rb_entry(p, struct afs_server, master_rb);189 server = rb_entry(p, struct afs_server, master_rb);
199 190
@@ -211,7 +202,7 @@ struct afs_server *afs_find_server(const struct sockaddr_rxrpc *srx) · 11 unmodified lines
211 202
212 server = NULL;203 server = NULL;
213found:204found:
214 read_unlock(&afs_servers_lock);205 read_unlock(&net->servers_lock);
215 ASSERTIFCMP(server, server->addr.s_addr, ==, addr.s_addr);206 ASSERTIFCMP(server, server->addr.s_addr, ==, addr.s_addr);
216 _leave(" = %p", server);207 _leave(" = %p", server);
217 return server;208 return server;
@@ -223,6 +214,8 @@ found: · 5 unmodified lines
223 */214 */
224void afs_put_server(struct afs_server *server)215void afs_put_server(struct afs_server *server)
225{216{
217 struct afs_net *net = server->cell->net;
218
226 if (!server)219 if (!server)
227 return;220 return;
228 221
@@ -239,14 +232,14 @@ void afs_put_server(struct afs_server *server) · 10 unmodified lines
239 232
240 afs_flush_callback_breaks(server);233 afs_flush_callback_breaks(server);
241 234
242 spin_lock(&afs_server_graveyard_lock);235 spin_lock(&net->server_graveyard_lock);
243 if (atomic_read(&server->usage) == 0) {236 if (atomic_read(&server->usage) == 0) {
244 list_move_tail(&server->grave, &afs_server_graveyard);237 list_move_tail(&server->grave, &net->server_graveyard);
245 server->time_of_death = ktime_get_real_seconds();238 server->time_of_death = ktime_get_real_seconds();
246 queue_delayed_work(afs_wq, &afs_server_reaper,239 queue_delayed_work(afs_wq, &net->server_reaper,
247 afs_server_timeout * HZ);240 net->live ? afs_server_timeout * HZ : 0);
248 }241 }
249 spin_unlock(&afs_server_graveyard_lock);242 spin_unlock(&net->server_graveyard_lock);
250 _leave(" [dead]");243 _leave(" [dead]");
251}244}
252 245
@@ -272,42 +265,45 @@ static void afs_destroy_server(struct afs_server *server) · 19 unmodified lines
272/*265/*
273 * reap dead server records266 * reap dead server records
274 */267 */
275static void afs_reap_server(struct work_struct *work)268void afs_reap_server(struct work_struct *work)
276{269{
277 LIST_HEAD(corpses);270 LIST_HEAD(corpses);
278 struct afs_server *server;271 struct afs_server *server;
272 struct afs_net *net = container_of(work, struct afs_net, server_reaper.work);
279 unsigned long delay, expiry;273 unsigned long delay, expiry;
280 time64_t now;274 time64_t now;
281 275
282 now = ktime_get_real_seconds();276 now = ktime_get_real_seconds();
283 spin_lock(&afs_server_graveyard_lock);277 spin_lock(&net->server_graveyard_lock);
284 278
285 while (!list_empty(&afs_server_graveyard)) {279 while (!list_empty(&net->server_graveyard)) {
286 server = list_entry(afs_server_graveyard.next,280 server = list_entry(net->server_graveyard.next,
287 struct afs_server, grave);281 struct afs_server, grave);
288 282
289 /* the queue is ordered most dead first */283 /* the queue is ordered most dead first */
290 expiry = server->time_of_death + afs_server_timeout;284 if (net->live) {
291 if (expiry > now) {285 expiry = server->time_of_death + afs_server_timeout;
292 delay = (expiry - now) * HZ;286 if (expiry > now) {
293 mod_delayed_work(afs_wq, &afs_server_reaper, delay);287 delay = (expiry - now) * HZ;
294 break;288 mod_delayed_work(afs_wq, &net->server_reaper, delay);
289 break;
290 }
295 }291 }
296 292
297 write_lock(&server->cell->servers_lock);293 write_lock(&server->cell->servers_lock);
298 write_lock(&afs_servers_lock);294 write_lock(&net->servers_lock);
299 if (atomic_read(&server->usage) > 0) {295 if (atomic_read(&server->usage) > 0) {
300 list_del_init(&server->grave);296 list_del_init(&server->grave);
301 } else {297 } else {
302 list_move_tail(&server->grave, &corpses);298 list_move_tail(&server->grave, &corpses);
303 list_del_init(&server->link);299 list_del_init(&server->link);
304 rb_erase(&server->master_rb, &afs_servers);300 rb_erase(&server->master_rb, &net->servers);
305 }301 }
306 write_unlock(&afs_servers_lock);302 write_unlock(&net->servers_lock);
307 write_unlock(&server->cell->servers_lock);303 write_unlock(&server->cell->servers_lock);
308 }304 }
309 305
310 spin_unlock(&afs_server_graveyard_lock);306 spin_unlock(&net->server_graveyard_lock);
311 307
312 /* now reap the corpses we've extracted */308 /* now reap the corpses we've extracted */
313 while (!list_empty(&corpses)) {309 while (!list_empty(&corpses)) {
@@ -318,10 +314,10 @@ static void afs_reap_server(struct work_struct *work) · 4 unmodified lines
318}314}
319 315
320/*316/*
321 * discard all the server records for rmmod317 * Discard all the server records from a net namespace when it is destroyed or
318 * the afs module is removed.
322 */319 */
323void __exit afs_purge_servers(void)320void __net_exit afs_purge_servers(struct afs_net *net)
324{321{
325 afs_server_timeout = 0;322 mod_delayed_work(afs_wq, &net->server_reaper, 0);
326 mod_delayed_work(afs_wq, &afs_server_reaper, 0);
327}323}
fs/afs/super.c+26−19
@@ -25,11 +25,10 @@ · 24 unmodified lines
25#include <linux/statfs.h>25#include <linux/statfs.h>
26#include <linux/sched.h>26#include <linux/sched.h>
27#include <linux/nsproxy.h>27#include <linux/nsproxy.h>
28#include <linux/magic.h>
28#include <net/net_namespace.h>29#include <net/net_namespace.h>
29#include "internal.h"30#include "internal.h"
30 31
31#define AFS_FS_MAGIC 0x6B414653 /* 'kAFS' */
32
33static void afs_i_init_once(void *foo);32static void afs_i_init_once(void *foo);
34static struct dentry *afs_mount(struct file_system_type *fs_type,33static struct dentry *afs_mount(struct file_system_type *fs_type,
35 int flags, const char *dev_name, void *data);34 int flags, const char *dev_name, void *data);
@@ -201,7 +200,8 @@ static int afs_parse_options(struct afs_mount_params *params, · 165 unmodified lines
201 token = match_token(p, afs_options_list, args);200 token = match_token(p, afs_options_list, args);
202 switch (token) {201 switch (token) {
203 case afs_opt_cell:202 case afs_opt_cell:
204 cell = afs_cell_lookup(args[0].from,203 cell = afs_cell_lookup(params->net,
204 args[0].from,
205 args[0].to - args[0].from,205 args[0].to - args[0].from,
206 false);206 false);
207 if (IS_ERR(cell))207 if (IS_ERR(cell))
@@ -308,7 +308,7 @@ static int afs_parse_device_name(struct afs_mount_params *params, · 100 unmodified lines
308 308
309 /* lookup the cell record */309 /* lookup the cell record */
310 if (cellname || !params->cell) {310 if (cellname || !params->cell) {
311 cell = afs_cell_lookup(cellname, cellnamesz, true);311 cell = afs_cell_lookup(params->net, cellname, cellnamesz, true);
312 if (IS_ERR(cell)) {312 if (IS_ERR(cell)) {
313 printk(KERN_ERR "kAFS: unable to lookup cell '%*.*s'\n",313 printk(KERN_ERR "kAFS: unable to lookup cell '%*.*s'\n",
314 cellnamesz, cellnamesz, cellname ?: "");314 cellnamesz, cellnamesz, cellname ?: "");
@@ -334,7 +334,7 @@ static int afs_test_super(struct super_block *sb, void *data) · 19 unmodified lines
334 struct afs_super_info *as1 = data;334 struct afs_super_info *as1 = data;
335 struct afs_super_info *as = sb->s_fs_info;335 struct afs_super_info *as = sb->s_fs_info;
336 336
337 return as->volume == as1->volume;337 return as->net == as1->net && as->volume == as1->volume;
338}338}
339 339
340static int afs_set_super(struct super_block *sb, void *data)340static int afs_set_super(struct super_block *sb, void *data)
@@ -411,6 +411,7 @@ static struct dentry *afs_mount(struct file_system_type *fs_type, · 70 unmodified lines
411 _enter(",,%s,%p", dev_name, options);411 _enter(",,%s,%p", dev_name, options);
412 412
413 memset(&params, 0, sizeof(params));413 memset(&params, 0, sizeof(params));
414 params.net = &__afs_net;
414 415
415 ret = -EINVAL;416 ret = -EINVAL;
416 if (current->nsproxy->net_ns != &init_net)417 if (current->nsproxy->net_ns != &init_net)
@@ -444,36 +445,32 @@ static struct dentry *afs_mount(struct file_system_type *fs_type, · 27 unmodified lines
444 }445 }
445 446
446 /* allocate a superblock info record */447 /* allocate a superblock info record */
448 ret = -ENOMEM;
447 as = kzalloc(sizeof(struct afs_super_info), GFP_KERNEL);449 as = kzalloc(sizeof(struct afs_super_info), GFP_KERNEL);
448 if (!as) {450 if (!as)
449 ret = -ENOMEM;451 goto error_vol;
450 afs_put_volume(vol);452
451 goto error;453 as->net = afs_get_net(params.net);
452 }
453 as->volume = vol;454 as->volume = vol;
454 455
455 /* allocate a deviceless superblock */456 /* allocate a deviceless superblock */
456 sb = sget(fs_type, afs_test_super, afs_set_super, flags, as);457 sb = sget(fs_type, afs_test_super, afs_set_super, flags, as);
457 if (IS_ERR(sb)) {458 if (IS_ERR(sb)) {
458 ret = PTR_ERR(sb);459 ret = PTR_ERR(sb);
459 afs_put_volume(vol);460 goto error_as;
460 kfree(as);
461 goto error;
462 }461 }
463 462
464 if (!sb->s_root) {463 if (!sb->s_root) {
465 /* initial superblock/root creation */464 /* initial superblock/root creation */
466 _debug("create");465 _debug("create");
467 ret = afs_fill_super(sb, &params);466 ret = afs_fill_super(sb, &params);
468 if (ret < 0) {467 if (ret < 0)
469 deactivate_locked_super(sb);468 goto error_sb;
470 goto error;
471 }
472 sb->s_flags |= MS_ACTIVE;469 sb->s_flags |= MS_ACTIVE;
473 } else {470 } else {
474 _debug("reuse");471 _debug("reuse");
475 ASSERTCMP(sb->s_flags, &, MS_ACTIVE);472 ASSERTCMP(sb->s_flags, &, MS_ACTIVE);
476 afs_put_volume(vol);473 afs_put_volume(params.net, vol);
477 kfree(as);474 kfree(as);
478 }475 }
479 476
@@ -482,6 +479,14 @@ static struct dentry *afs_mount(struct file_system_type *fs_type, · 2 unmodified lines
482 _leave(" = 0 [%p]", sb);479 _leave(" = 0 [%p]", sb);
483 return dget(sb->s_root);480 return dget(sb->s_root);
484 481
482error_sb:
483 deactivate_locked_super(sb);
484 goto error;
485error_as:
486 afs_put_net(as->net);
487 kfree(as);
488error_vol:
489 afs_put_volume(params.net, vol);
485error:490error:
486 afs_put_cell(params.cell);491 afs_put_cell(params.cell);
487 key_put(params.key);492 key_put(params.key);
@@ -493,8 +498,10 @@ error: · 5 unmodified lines
493static void afs_kill_super(struct super_block *sb)498static void afs_kill_super(struct super_block *sb)
494{499{
495 struct afs_super_info *as = sb->s_fs_info;500 struct afs_super_info *as = sb->s_fs_info;
501 struct afs_net *net = as->net;
502
496 kill_anon_super(sb);503 kill_anon_super(sb);
497 afs_put_volume(as->volume);504 afs_put_volume(net, as->volume);
498 kfree(as);505 kfree(as);
499}506}
500 507
fs/afs/vlclient.c+6−4
@@ -143,7 +143,8 @@ static const struct afs_call_type afs_RXVLGetEntryById = { · 142 unmodified lines
143/*143/*
144 * dispatch a get volume entry by name operation144 * dispatch a get volume entry by name operation
145 */145 */
146int afs_vl_get_entry_by_name(struct in_addr *addr,146int afs_vl_get_entry_by_name(struct afs_net *net,
147 struct in_addr *addr,
147 struct key *key,148 struct key *key,
148 const char *volname,149 const char *volname,
149 struct afs_cache_vlocation *entry,150 struct afs_cache_vlocation *entry,
@@ -159,7 +160,7 @@ int afs_vl_get_entry_by_name(struct in_addr *addr, · 9 unmodified lines
159 padsz = (4 - (volnamesz & 3)) & 3;160 padsz = (4 - (volnamesz & 3)) & 3;
160 reqsz = 8 + volnamesz + padsz;161 reqsz = 8 + volnamesz + padsz;
161 162
162 call = afs_alloc_flat_call(&afs_RXVLGetEntryByName, reqsz, 384);163 call = afs_alloc_flat_call(net, &afs_RXVLGetEntryByName, reqsz, 384);
163 if (!call)164 if (!call)
164 return -ENOMEM;165 return -ENOMEM;
165 166
@@ -183,7 +184,8 @@ int afs_vl_get_entry_by_name(struct in_addr *addr, · 17 unmodified lines
183/*184/*
184 * dispatch a get volume entry by ID operation185 * dispatch a get volume entry by ID operation
185 */186 */
186int afs_vl_get_entry_by_id(struct in_addr *addr,187int afs_vl_get_entry_by_id(struct afs_net *net,
188 struct in_addr *addr,
187 struct key *key,189 struct key *key,
188 afs_volid_t volid,190 afs_volid_t volid,
189 afs_voltype_t voltype,191 afs_voltype_t voltype,
@@ -195,7 +197,7 @@ int afs_vl_get_entry_by_id(struct in_addr *addr, · 5 unmodified lines
195 197
196 _enter("");198 _enter("");
197 199
198 call = afs_alloc_flat_call(&afs_RXVLGetEntryById, 12, 384);200 call = afs_alloc_flat_call(net, &afs_RXVLGetEntryById, 12, 384);
199 if (!call)201 if (!call)
200 return -ENOMEM;202 return -ENOMEM;
201 203
fs/afs/vlocation.c+68−83
@@ -16,20 +16,11 @@ · 15 unmodified lines
16#include <linux/sched.h>16#include <linux/sched.h>
17#include "internal.h"17#include "internal.h"
18 18
19struct workqueue_struct *afs_vlocation_update_worker;
20
19static unsigned afs_vlocation_timeout = 10; /* volume location timeout in seconds */21static unsigned afs_vlocation_timeout = 10; /* volume location timeout in seconds */
20static unsigned afs_vlocation_update_timeout = 10 * 60;22static unsigned afs_vlocation_update_timeout = 10 * 60;
21 23
22static void afs_vlocation_reaper(struct work_struct *);
23static void afs_vlocation_updater(struct work_struct *);
24
25static LIST_HEAD(afs_vlocation_updates);
26static LIST_HEAD(afs_vlocation_graveyard);
27static DEFINE_SPINLOCK(afs_vlocation_updates_lock);
28static DEFINE_SPINLOCK(afs_vlocation_graveyard_lock);
29static DECLARE_DELAYED_WORK(afs_vlocation_reap, afs_vlocation_reaper);
30static DECLARE_DELAYED_WORK(afs_vlocation_update, afs_vlocation_updater);
31static struct workqueue_struct *afs_vlocation_update_worker;
32
33/*24/*
34 * iterate through the VL servers in a cell until one of them admits knowing25 * iterate through the VL servers in a cell until one of them admits knowing
35 * about the volume in question26 * about the volume in question
@@ -52,8 +43,8 @@ static int afs_vlocation_access_vl_by_name(struct afs_vlocation *vl, · 16 unmodified lines
52 _debug("CellServ[%hu]: %08x", cell->vl_curr_svix, addr.s_addr);43 _debug("CellServ[%hu]: %08x", cell->vl_curr_svix, addr.s_addr);
53 44
54 /* attempt to access the VL server */45 /* attempt to access the VL server */
55 ret = afs_vl_get_entry_by_name(&addr, key, vl->vldb.name, vldb,46 ret = afs_vl_get_entry_by_name(cell->net, &addr, key,
56 false);47 vl->vldb.name, vldb, false);
57 switch (ret) {48 switch (ret) {
58 case 0:49 case 0:
59 goto out;50 goto out;
@@ -110,8 +101,8 @@ static int afs_vlocation_access_vl_by_id(struct afs_vlocation *vl, · 50 unmodified lines
110 _debug("CellServ[%hu]: %08x", cell->vl_curr_svix, addr.s_addr);101 _debug("CellServ[%hu]: %08x", cell->vl_curr_svix, addr.s_addr);
111 102
112 /* attempt to access the VL server */103 /* attempt to access the VL server */
113 ret = afs_vl_get_entry_by_id(&addr, key, volid, voltype, vldb,104 ret = afs_vl_get_entry_by_id(cell->net, &addr, key, volid,
114 false);105 voltype, vldb, false);
115 switch (ret) {106 switch (ret) {
116 case 0:107 case 0:
117 goto out;108 goto out;
@@ -335,7 +326,8 @@ static int afs_vlocation_fill_in_record(struct afs_vlocation *vl, · 217 unmodified lines
335/*326/*
336 * queue a vlocation record for updates327 * queue a vlocation record for updates
337 */328 */
338static void afs_vlocation_queue_for_updates(struct afs_vlocation *vl)329static void afs_vlocation_queue_for_updates(struct afs_net *net,
330 struct afs_vlocation *vl)
339{331{
340 struct afs_vlocation *xvl;332 struct afs_vlocation *xvl;
341 333
@@ -343,25 +335,25 @@ static void afs_vlocation_queue_for_updates(struct afs_vlocation *vl) · 1 unmodified line
343 vl->update_at = ktime_get_real_seconds() +335 vl->update_at = ktime_get_real_seconds() +
344 afs_vlocation_update_timeout;336 afs_vlocation_update_timeout;
345 337
346 spin_lock(&afs_vlocation_updates_lock);338 spin_lock(&net->vl_updates_lock);
347 339
348 if (!list_empty(&afs_vlocation_updates)) {340 if (!list_empty(&net->vl_updates)) {
349 /* ... but wait at least 1 second more than the newest record341 /* ... but wait at least 1 second more than the newest record
350 * already queued so that we don't spam the VL server suddenly342 * already queued so that we don't spam the VL server suddenly
351 * with lots of requests343 * with lots of requests
352 */344 */
353 xvl = list_entry(afs_vlocation_updates.prev,345 xvl = list_entry(net->vl_updates.prev,
354 struct afs_vlocation, update);346 struct afs_vlocation, update);
355 if (vl->update_at <= xvl->update_at)347 if (vl->update_at <= xvl->update_at)
356 vl->update_at = xvl->update_at + 1;348 vl->update_at = xvl->update_at + 1;
357 } else {349 } else if (net->live) {
358 queue_delayed_work(afs_vlocation_update_worker,350 queue_delayed_work(afs_vlocation_update_worker,
359 &afs_vlocation_update,351 &net->vl_updater,
360 afs_vlocation_update_timeout * HZ);352 afs_vlocation_update_timeout * HZ);
361 }353 }
362 354
363 list_add_tail(&vl->update, &afs_vlocation_updates);355 list_add_tail(&vl->update, &net->vl_updates);
364 spin_unlock(&afs_vlocation_updates_lock);356 spin_unlock(&net->vl_updates_lock);
365}357}
366 358
367/*359/*
@@ -371,7 +363,8 @@ static void afs_vlocation_queue_for_updates(struct afs_vlocation *vl) · 3 unmodified lines
371 * - lookup in the local cache if not able to find on the VL server363 * - lookup in the local cache if not able to find on the VL server
372 * - insert/update in the local cache if did get a VL response364 * - insert/update in the local cache if did get a VL response
373 */365 */
374struct afs_vlocation *afs_vlocation_lookup(struct afs_cell *cell,366struct afs_vlocation *afs_vlocation_lookup(struct afs_net *net,
367 struct afs_cell *cell,
375 struct key *key,368 struct key *key,
376 const char *name,369 const char *name,
377 size_t namesz)370 size_t namesz)
@@ -427,7 +420,7 @@ fill_in_record: · 49 unmodified lines
427#endif420#endif
428 421
429 /* schedule for regular updates */422 /* schedule for regular updates */
430 afs_vlocation_queue_for_updates(vl);423 afs_vlocation_queue_for_updates(net, vl);
431 goto success;424 goto success;
432 425
433found_in_memory:426found_in_memory:
@@ -436,9 +429,9 @@ found_in_memory: · 2 unmodified lines
436 atomic_inc(&vl->usage);429 atomic_inc(&vl->usage);
437 spin_unlock(&cell->vl_lock);430 spin_unlock(&cell->vl_lock);
438 if (!list_empty(&vl->grave)) {431 if (!list_empty(&vl->grave)) {
439 spin_lock(&afs_vlocation_graveyard_lock);432 spin_lock(&net->vl_graveyard_lock);
440 list_del_init(&vl->grave);433 list_del_init(&vl->grave);
441 spin_unlock(&afs_vlocation_graveyard_lock);434 spin_unlock(&net->vl_graveyard_lock);
442 }435 }
443 up_write(&cell->vl_sem);436 up_write(&cell->vl_sem);
444 437
@@ -481,7 +474,7 @@ error_abandon: · 36 unmodified lines
481 wake_up(&vl->waitq);474 wake_up(&vl->waitq);
482error:475error:
483 ASSERT(vl != NULL);476 ASSERT(vl != NULL);
484 afs_put_vlocation(vl);477 afs_put_vlocation(net, vl);
485 _leave(" = %d", ret);478 _leave(" = %d", ret);
486 return ERR_PTR(ret);479 return ERR_PTR(ret);
487}480}
@@ -489,7 +482,7 @@ error: · 1 unmodified line
489/*482/*
490 * finish using a volume location record483 * finish using a volume location record
491 */484 */
492void afs_put_vlocation(struct afs_vlocation *vl)485void afs_put_vlocation(struct afs_net *net, struct afs_vlocation *vl)
493{486{
494 if (!vl)487 if (!vl)
495 return;488 return;
@@ -503,22 +496,22 @@ void afs_put_vlocation(struct afs_vlocation *vl) · 7 unmodified lines
503 return;496 return;
504 }497 }
505 498
506 spin_lock(&afs_vlocation_graveyard_lock);499 spin_lock(&net->vl_graveyard_lock);
507 if (atomic_read(&vl->usage) == 0) {500 if (atomic_read(&vl->usage) == 0) {
508 _debug("buried");501 _debug("buried");
509 list_move_tail(&vl->grave, &afs_vlocation_graveyard);502 list_move_tail(&vl->grave, &net->vl_graveyard);
510 vl->time_of_death = ktime_get_real_seconds();503 vl->time_of_death = ktime_get_real_seconds();
511 queue_delayed_work(afs_wq, &afs_vlocation_reap,504 queue_delayed_work(afs_wq, &net->vl_reaper,
512 afs_vlocation_timeout * HZ);505 afs_vlocation_timeout * HZ);
513 506
514 /* suspend updates on this record */507 /* suspend updates on this record */
515 if (!list_empty(&vl->update)) {508 if (!list_empty(&vl->update)) {
516 spin_lock(&afs_vlocation_updates_lock);509 spin_lock(&net->vl_updates_lock);
517 list_del_init(&vl->update);510 list_del_init(&vl->update);
518 spin_unlock(&afs_vlocation_updates_lock);511 spin_unlock(&net->vl_updates_lock);
519 }512 }
520 }513 }
521 spin_unlock(&afs_vlocation_graveyard_lock);514 spin_unlock(&net->vl_graveyard_lock);
522 _leave(" [killed?]");515 _leave(" [killed?]");
523}516}
524 517
@@ -539,31 +532,34 @@ static void afs_vlocation_destroy(struct afs_vlocation *vl) · 14 unmodified lines
539/*532/*
540 * reap dead volume location records533 * reap dead volume location records
541 */534 */
542static void afs_vlocation_reaper(struct work_struct *work)535void afs_vlocation_reaper(struct work_struct *work)
543{536{
544 LIST_HEAD(corpses);537 LIST_HEAD(corpses);
545 struct afs_vlocation *vl;538 struct afs_vlocation *vl;
539 struct afs_net *net = container_of(work, struct afs_net, vl_reaper.work);
546 unsigned long delay, expiry;540 unsigned long delay, expiry;
547 time64_t now;541 time64_t now;
548 542
549 _enter("");543 _enter("");
550 544
551 now = ktime_get_real_seconds();545 now = ktime_get_real_seconds();
552 spin_lock(&afs_vlocation_graveyard_lock);546 spin_lock(&net->vl_graveyard_lock);
553 547
554 while (!list_empty(&afs_vlocation_graveyard)) {548 while (!list_empty(&net->vl_graveyard)) {
555 vl = list_entry(afs_vlocation_graveyard.next,549 vl = list_entry(net->vl_graveyard.next,
556 struct afs_vlocation, grave);550 struct afs_vlocation, grave);
557 551
558 _debug("check %p", vl);552 _debug("check %p", vl);
559 553
560 /* the queue is ordered most dead first */554 /* the queue is ordered most dead first */
561 expiry = vl->time_of_death + afs_vlocation_timeout;555 if (net->live) {
562 if (expiry > now) {556 expiry = vl->time_of_death + afs_vlocation_timeout;
563 delay = (expiry - now) * HZ;557 if (expiry > now) {
564 _debug("delay %lu", delay);558 delay = (expiry - now) * HZ;
565 mod_delayed_work(afs_wq, &afs_vlocation_reap, delay);559 _debug("delay %lu", delay);
566 break;560 mod_delayed_work(afs_wq, &net->vl_reaper, delay);
561 break;
562 }
567 }563 }
568 564
569 spin_lock(&vl->cell->vl_lock);565 spin_lock(&vl->cell->vl_lock);
@@ -578,7 +574,7 @@ static void afs_vlocation_reaper(struct work_struct *work) · 8 unmodified lines
578 spin_unlock(&vl->cell->vl_lock);574 spin_unlock(&vl->cell->vl_lock);
579 }575 }
580 576
581 spin_unlock(&afs_vlocation_graveyard_lock);577 spin_unlock(&net->vl_graveyard_lock);
582 578
583 /* now reap the corpses we've extracted */579 /* now reap the corpses we've extracted */
584 while (!list_empty(&corpses)) {580 while (!list_empty(&corpses)) {
@@ -590,57 +586,47 @@ static void afs_vlocation_reaper(struct work_struct *work) · 5 unmodified lines
590 _leave("");586 _leave("");
591}587}
592 588
593/*
594 * initialise the VL update process
595 */
596int __init afs_vlocation_update_init(void)
597{
598 afs_vlocation_update_worker = alloc_workqueue("kafs_vlupdated",
599 WQ_MEM_RECLAIM, 0);
600 return afs_vlocation_update_worker ? 0 : -ENOMEM;
601}
602
603/*589/*
604 * discard all the volume location records for rmmod590 * discard all the volume location records for rmmod
605 */591 */
606void afs_vlocation_purge(void)592void __net_exit afs_vlocation_purge(struct afs_net *net)
607{593{
608 afs_vlocation_timeout = 0;594 spin_lock(&net->vl_updates_lock);
609 595 list_del_init(&net->vl_updates);
610 spin_lock(&afs_vlocation_updates_lock);596 spin_unlock(&net->vl_updates_lock);
611 list_del_init(&afs_vlocation_updates);597 mod_delayed_work(afs_vlocation_update_worker, &net->vl_updater, 0);
612 spin_unlock(&afs_vlocation_updates_lock);598 mod_delayed_work(afs_wq, &net->vl_reaper, 0);
613 mod_delayed_work(afs_vlocation_update_worker, &afs_vlocation_update, 0);
614 destroy_workqueue(afs_vlocation_update_worker);
615
616 mod_delayed_work(afs_wq, &afs_vlocation_reap, 0);
617}599}
618 600
619/*601/*
620 * update a volume location602 * update a volume location
621 */603 */
622static void afs_vlocation_updater(struct work_struct *work)604void afs_vlocation_updater(struct work_struct *work)
623{605{
624 struct afs_cache_vlocation vldb;606 struct afs_cache_vlocation vldb;
625 struct afs_vlocation *vl, *xvl;607 struct afs_vlocation *vl, *xvl;
608 struct afs_net *net = container_of(work, struct afs_net, vl_updater.work);
626 time64_t now;609 time64_t now;
627 long timeout;610 long timeout;
628 int ret;611 int ret;
629 612
613 if (!net->live)
614 return;
615
630 _enter("");616 _enter("");
631 617
632 now = ktime_get_real_seconds();618 now = ktime_get_real_seconds();
633 619
634 /* find a record to update */620 /* find a record to update */
635 spin_lock(&afs_vlocation_updates_lock);621 spin_lock(&net->vl_updates_lock);
636 for (;;) {622 for (;;) {
637 if (list_empty(&afs_vlocation_updates)) {623 if (list_empty(&net->vl_updates) || !net->live) {
638 spin_unlock(&afs_vlocation_updates_lock);624 spin_unlock(&net->vl_updates_lock);
639 _leave(" [nothing]");625 _leave(" [nothing]");
640 return;626 return;
641 }627 }
642 628
643 vl = list_entry(afs_vlocation_updates.next,629 vl = list_entry(net->vl_updates.next,
644 struct afs_vlocation, update);630 struct afs_vlocation, update);
645 if (atomic_read(&vl->usage) > 0)631 if (atomic_read(&vl->usage) > 0)
646 break;632 break;
@@ -650,15 +636,15 @@ static void afs_vlocation_updater(struct work_struct *work) · 3 unmodified lines
650 timeout = vl->update_at - now;636 timeout = vl->update_at - now;
651 if (timeout > 0) {637 if (timeout > 0) {
652 queue_delayed_work(afs_vlocation_update_worker,638 queue_delayed_work(afs_vlocation_update_worker,
653 &afs_vlocation_update, timeout * HZ);639 &net->vl_updater, timeout * HZ);
654 spin_unlock(&afs_vlocation_updates_lock);640 spin_unlock(&net->vl_updates_lock);
655 _leave(" [nothing]");641 _leave(" [nothing]");
656 return;642 return;
657 }643 }
658 644
659 list_del_init(&vl->update);645 list_del_init(&vl->update);
660 atomic_inc(&vl->usage);646 atomic_inc(&vl->usage);
661 spin_unlock(&afs_vlocation_updates_lock);647 spin_unlock(&net->vl_updates_lock);
662 648
663 /* we can now perform the update */649 /* we can now perform the update */
664 _debug("update %s", vl->vldb.name);650 _debug("update %s", vl->vldb.name);
@@ -688,18 +674,18 @@ static void afs_vlocation_updater(struct work_struct *work) · 23 unmodified lines
688 vl->update_at = ktime_get_real_seconds() +674 vl->update_at = ktime_get_real_seconds() +
689 afs_vlocation_update_timeout;675 afs_vlocation_update_timeout;
690 676
691 spin_lock(&afs_vlocation_updates_lock);677 spin_lock(&net->vl_updates_lock);
692 678
693 if (!list_empty(&afs_vlocation_updates)) {679 if (!list_empty(&net->vl_updates)) {
694 /* next update in 10 minutes, but wait at least 1 second more680 /* next update in 10 minutes, but wait at least 1 second more
695 * than the newest record already queued so that we don't spam681 * than the newest record already queued so that we don't spam
696 * the VL server suddenly with lots of requests682 * the VL server suddenly with lots of requests
697 */683 */
698 xvl = list_entry(afs_vlocation_updates.prev,684 xvl = list_entry(net->vl_updates.prev,
699 struct afs_vlocation, update);685 struct afs_vlocation, update);
700 if (vl->update_at <= xvl->update_at)686 if (vl->update_at <= xvl->update_at)
701 vl->update_at = xvl->update_at + 1;687 vl->update_at = xvl->update_at + 1;
702 xvl = list_entry(afs_vlocation_updates.next,688 xvl = list_entry(net->vl_updates.next,
703 struct afs_vlocation, update);689 struct afs_vlocation, update);
704 timeout = xvl->update_at - now;690 timeout = xvl->update_at - now;
705 if (timeout < 0)691 if (timeout < 0)
@@ -710,11 +696,10 @@ static void afs_vlocation_updater(struct work_struct *work) · 4 unmodified lines
710 696
711 ASSERT(list_empty(&vl->update));697 ASSERT(list_empty(&vl->update));
712 698
713 list_add_tail(&vl->update, &afs_vlocation_updates);699 list_add_tail(&vl->update, &net->vl_updates);
714 700
715 _debug("timeout %ld", timeout);701 _debug("timeout %ld", timeout);
716 queue_delayed_work(afs_vlocation_update_worker,702 queue_delayed_work(afs_vlocation_update_worker, &net->vl_updater, timeout * HZ);
717 &afs_vlocation_update, timeout * HZ);703 spin_unlock(&net->vl_updates_lock);
718 spin_unlock(&afs_vlocation_updates_lock);704 afs_put_vlocation(net, vl);
719 afs_put_vlocation(vl);
720}705}
fs/afs/volume.c+5−5
@@ -54,7 +54,7 @@ struct afs_volume *afs_volume_lookup(struct afs_mount_params *params) · 53 unmodified lines
54 params->volnamesz, params->volnamesz, params->volname, params->rwpath);54 params->volnamesz, params->volnamesz, params->volname, params->rwpath);
55 55
56 /* lookup the volume location record */56 /* lookup the volume location record */
57 vlocation = afs_vlocation_lookup(params->cell, params->key,57 vlocation = afs_vlocation_lookup(params->net, params->cell, params->key,
58 params->volname, params->volnamesz);58 params->volname, params->volnamesz);
59 if (IS_ERR(vlocation)) {59 if (IS_ERR(vlocation)) {
60 ret = PTR_ERR(vlocation);60 ret = PTR_ERR(vlocation);
@@ -138,7 +138,7 @@ success: · 77 unmodified lines
138 _debug("kAFS selected %s volume %08x",138 _debug("kAFS selected %s volume %08x",
139 afs_voltypes[volume->type], volume->vid);139 afs_voltypes[volume->type], volume->vid);
140 up_write(&params->cell->vl_sem);140 up_write(&params->cell->vl_sem);
141 afs_put_vlocation(vlocation);141 afs_put_vlocation(params->net, vlocation);
142 _leave(" = %p", volume);142 _leave(" = %p", volume);
143 return volume;143 return volume;
144 144
@@ -146,7 +146,7 @@ success: · 1 unmodified line
146error_up:146error_up:
147 up_write(&params->cell->vl_sem);147 up_write(&params->cell->vl_sem);
148error:148error:
149 afs_put_vlocation(vlocation);149 afs_put_vlocation(params->net, vlocation);
150 _leave(" = %d", ret);150 _leave(" = %d", ret);
151 return ERR_PTR(ret);151 return ERR_PTR(ret);
152 152
@@ -163,7 +163,7 @@ error_discard: · 10 unmodified lines
163/*163/*
164 * destroy a volume record164 * destroy a volume record
165 */165 */
166void afs_put_volume(struct afs_volume *volume)166void afs_put_volume(struct afs_net *net, struct afs_volume *volume)
167{167{
168 struct afs_vlocation *vlocation;168 struct afs_vlocation *vlocation;
169 int loop;169 int loop;
@@ -195,7 +195,7 @@ void afs_put_volume(struct afs_volume *volume) · 25 unmodified lines
195#ifdef CONFIG_AFS_FSCACHE195#ifdef CONFIG_AFS_FSCACHE
196 fscache_relinquish_cookie(volume->cache, 0);196 fscache_relinquish_cookie(volume->cache, 0);
197#endif197#endif
198 afs_put_vlocation(vlocation);198 afs_put_vlocation(net, vlocation);
199 199
200 for (loop = volume->nservers - 1; loop >= 0; loop--)200 for (loop = volume->nservers - 1; loop >= 0; loop--)
201 afs_put_server(volume->servers[loop]);201 afs_put_server(volume->servers[loop]);
include/uapi/linux/magic.h+1−0
@@ -47,6 +47,7 @@ · 46 unmodified lines
47#define OPENPROM_SUPER_MAGIC 0x9fa147#define OPENPROM_SUPER_MAGIC 0x9fa1
48#define QNX4_SUPER_MAGIC 0x002f /* qnx4 fs detection */48#define QNX4_SUPER_MAGIC 0x002f /* qnx4 fs detection */
49#define QNX6_SUPER_MAGIC 0x68191122 /* qnx6 fs detection */49#define QNX6_SUPER_MAGIC 0x68191122 /* qnx6 fs detection */
50#define AFS_FS_MAGIC 0x6B414653
50 51
51#define REISERFS_SUPER_MAGIC 0x52654973 /* used by gcc */52#define REISERFS_SUPER_MAGIC 0x52654973 /* used by gcc */
52 /* used by file system utilities that53 /* used by file system utilities that