Skip to content

Commit a80d923

Browse files
Eric Van HensbergenEric Van Hensbergen
Eric Van Hensbergen
authored and
Eric Van Hensbergen
committed
9p: Make transports dynamic
This patch abstracts out the interfaces to underlying transports so that new transports can be added as modules. This should also allow kernel configuration of transports without ifdef-hell. Signed-off-by: Eric Van Hensbergen <ericvh@gmail.com>
1 parent 0eafaae commit a80d923

File tree

12 files changed

+379
-285
lines changed

12 files changed

+379
-285
lines changed

Documentation/filesystems/9p.txt

+4-4
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,12 @@ For remote file server:
3535

3636
For Plan 9 From User Space applications (http://swtch.com/plan9)
3737

38-
mount -t 9p `namespace`/acme /mnt/9 -o proto=unix,uname=$USER
38+
mount -t 9p `namespace`/acme /mnt/9 -o trans=unix,uname=$USER
3939

4040
OPTIONS
4141
=======
4242

43-
proto=name select an alternative transport. Valid options are
43+
trans=name select an alternative transport. Valid options are
4444
currently:
4545
unix - specifying a named pipe mount point
4646
tcp - specifying a normal TCP/IP connection
@@ -68,9 +68,9 @@ OPTIONS
6868
0x40 = display transport debug
6969
0x80 = display allocation debug
7070

71-
rfdno=n the file descriptor for reading with proto=fd
71+
rfdno=n the file descriptor for reading with trans=fd
7272

73-
wfdno=n the file descriptor for writing with proto=fd
73+
wfdno=n the file descriptor for writing with trans=fd
7474

7575
maxdata=n the number of bytes to use for 9p packet payload (msize)
7676

fs/9p/v9fs.c

+72-77
Original file line numberDiff line numberDiff line change
@@ -36,19 +36,59 @@
3636
#include "v9fs.h"
3737
#include "v9fs_vfs.h"
3838

39+
/*
40+
* Dynamic Transport Registration Routines
41+
*
42+
*/
43+
44+
static LIST_HEAD(v9fs_trans_list);
45+
static struct p9_trans_module *v9fs_default_trans;
46+
47+
/**
48+
* v9fs_register_trans - register a new transport with 9p
49+
* @m - structure describing the transport module and entry points
50+
*
51+
*/
52+
void v9fs_register_trans(struct p9_trans_module *m)
53+
{
54+
list_add_tail(&m->list, &v9fs_trans_list);
55+
if (m->def)
56+
v9fs_default_trans = m;
57+
}
58+
EXPORT_SYMBOL(v9fs_register_trans);
59+
60+
/**
61+
* v9fs_match_trans - match transport versus registered transports
62+
* @arg: string identifying transport
63+
*
64+
*/
65+
static struct p9_trans_module *v9fs_match_trans(const substring_t *name)
66+
{
67+
struct list_head *p;
68+
struct p9_trans_module *t = NULL;
69+
70+
list_for_each(p, &v9fs_trans_list) {
71+
t = list_entry(p, struct p9_trans_module, list);
72+
if (strncmp(t->name, name->from, name->to-name->from) == 0) {
73+
P9_DPRINTK(P9_DEBUG_TRANS, "trans=%s\n", t->name);
74+
break;
75+
}
76+
}
77+
return t;
78+
}
79+
3980
/*
4081
* Option Parsing (code inspired by NFS code)
41-
*
82+
* NOTE: each transport will parse its own options
4283
*/
4384

4485
enum {
4586
/* Options that take integer arguments */
46-
Opt_debug, Opt_port, Opt_msize, Opt_uid, Opt_gid, Opt_afid,
47-
Opt_rfdno, Opt_wfdno,
87+
Opt_debug, Opt_msize, Opt_uid, Opt_gid, Opt_afid,
4888
/* String options */
49-
Opt_uname, Opt_remotename,
89+
Opt_uname, Opt_remotename, Opt_trans,
5090
/* Options that take no arguments */
51-
Opt_legacy, Opt_nodevmap, Opt_unix, Opt_tcp, Opt_fd, Opt_pci,
91+
Opt_legacy, Opt_nodevmap,
5292
/* Cache options */
5393
Opt_cache_loose,
5494
/* Error token */
@@ -57,61 +97,42 @@ enum {
5797

5898
static match_table_t tokens = {
5999
{Opt_debug, "debug=%x"},
60-
{Opt_port, "port=%u"},
61100
{Opt_msize, "msize=%u"},
62101
{Opt_uid, "uid=%u"},
63102
{Opt_gid, "gid=%u"},
64103
{Opt_afid, "afid=%u"},
65-
{Opt_rfdno, "rfdno=%u"},
66-
{Opt_wfdno, "wfdno=%u"},
67104
{Opt_uname, "uname=%s"},
68105
{Opt_remotename, "aname=%s"},
69-
{Opt_unix, "proto=unix"},
70-
{Opt_tcp, "proto=tcp"},
71-
{Opt_fd, "proto=fd"},
72-
#ifdef CONFIG_PCI_9P
73-
{Opt_pci, "proto=pci"},
74-
#endif
75-
{Opt_tcp, "tcp"},
76-
{Opt_unix, "unix"},
77-
{Opt_fd, "fd"},
106+
{Opt_trans, "trans=%s"},
78107
{Opt_legacy, "noextend"},
79108
{Opt_nodevmap, "nodevmap"},
80109
{Opt_cache_loose, "cache=loose"},
81110
{Opt_cache_loose, "loose"},
82111
{Opt_err, NULL}
83112
};
84113

85-
extern struct p9_transport *p9pci_trans_create(void);
86-
87-
/*
88-
* Parse option string.
89-
*/
90-
91114
/**
92115
* v9fs_parse_options - parse mount options into session structure
93116
* @options: options string passed from mount
94117
* @v9ses: existing v9fs session information
95118
*
96119
*/
97120

98-
static void v9fs_parse_options(char *options, struct v9fs_session_info *v9ses)
121+
static void v9fs_parse_options(struct v9fs_session_info *v9ses)
99122
{
100-
char *p;
123+
char *options = v9ses->options;
101124
substring_t args[MAX_OPT_ARGS];
125+
char *p;
102126
int option;
103127
int ret;
104128

105129
/* setup defaults */
106-
v9ses->port = V9FS_PORT;
107-
v9ses->maxdata = 9000;
108-
v9ses->proto = PROTO_TCP;
130+
v9ses->maxdata = 8192;
109131
v9ses->extended = 1;
110132
v9ses->afid = ~0;
111133
v9ses->debug = 0;
112-
v9ses->rfdno = ~0;
113-
v9ses->wfdno = ~0;
114134
v9ses->cache = 0;
135+
v9ses->trans = v9fs_default_trans;
115136

116137
if (!options)
117138
return;
@@ -135,9 +156,6 @@ static void v9fs_parse_options(char *options, struct v9fs_session_info *v9ses)
135156
p9_debug_level = option;
136157
#endif
137158
break;
138-
case Opt_port:
139-
v9ses->port = option;
140-
break;
141159
case Opt_msize:
142160
v9ses->maxdata = option;
143161
break;
@@ -150,23 +168,8 @@ static void v9fs_parse_options(char *options, struct v9fs_session_info *v9ses)
150168
case Opt_afid:
151169
v9ses->afid = option;
152170
break;
153-
case Opt_rfdno:
154-
v9ses->rfdno = option;
155-
break;
156-
case Opt_wfdno:
157-
v9ses->wfdno = option;
158-
break;
159-
case Opt_tcp:
160-
v9ses->proto = PROTO_TCP;
161-
break;
162-
case Opt_unix:
163-
v9ses->proto = PROTO_UNIX;
164-
break;
165-
case Opt_pci:
166-
v9ses->proto = PROTO_PCI;
167-
break;
168-
case Opt_fd:
169-
v9ses->proto = PROTO_FD;
171+
case Opt_trans:
172+
v9ses->trans = v9fs_match_trans(&args[0]);
170173
break;
171174
case Opt_uname:
172175
match_strcpy(v9ses->name, &args[0]);
@@ -201,7 +204,7 @@ struct p9_fid *v9fs_session_init(struct v9fs_session_info *v9ses,
201204
const char *dev_name, char *data)
202205
{
203206
int retval = -EINVAL;
204-
struct p9_transport *trans;
207+
struct p9_trans *trans = NULL;
205208
struct p9_fid *fid;
206209

207210
v9ses->name = __getname();
@@ -217,39 +220,30 @@ struct p9_fid *v9fs_session_init(struct v9fs_session_info *v9ses,
217220
strcpy(v9ses->name, V9FS_DEFUSER);
218221
strcpy(v9ses->remotename, V9FS_DEFANAME);
219222

220-
v9fs_parse_options(data, v9ses);
221-
222-
switch (v9ses->proto) {
223-
case PROTO_TCP:
224-
trans = p9_trans_create_tcp(dev_name, v9ses->port);
225-
break;
226-
case PROTO_UNIX:
227-
trans = p9_trans_create_unix(dev_name);
228-
*v9ses->remotename = 0;
229-
break;
230-
case PROTO_FD:
231-
trans = p9_trans_create_fd(v9ses->rfdno, v9ses->wfdno);
232-
*v9ses->remotename = 0;
233-
break;
234-
#ifdef CONFIG_PCI_9P
235-
case PROTO_PCI:
236-
trans = p9pci_trans_create();
237-
*v9ses->remotename = 0;
238-
break;
239-
#endif
240-
default:
241-
printk(KERN_ERR "v9fs: Bad mount protocol %d\n", v9ses->proto);
242-
retval = -ENOPROTOOPT;
223+
v9ses->options = kstrdup(data, GFP_KERNEL);
224+
v9fs_parse_options(v9ses);
225+
226+
if ((v9ses->trans == NULL) && !list_empty(&v9fs_trans_list))
227+
v9ses->trans = list_first_entry(&v9fs_trans_list,
228+
struct p9_trans_module, list);
229+
230+
if (v9ses->trans == NULL) {
231+
retval = -EPROTONOSUPPORT;
232+
P9_DPRINTK(P9_DEBUG_ERROR,
233+
"No transport defined or default transport\n");
243234
goto error;
244-
};
235+
}
245236

237+
trans = v9ses->trans->create(dev_name, v9ses->options);
246238
if (IS_ERR(trans)) {
247239
retval = PTR_ERR(trans);
248240
trans = NULL;
249241
goto error;
250242
}
243+
if ((v9ses->maxdata+P9_IOHDRSZ) > v9ses->trans->maxsize)
244+
v9ses->maxdata = v9ses->trans->maxsize-P9_IOHDRSZ;
251245

252-
v9ses->clnt = p9_client_create(trans, v9ses->maxdata + P9_IOHDRSZ,
246+
v9ses->clnt = p9_client_create(trans, v9ses->maxdata+P9_IOHDRSZ,
253247
v9ses->extended);
254248

255249
if (IS_ERR(v9ses->clnt)) {
@@ -290,6 +284,7 @@ void v9fs_session_close(struct v9fs_session_info *v9ses)
290284

291285
__putname(v9ses->name);
292286
__putname(v9ses->remotename);
287+
kfree(v9ses->options);
293288
}
294289

295290
/**
@@ -311,7 +306,7 @@ extern int v9fs_error_init(void);
311306
static int __init init_v9fs(void)
312307
{
313308
printk(KERN_INFO "Installing v9fs 9p2000 file system support\n");
314-
309+
/* TODO: Setup list of registered trasnport modules */
315310
return register_filesystem(&v9fs_fs_type);
316311
}
317312

fs/9p/v9fs.h

+2-13
Original file line numberDiff line numberDiff line change
@@ -31,31 +31,20 @@ struct v9fs_session_info {
3131
unsigned int maxdata;
3232
unsigned char extended; /* set to 1 if we are using UNIX extensions */
3333
unsigned char nodev; /* set to 1 if no disable device mapping */
34-
unsigned short port; /* port to connect to */
3534
unsigned short debug; /* debug level */
36-
unsigned short proto; /* protocol to use */
3735
unsigned int afid; /* authentication fid */
38-
unsigned int rfdno; /* read file descriptor number */
39-
unsigned int wfdno; /* write file descriptor number */
4036
unsigned int cache; /* cache mode */
4137

38+
char *options; /* copy of mount options */
4239
char *name; /* user name to mount as */
4340
char *remotename; /* name of remote hierarchy being mounted */
4441
unsigned int uid; /* default uid/muid for legacy support */
4542
unsigned int gid; /* default gid for legacy support */
46-
43+
struct p9_trans_module *trans; /* 9p transport */
4744
struct p9_client *clnt; /* 9p client */
4845
struct dentry *debugfs_dir;
4946
};
5047

51-
/* possible values of ->proto */
52-
enum {
53-
PROTO_TCP,
54-
PROTO_UNIX,
55-
PROTO_FD,
56-
PROTO_PCI,
57-
};
58-
5948
/* possible values of ->cache */
6049
/* eventually support loose, tight, time, session, default always none */
6150
enum {

fs/9p/vfs_super.c

+1-18
Original file line numberDiff line numberDiff line change
@@ -216,24 +216,7 @@ static int v9fs_show_options(struct seq_file *m, struct vfsmount *mnt)
216216
{
217217
struct v9fs_session_info *v9ses = mnt->mnt_sb->s_fs_info;
218218

219-
if (v9ses->debug != 0)
220-
seq_printf(m, ",debug=%x", v9ses->debug);
221-
if (v9ses->port != V9FS_PORT)
222-
seq_printf(m, ",port=%u", v9ses->port);
223-
if (v9ses->maxdata != 9000)
224-
seq_printf(m, ",msize=%u", v9ses->maxdata);
225-
if (v9ses->afid != ~0)
226-
seq_printf(m, ",afid=%u", v9ses->afid);
227-
if (v9ses->proto == PROTO_UNIX)
228-
seq_puts(m, ",proto=unix");
229-
if (v9ses->extended == 0)
230-
seq_puts(m, ",noextend");
231-
if (v9ses->nodev == 1)
232-
seq_puts(m, ",nodevmap");
233-
seq_printf(m, ",name=%s", v9ses->name);
234-
seq_printf(m, ",aname=%s", v9ses->remotename);
235-
seq_printf(m, ",uid=%u", v9ses->uid);
236-
seq_printf(m, ",gid=%u", v9ses->gid);
219+
seq_printf(m, "%s", v9ses->options);
237220
return 0;
238221
}
239222

include/net/9p/client.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ struct p9_client {
2929
spinlock_t lock; /* protect client structure */
3030
int msize;
3131
unsigned char dotu;
32-
struct p9_transport *trans;
32+
struct p9_trans *trans;
3333
struct p9_conn *conn;
3434

3535
struct p9_idpool *fidpool;
@@ -52,7 +52,7 @@ struct p9_fid {
5252
struct list_head dlist; /* list of all fids attached to a dentry */
5353
};
5454

55-
struct p9_client *p9_client_create(struct p9_transport *trans, int msize,
55+
struct p9_client *p9_client_create(struct p9_trans *trans, int msize,
5656
int dotu);
5757
void p9_client_destroy(struct p9_client *clnt);
5858
void p9_client_disconnect(struct p9_client *clnt);

include/net/9p/conn.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,8 @@ struct p9_req;
4242
*/
4343
typedef void (*p9_conn_req_callback)(struct p9_req *req, void *a);
4444

45-
struct p9_conn *p9_conn_create(struct p9_transport *trans, int msize,
46-
unsigned char *dotu);
45+
struct p9_conn *p9_conn_create(struct p9_trans *trans, int msize,
46+
unsigned char *dotu);
4747
void p9_conn_destroy(struct p9_conn *);
4848
int p9_conn_rpc(struct p9_conn *m, struct p9_fcall *tc, struct p9_fcall **rc);
4949

0 commit comments

Comments
 (0)