diff options
Diffstat (limited to 'fs/9p')
-rw-r--r-- | fs/9p/v9fs.c | 149 | ||||
-rw-r--r-- | fs/9p/v9fs.h | 15 | ||||
-rw-r--r-- | fs/9p/vfs_super.c | 19 |
3 files changed, 75 insertions, 108 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 | ||
diff --git a/fs/9p/v9fs.h b/fs/9p/v9fs.h index abc4b1668ace..7eb135cf60ca 100644 --- a/fs/9p/v9fs.h +++ b/fs/9p/v9fs.h | |||
@@ -31,31 +31,20 @@ struct v9fs_session_info { | |||
31 | unsigned int maxdata; | 31 | unsigned int maxdata; |
32 | unsigned char extended; /* set to 1 if we are using UNIX extensions */ | 32 | unsigned char extended; /* set to 1 if we are using UNIX extensions */ |
33 | unsigned char nodev; /* set to 1 if no disable device mapping */ | 33 | unsigned char nodev; /* set to 1 if no disable device mapping */ |
34 | unsigned short port; /* port to connect to */ | ||
35 | unsigned short debug; /* debug level */ | 34 | unsigned short debug; /* debug level */ |
36 | unsigned short proto; /* protocol to use */ | ||
37 | unsigned int afid; /* authentication fid */ | 35 | unsigned int afid; /* authentication fid */ |
38 | unsigned int rfdno; /* read file descriptor number */ | ||
39 | unsigned int wfdno; /* write file descriptor number */ | ||
40 | unsigned int cache; /* cache mode */ | 36 | unsigned int cache; /* cache mode */ |
41 | 37 | ||
38 | char *options; /* copy of mount options */ | ||
42 | char *name; /* user name to mount as */ | 39 | char *name; /* user name to mount as */ |
43 | char *remotename; /* name of remote hierarchy being mounted */ | 40 | char *remotename; /* name of remote hierarchy being mounted */ |
44 | unsigned int uid; /* default uid/muid for legacy support */ | 41 | unsigned int uid; /* default uid/muid for legacy support */ |
45 | unsigned int gid; /* default gid for legacy support */ | 42 | unsigned int gid; /* default gid for legacy support */ |
46 | 43 | struct p9_trans_module *trans; /* 9p transport */ | |
47 | struct p9_client *clnt; /* 9p client */ | 44 | struct p9_client *clnt; /* 9p client */ |
48 | struct dentry *debugfs_dir; | 45 | struct dentry *debugfs_dir; |
49 | }; | 46 | }; |
50 | 47 | ||
51 | /* possible values of ->proto */ | ||
52 | enum { | ||
53 | PROTO_TCP, | ||
54 | PROTO_UNIX, | ||
55 | PROTO_FD, | ||
56 | PROTO_PCI, | ||
57 | }; | ||
58 | |||
59 | /* possible values of ->cache */ | 48 | /* possible values of ->cache */ |
60 | /* eventually support loose, tight, time, session, default always none */ | 49 | /* eventually support loose, tight, time, session, default always none */ |
61 | enum { | 50 | enum { |
diff --git a/fs/9p/vfs_super.c b/fs/9p/vfs_super.c index ba904371218b..bb0cef9a6b8a 100644 --- a/fs/9p/vfs_super.c +++ b/fs/9p/vfs_super.c | |||
@@ -216,24 +216,7 @@ static int v9fs_show_options(struct seq_file *m, struct vfsmount *mnt) | |||
216 | { | 216 | { |
217 | struct v9fs_session_info *v9ses = mnt->mnt_sb->s_fs_info; | 217 | struct v9fs_session_info *v9ses = mnt->mnt_sb->s_fs_info; |
218 | 218 | ||
219 | if (v9ses->debug != 0) | 219 | seq_printf(m, "%s", v9ses->options); |
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); | ||
237 | return 0; | 220 | return 0; |
238 | } | 221 | } |
239 | 222 | ||