Skip to content

Commit 5b86d4f

Browse files
committed
afs: Implement network namespacing
Implement network namespacing within AFS, but don't yet let mounts occur outside the init namespace. An additional patch will be required propagate the network namespace across automounts. Signed-off-by: David Howells <[email protected]>
1 parent 1588def commit 5b86d4f

File tree

8 files changed

+173
-295
lines changed

8 files changed

+173
-295
lines changed

fs/afs/cell.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -528,7 +528,7 @@ static int afs_activate_cell(struct afs_net *net, struct afs_cell *cell)
528528
NULL, 0,
529529
cell, 0, true);
530530
#endif
531-
ret = afs_proc_cell_setup(net, cell);
531+
ret = afs_proc_cell_setup(cell);
532532
if (ret < 0)
533533
return ret;
534534
spin_lock(&net->proc_cells_lock);
@@ -544,7 +544,7 @@ static void afs_deactivate_cell(struct afs_net *net, struct afs_cell *cell)
544544
{
545545
_enter("%s", cell->name);
546546

547-
afs_proc_cell_remove(net, cell);
547+
afs_proc_cell_remove(cell);
548548

549549
spin_lock(&net->proc_cells_lock);
550550
list_del_init(&cell->proc_link);

fs/afs/cmservice.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -550,7 +550,7 @@ static void SRXAFSCB_TellMeAboutYourself(struct work_struct *work)
550550
nifs = 0;
551551
ifs = kcalloc(32, sizeof(*ifs), GFP_KERNEL);
552552
if (ifs) {
553-
nifs = afs_get_ipv4_interfaces(ifs, 32, false);
553+
nifs = afs_get_ipv4_interfaces(call->net, ifs, 32, false);
554554
if (nifs < 0) {
555555
kfree(ifs);
556556
ifs = NULL;

fs/afs/internal.h

Lines changed: 24 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222
#include <linux/backing-dev.h>
2323
#include <linux/uuid.h>
2424
#include <net/net_namespace.h>
25+
#include <net/netns/generic.h>
26+
#include <net/sock.h>
2527
#include <net/af_rxrpc.h>
2628

2729
#include "afs.h"
@@ -40,7 +42,8 @@ struct afs_mount_params {
4042
afs_voltype_t type; /* type of volume requested */
4143
int volnamesz; /* size of volume name */
4244
const char *volname; /* name of volume to mount */
43-
struct afs_net *net; /* Network namespace in effect */
45+
struct net *net_ns; /* Network namespace in effect */
46+
struct afs_net *net; /* the AFS net namespace stuff */
4447
struct afs_cell *cell; /* cell in which to find volume */
4548
struct afs_volume *volume; /* volume record */
4649
struct key *key; /* key to use for secure mounting */
@@ -189,7 +192,7 @@ struct afs_read {
189192
* - there's one superblock per volume
190193
*/
191194
struct afs_super_info {
192-
struct afs_net *net; /* Network namespace */
195+
struct net *net_ns; /* Network namespace */
193196
struct afs_cell *cell; /* The cell in which the volume resides */
194197
struct afs_volume *volume; /* volume record */
195198
bool dyn_root; /* True if dynamic root */
@@ -210,14 +213,14 @@ struct afs_sysnames {
210213
char *subs[AFS_NR_SYSNAME];
211214
refcount_t usage;
212215
unsigned short nr;
213-
short error;
214216
char blank[1];
215217
};
216218

217219
/*
218220
* AFS network namespace record.
219221
*/
220222
struct afs_net {
223+
struct net *net; /* Backpointer to the owning net namespace */
221224
struct afs_uuid uuid;
222225
bool live; /* F if this namespace is being removed */
223226

@@ -280,7 +283,6 @@ struct afs_net {
280283
};
281284

282285
extern const char afs_init_sysname[];
283-
extern struct afs_net __afs_net;// Dummy AFS network namespace; TODO: replace with real netns
284286

285287
enum afs_cell_state {
286288
AFS_CELL_UNSET,
@@ -787,34 +789,36 @@ extern int afs_drop_inode(struct inode *);
787789
* main.c
788790
*/
789791
extern struct workqueue_struct *afs_wq;
792+
extern int afs_net_id;
790793

791-
static inline struct afs_net *afs_d2net(struct dentry *dentry)
794+
static inline struct afs_net *afs_net(struct net *net)
792795
{
793-
return &__afs_net;
796+
return net_generic(net, afs_net_id);
794797
}
795798

796-
static inline struct afs_net *afs_i2net(struct inode *inode)
799+
static inline struct afs_net *afs_sb2net(struct super_block *sb)
797800
{
798-
return &__afs_net;
801+
return afs_net(AFS_FS_S(sb)->net_ns);
799802
}
800803

801-
static inline struct afs_net *afs_v2net(struct afs_vnode *vnode)
804+
static inline struct afs_net *afs_d2net(struct dentry *dentry)
802805
{
803-
return &__afs_net;
806+
return afs_sb2net(dentry->d_sb);
804807
}
805808

806-
static inline struct afs_net *afs_sock2net(struct sock *sk)
809+
static inline struct afs_net *afs_i2net(struct inode *inode)
807810
{
808-
return &__afs_net;
811+
return afs_sb2net(inode->i_sb);
809812
}
810813

811-
static inline struct afs_net *afs_get_net(struct afs_net *net)
814+
static inline struct afs_net *afs_v2net(struct afs_vnode *vnode)
812815
{
813-
return net;
816+
return afs_i2net(&vnode->vfs_inode);
814817
}
815818

816-
static inline void afs_put_net(struct afs_net *net)
819+
static inline struct afs_net *afs_sock2net(struct sock *sk)
817820
{
821+
return net_generic(sock_net(sk), afs_net_id);
818822
}
819823

820824
static inline void __afs_stat(atomic_t *s)
@@ -842,15 +846,16 @@ extern void afs_mntpt_kill_timer(void);
842846
/*
843847
* netdevices.c
844848
*/
845-
extern int afs_get_ipv4_interfaces(struct afs_interface *, size_t, bool);
849+
extern int afs_get_ipv4_interfaces(struct afs_net *, struct afs_interface *,
850+
size_t, bool);
846851

847852
/*
848853
* proc.c
849854
*/
850855
extern int __net_init afs_proc_init(struct afs_net *);
851856
extern void __net_exit afs_proc_cleanup(struct afs_net *);
852-
extern int afs_proc_cell_setup(struct afs_net *, struct afs_cell *);
853-
extern void afs_proc_cell_remove(struct afs_net *, struct afs_cell *);
857+
extern int afs_proc_cell_setup(struct afs_cell *);
858+
extern void afs_proc_cell_remove(struct afs_cell *);
854859
extern void afs_put_sysnames(struct afs_sysnames *);
855860

856861
/*
@@ -983,7 +988,7 @@ extern bool afs_annotate_server_list(struct afs_server_list *, struct afs_server
983988
* super.c
984989
*/
985990
extern int __init afs_fs_init(void);
986-
extern void __exit afs_fs_exit(void);
991+
extern void afs_fs_exit(void);
987992

988993
/*
989994
* vlclient.c

fs/afs/main.c

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include <linux/completion.h>
1616
#include <linux/sched.h>
1717
#include <linux/random.h>
18+
#include <linux/proc_fs.h>
1819
#define CREATE_TRACE_POINTS
1920
#include "internal.h"
2021

@@ -32,7 +33,7 @@ module_param(rootcell, charp, 0);
3233
MODULE_PARM_DESC(rootcell, "root AFS cell name and VL server IP addr list");
3334

3435
struct workqueue_struct *afs_wq;
35-
struct afs_net __afs_net;
36+
static struct proc_dir_entry *afs_proc_symlink;
3637

3738
#if defined(CONFIG_ALPHA)
3839
const char afs_init_sysname[] = "alpha_linux26";
@@ -67,11 +68,13 @@ const char afs_init_sysname[] = "unknown_linux26";
6768
/*
6869
* Initialise an AFS network namespace record.
6970
*/
70-
static int __net_init afs_net_init(struct afs_net *net)
71+
static int __net_init afs_net_init(struct net *net_ns)
7172
{
7273
struct afs_sysnames *sysnames;
74+
struct afs_net *net = afs_net(net_ns);
7375
int ret;
7476

77+
net->net = net_ns;
7578
net->live = true;
7679
generate_random_uuid((unsigned char *)&net->uuid);
7780

@@ -142,8 +145,10 @@ static int __net_init afs_net_init(struct afs_net *net)
142145
/*
143146
* Clean up and destroy an AFS network namespace record.
144147
*/
145-
static void __net_exit afs_net_exit(struct afs_net *net)
148+
static void __net_exit afs_net_exit(struct net *net_ns)
146149
{
150+
struct afs_net *net = afs_net(net_ns);
151+
147152
net->live = false;
148153
afs_cell_purge(net);
149154
afs_purge_servers(net);
@@ -152,6 +157,13 @@ static void __net_exit afs_net_exit(struct afs_net *net)
152157
afs_put_sysnames(net->sysnames);
153158
}
154159

160+
static struct pernet_operations afs_net_ops = {
161+
.init = afs_net_init,
162+
.exit = afs_net_exit,
163+
.id = &afs_net_id,
164+
.size = sizeof(struct afs_net),
165+
};
166+
155167
/*
156168
* initialise the AFS client FS module
157169
*/
@@ -178,7 +190,7 @@ static int __init afs_init(void)
178190
goto error_cache;
179191
#endif
180192

181-
ret = afs_net_init(&__afs_net);
193+
ret = register_pernet_subsys(&afs_net_ops);
182194
if (ret < 0)
183195
goto error_net;
184196

@@ -187,10 +199,18 @@ static int __init afs_init(void)
187199
if (ret < 0)
188200
goto error_fs;
189201

202+
afs_proc_symlink = proc_symlink("fs/afs", NULL, "../self/net/afs");
203+
if (IS_ERR(afs_proc_symlink)) {
204+
ret = PTR_ERR(afs_proc_symlink);
205+
goto error_proc;
206+
}
207+
190208
return ret;
191209

210+
error_proc:
211+
afs_fs_exit();
192212
error_fs:
193-
afs_net_exit(&__afs_net);
213+
unregister_pernet_subsys(&afs_net_ops);
194214
error_net:
195215
#ifdef CONFIG_AFS_FSCACHE
196216
fscache_unregister_netfs(&afs_cache_netfs);
@@ -219,8 +239,9 @@ static void __exit afs_exit(void)
219239
{
220240
printk(KERN_INFO "kAFS: Red Hat AFS client v0.1 unregistering.\n");
221241

242+
proc_remove(afs_proc_symlink);
222243
afs_fs_exit();
223-
afs_net_exit(&__afs_net);
244+
unregister_pernet_subsys(&afs_net_ops);
224245
#ifdef CONFIG_AFS_FSCACHE
225246
fscache_unregister_netfs(&afs_cache_netfs);
226247
#endif

fs/afs/netdevices.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@
1717
* - maxbufs must be at least 1
1818
* - returns the number of interface records in the buffer
1919
*/
20-
int afs_get_ipv4_interfaces(struct afs_interface *bufs, size_t maxbufs,
21-
bool wantloopback)
20+
int afs_get_ipv4_interfaces(struct afs_net *net, struct afs_interface *bufs,
21+
size_t maxbufs, bool wantloopback)
2222
{
2323
struct net_device *dev;
2424
struct in_device *idev;
@@ -27,7 +27,7 @@ int afs_get_ipv4_interfaces(struct afs_interface *bufs, size_t maxbufs,
2727
ASSERT(maxbufs > 0);
2828

2929
rtnl_lock();
30-
for_each_netdev(&init_net, dev) {
30+
for_each_netdev(net->net, dev) {
3131
if (dev->type == ARPHRD_LOOPBACK && !wantloopback)
3232
continue;
3333
idev = __in_dev_get_rtnl(dev);

0 commit comments

Comments
 (0)