36
36
#include "v9fs.h"
37
37
#include "v9fs_vfs.h"
38
38
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
+
39
80
/*
40
81
* Option Parsing (code inspired by NFS code)
41
- *
82
+ * NOTE: each transport will parse its own options
42
83
*/
43
84
44
85
enum {
45
86
/* 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 ,
48
88
/* String options */
49
- Opt_uname , Opt_remotename ,
89
+ Opt_uname , Opt_remotename , Opt_trans ,
50
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
92
/* Cache options */
53
93
Opt_cache_loose ,
54
94
/* Error token */
@@ -57,61 +97,42 @@ enum {
57
97
58
98
static match_table_t tokens = {
59
99
{Opt_debug , "debug=%x" },
60
- {Opt_port , "port=%u" },
61
100
{Opt_msize , "msize=%u" },
62
101
{Opt_uid , "uid=%u" },
63
102
{Opt_gid , "gid=%u" },
64
103
{Opt_afid , "afid=%u" },
65
- {Opt_rfdno , "rfdno=%u" },
66
- {Opt_wfdno , "wfdno=%u" },
67
104
{Opt_uname , "uname=%s" },
68
105
{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" },
78
107
{Opt_legacy , "noextend" },
79
108
{Opt_nodevmap , "nodevmap" },
80
109
{Opt_cache_loose , "cache=loose" },
81
110
{Opt_cache_loose , "loose" },
82
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
115
* v9fs_parse_options - parse mount options into session structure
93
116
* @options: options string passed from mount
94
117
* @v9ses: existing v9fs session information
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
124
substring_t args [MAX_OPT_ARGS ];
125
+ char * p ;
102
126
int option ;
103
127
int ret ;
104
128
105
129
/* setup defaults */
106
- v9ses -> port = V9FS_PORT ;
107
- v9ses -> maxdata = 9000 ;
108
- v9ses -> proto = PROTO_TCP ;
130
+ v9ses -> maxdata = 8192 ;
109
131
v9ses -> extended = 1 ;
110
132
v9ses -> afid = ~0 ;
111
133
v9ses -> debug = 0 ;
112
- v9ses -> rfdno = ~0 ;
113
- v9ses -> wfdno = ~0 ;
114
134
v9ses -> cache = 0 ;
135
+ v9ses -> trans = v9fs_default_trans ;
115
136
116
137
if (!options )
117
138
return ;
@@ -135,9 +156,6 @@ static void v9fs_parse_options(char *options, struct v9fs_session_info *v9ses)
135
156
p9_debug_level = option ;
136
157
#endif
137
158
break ;
138
- case Opt_port :
139
- v9ses -> port = option ;
140
- break ;
141
159
case Opt_msize :
142
160
v9ses -> maxdata = option ;
143
161
break ;
@@ -150,23 +168,8 @@ static void v9fs_parse_options(char *options, struct v9fs_session_info *v9ses)
150
168
case Opt_afid :
151
169
v9ses -> afid = option ;
152
170
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 ]);
170
173
break ;
171
174
case Opt_uname :
172
175
match_strcpy (v9ses -> name , & args [0 ]);
@@ -201,7 +204,7 @@ struct p9_fid *v9fs_session_init(struct v9fs_session_info *v9ses,
201
204
const char * dev_name , char * data )
202
205
{
203
206
int retval = - EINVAL ;
204
- struct p9_transport * trans ;
207
+ struct p9_trans * trans = NULL ;
205
208
struct p9_fid * fid ;
206
209
207
210
v9ses -> name = __getname ();
@@ -217,39 +220,30 @@ struct p9_fid *v9fs_session_init(struct v9fs_session_info *v9ses,
217
220
strcpy (v9ses -> name , V9FS_DEFUSER );
218
221
strcpy (v9ses -> remotename , V9FS_DEFANAME );
219
222
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" );
243
234
goto error ;
244
- };
235
+ }
245
236
237
+ trans = v9ses -> trans -> create (dev_name , v9ses -> options );
246
238
if (IS_ERR (trans )) {
247
239
retval = PTR_ERR (trans );
248
240
trans = NULL ;
249
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
247
v9ses -> extended );
254
248
255
249
if (IS_ERR (v9ses -> clnt )) {
@@ -290,6 +284,7 @@ void v9fs_session_close(struct v9fs_session_info *v9ses)
290
284
291
285
__putname (v9ses -> name );
292
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
306
static int __init init_v9fs (void )
312
307
{
313
308
printk (KERN_INFO "Installing v9fs 9p2000 file system support\n" );
314
-
309
+ /* TODO: Setup list of registered trasnport modules */
315
310
return register_filesystem (& v9fs_fs_type );
316
311
}
317
312
0 commit comments