Skip to content

Commit f044c88

Browse files
committed
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. Signed-off-by: David Howells <[email protected]>
1 parent 5e4def2 commit f044c88

File tree

16 files changed

+603
-492
lines changed

16 files changed

+603
-492
lines changed

fs/afs/afs.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,15 @@ struct afs_callback {
7272

7373
#define AFSCBMAX 50 /* maximum callbacks transferred per bulk op */
7474

75+
struct 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+
7584
/*
7685
* AFS volume information
7786
*/

fs/afs/callback.c

Lines changed: 2 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,7 @@ unsigned afs_vnode_update_timeout = 10;
2828
CIRC_SPACE((server)->cb_break_head, (server)->cb_break_tail, \
2929
ARRAY_SIZE((server)->cb_break))
3030

31-
//static void afs_callback_updater(struct work_struct *);
32-
33-
static struct workqueue_struct *afs_callback_update_worker;
31+
struct workqueue_struct *afs_callback_update_worker;
3432

3533
/*
3634
* allow the fileserver to request callback state (re-)initialisation
@@ -343,7 +341,7 @@ void afs_dispatch_give_up_callbacks(struct work_struct *work)
343341
* had callbacks entirely, and the server will call us later to break
344342
* them
345343
*/
346-
afs_fs_give_up_callbacks(server, true);
344+
afs_fs_give_up_callbacks(server->cell->net, server, true);
347345
}
348346

349347
/*
@@ -456,21 +454,3 @@ static void afs_callback_updater(struct work_struct *work)
456454
afs_put_vnode(vl);
457455
}
458456
#endif
459-
460-
/*
461-
* initialise the callback update process
462-
*/
463-
int __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-
*/
473-
void afs_callback_update_kill(void)
474-
{
475-
destroy_workqueue(afs_callback_update_worker);
476-
}

fs/afs/cell.c

Lines changed: 63 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -18,20 +18,12 @@
1818
#include <keys/rxrpc-type.h>
1919
#include "internal.h"
2020

