diff options
-rw-r--r-- | fs/9p/v9fs.c | 2 | ||||
-rw-r--r-- | include/net/9p/client.h | 19 | ||||
-rw-r--r-- | include/net/9p/transport.h | 55 | ||||
-rw-r--r-- | net/9p/client.c | 21 | ||||
-rw-r--r-- | net/9p/mod.c | 1 | ||||
-rw-r--r-- | net/9p/trans_fd.c | 205 | ||||
-rw-r--r-- | net/9p/trans_virtio.c | 50 |
7 files changed, 146 insertions, 207 deletions
diff --git a/fs/9p/v9fs.c b/fs/9p/v9fs.c index c061c3f18e7c..b6b85cf01e0d 100644 --- a/fs/9p/v9fs.c +++ b/fs/9p/v9fs.c | |||
@@ -30,8 +30,8 @@ | |||
30 | #include <linux/parser.h> | 30 | #include <linux/parser.h> |
31 | #include <linux/idr.h> | 31 | #include <linux/idr.h> |
32 | #include <net/9p/9p.h> | 32 | #include <net/9p/9p.h> |
33 | #include <net/9p/transport.h> | ||
34 | #include <net/9p/client.h> | 33 | #include <net/9p/client.h> |
34 | #include <net/9p/transport.h> | ||
35 | #include "v9fs.h" | 35 | #include "v9fs.h" |
36 | #include "v9fs_vfs.h" | 36 | #include "v9fs_vfs.h" |
37 | 37 | ||
diff --git a/include/net/9p/client.h b/include/net/9p/client.h index c936dd14de41..c35fb548e7cf 100644 --- a/include/net/9p/client.h +++ b/include/net/9p/client.h | |||
@@ -27,6 +27,22 @@ | |||
27 | #define NET_9P_CLIENT_H | 27 | #define NET_9P_CLIENT_H |
28 | 28 | ||
29 | /** | 29 | /** |
30 | * enum p9_trans_status - different states of underlying transports | ||
31 | * @Connected: transport is connected and healthy | ||
32 | * @Disconnected: transport has been disconnected | ||
33 | * @Hung: transport is connected by wedged | ||
34 | * | ||
35 | * This enumeration details the various states a transport | ||
36 | * instatiation can be in. | ||
37 | */ | ||
38 | |||
39 | enum p9_trans_status { | ||
40 | Connected, | ||
41 | Disconnected, | ||
42 | Hung, | ||
43 | }; | ||
44 | |||
45 | /** | ||
30 | * struct p9_client - per client instance state | 46 | * struct p9_client - per client instance state |
31 | * @lock: protect @fidlist | 47 | * @lock: protect @fidlist |
32 | * @msize: maximum data size negotiated by protocol | 48 | * @msize: maximum data size negotiated by protocol |
@@ -48,7 +64,8 @@ struct p9_client { | |||
48 | int msize; | 64 | int msize; |
49 | unsigned char dotu; | 65 | unsigned char dotu; |
50 | struct p9_trans_module *trans_mod; | 66 | struct p9_trans_module *trans_mod; |
51 | struct p9_trans *trans; | 67 | enum p9_trans_status status; |
68 | void *trans; | ||
52 | struct p9_conn *conn; | 69 | struct p9_conn *conn; |
53 | 70 | ||
54 | struct p9_idpool *fidpool; | 71 | struct p9_idpool *fidpool; |
diff --git a/include/net/9p/transport.h b/include/net/9p/transport.h index 3ca737120a90..3e0f2f6beba2 100644 --- a/include/net/9p/transport.h +++ b/include/net/9p/transport.h | |||
@@ -26,52 +26,6 @@ | |||
26 | #ifndef NET_9P_TRANSPORT_H | 26 | #ifndef NET_9P_TRANSPORT_H |
27 | #define NET_9P_TRANSPORT_H | 27 | #define NET_9P_TRANSPORT_H |
28 | 28 | ||
29 | #include <linux/module.h> | ||
30 | |||
31 | /** | ||
32 | * enum p9_trans_status - different states of underlying transports | ||
33 | * @Connected: transport is connected and healthy | ||
34 | * @Disconnected: transport has been disconnected | ||
35 | * @Hung: transport is connected by wedged | ||
36 | * | ||
37 | * This enumeration details the various states a transport | ||
38 | * instatiation can be in. | ||
39 | */ | ||
40 | |||
41 | enum p9_trans_status { | ||
42 | Connected, | ||
43 | Disconnected, | ||
44 | Hung, | ||
45 | }; | ||
46 | |||
47 | /** | ||
48 | * struct p9_trans - per-transport state and API | ||
49 | * @status: transport &p9_trans_status | ||
50 | * @msize: negotiated maximum packet size (duplicate from client) | ||
51 | * @extended: negotiated protocol extensions (duplicate from client) | ||
52 | * @priv: transport private data | ||
53 | * @close: member function to disconnect and close the transport | ||
54 | * @rpc: member function to issue a request to the transport | ||
55 | * | ||
56 | * This is the basic API for a transport instance. It is used as | ||
57 | * a handle by the client to issue requests. This interface is currently | ||
58 | * in flux during reorganization. | ||
59 | * | ||
60 | * Bugs: there is lots of duplicated data here and its not clear that | ||
61 | * the member functions need to be per-instance versus per transport | ||
62 | * module. | ||
63 | */ | ||
64 | |||
65 | struct p9_trans { | ||
66 | enum p9_trans_status status; | ||
67 | int msize; | ||
68 | unsigned char extended; | ||
69 | void *priv; | ||
70 | void (*close) (struct p9_trans *); | ||
71 | int (*rpc) (struct p9_trans *t, struct p9_fcall *tc, | ||
72 | struct p9_fcall **rc); | ||
73 | }; | ||
74 | |||
75 | /** | 29 | /** |
76 | * struct p9_trans_module - transport module interface | 30 | * struct p9_trans_module - transport module interface |
77 | * @list: used to maintain a list of currently available transports | 31 | * @list: used to maintain a list of currently available transports |
@@ -79,12 +33,14 @@ struct p9_trans { | |||
79 | * @maxsize: transport provided maximum packet size | 33 | * @maxsize: transport provided maximum packet size |
80 | * @def: set if this transport should be considered the default | 34 | * @def: set if this transport should be considered the default |
81 | * @create: member function to create a new connection on this transport | 35 | * @create: member function to create a new connection on this transport |
36 | * @close: member function to disconnect and close the transport | ||
37 | * @rpc: member function to issue a request to the transport | ||
82 | * | 38 | * |
83 | * This is the basic API for a transport module which is registered by the | 39 | * This is the basic API for a transport module which is registered by the |
84 | * transport module with the 9P core network module and used by the client | 40 | * transport module with the 9P core network module and used by the client |
85 | * to instantiate a new connection on a transport. | 41 | * to instantiate a new connection on a transport. |
86 | * | 42 | * |
87 | * Bugs: the transport module list isn't protected. | 43 | * BUGS: the transport module list isn't protected. |
88 | */ | 44 | */ |
89 | 45 | ||
90 | struct p9_trans_module { | 46 | struct p9_trans_module { |
@@ -92,8 +48,11 @@ struct p9_trans_module { | |||
92 | char *name; /* name of transport */ | 48 | char *name; /* name of transport */ |
93 | int maxsize; /* max message size of transport */ | 49 | int maxsize; /* max message size of transport */ |
94 | int def; /* this transport should be default */ | 50 | int def; /* this transport should be default */ |
95 | struct p9_trans * (*create)(const char *, char *, int, unsigned char); | ||
96 | struct module *owner; | 51 | struct module *owner; |
52 | int (*create)(struct p9_client *, const char *, char *); | ||
53 | void (*close) (struct p9_client *); | ||
54 | int (*rpc) (struct p9_client *t, struct p9_fcall *tc, | ||
55 | struct p9_fcall **rc); | ||
97 | }; | 56 | }; |
98 | 57 | ||
99 | void v9fs_register_trans(struct p9_trans_module *m); | 58 | void v9fs_register_trans(struct p9_trans_module *m); |
diff --git a/net/9p/client.c b/net/9p/client.c index e053e06028a5..f1a52a7ed724 100644 --- a/net/9p/client.c +++ b/net/9p/client.c | |||
@@ -33,8 +33,8 @@ | |||
33 | #include <linux/uaccess.h> | 33 | #include <linux/uaccess.h> |
34 | #include <net/9p/9p.h> | 34 | #include <net/9p/9p.h> |
35 | #include <linux/parser.h> | 35 | #include <linux/parser.h> |
36 | #include <net/9p/transport.h> | ||
37 | #include <net/9p/client.h> | 36 | #include <net/9p/client.h> |
37 | #include <net/9p/transport.h> | ||
38 | 38 | ||
39 | static struct p9_fid *p9_fid_create(struct p9_client *clnt); | 39 | static struct p9_fid *p9_fid_create(struct p9_client *clnt); |
40 | static void p9_fid_destroy(struct p9_fid *fid); | 40 | static void p9_fid_destroy(struct p9_fid *fid); |
@@ -136,7 +136,7 @@ int | |||
136 | p9_client_rpc(struct p9_client *c, struct p9_fcall *tc, | 136 | p9_client_rpc(struct p9_client *c, struct p9_fcall *tc, |
137 | struct p9_fcall **rc) | 137 | struct p9_fcall **rc) |
138 | { | 138 | { |
139 | return c->trans->rpc(c->trans, tc, rc); | 139 | return c->trans_mod->rpc(c, tc, rc); |
140 | } | 140 | } |
141 | 141 | ||
142 | struct p9_client *p9_client_create(const char *dev_name, char *options) | 142 | struct p9_client *p9_client_create(const char *dev_name, char *options) |
@@ -179,13 +179,9 @@ struct p9_client *p9_client_create(const char *dev_name, char *options) | |||
179 | clnt, clnt->trans_mod, clnt->msize, clnt->dotu); | 179 | clnt, clnt->trans_mod, clnt->msize, clnt->dotu); |
180 | 180 | ||
181 | 181 | ||
182 | clnt->trans = clnt->trans_mod->create(dev_name, options, clnt->msize, | 182 | err = clnt->trans_mod->create(clnt, dev_name, options); |
183 | clnt->dotu); | 183 | if (err) |
184 | if (IS_ERR(clnt->trans)) { | ||
185 | err = PTR_ERR(clnt->trans); | ||
186 | clnt->trans = NULL; | ||
187 | goto error; | 184 | goto error; |
188 | } | ||
189 | 185 | ||
190 | if ((clnt->msize+P9_IOHDRSZ) > clnt->trans_mod->maxsize) | 186 | if ((clnt->msize+P9_IOHDRSZ) > clnt->trans_mod->maxsize) |
191 | clnt->msize = clnt->trans_mod->maxsize-P9_IOHDRSZ; | 187 | clnt->msize = clnt->trans_mod->maxsize-P9_IOHDRSZ; |
@@ -233,11 +229,8 @@ void p9_client_destroy(struct p9_client *clnt) | |||
233 | 229 | ||
234 | P9_DPRINTK(P9_DEBUG_9P, "clnt %p\n", clnt); | 230 | P9_DPRINTK(P9_DEBUG_9P, "clnt %p\n", clnt); |
235 | 231 | ||
236 | if (clnt->trans) { | 232 | if (clnt->trans_mod) |
237 | clnt->trans->close(clnt->trans); | 233 | clnt->trans_mod->close(clnt); |
238 | kfree(clnt->trans); | ||
239 | clnt->trans = NULL; | ||
240 | } | ||
241 | 234 | ||
242 | v9fs_put_trans(clnt->trans_mod); | 235 | v9fs_put_trans(clnt->trans_mod); |
243 | 236 | ||
@@ -254,7 +247,7 @@ EXPORT_SYMBOL(p9_client_destroy); | |||
254 | void p9_client_disconnect(struct p9_client *clnt) | 247 | void p9_client_disconnect(struct p9_client *clnt) |
255 | { | 248 | { |
256 | P9_DPRINTK(P9_DEBUG_9P, "clnt %p\n", clnt); | 249 | P9_DPRINTK(P9_DEBUG_9P, "clnt %p\n", clnt); |
257 | clnt->trans->status = Disconnected; | 250 | clnt->status = Disconnected; |
258 | } | 251 | } |
259 | EXPORT_SYMBOL(p9_client_disconnect); | 252 | EXPORT_SYMBOL(p9_client_disconnect); |
260 | 253 | ||
diff --git a/net/9p/mod.c b/net/9p/mod.c index 1084feb24cb0..cf8a4128cd5c 100644 --- a/net/9p/mod.c +++ b/net/9p/mod.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include <net/9p/9p.h> | 29 | #include <net/9p/9p.h> |
30 | #include <linux/fs.h> | 30 | #include <linux/fs.h> |
31 | #include <linux/parser.h> | 31 | #include <linux/parser.h> |
32 | #include <net/9p/client.h> | ||
32 | #include <net/9p/transport.h> | 33 | #include <net/9p/transport.h> |
33 | #include <linux/list.h> | 34 | #include <linux/list.h> |
34 | #include <linux/spinlock.h> | 35 | #include <linux/spinlock.h> |
diff --git a/net/9p/trans_fd.c b/net/9p/trans_fd.c index f84592345573..d09389f08382 100644 --- a/net/9p/trans_fd.c +++ b/net/9p/trans_fd.c | |||
@@ -39,6 +39,7 @@ | |||
39 | #include <linux/file.h> | 39 | #include <linux/file.h> |
40 | #include <linux/parser.h> | 40 | #include <linux/parser.h> |
41 | #include <net/9p/9p.h> | 41 | #include <net/9p/9p.h> |
42 | #include <net/9p/client.h> | ||
42 | #include <net/9p/transport.h> | 43 | #include <net/9p/transport.h> |
43 | 44 | ||
44 | #define P9_PORT 564 | 45 | #define P9_PORT 564 |
@@ -146,7 +147,7 @@ struct p9_poll_wait { | |||
146 | * @mux_list: list link for mux to manage multiple connections (?) | 147 | * @mux_list: list link for mux to manage multiple connections (?) |
147 | * @msize: maximum size for connection (dup) | 148 | * @msize: maximum size for connection (dup) |
148 | * @extended: 9p2000.u flag (dup) | 149 | * @extended: 9p2000.u flag (dup) |
149 | * @trans: reference to transport instance for this connection | 150 | * @client: reference to client instance for this connection |
150 | * @tagpool: id accounting for transactions | 151 | * @tagpool: id accounting for transactions |
151 | * @err: error state | 152 | * @err: error state |
152 | * @req_list: accounting for requests which have been sent | 153 | * @req_list: accounting for requests which have been sent |
@@ -171,7 +172,7 @@ struct p9_conn { | |||
171 | struct list_head mux_list; | 172 | struct list_head mux_list; |
172 | int msize; | 173 | int msize; |
173 | unsigned char extended; | 174 | unsigned char extended; |
174 | struct p9_trans *trans; | 175 | struct p9_client *client; |
175 | struct p9_idpool *tagpool; | 176 | struct p9_idpool *tagpool; |
176 | int err; | 177 | int err; |
177 | struct list_head req_list; | 178 | struct list_head req_list; |
@@ -214,8 +215,8 @@ static void p9_read_work(struct work_struct *work); | |||
214 | static void p9_write_work(struct work_struct *work); | 215 | static void p9_write_work(struct work_struct *work); |
215 | static void p9_pollwait(struct file *filp, wait_queue_head_t *wait_address, | 216 | static void p9_pollwait(struct file *filp, wait_queue_head_t *wait_address, |
216 | poll_table *p); | 217 | poll_table *p); |
217 | static int p9_fd_write(struct p9_trans *trans, void *v, int len); | 218 | static int p9_fd_write(struct p9_client *client, void *v, int len); |
218 | static int p9_fd_read(struct p9_trans *trans, void *v, int len); | 219 | static int p9_fd_read(struct p9_client *client, void *v, int len); |
219 | 220 | ||
220 | static DEFINE_SPINLOCK(p9_poll_lock); | 221 | static DEFINE_SPINLOCK(p9_poll_lock); |
221 | static LIST_HEAD(p9_poll_pending_list); | 222 | static LIST_HEAD(p9_poll_pending_list); |
@@ -223,7 +224,7 @@ static struct workqueue_struct *p9_mux_wq; | |||
223 | static struct task_struct *p9_poll_task; | 224 | static struct task_struct *p9_poll_task; |
224 | 225 | ||
225 | static void p9_conn_destroy(struct p9_conn *); | 226 | static void p9_conn_destroy(struct p9_conn *); |
226 | static unsigned int p9_fd_poll(struct p9_trans *trans, | 227 | static unsigned int p9_fd_poll(struct p9_client *client, |
227 | struct poll_table_struct *pt); | 228 | struct poll_table_struct *pt); |
228 | 229 | ||
229 | #ifdef P9_NONBLOCK | 230 | #ifdef P9_NONBLOCK |
@@ -271,27 +272,26 @@ static void p9_mux_poll_stop(struct p9_conn *m) | |||
271 | 272 | ||
272 | /** | 273 | /** |
273 | * p9_conn_create - allocate and initialize the per-session mux data | 274 | * p9_conn_create - allocate and initialize the per-session mux data |
274 | * @trans: transport structure | 275 | * @client: client instance |
275 | * | 276 | * |
276 | * Note: Creates the polling task if this is the first session. | 277 | * Note: Creates the polling task if this is the first session. |
277 | */ | 278 | */ |
278 | 279 | ||
279 | static struct p9_conn *p9_conn_create(struct p9_trans *trans) | 280 | static struct p9_conn *p9_conn_create(struct p9_client *client) |
280 | { | 281 | { |
281 | int i, n; | 282 | int i, n; |
282 | struct p9_conn *m; | 283 | struct p9_conn *m; |
283 | 284 | ||
284 | P9_DPRINTK(P9_DEBUG_MUX, "transport %p msize %d\n", trans, | 285 | P9_DPRINTK(P9_DEBUG_MUX, "client %p msize %d\n", client, client->msize); |
285 | trans->msize); | ||
286 | m = kzalloc(sizeof(struct p9_conn), GFP_KERNEL); | 286 | m = kzalloc(sizeof(struct p9_conn), GFP_KERNEL); |
287 | if (!m) | 287 | if (!m) |
288 | return ERR_PTR(-ENOMEM); | 288 | return ERR_PTR(-ENOMEM); |
289 | 289 | ||
290 | spin_lock_init(&m->lock); | 290 | spin_lock_init(&m->lock); |
291 | INIT_LIST_HEAD(&m->mux_list); | 291 | INIT_LIST_HEAD(&m->mux_list); |
292 | m->msize = trans->msize; | 292 | m->msize = client->msize; |
293 | m->extended = trans->extended; | 293 | m->extended = client->dotu; |
294 | m->trans = trans; | 294 | m->client = client; |
295 | m->tagpool = p9_idpool_create(); | 295 | m->tagpool = p9_idpool_create(); |
296 | if (IS_ERR(m->tagpool)) { | 296 | if (IS_ERR(m->tagpool)) { |
297 | kfree(m); | 297 | kfree(m); |
@@ -305,7 +305,7 @@ static struct p9_conn *p9_conn_create(struct p9_trans *trans) | |||
305 | INIT_LIST_HEAD(&m->poll_pending_link); | 305 | INIT_LIST_HEAD(&m->poll_pending_link); |
306 | init_poll_funcptr(&m->pt, p9_pollwait); | 306 | init_poll_funcptr(&m->pt, p9_pollwait); |
307 | 307 | ||
308 | n = p9_fd_poll(trans, &m->pt); | 308 | n = p9_fd_poll(client, &m->pt); |
309 | if (n & POLLIN) { | 309 | if (n & POLLIN) { |
310 | P9_DPRINTK(P9_DEBUG_MUX, "mux %p can read\n", m); | 310 | P9_DPRINTK(P9_DEBUG_MUX, "mux %p can read\n", m); |
311 | set_bit(Rpending, &m->wsched); | 311 | set_bit(Rpending, &m->wsched); |
@@ -345,7 +345,7 @@ static void p9_conn_destroy(struct p9_conn *m) | |||
345 | 345 | ||
346 | p9_conn_cancel(m, -ECONNRESET); | 346 | p9_conn_cancel(m, -ECONNRESET); |
347 | 347 | ||
348 | m->trans = NULL; | 348 | m->client = NULL; |
349 | p9_idpool_destroy(m->tagpool); | 349 | p9_idpool_destroy(m->tagpool); |
350 | kfree(m); | 350 | kfree(m); |
351 | } | 351 | } |
@@ -420,7 +420,7 @@ static void p9_poll_mux(struct p9_conn *m) | |||
420 | if (m->err < 0) | 420 | if (m->err < 0) |
421 | return; | 421 | return; |
422 | 422 | ||
423 | n = p9_fd_poll(m->trans, NULL); | 423 | n = p9_fd_poll(m->client, NULL); |
424 | if (n < 0 || n & (POLLERR | POLLHUP | POLLNVAL)) { | 424 | if (n < 0 || n & (POLLERR | POLLHUP | POLLNVAL)) { |
425 | P9_DPRINTK(P9_DEBUG_MUX, "error mux %p err %d\n", m, n); | 425 | P9_DPRINTK(P9_DEBUG_MUX, "error mux %p err %d\n", m, n); |
426 | if (n >= 0) | 426 | if (n >= 0) |
@@ -533,7 +533,7 @@ again: | |||
533 | P9_DPRINTK(P9_DEBUG_MUX, "mux %p pos %d size %d\n", m, m->wpos, | 533 | P9_DPRINTK(P9_DEBUG_MUX, "mux %p pos %d size %d\n", m, m->wpos, |
534 | m->wsize); | 534 | m->wsize); |
535 | clear_bit(Wpending, &m->wsched); | 535 | clear_bit(Wpending, &m->wsched); |
536 | err = p9_fd_write(m->trans, m->wbuf + m->wpos, m->wsize - m->wpos); | 536 | err = p9_fd_write(m->client, m->wbuf + m->wpos, m->wsize - m->wpos); |
537 | P9_DPRINTK(P9_DEBUG_MUX, "mux %p sent %d bytes\n", m, err); | 537 | P9_DPRINTK(P9_DEBUG_MUX, "mux %p sent %d bytes\n", m, err); |
538 | if (err == -EAGAIN) { | 538 | if (err == -EAGAIN) { |
539 | clear_bit(Wworksched, &m->wsched); | 539 | clear_bit(Wworksched, &m->wsched); |
@@ -555,7 +555,7 @@ again: | |||
555 | if (test_and_clear_bit(Wpending, &m->wsched)) | 555 | if (test_and_clear_bit(Wpending, &m->wsched)) |
556 | n = POLLOUT; | 556 | n = POLLOUT; |
557 | else | 557 | else |
558 | n = p9_fd_poll(m->trans, NULL); | 558 | n = p9_fd_poll(m->client, NULL); |
559 | 559 | ||
560 | if (n & POLLOUT) { | 560 | if (n & POLLOUT) { |
561 | P9_DPRINTK(P9_DEBUG_MUX, "schedule write work %p\n", m); | 561 | P9_DPRINTK(P9_DEBUG_MUX, "schedule write work %p\n", m); |
@@ -640,7 +640,7 @@ static void p9_read_work(struct work_struct *work) | |||
640 | } | 640 | } |
641 | 641 | ||
642 | clear_bit(Rpending, &m->wsched); | 642 | clear_bit(Rpending, &m->wsched); |
643 | err = p9_fd_read(m->trans, m->rbuf + m->rpos, m->msize - m->rpos); | 643 | err = p9_fd_read(m->client, m->rbuf + m->rpos, m->msize - m->rpos); |
644 | P9_DPRINTK(P9_DEBUG_MUX, "mux %p got %d bytes\n", m, err); | 644 | P9_DPRINTK(P9_DEBUG_MUX, "mux %p got %d bytes\n", m, err); |
645 | if (err == -EAGAIN) { | 645 | if (err == -EAGAIN) { |
646 | clear_bit(Rworksched, &m->wsched); | 646 | clear_bit(Rworksched, &m->wsched); |
@@ -735,7 +735,7 @@ static void p9_read_work(struct work_struct *work) | |||
735 | if (test_and_clear_bit(Rpending, &m->wsched)) | 735 | if (test_and_clear_bit(Rpending, &m->wsched)) |
736 | n = POLLIN; | 736 | n = POLLIN; |
737 | else | 737 | else |
738 | n = p9_fd_poll(m->trans, NULL); | 738 | n = p9_fd_poll(m->client, NULL); |
739 | 739 | ||
740 | if (n & POLLIN) { | 740 | if (n & POLLIN) { |
741 | P9_DPRINTK(P9_DEBUG_MUX, "schedule read work %p\n", m); | 741 | P9_DPRINTK(P9_DEBUG_MUX, "schedule read work %p\n", m); |
@@ -819,7 +819,7 @@ static struct p9_req *p9_send_request(struct p9_conn *m, | |||
819 | if (test_and_clear_bit(Wpending, &m->wsched)) | 819 | if (test_and_clear_bit(Wpending, &m->wsched)) |
820 | n = POLLOUT; | 820 | n = POLLOUT; |
821 | else | 821 | else |
822 | n = p9_fd_poll(m->trans, NULL); | 822 | n = p9_fd_poll(m->client, NULL); |
823 | 823 | ||
824 | if (n & POLLOUT && !test_and_set_bit(Wworksched, &m->wsched)) | 824 | if (n & POLLOUT && !test_and_set_bit(Wworksched, &m->wsched)) |
825 | queue_work(p9_mux_wq, &m->wq); | 825 | queue_work(p9_mux_wq, &m->wq); |
@@ -933,16 +933,16 @@ p9_conn_rpc_cb(struct p9_req *req, void *a) | |||
933 | /** | 933 | /** |
934 | * p9_fd_rpc- sends 9P request and waits until a response is available. | 934 | * p9_fd_rpc- sends 9P request and waits until a response is available. |
935 | * The function can be interrupted. | 935 | * The function can be interrupted. |
936 | * @t: transport data | 936 | * @client: client instance |
937 | * @tc: request to be sent | 937 | * @tc: request to be sent |
938 | * @rc: pointer where a pointer to the response is stored | 938 | * @rc: pointer where a pointer to the response is stored |
939 | * | 939 | * |
940 | */ | 940 | */ |
941 | 941 | ||
942 | int | 942 | int |
943 | p9_fd_rpc(struct p9_trans *t, struct p9_fcall *tc, struct p9_fcall **rc) | 943 | p9_fd_rpc(struct p9_client *client, struct p9_fcall *tc, struct p9_fcall **rc) |
944 | { | 944 | { |
945 | struct p9_trans_fd *p = t->priv; | 945 | struct p9_trans_fd *p = client->trans; |
946 | struct p9_conn *m = p->conn; | 946 | struct p9_conn *m = p->conn; |
947 | int err, sigpending; | 947 | int err, sigpending; |
948 | unsigned long flags; | 948 | unsigned long flags; |
@@ -975,7 +975,7 @@ p9_fd_rpc(struct p9_trans *t, struct p9_fcall *tc, struct p9_fcall **rc) | |||
975 | if (r.err < 0) | 975 | if (r.err < 0) |
976 | err = r.err; | 976 | err = r.err; |
977 | 977 | ||
978 | if (err == -ERESTARTSYS && m->trans->status == Connected | 978 | if (err == -ERESTARTSYS && client->status == Connected |
979 | && m->err == 0) { | 979 | && m->err == 0) { |
980 | if (p9_mux_flush_request(m, req)) { | 980 | if (p9_mux_flush_request(m, req)) { |
981 | /* wait until we get response of the flush message */ | 981 | /* wait until we get response of the flush message */ |
@@ -984,7 +984,7 @@ p9_fd_rpc(struct p9_trans *t, struct p9_fcall *tc, struct p9_fcall **rc) | |||
984 | err = wait_event_interruptible(r.wqueue, | 984 | err = wait_event_interruptible(r.wqueue, |
985 | r.rcall || r.err); | 985 | r.rcall || r.err); |
986 | } while (!r.rcall && !r.err && err == -ERESTARTSYS && | 986 | } while (!r.rcall && !r.err && err == -ERESTARTSYS && |
987 | m->trans->status == Connected && !m->err); | 987 | client->status == Connected && !m->err); |
988 | 988 | ||
989 | err = -ERESTARTSYS; | 989 | err = -ERESTARTSYS; |
990 | } | 990 | } |
@@ -1133,7 +1133,7 @@ static int parse_opts(char *params, struct p9_fd_opts *opts) | |||
1133 | return 0; | 1133 | return 0; |
1134 | } | 1134 | } |
1135 | 1135 | ||
1136 | static int p9_fd_open(struct p9_trans *trans, int rfd, int wfd) | 1136 | static int p9_fd_open(struct p9_client *client, int rfd, int wfd) |
1137 | { | 1137 | { |
1138 | struct p9_trans_fd *ts = kmalloc(sizeof(struct p9_trans_fd), | 1138 | struct p9_trans_fd *ts = kmalloc(sizeof(struct p9_trans_fd), |
1139 | GFP_KERNEL); | 1139 | GFP_KERNEL); |
@@ -1151,13 +1151,13 @@ static int p9_fd_open(struct p9_trans *trans, int rfd, int wfd) | |||
1151 | return -EIO; | 1151 | return -EIO; |
1152 | } | 1152 | } |
1153 | 1153 | ||
1154 | trans->priv = ts; | 1154 | client->trans = ts; |
1155 | trans->status = Connected; | 1155 | client->status = Connected; |
1156 | 1156 | ||
1157 | return 0; | 1157 | return 0; |
1158 | } | 1158 | } |
1159 | 1159 | ||
1160 | static int p9_socket_open(struct p9_trans *trans, struct socket *csocket) | 1160 | static int p9_socket_open(struct p9_client *client, struct socket *csocket) |
1161 | { | 1161 | { |
1162 | int fd, ret; | 1162 | int fd, ret; |
1163 | 1163 | ||
@@ -1168,33 +1168,33 @@ static int p9_socket_open(struct p9_trans *trans, struct socket *csocket) | |||
1168 | return fd; | 1168 | return fd; |
1169 | } | 1169 | } |
1170 | 1170 | ||
1171 | ret = p9_fd_open(trans, fd, fd); | 1171 | ret = p9_fd_open(client, fd, fd); |
1172 | if (ret < 0) { | 1172 | if (ret < 0) { |
1173 | P9_EPRINTK(KERN_ERR, "p9_socket_open: failed to open fd\n"); | 1173 | P9_EPRINTK(KERN_ERR, "p9_socket_open: failed to open fd\n"); |
1174 | sockfd_put(csocket); | 1174 | sockfd_put(csocket); |
1175 | return ret; | 1175 | return ret; |
1176 | } | 1176 | } |
1177 | 1177 | ||
1178 | ((struct p9_trans_fd *)trans->priv)->rd->f_flags |= O_NONBLOCK; | 1178 | ((struct p9_trans_fd *)client->trans)->rd->f_flags |= O_NONBLOCK; |
1179 | 1179 | ||
1180 | return 0; | 1180 | return 0; |
1181 | } | 1181 | } |
1182 | 1182 | ||
1183 | /** | 1183 | /** |
1184 | * p9_fd_read- read from a fd | 1184 | * p9_fd_read- read from a fd |
1185 | * @trans: transport instance state | 1185 | * @client: client instance |
1186 | * @v: buffer to receive data into | 1186 | * @v: buffer to receive data into |
1187 | * @len: size of receive buffer | 1187 | * @len: size of receive buffer |
1188 | * | 1188 | * |
1189 | */ | 1189 | */ |
1190 | 1190 | ||
1191 | static int p9_fd_read(struct p9_trans *trans, void *v, int len) | 1191 | static int p9_fd_read(struct p9_client *client, void *v, int len) |
1192 | { | 1192 | { |
1193 | int ret; | 1193 | int ret; |
1194 | struct p9_trans_fd *ts = NULL; | 1194 | struct p9_trans_fd *ts = NULL; |
1195 | 1195 | ||
1196 | if (trans && trans->status != Disconnected) | 1196 | if (client && client->status != Disconnected) |
1197 | ts = trans->priv; | 1197 | ts = client->trans; |
1198 | 1198 | ||
1199 | if (!ts) | 1199 | if (!ts) |
1200 | return -EREMOTEIO; | 1200 | return -EREMOTEIO; |
@@ -1204,26 +1204,26 @@ static int p9_fd_read(struct p9_trans *trans, void *v, int len) | |||
1204 | 1204 | ||
1205 | ret = kernel_read(ts->rd, ts->rd->f_pos, v, len); | 1205 | ret = kernel_read(ts->rd, ts->rd->f_pos, v, len); |
1206 | if (ret <= 0 && ret != -ERESTARTSYS && ret != -EAGAIN) | 1206 | if (ret <= 0 && ret != -ERESTARTSYS && ret != -EAGAIN) |
1207 | trans->status = Disconnected; | 1207 | client->status = Disconnected; |
1208 | return ret; | 1208 | return ret; |
1209 | } | 1209 | } |
1210 | 1210 | ||
1211 | /** | 1211 | /** |
1212 | * p9_fd_write - write to a socket | 1212 | * p9_fd_write - write to a socket |
1213 | * @trans: transport instance state | 1213 | * @client: client instance |
1214 | * @v: buffer to send data from | 1214 | * @v: buffer to send data from |
1215 | * @len: size of send buffer | 1215 | * @len: size of send buffer |
1216 | * | 1216 | * |
1217 | */ | 1217 | */ |
1218 | 1218 | ||
1219 | static int p9_fd_write(struct p9_trans *trans, void *v, int len) | 1219 | static int p9_fd_write(struct p9_client *client, void *v, int len) |
1220 | { | 1220 | { |
1221 | int ret; | 1221 | int ret; |
1222 | mm_segment_t oldfs; | 1222 | mm_segment_t oldfs; |
1223 | struct p9_trans_fd *ts = NULL; | 1223 | struct p9_trans_fd *ts = NULL; |
1224 | 1224 | ||
1225 | if (trans && trans->status != Disconnected) | 1225 | if (client && client->status != Disconnected) |
1226 | ts = trans->priv; | 1226 | ts = client->trans; |
1227 | 1227 | ||
1228 | if (!ts) | 1228 | if (!ts) |
1229 | return -EREMOTEIO; | 1229 | return -EREMOTEIO; |
@@ -1238,18 +1238,18 @@ static int p9_fd_write(struct p9_trans *trans, void *v, int len) | |||
1238 | set_fs(oldfs); | 1238 | set_fs(oldfs); |
1239 | 1239 | ||
1240 | if (ret <= 0 && ret != -ERESTARTSYS && ret != -EAGAIN) | 1240 | if (ret <= 0 && ret != -ERESTARTSYS && ret != -EAGAIN) |
1241 | trans->status = Disconnected; | 1241 | client->status = Disconnected; |
1242 | return ret; | 1242 | return ret; |
1243 | } | 1243 | } |
1244 | 1244 | ||
1245 | static unsigned int | 1245 | static unsigned int |
1246 | p9_fd_poll(struct p9_trans *trans, struct poll_table_struct *pt) | 1246 | p9_fd_poll(struct p9_client *client, struct poll_table_struct *pt) |
1247 | { | 1247 | { |
1248 | int ret, n; | 1248 | int ret, n; |
1249 | struct p9_trans_fd *ts = NULL; | 1249 | struct p9_trans_fd *ts = NULL; |
1250 | 1250 | ||
1251 | if (trans && trans->status == Connected) | 1251 | if (client && client->status == Connected) |
1252 | ts = trans->priv; | 1252 | ts = client->trans; |
1253 | 1253 | ||
1254 | if (!ts) | 1254 | if (!ts) |
1255 | return -EREMOTEIO; | 1255 | return -EREMOTEIO; |
@@ -1275,30 +1275,31 @@ p9_fd_poll(struct p9_trans *trans, struct poll_table_struct *pt) | |||
1275 | } | 1275 | } |
1276 | 1276 | ||
1277 | /** | 1277 | /** |
1278 | * p9_fd_close - shutdown socket | 1278 | * p9_fd_close - shutdown file descriptor transport |
1279 | * @trans: private socket structure | 1279 | * @client: client instance |
1280 | * | 1280 | * |
1281 | */ | 1281 | */ |
1282 | 1282 | ||
1283 | static void p9_fd_close(struct p9_trans *trans) | 1283 | static void p9_fd_close(struct p9_client *client) |
1284 | { | 1284 | { |
1285 | struct p9_trans_fd *ts; | 1285 | struct p9_trans_fd *ts; |
1286 | 1286 | ||
1287 | if (!trans) | 1287 | if (!client) |
1288 | return; | 1288 | return; |
1289 | 1289 | ||
1290 | ts = xchg(&trans->priv, NULL); | 1290 | ts = client->trans; |
1291 | |||
1292 | if (!ts) | 1291 | if (!ts) |
1293 | return; | 1292 | return; |
1294 | 1293 | ||
1294 | client->status = Disconnected; | ||
1295 | |||
1295 | p9_conn_destroy(ts->conn); | 1296 | p9_conn_destroy(ts->conn); |
1296 | 1297 | ||
1297 | trans->status = Disconnected; | ||
1298 | if (ts->rd) | 1298 | if (ts->rd) |
1299 | fput(ts->rd); | 1299 | fput(ts->rd); |
1300 | if (ts->wr) | 1300 | if (ts->wr) |
1301 | fput(ts->wr); | 1301 | fput(ts->wr); |
1302 | |||
1302 | kfree(ts); | 1303 | kfree(ts); |
1303 | } | 1304 | } |
1304 | 1305 | ||
@@ -1319,31 +1320,23 @@ static inline int valid_ipaddr4(const char *buf) | |||
1319 | return 0; | 1320 | return 0; |
1320 | } | 1321 | } |
1321 | 1322 | ||
1322 | static struct p9_trans * | 1323 | static int |
1323 | p9_trans_create_tcp(const char *addr, char *args, int msize, unsigned char dotu) | 1324 | p9_fd_create_tcp(struct p9_client *client, const char *addr, char *args) |
1324 | { | 1325 | { |
1325 | int err; | 1326 | int err; |
1326 | struct p9_trans *trans; | ||
1327 | struct socket *csocket; | 1327 | struct socket *csocket; |
1328 | struct sockaddr_in sin_server; | 1328 | struct sockaddr_in sin_server; |
1329 | struct p9_fd_opts opts; | 1329 | struct p9_fd_opts opts; |
1330 | struct p9_trans_fd *p; | 1330 | struct p9_trans_fd *p = NULL; /* this gets allocated in p9_fd_open */ |
1331 | 1331 | ||
1332 | err = parse_opts(args, &opts); | 1332 | err = parse_opts(args, &opts); |
1333 | if (err < 0) | 1333 | if (err < 0) |
1334 | return ERR_PTR(err); | 1334 | return err; |
1335 | 1335 | ||
1336 | if (valid_ipaddr4(addr) < 0) | 1336 | if (valid_ipaddr4(addr) < 0) |
1337 | return ERR_PTR(-EINVAL); | 1337 | return -EINVAL; |
1338 | 1338 | ||
1339 | csocket = NULL; | 1339 | csocket = NULL; |
1340 | trans = kmalloc(sizeof(struct p9_trans), GFP_KERNEL); | ||
1341 | if (!trans) | ||
1342 | return ERR_PTR(-ENOMEM); | ||
1343 | trans->msize = msize; | ||
1344 | trans->extended = dotu; | ||
1345 | trans->rpc = p9_fd_rpc; | ||
1346 | trans->close = p9_fd_close; | ||
1347 | 1340 | ||
1348 | sin_server.sin_family = AF_INET; | 1341 | sin_server.sin_family = AF_INET; |
1349 | sin_server.sin_addr.s_addr = in_aton(addr); | 1342 | sin_server.sin_addr.s_addr = in_aton(addr); |
@@ -1366,45 +1359,38 @@ p9_trans_create_tcp(const char *addr, char *args, int msize, unsigned char dotu) | |||
1366 | goto error; | 1359 | goto error; |
1367 | } | 1360 | } |
1368 | 1361 | ||
1369 | err = p9_socket_open(trans, csocket); | 1362 | err = p9_socket_open(client, csocket); |
1370 | if (err < 0) | 1363 | if (err < 0) |
1371 | goto error; | 1364 | goto error; |
1372 | 1365 | ||
1373 | p = (struct p9_trans_fd *) trans->priv; | 1366 | p = (struct p9_trans_fd *) client->trans; |
1374 | p->conn = p9_conn_create(trans); | 1367 | p->conn = p9_conn_create(client); |
1375 | if (IS_ERR(p->conn)) { | 1368 | if (IS_ERR(p->conn)) { |
1376 | err = PTR_ERR(p->conn); | 1369 | err = PTR_ERR(p->conn); |
1377 | p->conn = NULL; | 1370 | p->conn = NULL; |
1378 | goto error; | 1371 | goto error; |
1379 | } | 1372 | } |
1380 | 1373 | ||
1381 | return trans; | 1374 | return 0; |
1382 | 1375 | ||
1383 | error: | 1376 | error: |
1384 | if (csocket) | 1377 | if (csocket) |
1385 | sock_release(csocket); | 1378 | sock_release(csocket); |
1386 | 1379 | ||
1387 | kfree(trans); | 1380 | kfree(p); |
1388 | return ERR_PTR(err); | 1381 | |
1382 | return err; | ||
1389 | } | 1383 | } |
1390 | 1384 | ||
1391 | static struct p9_trans * | 1385 | static int |
1392 | p9_trans_create_unix(const char *addr, char *args, int msize, | 1386 | p9_fd_create_unix(struct p9_client *client, const char *addr, char *args) |
1393 | unsigned char dotu) | ||
1394 | { | 1387 | { |
1395 | int err; | 1388 | int err; |
1396 | struct socket *csocket; | 1389 | struct socket *csocket; |
1397 | struct sockaddr_un sun_server; | 1390 | struct sockaddr_un sun_server; |
1398 | struct p9_trans *trans; | 1391 | struct p9_trans_fd *p = NULL; /* this gets allocated in p9_fd_open */ |
1399 | struct p9_trans_fd *p; | ||
1400 | 1392 | ||
1401 | csocket = NULL; | 1393 | csocket = NULL; |
1402 | trans = kmalloc(sizeof(struct p9_trans), GFP_KERNEL); | ||
1403 | if (!trans) | ||
1404 | return ERR_PTR(-ENOMEM); | ||
1405 | |||
1406 | trans->rpc = p9_fd_rpc; | ||
1407 | trans->close = p9_fd_close; | ||
1408 | 1394 | ||
1409 | if (strlen(addr) > UNIX_PATH_MAX) { | 1395 | if (strlen(addr) > UNIX_PATH_MAX) { |
1410 | P9_EPRINTK(KERN_ERR, "p9_trans_unix: address too long: %s\n", | 1396 | P9_EPRINTK(KERN_ERR, "p9_trans_unix: address too long: %s\n", |
@@ -1425,79 +1411,68 @@ p9_trans_create_unix(const char *addr, char *args, int msize, | |||
1425 | goto error; | 1411 | goto error; |
1426 | } | 1412 | } |
1427 | 1413 | ||
1428 | err = p9_socket_open(trans, csocket); | 1414 | err = p9_socket_open(client, csocket); |
1429 | if (err < 0) | 1415 | if (err < 0) |
1430 | goto error; | 1416 | goto error; |
1431 | 1417 | ||
1432 | trans->msize = msize; | 1418 | p = (struct p9_trans_fd *) client->trans; |
1433 | trans->extended = dotu; | 1419 | p->conn = p9_conn_create(client); |
1434 | p = (struct p9_trans_fd *) trans->priv; | ||
1435 | p->conn = p9_conn_create(trans); | ||
1436 | if (IS_ERR(p->conn)) { | 1420 | if (IS_ERR(p->conn)) { |
1437 | err = PTR_ERR(p->conn); | 1421 | err = PTR_ERR(p->conn); |
1438 | p->conn = NULL; | 1422 | p->conn = NULL; |
1439 | goto error; | 1423 | goto error; |
1440 | } | 1424 | } |
1441 | 1425 | ||
1442 | return trans; | 1426 | return 0; |
1443 | 1427 | ||
1444 | error: | 1428 | error: |
1445 | if (csocket) | 1429 | if (csocket) |
1446 | sock_release(csocket); | 1430 | sock_release(csocket); |
1447 | 1431 | ||
1448 | kfree(trans); | 1432 | kfree(p); |
1449 | return ERR_PTR(err); | 1433 | return err; |
1450 | } | 1434 | } |
1451 | 1435 | ||
1452 | static struct p9_trans * | 1436 | static int |
1453 | p9_trans_create_fd(const char *name, char *args, int msize, | 1437 | p9_fd_create(struct p9_client *client, const char *addr, char *args) |
1454 | unsigned char extended) | ||
1455 | { | 1438 | { |
1456 | int err; | 1439 | int err; |
1457 | struct p9_trans *trans; | ||
1458 | struct p9_fd_opts opts; | 1440 | struct p9_fd_opts opts; |
1459 | struct p9_trans_fd *p; | 1441 | struct p9_trans_fd *p = NULL; /* this get allocated in p9_fd_open */ |
1460 | 1442 | ||
1461 | parse_opts(args, &opts); | 1443 | parse_opts(args, &opts); |
1462 | 1444 | ||
1463 | if (opts.rfd == ~0 || opts.wfd == ~0) { | 1445 | if (opts.rfd == ~0 || opts.wfd == ~0) { |
1464 | printk(KERN_ERR "v9fs: Insufficient options for proto=fd\n"); | 1446 | printk(KERN_ERR "v9fs: Insufficient options for proto=fd\n"); |
1465 | return ERR_PTR(-ENOPROTOOPT); | 1447 | return -ENOPROTOOPT; |
1466 | } | 1448 | } |
1467 | 1449 | ||
1468 | trans = kmalloc(sizeof(struct p9_trans), GFP_KERNEL); | 1450 | err = p9_fd_open(client, opts.rfd, opts.wfd); |
1469 | if (!trans) | ||
1470 | return ERR_PTR(-ENOMEM); | ||
1471 | |||
1472 | trans->rpc = p9_fd_rpc; | ||
1473 | trans->close = p9_fd_close; | ||
1474 | |||
1475 | err = p9_fd_open(trans, opts.rfd, opts.wfd); | ||
1476 | if (err < 0) | 1451 | if (err < 0) |
1477 | goto error; | 1452 | goto error; |
1478 | 1453 | ||
1479 | trans->msize = msize; | 1454 | p = (struct p9_trans_fd *) client->trans; |
1480 | trans->extended = extended; | 1455 | p->conn = p9_conn_create(client); |
1481 | p = (struct p9_trans_fd *) trans->priv; | ||
1482 | p->conn = p9_conn_create(trans); | ||
1483 | if (IS_ERR(p->conn)) { | 1456 | if (IS_ERR(p->conn)) { |
1484 | err = PTR_ERR(p->conn); | 1457 | err = PTR_ERR(p->conn); |
1485 | p->conn = NULL; | 1458 | p->conn = NULL; |
1486 | goto error; | 1459 | goto error; |
1487 | } | 1460 | } |
1488 | 1461 | ||
1489 | return trans; | 1462 | return 0; |
1490 | 1463 | ||
1491 | error: | 1464 | error: |
1492 | kfree(trans); | 1465 | kfree(p); |
1493 | return ERR_PTR(err); | 1466 | return err; |
1494 | } | 1467 | } |
1495 | 1468 | ||
1496 | static struct p9_trans_module p9_tcp_trans = { | 1469 | static struct p9_trans_module p9_tcp_trans = { |
1497 | .name = "tcp", | 1470 | .name = "tcp", |
1498 | .maxsize = MAX_SOCK_BUF, | 1471 | .maxsize = MAX_SOCK_BUF, |
1499 | .def = 1, | 1472 | .def = 1, |
1500 | .create = p9_trans_create_tcp, | 1473 | .create = p9_fd_create_tcp, |
1474 | .close = p9_fd_close, | ||
1475 | .rpc = p9_fd_rpc, | ||
1501 | .owner = THIS_MODULE, | 1476 | .owner = THIS_MODULE, |
1502 | }; | 1477 | }; |
1503 | 1478 | ||
@@ -1505,7 +1480,9 @@ static struct p9_trans_module p9_unix_trans = { | |||
1505 | .name = "unix", | 1480 | .name = "unix", |
1506 | .maxsize = MAX_SOCK_BUF, | 1481 | .maxsize = MAX_SOCK_BUF, |
1507 | .def = 0, | 1482 | .def = 0, |
1508 | .create = p9_trans_create_unix, | 1483 | .create = p9_fd_create_unix, |
1484 | .close = p9_fd_close, | ||
1485 | .rpc = p9_fd_rpc, | ||
1509 | .owner = THIS_MODULE, | 1486 | .owner = THIS_MODULE, |
1510 | }; | 1487 | }; |
1511 | 1488 | ||
@@ -1513,7 +1490,9 @@ static struct p9_trans_module p9_fd_trans = { | |||
1513 | .name = "fd", | 1490 | .name = "fd", |
1514 | .maxsize = MAX_SOCK_BUF, | 1491 | .maxsize = MAX_SOCK_BUF, |
1515 | .def = 0, | 1492 | .def = 0, |
1516 | .create = p9_trans_create_fd, | 1493 | .create = p9_fd_create, |
1494 | .close = p9_fd_close, | ||
1495 | .rpc = p9_fd_rpc, | ||
1517 | .owner = THIS_MODULE, | 1496 | .owner = THIS_MODULE, |
1518 | }; | 1497 | }; |
1519 | 1498 | ||
diff --git a/net/9p/trans_virtio.c b/net/9p/trans_virtio.c index 94912e077a55..72493f04a76d 100644 --- a/net/9p/trans_virtio.c +++ b/net/9p/trans_virtio.c | |||
@@ -41,6 +41,7 @@ | |||
41 | #include <linux/file.h> | 41 | #include <linux/file.h> |
42 | #include <net/9p/9p.h> | 42 | #include <net/9p/9p.h> |
43 | #include <linux/parser.h> | 43 | #include <linux/parser.h> |
44 | #include <net/9p/client.h> | ||
44 | #include <net/9p/transport.h> | 45 | #include <net/9p/transport.h> |
45 | #include <linux/scatterlist.h> | 46 | #include <linux/scatterlist.h> |
46 | #include <linux/virtio.h> | 47 | #include <linux/virtio.h> |
@@ -55,7 +56,6 @@ static int chan_index; | |||
55 | 56 | ||
56 | #define P9_INIT_MAXTAG 16 | 57 | #define P9_INIT_MAXTAG 16 |
57 | 58 | ||
58 | |||
59 | /** | 59 | /** |
60 | * enum p9_req_status_t - virtio request status | 60 | * enum p9_req_status_t - virtio request status |
61 | * @REQ_STATUS_IDLE: request slot unused | 61 | * @REQ_STATUS_IDLE: request slot unused |
@@ -197,9 +197,9 @@ static unsigned int rest_of_page(void *data) | |||
197 | * | 197 | * |
198 | */ | 198 | */ |
199 | 199 | ||
200 | static void p9_virtio_close(struct p9_trans *trans) | 200 | static void p9_virtio_close(struct p9_client *client) |
201 | { | 201 | { |
202 | struct virtio_chan *chan = trans->priv; | 202 | struct virtio_chan *chan = client->trans; |
203 | int count; | 203 | int count; |
204 | unsigned long flags; | 204 | unsigned long flags; |
205 | 205 | ||
@@ -215,7 +215,7 @@ static void p9_virtio_close(struct p9_trans *trans) | |||
215 | chan->inuse = false; | 215 | chan->inuse = false; |
216 | mutex_unlock(&virtio_9p_lock); | 216 | mutex_unlock(&virtio_9p_lock); |
217 | 217 | ||
218 | kfree(trans); | 218 | client->trans = NULL; |
219 | } | 219 | } |
220 | 220 | ||
221 | /** | 221 | /** |
@@ -292,17 +292,17 @@ pack_sg_list(struct scatterlist *sg, int start, int limit, char *data, | |||
292 | */ | 292 | */ |
293 | 293 | ||
294 | static int | 294 | static int |
295 | p9_virtio_rpc(struct p9_trans *t, struct p9_fcall *tc, struct p9_fcall **rc) | 295 | p9_virtio_rpc(struct p9_client *c, struct p9_fcall *tc, struct p9_fcall **rc) |
296 | { | 296 | { |
297 | int in, out; | 297 | int in, out; |
298 | int n, err, size; | 298 | int n, err, size; |
299 | struct virtio_chan *chan = t->priv; | 299 | struct virtio_chan *chan = c->trans; |
300 | char *rdata; | 300 | char *rdata; |
301 | struct p9_req_t *req; | 301 | struct p9_req_t *req; |
302 | unsigned long flags; | 302 | unsigned long flags; |
303 | 303 | ||
304 | if (*rc == NULL) { | 304 | if (*rc == NULL) { |
305 | *rc = kmalloc(sizeof(struct p9_fcall) + t->msize, GFP_KERNEL); | 305 | *rc = kmalloc(sizeof(struct p9_fcall) + c->msize, GFP_KERNEL); |
306 | if (!*rc) | 306 | if (!*rc) |
307 | return -ENOMEM; | 307 | return -ENOMEM; |
308 | } | 308 | } |
@@ -325,7 +325,7 @@ p9_virtio_rpc(struct p9_trans *t, struct p9_fcall *tc, struct p9_fcall **rc) | |||
325 | P9_DPRINTK(P9_DEBUG_TRANS, "9p debug: virtio rpc tag %d\n", n); | 325 | P9_DPRINTK(P9_DEBUG_TRANS, "9p debug: virtio rpc tag %d\n", n); |
326 | 326 | ||
327 | out = pack_sg_list(chan->sg, 0, VIRTQUEUE_NUM, tc->sdata, tc->size); | 327 | out = pack_sg_list(chan->sg, 0, VIRTQUEUE_NUM, tc->sdata, tc->size); |
328 | in = pack_sg_list(chan->sg, out, VIRTQUEUE_NUM-out, rdata, t->msize); | 328 | in = pack_sg_list(chan->sg, out, VIRTQUEUE_NUM-out, rdata, c->msize); |
329 | 329 | ||
330 | req->status = REQ_STATUS_SENT; | 330 | req->status = REQ_STATUS_SENT; |
331 | 331 | ||
@@ -341,7 +341,7 @@ p9_virtio_rpc(struct p9_trans *t, struct p9_fcall *tc, struct p9_fcall **rc) | |||
341 | 341 | ||
342 | size = le32_to_cpu(*(__le32 *) rdata); | 342 | size = le32_to_cpu(*(__le32 *) rdata); |
343 | 343 | ||
344 | err = p9_deserialize_fcall(rdata, size, *rc, t->extended); | 344 | err = p9_deserialize_fcall(rdata, size, *rc, c->dotu); |
345 | if (err < 0) { | 345 | if (err < 0) { |
346 | P9_DPRINTK(P9_DEBUG_TRANS, | 346 | P9_DPRINTK(P9_DEBUG_TRANS, |
347 | "9p debug: virtio rpc deserialize returned %d\n", err); | 347 | "9p debug: virtio rpc deserialize returned %d\n", err); |
@@ -352,8 +352,8 @@ p9_virtio_rpc(struct p9_trans *t, struct p9_fcall *tc, struct p9_fcall **rc) | |||
352 | if ((p9_debug_level&P9_DEBUG_FCALL) == P9_DEBUG_FCALL) { | 352 | if ((p9_debug_level&P9_DEBUG_FCALL) == P9_DEBUG_FCALL) { |
353 | char buf[150]; | 353 | char buf[150]; |
354 | 354 | ||
355 | p9_printfcall(buf, sizeof(buf), *rc, t->extended); | 355 | p9_printfcall(buf, sizeof(buf), *rc, c->dotu); |
356 | printk(KERN_NOTICE ">>> %p %s\n", t, buf); | 356 | printk(KERN_NOTICE ">>> %p %s\n", c, buf); |
357 | } | 357 | } |
358 | #endif | 358 | #endif |
359 | 359 | ||
@@ -422,10 +422,9 @@ fail: | |||
422 | 422 | ||
423 | /** | 423 | /** |
424 | * p9_virtio_create - allocate a new virtio channel | 424 | * p9_virtio_create - allocate a new virtio channel |
425 | * @client: client instance invoking this transport | ||
425 | * @devname: string identifying the channel to connect to (unused) | 426 | * @devname: string identifying the channel to connect to (unused) |
426 | * @args: args passed from sys_mount() for per-transport options (unused) | 427 | * @args: args passed from sys_mount() for per-transport options (unused) |
427 | * @msize: requested maximum packet size | ||
428 | * @extended: 9p2000.u enabled flag | ||
429 | * | 428 | * |
430 | * This sets up a transport channel for 9p communication. Right now | 429 | * This sets up a transport channel for 9p communication. Right now |
431 | * we only match the first available channel, but eventually we couldlook up | 430 | * we only match the first available channel, but eventually we couldlook up |
@@ -441,11 +440,9 @@ fail: | |||
441 | * | 440 | * |
442 | */ | 441 | */ |
443 | 442 | ||
444 | static struct p9_trans * | 443 | static int |
445 | p9_virtio_create(const char *devname, char *args, int msize, | 444 | p9_virtio_create(struct p9_client *client, const char *devname, char *args) |
446 | unsigned char extended) | ||
447 | { | 445 | { |
448 | struct p9_trans *trans; | ||
449 | struct virtio_chan *chan = channels; | 446 | struct virtio_chan *chan = channels; |
450 | int index = 0; | 447 | int index = 0; |
451 | 448 | ||
@@ -463,30 +460,21 @@ p9_virtio_create(const char *devname, char *args, int msize, | |||
463 | 460 | ||
464 | if (index >= MAX_9P_CHAN) { | 461 | if (index >= MAX_9P_CHAN) { |
465 | printk(KERN_ERR "9p: no channels available\n"); | 462 | printk(KERN_ERR "9p: no channels available\n"); |
466 | return ERR_PTR(-ENODEV); | 463 | return -ENODEV; |
467 | } | 464 | } |
468 | 465 | ||
469 | chan->tagpool = p9_idpool_create(); | 466 | chan->tagpool = p9_idpool_create(); |
470 | if (IS_ERR(chan->tagpool)) { | 467 | if (IS_ERR(chan->tagpool)) { |
471 | printk(KERN_ERR "9p: couldn't allocate tagpool\n"); | 468 | printk(KERN_ERR "9p: couldn't allocate tagpool\n"); |
472 | return ERR_PTR(-ENOMEM); | 469 | return -ENOMEM; |
473 | } | 470 | } |
474 | p9_idpool_get(chan->tagpool); /* reserve tag 0 */ | 471 | p9_idpool_get(chan->tagpool); /* reserve tag 0 */ |
475 | chan->max_tag = 0; | 472 | chan->max_tag = 0; |
476 | chan->reqs = NULL; | 473 | chan->reqs = NULL; |
477 | 474 | ||
478 | trans = kmalloc(sizeof(struct p9_trans), GFP_KERNEL); | 475 | client->trans = (void *)chan; |
479 | if (!trans) { | ||
480 | printk(KERN_ERR "9p: couldn't allocate transport\n"); | ||
481 | return ERR_PTR(-ENOMEM); | ||
482 | } | ||
483 | trans->extended = extended; | ||
484 | trans->msize = msize; | ||
485 | trans->close = p9_virtio_close; | ||
486 | trans->rpc = p9_virtio_rpc; | ||
487 | trans->priv = chan; | ||
488 | 476 | ||
489 | return trans; | 477 | return 0; |
490 | } | 478 | } |
491 | 479 | ||
492 | /** | 480 | /** |
@@ -526,6 +514,8 @@ static struct virtio_driver p9_virtio_drv = { | |||
526 | static struct p9_trans_module p9_virtio_trans = { | 514 | static struct p9_trans_module p9_virtio_trans = { |
527 | .name = "virtio", | 515 | .name = "virtio", |
528 | .create = p9_virtio_create, | 516 | .create = p9_virtio_create, |
517 | .close = p9_virtio_close, | ||
518 | .rpc = p9_virtio_rpc, | ||
529 | .maxsize = PAGE_SIZE*16, | 519 | .maxsize = PAGE_SIZE*16, |
530 | .def = 0, | 520 | .def = 0, |
531 | .owner = THIS_MODULE, | 521 | .owner = THIS_MODULE, |