diff options
Diffstat (limited to 'fs/9p/v9fs.c')
-rw-r--r-- | fs/9p/v9fs.c | 149 |
1 files changed, 72 insertions, 77 deletions
diff --git a/fs/9p/v9fs.c b/fs/9p/v9fs.c index 0a7068e30ecb..08d880fb5b6a 100644 --- a/fs/9p/v9fs.c +++ b/fs/9p/v9fs.c | |||
@@ -37,18 +37,58 @@ | |||
37 | #include "v9fs_vfs.h" | 37 | #include "v9fs_vfs.h" |
38 | 38 | ||
39 | /* | 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 | |||
80 | /* | ||
40 | * Option Parsing (code inspired by NFS code) | 81 | * Option Parsing (code inspired by NFS code) |
41 | * | 82 | * NOTE: each transport will parse its own options |
42 | */ | 83 | */ |
43 | 84 | ||
44 | enum { | 85 | enum { |
45 | /* Options that take integer arguments */ | 86 | /* Options that take integer arguments */ |
46 | Opt_debug, Opt_port, Opt_msize, Opt_uid, Opt_gid, Opt_afid, | 87 | Opt_debug, Opt_msize, Opt_uid, Opt_gid, Opt_afid, |
47 | Opt_rfdno, Opt_wfdno, | ||
48 | /* String options */ | 88 | /* String options */ |
49 | Opt_uname, Opt_remotename, | 89 | Opt_uname, Opt_remotename, Opt_trans, |
50 | /* Options that take no arguments */ | 90 | /* Options that take no arguments */ |
51 | Opt_legacy, Opt_nodevmap, Opt_unix, Opt_tcp, Opt_fd, Opt_pci, | 91 | Opt_legacy, Opt_nodevmap, |
52 | /* Cache options */ | 92 | /* Cache options */ |
53 | Opt_cache_loose, | 93 | Opt_cache_loose, |
54 | /* Error token */ | 94 | /* Error token */ |
@@ -57,24 +97,13 @@ enum { | |||
57 | 97 | ||
58 | static match_table_t tokens = { | 98 | static match_table_t tokens = { |
59 | {Opt_debug, "debug=%x"}, | 99 | {Opt_debug, "debug=%x"}, |
60 | {Opt_port, "port=%u"}, | ||
61 | {Opt_msize, "msize=%u"}, | 100 | {Opt_msize, "msize=%u"}, |
62 | {Opt_uid, "uid=%u"}, | 101 | {Opt_uid, "uid=%u"}, |
63 | {Opt_gid, "gid=%u"}, | 102 | {Opt_gid, "gid=%u"}, |
64 | {Opt_afid, "afid=%u"}, | 103 | {Opt_afid, "afid=%u"}, |
65 | {Opt_rfdno, "rfdno=%u"}, | ||
66 | {Opt_wfdno, "wfdno=%u"}, | ||
67 | {Opt_uname, "uname=%s"}, | 104 | {Opt_uname, "uname=%s"}, |
68 | {Opt_remotename, "aname=%s"}, | 105 | {Opt_remotename, "aname=%s"}, |
69 | {Opt_unix, "proto=unix"}, | 106 | {Opt_trans, "trans=%s"}, |
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"}, | ||
78 | {Opt_legacy, "noextend"}, | 107 | {Opt_legacy, "noextend"}, |
79 | {Opt_nodevmap, "nodevmap"}, | 108 | {Opt_nodevmap, "nodevmap"}, |
80 | {Opt_cache_loose, "cache=loose"}, | 109 | {Opt_cache_loose, "cache=loose"}, |
@@ -82,12 +111,6 @@ static match_table_t tokens = { | |||
82 | {Opt_err, NULL} | 111 | {Opt_err, NULL} |
83 | }; | 112 | }; |
84 | 113 | ||
85 | extern struct p9_transport *p9pci_trans_create(void); | ||
86 | |||
87 | /* | ||
88 | * Parse option string. | ||
89 | */ | ||
90 | |||
91 | /** | 114 | /** |
92 | * v9fs_parse_options - parse mount options into session structure | 115 | * v9fs_parse_options - parse mount options into session structure |
93 | * @options: options string passed from mount | 116 | * @options: options string passed from mount |
@@ -95,23 +118,21 @@ extern struct p9_transport *p9pci_trans_create(void); | |||
95 | * | 118 | * |
96 | */ | 119 | */ |
97 | 120 | ||
98 | static void v9fs_parse_options(char *options, struct v9fs_session_info *v9ses) | 121 | static void v9fs_parse_options(struct v9fs_session_info *v9ses) |
99 | { | 122 | { |
100 | char *p; | 123 | char *options = v9ses->options; |
101 | substring_t args[MAX_OPT_ARGS]; | 124 | substring_t args[MAX_OPT_ARGS]; |
125 | char *p; | ||
102 | int option; | 126 | int option; |
103 | int ret; | 127 | int ret; |
104 | 128 | ||
105 | /* setup defaults */ | 129 | /* setup defaults */ |
106 | v9ses->port = V9FS_PORT; | 130 | v9ses->maxdata = 8192; |
107 | v9ses->maxdata = 9000; | ||
108 | v9ses->proto = PROTO_TCP; | ||
109 | v9ses->extended = 1; | 131 | v9ses->extended = 1; |
110 | v9ses->afid = ~0; | 132 | v9ses->afid = ~0; |
111 | v9ses->debug = 0; | 133 | v9ses->debug = 0; |
112 | v9ses->rfdno = ~0; | ||
113 | v9ses->wfdno = ~0; | ||
114 | v9ses->cache = 0; | 134 | v9ses->cache = 0; |
135 | v9ses->trans = v9fs_default_trans; | ||
115 | 136 | ||
116 | if (!options) | 137 | if (!options) |
117 | return; | 138 | return; |
@@ -135,9 +156,6 @@ static void v9fs_parse_options(char *options, struct v9fs_session_info *v9ses) | |||
135 | p9_debug_level = option; | 156 | p9_debug_level = option; |
136 | #endif | 157 | #endif |
137 | break; | 158 | break; |
138 | case Opt_port: | ||
139 | v9ses->port = option; | ||
140 | break; | ||
141 | case Opt_msize: | 159 | case Opt_msize: |
142 | v9ses->maxdata = option; | 160 | v9ses->maxdata = option; |
143 | break; | 161 | break; |
@@ -150,23 +168,8 @@ static void v9fs_parse_options(char *options, struct v9fs_session_info *v9ses) | |||
150 | case Opt_afid: | 168 | case Opt_afid: |
151 | v9ses->afid = option; | 169 | v9ses->afid = option; |
152 | break; | 170 | break; |
153 | case Opt_rfdno: | 171 | case Opt_trans: |
154 | v9ses->rfdno = option; | 172 | v9ses->trans = v9fs_match_trans(&args[0]); |
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; | ||
170 | break; | 173 | break; |
171 | case Opt_uname: | 174 | case Opt_uname: |
172 | match_strcpy(v9ses->name, &args[0]); | 175 | match_strcpy(v9ses->name, &args[0]); |
@@ -201,7 +204,7 @@ struct p9_fid *v9fs_session_init(struct v9fs_session_info *v9ses, | |||
201 | const char *dev_name, char *data) | 204 | const char *dev_name, char *data) |
202 | { | 205 | { |
203 | int retval = -EINVAL; | 206 | int retval = -EINVAL; |
204 | struct p9_transport *trans; | 207 | struct p9_trans *trans = NULL; |
205 | struct p9_fid *fid; | 208 | struct p9_fid *fid; |
206 | 209 | ||
207 | v9ses->name = __getname(); | 210 | v9ses->name = __getname(); |
@@ -217,39 +220,30 @@ struct p9_fid *v9fs_session_init(struct v9fs_session_info *v9ses, | |||
217 | strcpy(v9ses->name, V9FS_DEFUSER); | 220 | strcpy(v9ses->name, V9FS_DEFUSER); |
218 | strcpy(v9ses->remotename, V9FS_DEFANAME); | 221 | strcpy(v9ses->remotename, V9FS_DEFANAME); |
219 | 222 | ||
220 | v9fs_parse_options(data, v9ses); | 223 | v9ses->options = kstrdup(data, GFP_KERNEL); |
221 | 224 | v9fs_parse_options(v9ses); | |
222 | switch (v9ses->proto) { | 225 | |
223 | case PROTO_TCP: | 226 | if ((v9ses->trans == NULL) && !list_empty(&v9fs_trans_list)) |
224 | trans = p9_trans_create_tcp(dev_name, v9ses->port); | 227 | v9ses->trans = list_first_entry(&v9fs_trans_list, |
225 | break; | 228 | struct p9_trans_module, list); |
226 | case PROTO_UNIX: | 229 | |
227 | trans = p9_trans_create_unix(dev_name); | 230 | if (v9ses->trans == NULL) { |
228 | *v9ses->remotename = 0; | 231 | retval = -EPROTONOSUPPORT; |
229 | break; | 232 | P9_DPRINTK(P9_DEBUG_ERROR, |
230 | case PROTO_FD: | 233 | "No transport defined or default transport\n"); |
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; | ||
243 | goto error; | 234 | goto error; |
244 | }; | 235 | } |
245 | 236 | ||
237 | trans = v9ses->trans->create(dev_name, v9ses->options); | ||
246 | if (IS_ERR(trans)) { | 238 | if (IS_ERR(trans)) { |
247 | retval = PTR_ERR(trans); | 239 | retval = PTR_ERR(trans); |
248 | trans = NULL; | 240 | trans = NULL; |
249 | goto error; | 241 | goto error; |
250 | } | 242 | } |
243 | if ((v9ses->maxdata+P9_IOHDRSZ) > v9ses->trans->maxsize) | ||
244 | v9ses->maxdata = v9ses->trans->maxsize-P9_IOHDRSZ; | ||
251 | 245 | ||
252 | v9ses->clnt = p9_client_create(trans, v9ses->maxdata + P9_IOHDRSZ, | 246 | v9ses->clnt = p9_client_create(trans, v9ses->maxdata+P9_IOHDRSZ, |
253 | v9ses->extended); | 247 | v9ses->extended); |
254 | 248 | ||
255 | if (IS_ERR(v9ses->clnt)) { | 249 | if (IS_ERR(v9ses->clnt)) { |
@@ -290,6 +284,7 @@ void v9fs_session_close(struct v9fs_session_info *v9ses) | |||
290 | 284 | ||
291 | __putname(v9ses->name); | 285 | __putname(v9ses->name); |
292 | __putname(v9ses->remotename); | 286 | __putname(v9ses->remotename); |
287 | kfree(v9ses->options); | ||
293 | } | 288 | } |
294 | 289 | ||
295 | /** | 290 | /** |
@@ -311,7 +306,7 @@ extern int v9fs_error_init(void); | |||
311 | static int __init init_v9fs(void) | 306 | static int __init init_v9fs(void) |
312 | { | 307 | { |
313 | printk(KERN_INFO "Installing v9fs 9p2000 file system support\n"); | 308 | printk(KERN_INFO "Installing v9fs 9p2000 file system support\n"); |
314 | 309 | /* TODO: Setup list of registered trasnport modules */ | |
315 | return register_filesystem(&v9fs_fs_type); | 310 | return register_filesystem(&v9fs_fs_type); |
316 | } | 311 | } |
317 | 312 | ||