21-
DECLARE_RWSEM(afs_proc_cells_sem);
22-
LIST_HEAD(afs_proc_cells);
23-
24-
static LIST_HEAD(afs_cells);
25-
static DEFINE_RWLOCK(afs_cells_lock);
26-
static DECLARE_RWSEM(afs_cells_sem); /* add/remove serialisation */
27-
static DECLARE_WAIT_QUEUE_HEAD(afs_cells_freeable_wq);
28-
static struct afs_cell *afs_cell_root;
29-
3021
/*
3122
* allocate a cell record and fill in its name, VL server address list and
3223
* allocate an anonymous key
3324
*/
34-
static struct afs_cell *afs_cell_alloc(const char *name, unsigned namelen,
25+
static struct afs_cell *afs_cell_alloc(struct afs_net *net,
26+
const char *name, unsigned namelen,
3527
char *vllist)
3628
{
3729
struct afs_cell *cell;
@@ -62,6 +54,7 @@ static struct afs_cell *afs_cell_alloc(const char *name, unsigned namelen,
6254

6355
atomic_set(&cell->usage, 1);
6456
INIT_LIST_HEAD(&cell->link);
57+
cell->net = net;
6558
rwlock_init(&cell->servers_lock);
6659
INIT_LIST_HEAD(&cell->servers);
6760
init_rwsem(&cell->vl_sem);
@@ -142,36 +135,38 @@ static struct afs_cell *afs_cell_alloc(const char *name, unsigned namelen,
142135

143136
/*
144137
* afs_cell_crate() - create a cell record
138+
* @net: The network namespace
145139
* @name: is the name of the cell.
146140
* @namsesz: is the strlen of the cell name.
147141
* @vllist: is a colon separated list of IP addresses in "a.b.c.d" format.
148142
* @retref: is T to return the cell reference when the cell exists.
149143
*/
150-
struct afs_cell *afs_cell_create(const char *name, unsigned namesz,
144+
struct afs_cell *afs_cell_create(struct afs_net *net,
145+
const char *name, unsigned namesz,
151146
char *vllist, bool retref)
152147
{
153148
struct afs_cell *cell;
154149
int ret;
155150

156151
_enter("%*.*s,%s", namesz, namesz, name ?: "", vllist);
157152

158-
down_write(&afs_cells_sem);
159-
read_lock(&afs_cells_lock);
160-
list_for_each_entry(cell, &afs_cells, link) {
153+
down_write(&net->cells_sem);
154+
read_lock(&net->cells_lock);
155+
list_for_each_entry(cell, &net->cells, link) {
161156
if (strncasecmp(cell->name, name, namesz) == 0)
162157
goto duplicate_name;
163158
}
164-
read_unlock(&afs_cells_lock);
159+
read_unlock(&net->cells_lock);
165160

166-
cell = afs_cell_alloc(name, namesz, vllist);
161+
cell = afs_cell_alloc(net, name, namesz, vllist);
167162
if (IS_ERR(cell)) {
168163
_leave(" = %ld", PTR_ERR(cell));
169-
up_write(&afs_cells_sem);
164+
up_write(&net->cells_sem);
170165
return cell;
171166
}
172167

173168
/* add a proc directory for this cell */
174-
ret = afs_proc_cell_setup(cell);
169+
ret = afs_proc_cell_setup(net, cell);
175170
if (ret < 0)
176171
goto error;
177172

@@ -183,20 +178,20 @@ struct afs_cell *afs_cell_create(const char *name, unsigned namesz,
183178
#endif
184179

185180
/* add to the cell lists */
186-
write_lock(&afs_cells_lock);
187-
list_add_tail(&cell->link, &afs_cells);
188-
write_unlock(&afs_cells_lock);
181+
write_lock(&net->cells_lock);
182+
list_add_tail(&cell->link, &net->cells);
183+
write_unlock(&net->cells_lock);
189184

190-
down_write(&afs_proc_cells_sem);
191-
list_add_tail(&cell->proc_link, &afs_proc_cells);
192-
up_write(&afs_proc_cells_sem);
193-
up_write(&afs_cells_sem);
185+
down_write(&net->proc_cells_sem);
186+
list_add_tail(&cell->proc_link, &net->proc_cells);
187+
up_write(&net->proc_cells_sem);
188+
up_write(&net->cells_sem);
194189

195190
_leave(" = %p", cell);
196191
return cell;
197192

198193
error:
199-
up_write(&afs_cells_sem);
194+
up_write(&net->cells_sem);
200195
key_put(cell->anonymous_key);
201196
kfree(cell);
202197
_leave(" = %d", ret);
@@ -206,8 +201,8 @@ struct afs_cell *afs_cell_create(const char *name, unsigned namesz,
206201
if (retref && !IS_ERR(cell))
207202
afs_get_cell(cell);
208203

209-
read_unlock(&afs_cells_lock);
210-
up_write(&afs_cells_sem);
204+
read_unlock(&net->cells_lock);
205+
up_write(&net->cells_sem);
211206

212207
if (retref) {
213208
_leave(" = %p", cell);
@@ -223,7 +218,7 @@ struct afs_cell *afs_cell_create(const char *name, unsigned namesz,
223218
* - can be called with a module parameter string
224219
* - can be called from a write to /proc/fs/afs/rootcell
225220
*/
226-
int afs_cell_init(char *rootcell)
221+
int afs_cell_init(struct afs_net *net, char *rootcell)
227222
{
228223
struct afs_cell *old_root, *new_root;
229224
char *cp;
@@ -245,17 +240,17 @@ int afs_cell_init(char *rootcell)
245240
*cp++ = 0;
246241

247242
/* 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);
249244
if (IS_ERR(new_root)) {
250245
_leave(" = %ld", PTR_ERR(new_root));
251246
return PTR_ERR(new_root);
252247
}
253248

254249
/* install the new cell */
255-
write_lock(&afs_cells_lock);
256-
old_root = afs_cell_root;
257-
afs_cell_root = new_root;
258-
write_unlock(&afs_cells_lock);
250+
write_lock(&net->cells_lock);
251+
old_root = net->ws_cell;
252+
net->ws_cell = new_root;
253+
write_unlock(&net->cells_lock);
259254
afs_put_cell(old_root);
260255

261256
_leave(" = 0");
@@ -265,19 +260,20 @@ int afs_cell_init(char *rootcell)
265260
/*
266261
* lookup a cell record
267262
*/
268-
struct afs_cell *afs_cell_lookup(const char *name, unsigned namesz,
263+
struct afs_cell *afs_cell_lookup(struct afs_net *net,
264+
const char *name, unsigned namesz,
269265
bool dns_cell)
270266
{
271267
struct afs_cell *cell;
272268

273269
_enter("\"%*.*s\",", namesz, namesz, name ?: "");
274270

275-
down_read(&afs_cells_sem);
276-
read_lock(&afs_cells_lock);
271+
down_read(&net->cells_sem);
272+
read_lock(&net->cells_lock);
277273

278274
if (name) {
279275
/* 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) {
281277
if (strncmp(cell->name, name, namesz) == 0) {
282278
afs_get_cell(cell);
283279
goto found;
@@ -289,7 +285,7 @@ struct afs_cell *afs_cell_lookup(const char *name, unsigned namesz,
289285
found:
290286
;
291287
} else {
292-
cell = afs_cell_root;
288+
cell = net->ws_cell;
293289
if (!cell) {
294290
/* this should not happen unless user tries to mount
295291
* when root cell is not set. Return an impossibly
@@ -304,16 +300,16 @@ struct afs_cell *afs_cell_lookup(const char *name, unsigned namesz,
304300

305301
}
306302

307-
read_unlock(&afs_cells_lock);
308-
up_read(&afs_cells_sem);
303+
read_unlock(&net->cells_lock);
304+
up_read(&net->cells_sem);
309305
_leave(" = %p", cell);
310306
return cell;
311307

312308
create_cell:
313-
read_unlock(&afs_cells_lock);
314-
up_read(&afs_cells_sem);
309+
read_unlock(&net->cells_lock);
310+
up_read(&net->cells_sem);
315311

316-
cell = afs_cell_create(name, namesz, NULL, true);
312+
cell = afs_cell_create(net, name, namesz, NULL, true);
317313

318314
_leave(" = %p", cell);
319315
return cell;
@@ -325,14 +321,14 @@ struct afs_cell *afs_cell_lookup(const char *name, unsigned namesz,
325321
*/
326322
struct afs_cell *afs_get_cell_maybe(struct afs_cell *cell)
327323
{
328-
write_lock(&afs_cells_lock);
324+
write_lock(&net->cells_lock);
329325

330326
if (cell && !list_empty(&cell->link))
331327
afs_get_cell(cell);
332328
else
333329
cell = NULL;
334330

335-
write_unlock(&afs_cells_lock);
331+
write_unlock(&net->cells_lock);
336332
return cell;
337333
}
338334
#endif /* 0 */
@@ -351,30 +347,30 @@ void afs_put_cell(struct afs_cell *cell)
351347

352348
/* to prevent a race, the decrement and the dequeue must be effectively
353349
* atomic */
354-
write_lock(&afs_cells_lock);
350+
write_lock(&cell->net->cells_lock);
355351

356352
if (likely(!atomic_dec_and_test(&cell->usage))) {
357-
write_unlock(&afs_cells_lock);
353+
write_unlock(&cell->net->cells_lock);
358354
_leave("");
359355
return;
360356
}
361357

362358
ASSERT(list_empty(&cell->servers));
363359
ASSERT(list_empty(&cell->vl_list));
364360

365-
write_unlock(&afs_cells_lock);
361+
wake_up(&cell->net->cells_freeable_wq);
366362

367-
wake_up(&afs_cells_freeable_wq);
363+
write_unlock(&cell->net->cells_lock);
368364

369365
_leave(" [unused]");
370366
}
371367

372368
/*
373369
* destroy a cell record
374-
* - must be called with the afs_cells_sem write-locked
370+
* - must be called with the net->cells_sem write-locked
375371
* - cell->link should have been broken by the caller
376372
*/
377-
static void afs_cell_destroy(struct afs_cell *cell)
373+
static void afs_cell_destroy(struct afs_net *net, struct afs_cell *cell)
378374
{
379375
_enter("%p{%d,%s}", cell, atomic_read(&cell->usage), cell->name);
380376

@@ -387,14 +383,14 @@ static void afs_cell_destroy(struct afs_cell *cell)
387383

388384
_debug("wait for cell %s", cell->name);
389385
set_current_state(TASK_UNINTERRUPTIBLE);
390-
add_wait_queue(&afs_cells_freeable_wq, &myself);
386+
add_wait_queue(&net->cells_freeable_wq, &myself);
391387

392388
while (atomic_read(&cell->usage) > 0) {
393389
schedule();
394390
set_current_state(TASK_UNINTERRUPTIBLE);
395391
}
396392

397-
remove_wait_queue(&afs_cells_freeable_wq, &myself);
393+
remove_wait_queue(&net->cells_freeable_wq, &myself);
398394
set_current_state(TASK_RUNNING);
399395
}
400396

@@ -403,11 +399,11 @@ static void afs_cell_destroy(struct afs_cell *cell)
403399
ASSERT(list_empty(&cell->servers));
404400
ASSERT(list_empty(&cell->vl_list));
405401

406-
afs_proc_cell_remove(cell);
402+
afs_proc_cell_remove(net, cell);
407403

408-
down_write(&afs_proc_cells_sem);
404+
down_write(&net->proc_cells_sem);
409405
list_del_init(&cell->proc_link);
410-
up_write(&afs_proc_cells_sem);
406+
up_write(&net->proc_cells_sem);
411407

412408
#ifdef CONFIG_AFS_FSCACHE
413409
fscache_relinquish_cookie(cell->cache, 0);
@@ -422,39 +418,39 @@ static void afs_cell_destroy(struct afs_cell *cell)
422418
* purge in-memory cell database on module unload or afs_init() failure
423419
* - the timeout daemon is stopped before calling this
424420
*/
425-
void afs_cell_purge(void)
421+
void afs_cell_purge(struct afs_net *net)
426422
{
427423
struct afs_cell *cell;
428424

429425
_enter("");
430426

431-
afs_put_cell(afs_cell_root);
427+
afs_put_cell(net->ws_cell);
432428

433-
down_write(&afs_cells_sem);
429+
down_write(&net->cells_sem);
434430

435-
while (!list_empty(&afs_cells)) {
431+
while (!list_empty(&net->cells)) {
436432
cell = NULL;
437433

438434
/* remove the next cell from the front of the list */
439-
write_lock(&afs_cells_lock);
435+
write_lock(&net->cells_lock);
440436

441-
if (!list_empty(&afs_cells)) {
442-
cell = list_entry(afs_cells.next,
437+
if (!list_empty(&net->cells)) {
438+
cell = list_entry(net->cells.next,
443439
struct afs_cell, link);
444440
list_del_init(&cell->link);
445441
}
446442

447-
write_unlock(&afs_cells_lock);
443+
write_unlock(&net->cells_lock);
448444

449445
if (cell) {
450446
_debug("PURGING CELL %s (%d)",
451447
cell->name, atomic_read(&cell->usage));
452448

453449
/* now the cell should be left with no references */
454-
afs_cell_destroy(cell);
450+
afs_cell_destroy(net, cell);
455451
}
456452
}
457453

458-
up_write(&afs_cells_sem);
454+
up_write(&net->cells_sem);
459455
_leave("");
460456
}

0 commit comments

Comments
 (0)