aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2008-10-24 06:48:46 -0400
committerIngo Molnar <mingo@elte.hu>2008-10-24 06:48:46 -0400
commit8c82a17e9c924c0e9f13e75e4c2f6bca19a4b516 (patch)
treed535f46a917e14e90deccb29ad00aac016ad18dd /net
parent4ce72a2c063a7fa8e42a9435440ae3364115a58d (diff)
parent57f8f7b60db6f1ed2c6918ab9230c4623a9dbe37 (diff)
Merge commit 'v2.6.28-rc1' into sched/urgent
Diffstat (limited to 'net')
-rw-r--r--net/9p/Kconfig6
-rw-r--r--net/9p/Makefile7
-rw-r--r--net/9p/client.c1468
-rw-r--r--net/9p/conv.c1054
-rw-r--r--net/9p/fcprint.c366
-rw-r--r--net/9p/mod.c1
-rw-r--r--net/9p/protocol.c567
-rw-r--r--net/9p/protocol.h34
-rw-r--r--net/9p/trans_fd.c1429
-rw-r--r--net/9p/trans_rdma.c712
-rw-r--r--net/9p/trans_virtio.c246
-rw-r--r--net/9p/util.c4
-rw-r--r--net/bluetooth/af_bluetooth.c8
-rw-r--r--net/bridge/br_device.c2
-rw-r--r--net/bridge/br_if.c14
-rw-r--r--net/bridge/br_netfilter.c2
-rw-r--r--net/bridge/netfilter/ebtables.c15
-rw-r--r--net/can/af_can.c4
-rw-r--r--net/core/dev.c143
-rw-r--r--net/core/rtnetlink.c4
-rw-r--r--net/dccp/ccid.c2
-rw-r--r--net/dccp/ipv6.c4
-rw-r--r--net/dccp/minisocks.c1
-rw-r--r--net/dccp/output.c2
-rw-r--r--net/decnet/dn_dev.c2
-rw-r--r--net/ipv4/arp.c4
-rw-r--r--net/ipv4/devinet.c2
-rw-r--r--net/ipv4/inet_diag.c2
-rw-r--r--net/ipv4/netfilter/nf_nat_snmp_basic.c1
-rw-r--r--net/ipv4/route.c7
-rw-r--r--net/ipv4/tcp_cong.c4
-rw-r--r--net/ipv4/tcp_output.c25
-rw-r--r--net/ipv6/syncookies.c1
-rw-r--r--net/ipv6/tcp_ipv6.c6
-rw-r--r--net/netfilter/Kconfig1
-rw-r--r--net/netfilter/ipvs/Kconfig4
-rw-r--r--net/netfilter/nf_conntrack_netlink.c4
-rw-r--r--net/netfilter/nfnetlink.c2
-rw-r--r--net/netfilter/xt_NFQUEUE.c2
-rw-r--r--net/netfilter/xt_iprange.c8
-rw-r--r--net/netfilter/xt_recent.c10
-rw-r--r--net/netlink/af_netlink.c2
-rw-r--r--net/phonet/af_phonet.c3
-rw-r--r--net/sched/act_api.c2
-rw-r--r--net/sched/cls_api.c2
-rw-r--r--net/sched/ematch.c2
-rw-r--r--net/sched/sch_api.c2
-rw-r--r--net/sched/sch_cbq.c7
-rw-r--r--net/sched/sch_generic.c2
-rw-r--r--net/sctp/input.c2
-rw-r--r--net/sctp/sm_statefuns.c54
-rw-r--r--net/sctp/sm_statetable.c4
-rw-r--r--net/socket.c2
-rw-r--r--net/sunrpc/auth.c2
-rw-r--r--net/unix/af_unix.c18
55 files changed, 2888 insertions, 3396 deletions
diff --git a/net/9p/Kconfig b/net/9p/Kconfig
index ff34c5acc130..c42c0c400bf9 100644
--- a/net/9p/Kconfig
+++ b/net/9p/Kconfig
@@ -20,6 +20,12 @@ config NET_9P_VIRTIO
20 This builds support for a transports between 20 This builds support for a transports between
21 guest partitions and a host partition. 21 guest partitions and a host partition.
22 22
23config NET_9P_RDMA
24 depends on NET_9P && INFINIBAND && EXPERIMENTAL
25 tristate "9P RDMA Transport (Experimental)"
26 help
27 This builds support for a RDMA transport.
28
23config NET_9P_DEBUG 29config NET_9P_DEBUG
24 bool "Debug information" 30 bool "Debug information"
25 depends on NET_9P 31 depends on NET_9P
diff --git a/net/9p/Makefile b/net/9p/Makefile
index 519219480db1..198a640d53a6 100644
--- a/net/9p/Makefile
+++ b/net/9p/Makefile
@@ -1,14 +1,17 @@
1obj-$(CONFIG_NET_9P) := 9pnet.o 1obj-$(CONFIG_NET_9P) := 9pnet.o
2obj-$(CONFIG_NET_9P_VIRTIO) += 9pnet_virtio.o 2obj-$(CONFIG_NET_9P_VIRTIO) += 9pnet_virtio.o
3obj-$(CONFIG_NET_9P_RDMA) += 9pnet_rdma.o
3 4
49pnet-objs := \ 59pnet-objs := \
5 mod.o \ 6 mod.o \
6 client.o \ 7 client.o \
7 conv.o \
8 error.o \ 8 error.o \
9 fcprint.o \
10 util.o \ 9 util.o \
10 protocol.o \
11 trans_fd.o \ 11 trans_fd.o \
12 12
139pnet_virtio-objs := \ 139pnet_virtio-objs := \
14 trans_virtio.o \ 14 trans_virtio.o \
15
169pnet_rdma-objs := \
17 trans_rdma.o \
diff --git a/net/9p/client.c b/net/9p/client.c
index e053e06028a5..67717f69412e 100644
--- a/net/9p/client.c
+++ b/net/9p/client.c
@@ -33,12 +33,9 @@
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>
38 37#include <net/9p/transport.h>
39static struct p9_fid *p9_fid_create(struct p9_client *clnt); 38#include "protocol.h"
40static void p9_fid_destroy(struct p9_fid *fid);
41static struct p9_stat *p9_clone_stat(struct p9_stat *st, int dotu);
42 39
43/* 40/*
44 * Client Option Parsing (code inspired by NFS code) 41 * Client Option Parsing (code inspired by NFS code)
@@ -59,6 +56,9 @@ static const match_table_t tokens = {
59 {Opt_err, NULL}, 56 {Opt_err, NULL},
60}; 57};
61 58
59static struct p9_req_t *
60p9_client_rpc(struct p9_client *c, int8_t type, const char *fmt, ...);
61
62/** 62/**
63 * v9fs_parse_options - parse mount options into session structure 63 * v9fs_parse_options - parse mount options into session structure
64 * @options: options string passed from mount 64 * @options: options string passed from mount
@@ -124,31 +124,586 @@ static int parse_opts(char *opts, struct p9_client *clnt)
124 return ret; 124 return ret;
125} 125}
126 126
127/**
128 * p9_tag_alloc - lookup/allocate a request by tag
129 * @c: client session to lookup tag within
130 * @tag: numeric id for transaction
131 *
132 * this is a simple array lookup, but will grow the
133 * request_slots as necessary to accomodate transaction
134 * ids which did not previously have a slot.
135 *
136 * this code relies on the client spinlock to manage locks, its
137 * possible we should switch to something else, but I'd rather
138 * stick with something low-overhead for the common case.
139 *
140 */
141
142static struct p9_req_t *p9_tag_alloc(struct p9_client *c, u16 tag)
143{
144 unsigned long flags;
145 int row, col;
146 struct p9_req_t *req;
147
148 /* This looks up the original request by tag so we know which
149 * buffer to read the data into */
150 tag++;
151
152 if (tag >= c->max_tag) {
153 spin_lock_irqsave(&c->lock, flags);
154 /* check again since original check was outside of lock */
155 while (tag >= c->max_tag) {
156 row = (tag / P9_ROW_MAXTAG);
157 c->reqs[row] = kcalloc(P9_ROW_MAXTAG,
158 sizeof(struct p9_req_t), GFP_ATOMIC);
159
160 if (!c->reqs[row]) {
161 printk(KERN_ERR "Couldn't grow tag array\n");
162 spin_unlock_irqrestore(&c->lock, flags);
163 return ERR_PTR(-ENOMEM);
164 }
165 for (col = 0; col < P9_ROW_MAXTAG; col++) {
166 c->reqs[row][col].status = REQ_STATUS_IDLE;
167 c->reqs[row][col].tc = NULL;
168 }
169 c->max_tag += P9_ROW_MAXTAG;
170 }
171 spin_unlock_irqrestore(&c->lock, flags);
172 }
173 row = tag / P9_ROW_MAXTAG;
174 col = tag % P9_ROW_MAXTAG;
175
176 req = &c->reqs[row][col];
177 if (!req->tc) {
178 req->wq = kmalloc(sizeof(wait_queue_head_t), GFP_KERNEL);
179 if (!req->wq) {
180 printk(KERN_ERR "Couldn't grow tag array\n");
181 return ERR_PTR(-ENOMEM);
182 }
183 init_waitqueue_head(req->wq);
184 req->tc = kmalloc(sizeof(struct p9_fcall)+c->msize,
185 GFP_KERNEL);
186 req->rc = kmalloc(sizeof(struct p9_fcall)+c->msize,
187 GFP_KERNEL);
188 if ((!req->tc) || (!req->rc)) {
189 printk(KERN_ERR "Couldn't grow tag array\n");
190 kfree(req->tc);
191 kfree(req->rc);
192 return ERR_PTR(-ENOMEM);
193 }
194 req->tc->sdata = (char *) req->tc + sizeof(struct p9_fcall);
195 req->tc->capacity = c->msize;
196 req->rc->sdata = (char *) req->rc + sizeof(struct p9_fcall);
197 req->rc->capacity = c->msize;
198 }
199
200 p9pdu_reset(req->tc);
201 p9pdu_reset(req->rc);
202
203 req->flush_tag = 0;
204 req->tc->tag = tag-1;
205 req->status = REQ_STATUS_ALLOC;
206
207 return &c->reqs[row][col];
208}
209
210/**
211 * p9_tag_lookup - lookup a request by tag
212 * @c: client session to lookup tag within
213 * @tag: numeric id for transaction
214 *
215 */
216
217struct p9_req_t *p9_tag_lookup(struct p9_client *c, u16 tag)
218{
219 int row, col;
220
221 /* This looks up the original request by tag so we know which
222 * buffer to read the data into */
223 tag++;
224
225 BUG_ON(tag >= c->max_tag);
226
227 row = tag / P9_ROW_MAXTAG;
228 col = tag % P9_ROW_MAXTAG;
229
230 return &c->reqs[row][col];
231}
232EXPORT_SYMBOL(p9_tag_lookup);
233
234/**
235 * p9_tag_init - setup tags structure and contents
236 * @tags: tags structure from the client struct
237 *
238 * This initializes the tags structure for each client instance.
239 *
240 */
241
242static int p9_tag_init(struct p9_client *c)
243{
244 int err = 0;
245
246 c->tagpool = p9_idpool_create();
247 if (IS_ERR(c->tagpool)) {
248 err = PTR_ERR(c->tagpool);
249 c->tagpool = NULL;
250 goto error;
251 }
252
253 p9_idpool_get(c->tagpool); /* reserve tag 0 */
254
255 c->max_tag = 0;
256error:
257 return err;
258}
127 259
128/** 260/**
129 * p9_client_rpc - sends 9P request and waits until a response is available. 261 * p9_tag_cleanup - cleans up tags structure and reclaims resources
130 * The function can be interrupted. 262 * @tags: tags structure from the client struct
131 * @c: client data 263 *
132 * @tc: request to be sent 264 * This frees resources associated with the tags structure
133 * @rc: pointer where a pointer to the response is stored 265 *
134 */ 266 */
267static void p9_tag_cleanup(struct p9_client *c)
268{
269 int row, col;
270
271 /* check to insure all requests are idle */
272 for (row = 0; row < (c->max_tag/P9_ROW_MAXTAG); row++) {
273 for (col = 0; col < P9_ROW_MAXTAG; col++) {
274 if (c->reqs[row][col].status != REQ_STATUS_IDLE) {
275 P9_DPRINTK(P9_DEBUG_MUX,
276 "Attempting to cleanup non-free tag %d,%d\n",
277 row, col);
278 /* TODO: delay execution of cleanup */
279 return;
280 }
281 }
282 }
283
284 if (c->tagpool)
285 p9_idpool_destroy(c->tagpool);
286
287 /* free requests associated with tags */
288 for (row = 0; row < (c->max_tag/P9_ROW_MAXTAG); row++) {
289 for (col = 0; col < P9_ROW_MAXTAG; col++) {
290 kfree(c->reqs[row][col].wq);
291 kfree(c->reqs[row][col].tc);
292 kfree(c->reqs[row][col].rc);
293 }
294 kfree(c->reqs[row]);
295 }
296 c->max_tag = 0;
297}
298
299/**
300 * p9_free_req - free a request and clean-up as necessary
301 * c: client state
302 * r: request to release
303 *
304 */
305
306static void p9_free_req(struct p9_client *c, struct p9_req_t *r)
307{
308 int tag = r->tc->tag;
309 P9_DPRINTK(P9_DEBUG_MUX, "clnt %p req %p tag: %d\n", c, r, tag);
310
311 r->status = REQ_STATUS_IDLE;
312 if (tag != P9_NOTAG && p9_idpool_check(tag, c->tagpool))
313 p9_idpool_put(tag, c->tagpool);
314
315 /* if this was a flush request we have to free response fcall */
316 if (r->rc->id == P9_RFLUSH) {
317 kfree(r->tc);
318 kfree(r->rc);
319 }
320}
321
322/**
323 * p9_client_cb - call back from transport to client
324 * c: client state
325 * req: request received
326 *
327 */
328void p9_client_cb(struct p9_client *c, struct p9_req_t *req)
329{
330 struct p9_req_t *other_req;
331 unsigned long flags;
332
333 P9_DPRINTK(P9_DEBUG_MUX, " tag %d\n", req->tc->tag);
334
335 if (req->status == REQ_STATUS_ERROR)
336 wake_up(req->wq);
337
338 if (req->flush_tag) { /* flush receive path */
339 P9_DPRINTK(P9_DEBUG_9P, "<<< RFLUSH %d\n", req->tc->tag);
340 spin_lock_irqsave(&c->lock, flags);
341 other_req = p9_tag_lookup(c, req->flush_tag);
342 if (other_req->status != REQ_STATUS_FLSH) /* stale flush */
343 spin_unlock_irqrestore(&c->lock, flags);
344 else {
345 other_req->status = REQ_STATUS_FLSHD;
346 spin_unlock_irqrestore(&c->lock, flags);
347 wake_up(other_req->wq);
348 }
349 p9_free_req(c, req);
350 } else { /* normal receive path */
351 P9_DPRINTK(P9_DEBUG_MUX, "normal: tag %d\n", req->tc->tag);
352 spin_lock_irqsave(&c->lock, flags);
353 if (req->status != REQ_STATUS_FLSHD)
354 req->status = REQ_STATUS_RCVD;
355 spin_unlock_irqrestore(&c->lock, flags);
356 wake_up(req->wq);
357 P9_DPRINTK(P9_DEBUG_MUX, "wakeup: %d\n", req->tc->tag);
358 }
359}
360EXPORT_SYMBOL(p9_client_cb);
361
362/**
363 * p9_parse_header - parse header arguments out of a packet
364 * @pdu: packet to parse
365 * @size: size of packet
366 * @type: type of request
367 * @tag: tag of packet
368 * @rewind: set if we need to rewind offset afterwards
369 */
370
135int 371int
136p9_client_rpc(struct p9_client *c, struct p9_fcall *tc, 372p9_parse_header(struct p9_fcall *pdu, int32_t *size, int8_t *type, int16_t *tag,
137 struct p9_fcall **rc) 373 int rewind)
138{ 374{
139 return c->trans->rpc(c->trans, tc, rc); 375 int8_t r_type;
376 int16_t r_tag;
377 int32_t r_size;
378 int offset = pdu->offset;
379 int err;
380
381 pdu->offset = 0;
382 if (pdu->size == 0)
383 pdu->size = 7;
384
385 err = p9pdu_readf(pdu, 0, "dbw", &r_size, &r_type, &r_tag);
386 if (err)
387 goto rewind_and_exit;
388
389 pdu->size = r_size;
390 pdu->id = r_type;
391 pdu->tag = r_tag;
392
393 P9_DPRINTK(P9_DEBUG_9P, "<<< size=%d type: %d tag: %d\n", pdu->size,
394 pdu->id, pdu->tag);
395
396 if (type)
397 *type = r_type;
398 if (tag)
399 *tag = r_tag;
400 if (size)
401 *size = r_size;
402
403
404rewind_and_exit:
405 if (rewind)
406 pdu->offset = offset;
407 return err;
140} 408}
409EXPORT_SYMBOL(p9_parse_header);
410
411/**
412 * p9_check_errors - check 9p packet for error return and process it
413 * @c: current client instance
414 * @req: request to parse and check for error conditions
415 *
416 * returns error code if one is discovered, otherwise returns 0
417 *
418 * this will have to be more complicated if we have multiple
419 * error packet types
420 */
421
422static int p9_check_errors(struct p9_client *c, struct p9_req_t *req)
423{
424 int8_t type;
425 int err;
426
427 err = p9_parse_header(req->rc, NULL, &type, NULL, 0);
428 if (err) {
429 P9_DPRINTK(P9_DEBUG_ERROR, "couldn't parse header %d\n", err);
430 return err;
431 }
432
433 if (type == P9_RERROR) {
434 int ecode;
435 char *ename;
436
437 err = p9pdu_readf(req->rc, c->dotu, "s?d", &ename, &ecode);
438 if (err) {
439 P9_DPRINTK(P9_DEBUG_ERROR, "couldn't parse error%d\n",
440 err);
441 return err;
442 }
443
444 if (c->dotu)
445 err = -ecode;
446
447 if (!err) {
448 err = p9_errstr2errno(ename, strlen(ename));
449
450 /* string match failed */
451 if (!err)
452 err = -ESERVERFAULT;
453 }
454
455 P9_DPRINTK(P9_DEBUG_9P, "<<< RERROR (%d) %s\n", -ecode, ename);
456
457 kfree(ename);
458 } else
459 err = 0;
460
461 return err;
462}
463
464/**
465 * p9_client_flush - flush (cancel) a request
466 * c: client state
467 * req: request to cancel
468 *
469 * This sents a flush for a particular requests and links
470 * the flush request to the original request. The current
471 * code only supports a single flush request although the protocol
472 * allows for multiple flush requests to be sent for a single request.
473 *
474 */
475
476static int p9_client_flush(struct p9_client *c, struct p9_req_t *oldreq)
477{
478 struct p9_req_t *req;
479 int16_t oldtag;
480 int err;
481
482 err = p9_parse_header(oldreq->tc, NULL, NULL, &oldtag, 1);
483 if (err)
484 return err;
485
486 P9_DPRINTK(P9_DEBUG_9P, ">>> TFLUSH tag %d\n", oldtag);
487
488 req = p9_client_rpc(c, P9_TFLUSH, "w", oldtag);
489 if (IS_ERR(req))
490 return PTR_ERR(req);
491
492 req->flush_tag = oldtag;
493
494 /* we don't free anything here because RPC isn't complete */
495 return 0;
496}
497
498/**
499 * p9_client_rpc - issue a request and wait for a response
500 * @c: client session
501 * @type: type of request
502 * @fmt: protocol format string (see protocol.c)
503 *
504 * Returns request structure (which client must free using p9_free_req)
505 */
506
507static struct p9_req_t *
508p9_client_rpc(struct p9_client *c, int8_t type, const char *fmt, ...)
509{
510 va_list ap;
511 int tag, err;
512 struct p9_req_t *req;
513 unsigned long flags;
514 int sigpending;
515 int flushed = 0;
516
517 P9_DPRINTK(P9_DEBUG_MUX, "client %p op %d\n", c, type);
518
519 if (c->status != Connected)
520 return ERR_PTR(-EIO);
521
522 if (signal_pending(current)) {
523 sigpending = 1;
524 clear_thread_flag(TIF_SIGPENDING);
525 } else
526 sigpending = 0;
527
528 tag = P9_NOTAG;
529 if (type != P9_TVERSION) {
530 tag = p9_idpool_get(c->tagpool);
531 if (tag < 0)
532 return ERR_PTR(-ENOMEM);
533 }
534
535 req = p9_tag_alloc(c, tag);
536 if (IS_ERR(req))
537 return req;
538
539 /* marshall the data */
540 p9pdu_prepare(req->tc, tag, type);
541 va_start(ap, fmt);
542 err = p9pdu_vwritef(req->tc, c->dotu, fmt, ap);
543 va_end(ap);
544 p9pdu_finalize(req->tc);
545
546 err = c->trans_mod->request(c, req);
547 if (err < 0) {
548 c->status = Disconnected;
549 goto reterr;
550 }
551
552 /* if it was a flush we just transmitted, return our tag */
553 if (type == P9_TFLUSH)
554 return req;
555again:
556 P9_DPRINTK(P9_DEBUG_MUX, "wait %p tag: %d\n", req->wq, tag);
557 err = wait_event_interruptible(*req->wq,
558 req->status >= REQ_STATUS_RCVD);
559 P9_DPRINTK(P9_DEBUG_MUX, "wait %p tag: %d returned %d (flushed=%d)\n",
560 req->wq, tag, err, flushed);
561
562 if (req->status == REQ_STATUS_ERROR) {
563 P9_DPRINTK(P9_DEBUG_ERROR, "req_status error %d\n", req->t_err);
564 err = req->t_err;
565 } else if (err == -ERESTARTSYS && flushed) {
566 P9_DPRINTK(P9_DEBUG_MUX, "flushed - going again\n");
567 goto again;
568 } else if (req->status == REQ_STATUS_FLSHD) {
569 P9_DPRINTK(P9_DEBUG_MUX, "flushed - erestartsys\n");
570 err = -ERESTARTSYS;
571 }
572
573 if ((err == -ERESTARTSYS) && (c->status == Connected) && (!flushed)) {
574 P9_DPRINTK(P9_DEBUG_MUX, "flushing\n");
575 spin_lock_irqsave(&c->lock, flags);
576 if (req->status == REQ_STATUS_SENT)
577 req->status = REQ_STATUS_FLSH;
578 spin_unlock_irqrestore(&c->lock, flags);
579 sigpending = 1;
580 flushed = 1;
581 clear_thread_flag(TIF_SIGPENDING);
582
583 if (c->trans_mod->cancel(c, req)) {
584 err = p9_client_flush(c, req);
585 if (err == 0)
586 goto again;
587 }
588 }
589
590 if (sigpending) {
591 spin_lock_irqsave(&current->sighand->siglock, flags);
592 recalc_sigpending();
593 spin_unlock_irqrestore(&current->sighand->siglock, flags);
594 }
595
596 if (err < 0)
597 goto reterr;
598
599 err = p9_check_errors(c, req);
600 if (!err) {
601 P9_DPRINTK(P9_DEBUG_MUX, "exit: client %p op %d\n", c, type);
602 return req;
603 }
604
605reterr:
606 P9_DPRINTK(P9_DEBUG_MUX, "exit: client %p op %d error: %d\n", c, type,
607 err);
608 p9_free_req(c, req);
609 return ERR_PTR(err);
610}
611
612static struct p9_fid *p9_fid_create(struct p9_client *clnt)
613{
614 int err;
615 struct p9_fid *fid;
616
617 P9_DPRINTK(P9_DEBUG_FID, "clnt %p\n", clnt);
618 fid = kmalloc(sizeof(struct p9_fid), GFP_KERNEL);
619 if (!fid)
620 return ERR_PTR(-ENOMEM);
621
622 fid->fid = p9_idpool_get(clnt->fidpool);
623 if (fid->fid < 0) {
624 err = -ENOSPC;
625 goto error;
626 }
627
628 memset(&fid->qid, 0, sizeof(struct p9_qid));
629 fid->mode = -1;
630 fid->rdir_fpos = 0;
631 fid->uid = current->fsuid;
632 fid->clnt = clnt;
633 fid->aux = NULL;
634
635 spin_lock(&clnt->lock);
636 list_add(&fid->flist, &clnt->fidlist);
637 spin_unlock(&clnt->lock);
638
639 return fid;
640
641error:
642 kfree(fid);
643 return ERR_PTR(err);
644}
645
646static void p9_fid_destroy(struct p9_fid *fid)
647{
648 struct p9_client *clnt;
649
650 P9_DPRINTK(P9_DEBUG_FID, "fid %d\n", fid->fid);
651 clnt = fid->clnt;
652 p9_idpool_put(fid->fid, clnt->fidpool);
653 spin_lock(&clnt->lock);
654 list_del(&fid->flist);
655 spin_unlock(&clnt->lock);
656 kfree(fid);
657}
658
659int p9_client_version(struct p9_client *c)
660{
661 int err = 0;
662 struct p9_req_t *req;
663 char *version;
664 int msize;
665
666 P9_DPRINTK(P9_DEBUG_9P, ">>> TVERSION msize %d extended %d\n",
667 c->msize, c->dotu);
668 req = p9_client_rpc(c, P9_TVERSION, "ds", c->msize,
669 c->dotu ? "9P2000.u" : "9P2000");
670 if (IS_ERR(req))
671 return PTR_ERR(req);
672
673 err = p9pdu_readf(req->rc, c->dotu, "ds", &msize, &version);
674 if (err) {
675 P9_DPRINTK(P9_DEBUG_9P, "version error %d\n", err);
676 p9pdu_dump(1, req->rc);
677 goto error;
678 }
679
680 P9_DPRINTK(P9_DEBUG_9P, "<<< RVERSION msize %d %s\n", msize, version);
681 if (!memcmp(version, "9P2000.u", 8))
682 c->dotu = 1;
683 else if (!memcmp(version, "9P2000", 6))
684 c->dotu = 0;
685 else {
686 err = -EREMOTEIO;
687 goto error;
688 }
689
690 if (msize < c->msize)
691 c->msize = msize;
692
693error:
694 kfree(version);
695 p9_free_req(c, req);
696
697 return err;
698}
699EXPORT_SYMBOL(p9_client_version);
141 700
142struct p9_client *p9_client_create(const char *dev_name, char *options) 701struct p9_client *p9_client_create(const char *dev_name, char *options)
143{ 702{
144 int err, n; 703 int err;
145 struct p9_client *clnt; 704 struct p9_client *clnt;
146 struct p9_fcall *tc, *rc;
147 struct p9_str *version;
148 705
149 err = 0; 706 err = 0;
150 tc = NULL;
151 rc = NULL;
152 clnt = kmalloc(sizeof(struct p9_client), GFP_KERNEL); 707 clnt = kmalloc(sizeof(struct p9_client), GFP_KERNEL);
153 if (!clnt) 708 if (!clnt)
154 return ERR_PTR(-ENOMEM); 709 return ERR_PTR(-ENOMEM);
@@ -164,6 +719,8 @@ struct p9_client *p9_client_create(const char *dev_name, char *options)
164 goto error; 719 goto error;
165 } 720 }
166 721
722 p9_tag_init(clnt);
723
167 err = parse_opts(options, clnt); 724 err = parse_opts(options, clnt);
168 if (err < 0) 725 if (err < 0)
169 goto error; 726 goto error;
@@ -175,53 +732,23 @@ struct p9_client *p9_client_create(const char *dev_name, char *options)
175 goto error; 732 goto error;
176 } 733 }
177 734
178 P9_DPRINTK(P9_DEBUG_9P, "clnt %p trans %p msize %d dotu %d\n", 735 P9_DPRINTK(P9_DEBUG_MUX, "clnt %p trans %p msize %d dotu %d\n",
179 clnt, clnt->trans_mod, clnt->msize, clnt->dotu); 736 clnt, clnt->trans_mod, clnt->msize, clnt->dotu);
180 737
181 738 err = clnt->trans_mod->create(clnt, dev_name, options);
182 clnt->trans = clnt->trans_mod->create(dev_name, options, clnt->msize, 739 if (err)
183 clnt->dotu);
184 if (IS_ERR(clnt->trans)) {
185 err = PTR_ERR(clnt->trans);
186 clnt->trans = NULL;
187 goto error; 740 goto error;
188 }
189 741
190 if ((clnt->msize+P9_IOHDRSZ) > clnt->trans_mod->maxsize) 742 if ((clnt->msize+P9_IOHDRSZ) > clnt->trans_mod->maxsize)
191 clnt->msize = clnt->trans_mod->maxsize-P9_IOHDRSZ; 743 clnt->msize = clnt->trans_mod->maxsize-P9_IOHDRSZ;
192 744
193 tc = p9_create_tversion(clnt->msize, clnt->dotu?"9P2000.u":"9P2000"); 745 err = p9_client_version(clnt);
194 if (IS_ERR(tc)) {
195 err = PTR_ERR(tc);
196 tc = NULL;
197 goto error;
198 }
199
200 err = p9_client_rpc(clnt, tc, &rc);
201 if (err) 746 if (err)
202 goto error; 747 goto error;
203 748
204 version = &rc->params.rversion.version;
205 if (version->len == 8 && !memcmp(version->str, "9P2000.u", 8))
206 clnt->dotu = 1;
207 else if (version->len == 6 && !memcmp(version->str, "9P2000", 6))
208 clnt->dotu = 0;
209 else {
210 err = -EREMOTEIO;
211 goto error;
212 }
213
214 n = rc->params.rversion.msize;
215 if (n < clnt->msize)
216 clnt->msize = n;
217
218 kfree(tc);
219 kfree(rc);
220 return clnt; 749 return clnt;
221 750
222error: 751error:
223 kfree(tc);
224 kfree(rc);
225 p9_client_destroy(clnt); 752 p9_client_destroy(clnt);
226 return ERR_PTR(err); 753 return ERR_PTR(err);
227} 754}
@@ -231,13 +758,10 @@ void p9_client_destroy(struct p9_client *clnt)
231{ 758{
232 struct p9_fid *fid, *fidptr; 759 struct p9_fid *fid, *fidptr;
233 760
234 P9_DPRINTK(P9_DEBUG_9P, "clnt %p\n", clnt); 761 P9_DPRINTK(P9_DEBUG_MUX, "clnt %p\n", clnt);
235 762
236 if (clnt->trans) { 763 if (clnt->trans_mod)
237 clnt->trans->close(clnt->trans); 764 clnt->trans_mod->close(clnt);
238 kfree(clnt->trans);
239 clnt->trans = NULL;
240 }
241 765
242 v9fs_put_trans(clnt->trans_mod); 766 v9fs_put_trans(clnt->trans_mod);
243 767
@@ -247,6 +771,8 @@ void p9_client_destroy(struct p9_client *clnt)
247 if (clnt->fidpool) 771 if (clnt->fidpool)
248 p9_idpool_destroy(clnt->fidpool); 772 p9_idpool_destroy(clnt->fidpool);
249 773
774 p9_tag_cleanup(clnt);
775
250 kfree(clnt); 776 kfree(clnt);
251} 777}
252EXPORT_SYMBOL(p9_client_destroy); 778EXPORT_SYMBOL(p9_client_destroy);
@@ -254,7 +780,7 @@ EXPORT_SYMBOL(p9_client_destroy);
254void p9_client_disconnect(struct p9_client *clnt) 780void p9_client_disconnect(struct p9_client *clnt)
255{ 781{
256 P9_DPRINTK(P9_DEBUG_9P, "clnt %p\n", clnt); 782 P9_DPRINTK(P9_DEBUG_9P, "clnt %p\n", clnt);
257 clnt->trans->status = Disconnected; 783 clnt->status = Disconnected;
258} 784}
259EXPORT_SYMBOL(p9_client_disconnect); 785EXPORT_SYMBOL(p9_client_disconnect);
260 786
@@ -262,14 +788,13 @@ struct p9_fid *p9_client_attach(struct p9_client *clnt, struct p9_fid *afid,
262 char *uname, u32 n_uname, char *aname) 788 char *uname, u32 n_uname, char *aname)
263{ 789{
264 int err; 790 int err;
265 struct p9_fcall *tc, *rc; 791 struct p9_req_t *req;
266 struct p9_fid *fid; 792 struct p9_fid *fid;
793 struct p9_qid qid;
267 794
268 P9_DPRINTK(P9_DEBUG_9P, "clnt %p afid %d uname %s aname %s\n", 795 P9_DPRINTK(P9_DEBUG_9P, ">>> TATTACH afid %d uname %s aname %s\n",
269 clnt, afid?afid->fid:-1, uname, aname); 796 afid ? afid->fid : -1, uname, aname);
270 err = 0; 797 err = 0;
271 tc = NULL;
272 rc = NULL;
273 798
274 fid = p9_fid_create(clnt); 799 fid = p9_fid_create(clnt);
275 if (IS_ERR(fid)) { 800 if (IS_ERR(fid)) {
@@ -278,73 +803,77 @@ struct p9_fid *p9_client_attach(struct p9_client *clnt, struct p9_fid *afid,
278 goto error; 803 goto error;
279 } 804 }
280 805
281 tc = p9_create_tattach(fid->fid, afid?afid->fid:P9_NOFID, uname, aname, 806 req = p9_client_rpc(clnt, P9_TATTACH, "ddss?d", fid->fid,
282 n_uname, clnt->dotu); 807 afid ? afid->fid : P9_NOFID, uname, aname, n_uname);
283 if (IS_ERR(tc)) { 808 if (IS_ERR(req)) {
284 err = PTR_ERR(tc); 809 err = PTR_ERR(req);
285 tc = NULL;
286 goto error; 810 goto error;
287 } 811 }
288 812
289 err = p9_client_rpc(clnt, tc, &rc); 813 err = p9pdu_readf(req->rc, clnt->dotu, "Q", &qid);
290 if (err) 814 if (err) {
815 p9pdu_dump(1, req->rc);
816 p9_free_req(clnt, req);
291 goto error; 817 goto error;
818 }
819
820 P9_DPRINTK(P9_DEBUG_9P, "<<< RATTACH qid %x.%llx.%x\n",
821 qid.type, qid.path, qid.version);
292 822
293 memmove(&fid->qid, &rc->params.rattach.qid, sizeof(struct p9_qid)); 823 memmove(&fid->qid, &qid, sizeof(struct p9_qid));
294 kfree(tc); 824
295 kfree(rc); 825 p9_free_req(clnt, req);
296 return fid; 826 return fid;
297 827
298error: 828error:
299 kfree(tc);
300 kfree(rc);
301 if (fid) 829 if (fid)
302 p9_fid_destroy(fid); 830 p9_fid_destroy(fid);
303 return ERR_PTR(err); 831 return ERR_PTR(err);
304} 832}
305EXPORT_SYMBOL(p9_client_attach); 833EXPORT_SYMBOL(p9_client_attach);
306 834
307struct p9_fid *p9_client_auth(struct p9_client *clnt, char *uname, 835struct p9_fid *
308 u32 n_uname, char *aname) 836p9_client_auth(struct p9_client *clnt, char *uname, u32 n_uname, char *aname)
309{ 837{
310 int err; 838 int err;
311 struct p9_fcall *tc, *rc; 839 struct p9_req_t *req;
312 struct p9_fid *fid; 840 struct p9_qid qid;
841 struct p9_fid *afid;
313 842
314 P9_DPRINTK(P9_DEBUG_9P, "clnt %p uname %s aname %s\n", clnt, uname, 843 P9_DPRINTK(P9_DEBUG_9P, ">>> TAUTH uname %s aname %s\n", uname, aname);
315 aname);
316 err = 0; 844 err = 0;
317 tc = NULL;
318 rc = NULL;
319 845
320 fid = p9_fid_create(clnt); 846 afid = p9_fid_create(clnt);
321 if (IS_ERR(fid)) { 847 if (IS_ERR(afid)) {
322 err = PTR_ERR(fid); 848 err = PTR_ERR(afid);
323 fid = NULL; 849 afid = NULL;
324 goto error; 850 goto error;
325 } 851 }
326 852
327 tc = p9_create_tauth(fid->fid, uname, aname, n_uname, clnt->dotu); 853 req = p9_client_rpc(clnt, P9_TAUTH, "dss?d",
328 if (IS_ERR(tc)) { 854 afid ? afid->fid : P9_NOFID, uname, aname, n_uname);
329 err = PTR_ERR(tc); 855 if (IS_ERR(req)) {
330 tc = NULL; 856 err = PTR_ERR(req);
331 goto error; 857 goto error;
332 } 858 }
333 859
334 err = p9_client_rpc(clnt, tc, &rc); 860 err = p9pdu_readf(req->rc, clnt->dotu, "Q", &qid);
335 if (err) 861 if (err) {
862 p9pdu_dump(1, req->rc);
863 p9_free_req(clnt, req);
336 goto error; 864 goto error;
865 }
337 866
338 memmove(&fid->qid, &rc->params.rauth.qid, sizeof(struct p9_qid)); 867 P9_DPRINTK(P9_DEBUG_9P, "<<< RAUTH qid %x.%llx.%x\n",
339 kfree(tc); 868 qid.type, qid.path, qid.version);
340 kfree(rc); 869
341 return fid; 870 memmove(&afid->qid, &qid, sizeof(struct p9_qid));
871 p9_free_req(clnt, req);
872 return afid;
342 873
343error: 874error:
344 kfree(tc); 875 if (afid)
345 kfree(rc); 876 p9_fid_destroy(afid);
346 if (fid)
347 p9_fid_destroy(fid);
348 return ERR_PTR(err); 877 return ERR_PTR(err);
349} 878}
350EXPORT_SYMBOL(p9_client_auth); 879EXPORT_SYMBOL(p9_client_auth);
@@ -353,15 +882,13 @@ struct p9_fid *p9_client_walk(struct p9_fid *oldfid, int nwname, char **wnames,
353 int clone) 882 int clone)
354{ 883{
355 int err; 884 int err;
356 struct p9_fcall *tc, *rc;
357 struct p9_client *clnt; 885 struct p9_client *clnt;
358 struct p9_fid *fid; 886 struct p9_fid *fid;
887 struct p9_qid *wqids;
888 struct p9_req_t *req;
889 int16_t nwqids, count;
359 890
360 P9_DPRINTK(P9_DEBUG_9P, "fid %d nwname %d wname[0] %s\n",
361 oldfid->fid, nwname, wnames?wnames[0]:NULL);
362 err = 0; 891 err = 0;
363 tc = NULL;
364 rc = NULL;
365 clnt = oldfid->clnt; 892 clnt = oldfid->clnt;
366 if (clone) { 893 if (clone) {
367 fid = p9_fid_create(clnt); 894 fid = p9_fid_create(clnt);
@@ -375,53 +902,49 @@ struct p9_fid *p9_client_walk(struct p9_fid *oldfid, int nwname, char **wnames,
375 } else 902 } else
376 fid = oldfid; 903 fid = oldfid;
377 904
378 tc = p9_create_twalk(oldfid->fid, fid->fid, nwname, wnames); 905
379 if (IS_ERR(tc)) { 906 P9_DPRINTK(P9_DEBUG_9P, ">>> TWALK fids %d,%d nwname %d wname[0] %s\n",
380 err = PTR_ERR(tc); 907 oldfid->fid, fid->fid, nwname, wnames ? wnames[0] : NULL);
381 tc = NULL; 908
909 req = p9_client_rpc(clnt, P9_TWALK, "ddT", oldfid->fid, fid->fid,
910 nwname, wnames);
911 if (IS_ERR(req)) {
912 err = PTR_ERR(req);
382 goto error; 913 goto error;
383 } 914 }
384 915
385 err = p9_client_rpc(clnt, tc, &rc); 916 err = p9pdu_readf(req->rc, clnt->dotu, "R", &nwqids, &wqids);
386 if (err) { 917 if (err) {
387 if (rc && rc->id == P9_RWALK) 918 p9pdu_dump(1, req->rc);
388 goto clunk_fid; 919 p9_free_req(clnt, req);
389 else 920 goto clunk_fid;
390 goto error;
391 } 921 }
922 p9_free_req(clnt, req);
392 923
393 if (rc->params.rwalk.nwqid != nwname) { 924 P9_DPRINTK(P9_DEBUG_9P, "<<< RWALK nwqid %d:\n", nwqids);
925
926 if (nwqids != nwname) {
394 err = -ENOENT; 927 err = -ENOENT;
395 goto clunk_fid; 928 goto clunk_fid;
396 } 929 }
397 930
931 for (count = 0; count < nwqids; count++)
932 P9_DPRINTK(P9_DEBUG_9P, "<<< [%d] %x.%llx.%x\n",
933 count, wqids[count].type, wqids[count].path,
934 wqids[count].version);
935
398 if (nwname) 936 if (nwname)
399 memmove(&fid->qid, 937 memmove(&fid->qid, &wqids[nwqids - 1], sizeof(struct p9_qid));
400 &rc->params.rwalk.wqids[rc->params.rwalk.nwqid - 1],
401 sizeof(struct p9_qid));
402 else 938 else
403 fid->qid = oldfid->qid; 939 fid->qid = oldfid->qid;
404 940
405 kfree(tc);
406 kfree(rc);
407 return fid; 941 return fid;
408 942
409clunk_fid: 943clunk_fid:
410 kfree(tc); 944 p9_client_clunk(fid);
411 kfree(rc); 945 fid = NULL;
412 rc = NULL;
413 tc = p9_create_tclunk(fid->fid);
414 if (IS_ERR(tc)) {
415 err = PTR_ERR(tc);
416 tc = NULL;
417 goto error;
418 }
419
420 p9_client_rpc(clnt, tc, &rc);
421 946
422error: 947error:
423 kfree(tc);
424 kfree(rc);
425 if (fid && (fid != oldfid)) 948 if (fid && (fid != oldfid))
426 p9_fid_destroy(fid); 949 p9_fid_destroy(fid);
427 950
@@ -432,35 +955,39 @@ EXPORT_SYMBOL(p9_client_walk);
432int p9_client_open(struct p9_fid *fid, int mode) 955int p9_client_open(struct p9_fid *fid, int mode)
433{ 956{
434 int err; 957 int err;
435 struct p9_fcall *tc, *rc;
436 struct p9_client *clnt; 958 struct p9_client *clnt;
959 struct p9_req_t *req;
960 struct p9_qid qid;
961 int iounit;
437 962
438 P9_DPRINTK(P9_DEBUG_9P, "fid %d mode %d\n", fid->fid, mode); 963 P9_DPRINTK(P9_DEBUG_9P, ">>> TOPEN fid %d mode %d\n", fid->fid, mode);
439 err = 0; 964 err = 0;
440 tc = NULL;
441 rc = NULL;
442 clnt = fid->clnt; 965 clnt = fid->clnt;
443 966
444 if (fid->mode != -1) 967 if (fid->mode != -1)
445 return -EINVAL; 968 return -EINVAL;
446 969
447 tc = p9_create_topen(fid->fid, mode); 970 req = p9_client_rpc(clnt, P9_TOPEN, "db", fid->fid, mode);
448 if (IS_ERR(tc)) { 971 if (IS_ERR(req)) {
449 err = PTR_ERR(tc); 972 err = PTR_ERR(req);
450 tc = NULL; 973 goto error;
451 goto done;
452 } 974 }
453 975
454 err = p9_client_rpc(clnt, tc, &rc); 976 err = p9pdu_readf(req->rc, clnt->dotu, "Qd", &qid, &iounit);
455 if (err) 977 if (err) {
456 goto done; 978 p9pdu_dump(1, req->rc);
979 goto free_and_error;
980 }
981
982 P9_DPRINTK(P9_DEBUG_9P, "<<< ROPEN qid %x.%llx.%x iounit %x\n",
983 qid.type, qid.path, qid.version, iounit);
457 984
458 fid->mode = mode; 985 fid->mode = mode;
459 fid->iounit = rc->params.ropen.iounit; 986 fid->iounit = iounit;
460 987
461done: 988free_and_error:
462 kfree(tc); 989 p9_free_req(clnt, req);
463 kfree(rc); 990error:
464 return err; 991 return err;
465} 992}
466EXPORT_SYMBOL(p9_client_open); 993EXPORT_SYMBOL(p9_client_open);
@@ -469,37 +996,41 @@ int p9_client_fcreate(struct p9_fid *fid, char *name, u32 perm, int mode,
469 char *extension) 996 char *extension)
470{ 997{
471 int err; 998 int err;
472 struct p9_fcall *tc, *rc;
473 struct p9_client *clnt; 999 struct p9_client *clnt;
1000 struct p9_req_t *req;
1001 struct p9_qid qid;
1002 int iounit;
474 1003
475 P9_DPRINTK(P9_DEBUG_9P, "fid %d name %s perm %d mode %d\n", fid->fid, 1004 P9_DPRINTK(P9_DEBUG_9P, ">>> TCREATE fid %d name %s perm %d mode %d\n",
476 name, perm, mode); 1005 fid->fid, name, perm, mode);
477 err = 0; 1006 err = 0;
478 tc = NULL;
479 rc = NULL;
480 clnt = fid->clnt; 1007 clnt = fid->clnt;
481 1008
482 if (fid->mode != -1) 1009 if (fid->mode != -1)
483 return -EINVAL; 1010 return -EINVAL;
484 1011
485 tc = p9_create_tcreate(fid->fid, name, perm, mode, extension, 1012 req = p9_client_rpc(clnt, P9_TCREATE, "dsdb?s", fid->fid, name, perm,
486 clnt->dotu); 1013 mode, extension);
487 if (IS_ERR(tc)) { 1014 if (IS_ERR(req)) {
488 err = PTR_ERR(tc); 1015 err = PTR_ERR(req);
489 tc = NULL; 1016 goto error;
490 goto done;
491 } 1017 }
492 1018
493 err = p9_client_rpc(clnt, tc, &rc); 1019 err = p9pdu_readf(req->rc, clnt->dotu, "Qd", &qid, &iounit);
494 if (err) 1020 if (err) {
495 goto done; 1021 p9pdu_dump(1, req->rc);
1022 goto free_and_error;
1023 }
1024
1025 P9_DPRINTK(P9_DEBUG_9P, "<<< RCREATE qid %x.%llx.%x iounit %x\n",
1026 qid.type, qid.path, qid.version, iounit);
496 1027
497 fid->mode = mode; 1028 fid->mode = mode;
498 fid->iounit = rc->params.ropen.iounit; 1029 fid->iounit = iounit;
499 1030
500done: 1031free_and_error:
501 kfree(tc); 1032 p9_free_req(clnt, req);
502 kfree(rc); 1033error:
503 return err; 1034 return err;
504} 1035}
505EXPORT_SYMBOL(p9_client_fcreate); 1036EXPORT_SYMBOL(p9_client_fcreate);
@@ -507,31 +1038,25 @@ EXPORT_SYMBOL(p9_client_fcreate);
507int p9_client_clunk(struct p9_fid *fid) 1038int p9_client_clunk(struct p9_fid *fid)
508{ 1039{
509 int err; 1040 int err;
510 struct p9_fcall *tc, *rc;
511 struct p9_client *clnt; 1041 struct p9_client *clnt;
1042 struct p9_req_t *req;
512 1043
513 P9_DPRINTK(P9_DEBUG_9P, "fid %d\n", fid->fid); 1044 P9_DPRINTK(P9_DEBUG_9P, ">>> TCLUNK fid %d\n", fid->fid);
514 err = 0; 1045 err = 0;
515 tc = NULL;
516 rc = NULL;
517 clnt = fid->clnt; 1046 clnt = fid->clnt;
518 1047
519 tc = p9_create_tclunk(fid->fid); 1048 req = p9_client_rpc(clnt, P9_TCLUNK, "d", fid->fid);
520 if (IS_ERR(tc)) { 1049 if (IS_ERR(req)) {
521 err = PTR_ERR(tc); 1050 err = PTR_ERR(req);
522 tc = NULL; 1051 goto error;
523 goto done;
524 } 1052 }
525 1053
526 err = p9_client_rpc(clnt, tc, &rc); 1054 P9_DPRINTK(P9_DEBUG_9P, "<<< RCLUNK fid %d\n", fid->fid);
527 if (err)
528 goto done;
529 1055
1056 p9_free_req(clnt, req);
530 p9_fid_destroy(fid); 1057 p9_fid_destroy(fid);
531 1058
532done: 1059error:
533 kfree(tc);
534 kfree(rc);
535 return err; 1060 return err;
536} 1061}
537EXPORT_SYMBOL(p9_client_clunk); 1062EXPORT_SYMBOL(p9_client_clunk);
@@ -539,157 +1064,41 @@ EXPORT_SYMBOL(p9_client_clunk);
539int p9_client_remove(struct p9_fid *fid) 1064int p9_client_remove(struct p9_fid *fid)
540{ 1065{
541 int err; 1066 int err;
542 struct p9_fcall *tc, *rc;
543 struct p9_client *clnt; 1067 struct p9_client *clnt;
1068 struct p9_req_t *req;
544 1069
545 P9_DPRINTK(P9_DEBUG_9P, "fid %d\n", fid->fid); 1070 P9_DPRINTK(P9_DEBUG_9P, ">>> TREMOVE fid %d\n", fid->fid);
546 err = 0; 1071 err = 0;
547 tc = NULL;
548 rc = NULL;
549 clnt = fid->clnt; 1072 clnt = fid->clnt;
550 1073
551 tc = p9_create_tremove(fid->fid); 1074 req = p9_client_rpc(clnt, P9_TREMOVE, "d", fid->fid);
552 if (IS_ERR(tc)) { 1075 if (IS_ERR(req)) {
553 err = PTR_ERR(tc); 1076 err = PTR_ERR(req);
554 tc = NULL; 1077 goto error;
555 goto done;
556 } 1078 }
557 1079
558 err = p9_client_rpc(clnt, tc, &rc); 1080 P9_DPRINTK(P9_DEBUG_9P, "<<< RREMOVE fid %d\n", fid->fid);
559 if (err)
560 goto done;
561 1081
1082 p9_free_req(clnt, req);
562 p9_fid_destroy(fid); 1083 p9_fid_destroy(fid);
563 1084
564done:
565 kfree(tc);
566 kfree(rc);
567 return err;
568}
569EXPORT_SYMBOL(p9_client_remove);
570
571int p9_client_read(struct p9_fid *fid, char *data, u64 offset, u32 count)
572{
573 int err, n, rsize, total;
574 struct p9_fcall *tc, *rc;
575 struct p9_client *clnt;
576
577 P9_DPRINTK(P9_DEBUG_9P, "fid %d offset %llu %d\n", fid->fid,
578 (long long unsigned) offset, count);
579 err = 0;
580 tc = NULL;
581 rc = NULL;
582 clnt = fid->clnt;
583 total = 0;
584
585 rsize = fid->iounit;
586 if (!rsize || rsize > clnt->msize-P9_IOHDRSZ)
587 rsize = clnt->msize - P9_IOHDRSZ;
588
589 do {
590 if (count < rsize)
591 rsize = count;
592
593 tc = p9_create_tread(fid->fid, offset, rsize);
594 if (IS_ERR(tc)) {
595 err = PTR_ERR(tc);
596 tc = NULL;
597 goto error;
598 }
599
600 err = p9_client_rpc(clnt, tc, &rc);
601 if (err)
602 goto error;
603
604 n = rc->params.rread.count;
605 if (n > count)
606 n = count;
607
608 memmove(data, rc->params.rread.data, n);
609 count -= n;
610 data += n;
611 offset += n;
612 total += n;
613 kfree(tc);
614 tc = NULL;
615 kfree(rc);
616 rc = NULL;
617 } while (count > 0 && n == rsize);
618
619 return total;
620
621error: 1085error:
622 kfree(tc);
623 kfree(rc);
624 return err; 1086 return err;
625} 1087}
626EXPORT_SYMBOL(p9_client_read); 1088EXPORT_SYMBOL(p9_client_remove);
627
628int p9_client_write(struct p9_fid *fid, char *data, u64 offset, u32 count)
629{
630 int err, n, rsize, total;
631 struct p9_fcall *tc, *rc;
632 struct p9_client *clnt;
633
634 P9_DPRINTK(P9_DEBUG_9P, "fid %d offset %llu count %d\n", fid->fid,
635 (long long unsigned) offset, count);
636 err = 0;
637 tc = NULL;
638 rc = NULL;
639 clnt = fid->clnt;
640 total = 0;
641
642 rsize = fid->iounit;
643 if (!rsize || rsize > clnt->msize-P9_IOHDRSZ)
644 rsize = clnt->msize - P9_IOHDRSZ;
645
646 do {
647 if (count < rsize)
648 rsize = count;
649
650 tc = p9_create_twrite(fid->fid, offset, rsize, data);
651 if (IS_ERR(tc)) {
652 err = PTR_ERR(tc);
653 tc = NULL;
654 goto error;
655 }
656
657 err = p9_client_rpc(clnt, tc, &rc);
658 if (err)
659 goto error;
660
661 n = rc->params.rread.count;
662 count -= n;
663 data += n;
664 offset += n;
665 total += n;
666 kfree(tc);
667 tc = NULL;
668 kfree(rc);
669 rc = NULL;
670 } while (count > 0);
671
672 return total;
673
674error:
675 kfree(tc);
676 kfree(rc);
677 return err;
678}
679EXPORT_SYMBOL(p9_client_write);
680 1089
681int 1090int
682p9_client_uread(struct p9_fid *fid, char __user *data, u64 offset, u32 count) 1091p9_client_read(struct p9_fid *fid, char *data, char __user *udata, u64 offset,
1092 u32 count)
683{ 1093{
684 int err, n, rsize, total; 1094 int err, rsize, total;
685 struct p9_fcall *tc, *rc;
686 struct p9_client *clnt; 1095 struct p9_client *clnt;
1096 struct p9_req_t *req;
1097 char *dataptr;
687 1098
688 P9_DPRINTK(P9_DEBUG_9P, "fid %d offset %llu count %d\n", fid->fid, 1099 P9_DPRINTK(P9_DEBUG_9P, ">>> TREAD fid %d offset %llu %d\n", fid->fid,
689 (long long unsigned) offset, count); 1100 (long long unsigned) offset, count);
690 err = 0; 1101 err = 0;
691 tc = NULL;
692 rc = NULL;
693 clnt = fid->clnt; 1102 clnt = fid->clnt;
694 total = 0; 1103 total = 0;
695 1104
@@ -697,63 +1106,57 @@ p9_client_uread(struct p9_fid *fid, char __user *data, u64 offset, u32 count)
697 if (!rsize || rsize > clnt->msize-P9_IOHDRSZ) 1106 if (!rsize || rsize > clnt->msize-P9_IOHDRSZ)
698 rsize = clnt->msize - P9_IOHDRSZ; 1107 rsize = clnt->msize - P9_IOHDRSZ;
699 1108
700 do { 1109 if (count < rsize)
701 if (count < rsize) 1110 rsize = count;
702 rsize = count;
703 1111
704 tc = p9_create_tread(fid->fid, offset, rsize); 1112 req = p9_client_rpc(clnt, P9_TREAD, "dqd", fid->fid, offset, rsize);
705 if (IS_ERR(tc)) { 1113 if (IS_ERR(req)) {
706 err = PTR_ERR(tc); 1114 err = PTR_ERR(req);
707 tc = NULL; 1115 goto error;
708 goto error; 1116 }
709 }
710 1117
711 err = p9_client_rpc(clnt, tc, &rc); 1118 err = p9pdu_readf(req->rc, clnt->dotu, "D", &count, &dataptr);
712 if (err) 1119 if (err) {
713 goto error; 1120 p9pdu_dump(1, req->rc);
1121 goto free_and_error;
1122 }
1123
1124 P9_DPRINTK(P9_DEBUG_9P, "<<< RREAD count %d\n", count);
714 1125
715 n = rc->params.rread.count; 1126 if (data) {
716 if (n > count) 1127 memmove(data, dataptr, count);
717 n = count; 1128 data += count;
1129 }
718 1130
719 err = copy_to_user(data, rc->params.rread.data, n); 1131 if (udata) {
1132 err = copy_to_user(udata, dataptr, count);
720 if (err) { 1133 if (err) {
721 err = -EFAULT; 1134 err = -EFAULT;
722 goto error; 1135 goto free_and_error;
723 } 1136 }
1137 }
724 1138
725 count -= n; 1139 p9_free_req(clnt, req);
726 data += n; 1140 return count;
727 offset += n;
728 total += n;
729 kfree(tc);
730 tc = NULL;
731 kfree(rc);
732 rc = NULL;
733 } while (count > 0 && n == rsize);
734
735 return total;
736 1141
1142free_and_error:
1143 p9_free_req(clnt, req);
737error: 1144error:
738 kfree(tc);
739 kfree(rc);
740 return err; 1145 return err;
741} 1146}
742EXPORT_SYMBOL(p9_client_uread); 1147EXPORT_SYMBOL(p9_client_read);
743 1148
744int 1149int
745p9_client_uwrite(struct p9_fid *fid, const char __user *data, u64 offset, 1150p9_client_write(struct p9_fid *fid, char *data, const char __user *udata,
746 u32 count) 1151 u64 offset, u32 count)
747{ 1152{
748 int err, n, rsize, total; 1153 int err, rsize, total;
749 struct p9_fcall *tc, *rc;
750 struct p9_client *clnt; 1154 struct p9_client *clnt;
1155 struct p9_req_t *req;
751 1156
752 P9_DPRINTK(P9_DEBUG_9P, "fid %d offset %llu count %d\n", fid->fid, 1157 P9_DPRINTK(P9_DEBUG_9P, ">>> TWRITE fid %d offset %llu count %d\n",
753 (long long unsigned) offset, count); 1158 fid->fid, (long long unsigned) offset, count);
754 err = 0; 1159 err = 0;
755 tc = NULL;
756 rc = NULL;
757 clnt = fid->clnt; 1160 clnt = fid->clnt;
758 total = 0; 1161 total = 0;
759 1162
@@ -761,325 +1164,114 @@ p9_client_uwrite(struct p9_fid *fid, const char __user *data, u64 offset,
761 if (!rsize || rsize > clnt->msize-P9_IOHDRSZ) 1164 if (!rsize || rsize > clnt->msize-P9_IOHDRSZ)
762 rsize = clnt->msize - P9_IOHDRSZ; 1165 rsize = clnt->msize - P9_IOHDRSZ;
763 1166
764 do { 1167 if (count < rsize)
765 if (count < rsize) 1168 rsize = count;
766 rsize = count; 1169 if (data)
767 1170 req = p9_client_rpc(clnt, P9_TWRITE, "dqD", fid->fid, offset,
768 tc = p9_create_twrite_u(fid->fid, offset, rsize, data); 1171 rsize, data);
769 if (IS_ERR(tc)) { 1172 else
770 err = PTR_ERR(tc); 1173 req = p9_client_rpc(clnt, P9_TWRITE, "dqU", fid->fid, offset,
771 tc = NULL; 1174 rsize, udata);
772 goto error; 1175 if (IS_ERR(req)) {
773 } 1176 err = PTR_ERR(req);
1177 goto error;
1178 }
774 1179
775 err = p9_client_rpc(clnt, tc, &rc); 1180 err = p9pdu_readf(req->rc, clnt->dotu, "d", &count);
776 if (err) 1181 if (err) {
777 goto error; 1182 p9pdu_dump(1, req->rc);
1183 goto free_and_error;
1184 }
778 1185
779 n = rc->params.rread.count; 1186 P9_DPRINTK(P9_DEBUG_9P, "<<< RWRITE count %d\n", count);
780 count -= n;
781 data += n;
782 offset += n;
783 total += n;
784 kfree(tc);
785 tc = NULL;
786 kfree(rc);
787 rc = NULL;
788 } while (count > 0);
789 1187
790 return total; 1188 p9_free_req(clnt, req);
1189 return count;
791 1190
1191free_and_error:
1192 p9_free_req(clnt, req);
792error: 1193error:
793 kfree(tc);
794 kfree(rc);
795 return err; 1194 return err;
796} 1195}
797EXPORT_SYMBOL(p9_client_uwrite); 1196EXPORT_SYMBOL(p9_client_write);
798
799int p9_client_readn(struct p9_fid *fid, char *data, u64 offset, u32 count)
800{
801 int n, total;
802
803 P9_DPRINTK(P9_DEBUG_9P, "fid %d offset %llu count %d\n", fid->fid,
804 (long long unsigned) offset, count);
805 n = 0;
806 total = 0;
807 while (count) {
808 n = p9_client_read(fid, data, offset, count);
809 if (n <= 0)
810 break;
811
812 data += n;
813 offset += n;
814 count -= n;
815 total += n;
816 }
817
818 if (n < 0)
819 total = n;
820
821 return total;
822}
823EXPORT_SYMBOL(p9_client_readn);
824 1197
825struct p9_stat *p9_client_stat(struct p9_fid *fid) 1198struct p9_wstat *p9_client_stat(struct p9_fid *fid)
826{ 1199{
827 int err; 1200 int err;
828 struct p9_fcall *tc, *rc;
829 struct p9_client *clnt; 1201 struct p9_client *clnt;
830 struct p9_stat *ret; 1202 struct p9_wstat *ret = kmalloc(sizeof(struct p9_wstat), GFP_KERNEL);
1203 struct p9_req_t *req;
1204 u16 ignored;
1205
1206 P9_DPRINTK(P9_DEBUG_9P, ">>> TSTAT fid %d\n", fid->fid);
1207
1208 if (!ret)
1209 return ERR_PTR(-ENOMEM);
831 1210
832 P9_DPRINTK(P9_DEBUG_9P, "fid %d\n", fid->fid);
833 err = 0; 1211 err = 0;
834 tc = NULL;
835 rc = NULL;
836 ret = NULL;
837 clnt = fid->clnt; 1212 clnt = fid->clnt;
838 1213
839 tc = p9_create_tstat(fid->fid); 1214 req = p9_client_rpc(clnt, P9_TSTAT, "d", fid->fid);
840 if (IS_ERR(tc)) { 1215 if (IS_ERR(req)) {
841 err = PTR_ERR(tc); 1216 err = PTR_ERR(req);
842 tc = NULL;
843 goto error; 1217 goto error;
844 } 1218 }
845 1219
846 err = p9_client_rpc(clnt, tc, &rc); 1220 err = p9pdu_readf(req->rc, clnt->dotu, "wS", &ignored, ret);
847 if (err) 1221 if (err) {
848 goto error; 1222 ret = ERR_PTR(err);
849 1223 p9pdu_dump(1, req->rc);
850 ret = p9_clone_stat(&rc->params.rstat.stat, clnt->dotu); 1224 goto free_and_error;
851 if (IS_ERR(ret)) {
852 err = PTR_ERR(ret);
853 ret = NULL;
854 goto error;
855 } 1225 }
856 1226
857 kfree(tc); 1227 P9_DPRINTK(P9_DEBUG_9P,
858 kfree(rc); 1228 "<<< RSTAT sz=%x type=%x dev=%x qid=%x.%llx.%x\n"
859 return ret; 1229 "<<< mode=%8.8x atime=%8.8x mtime=%8.8x length=%llx\n"
860 1230 "<<< name=%s uid=%s gid=%s muid=%s extension=(%s)\n"
1231 "<<< uid=%d gid=%d n_muid=%d\n",
1232 ret->size, ret->type, ret->dev, ret->qid.type,
1233 ret->qid.path, ret->qid.version, ret->mode,
1234 ret->atime, ret->mtime, ret->length, ret->name,
1235 ret->uid, ret->gid, ret->muid, ret->extension,
1236 ret->n_uid, ret->n_gid, ret->n_muid);
1237
1238free_and_error:
1239 p9_free_req(clnt, req);
861error: 1240error:
862 kfree(tc); 1241 return ret;
863 kfree(rc);
864 kfree(ret);
865 return ERR_PTR(err);
866} 1242}
867EXPORT_SYMBOL(p9_client_stat); 1243EXPORT_SYMBOL(p9_client_stat);
868 1244
869int p9_client_wstat(struct p9_fid *fid, struct p9_wstat *wst) 1245int p9_client_wstat(struct p9_fid *fid, struct p9_wstat *wst)
870{ 1246{
871 int err; 1247 int err;
872 struct p9_fcall *tc, *rc; 1248 struct p9_req_t *req;
873 struct p9_client *clnt; 1249 struct p9_client *clnt;
874 1250
875 P9_DPRINTK(P9_DEBUG_9P, "fid %d\n", fid->fid); 1251 P9_DPRINTK(P9_DEBUG_9P, ">>> TWSTAT fid %d\n", fid->fid);
1252 P9_DPRINTK(P9_DEBUG_9P,
1253 " sz=%x type=%x dev=%x qid=%x.%llx.%x\n"
1254 " mode=%8.8x atime=%8.8x mtime=%8.8x length=%llx\n"
1255 " name=%s uid=%s gid=%s muid=%s extension=(%s)\n"
1256 " uid=%d gid=%d n_muid=%d\n",
1257 wst->size, wst->type, wst->dev, wst->qid.type,
1258 wst->qid.path, wst->qid.version, wst->mode,
1259 wst->atime, wst->mtime, wst->length, wst->name,
1260 wst->uid, wst->gid, wst->muid, wst->extension,
1261 wst->n_uid, wst->n_gid, wst->n_muid);
876 err = 0; 1262 err = 0;
877 tc = NULL;
878 rc = NULL;
879 clnt = fid->clnt; 1263 clnt = fid->clnt;
880 1264
881 tc = p9_create_twstat(fid->fid, wst, clnt->dotu); 1265 req = p9_client_rpc(clnt, P9_TWSTAT, "dwS", fid->fid, 0, wst);
882 if (IS_ERR(tc)) { 1266 if (IS_ERR(req)) {
883 err = PTR_ERR(tc); 1267 err = PTR_ERR(req);
884 tc = NULL;
885 goto done;
886 }
887
888 err = p9_client_rpc(clnt, tc, &rc);
889
890done:
891 kfree(tc);
892 kfree(rc);
893 return err;
894}
895EXPORT_SYMBOL(p9_client_wstat);
896
897struct p9_stat *p9_client_dirread(struct p9_fid *fid, u64 offset)
898{
899 int err, n, m;
900 struct p9_fcall *tc, *rc;
901 struct p9_client *clnt;
902 struct p9_stat st, *ret;
903
904 P9_DPRINTK(P9_DEBUG_9P, "fid %d offset %llu\n", fid->fid,
905 (long long unsigned) offset);
906 err = 0;
907 tc = NULL;
908 rc = NULL;
909 ret = NULL;
910 clnt = fid->clnt;
911
912 /* if the offset is below or above the current response, free it */
913 if (offset < fid->rdir_fpos || (fid->rdir_fcall &&
914 offset >= fid->rdir_fpos+fid->rdir_fcall->params.rread.count)) {
915 fid->rdir_pos = 0;
916 if (fid->rdir_fcall)
917 fid->rdir_fpos += fid->rdir_fcall->params.rread.count;
918
919 kfree(fid->rdir_fcall);
920 fid->rdir_fcall = NULL;
921 if (offset < fid->rdir_fpos)
922 fid->rdir_fpos = 0;
923 }
924
925 if (!fid->rdir_fcall) {
926 n = fid->iounit;
927 if (!n || n > clnt->msize-P9_IOHDRSZ)
928 n = clnt->msize - P9_IOHDRSZ;
929
930 while (1) {
931 if (fid->rdir_fcall) {
932 fid->rdir_fpos +=
933 fid->rdir_fcall->params.rread.count;
934 kfree(fid->rdir_fcall);
935 fid->rdir_fcall = NULL;
936 }
937
938 tc = p9_create_tread(fid->fid, fid->rdir_fpos, n);
939 if (IS_ERR(tc)) {
940 err = PTR_ERR(tc);
941 tc = NULL;
942 goto error;
943 }
944
945 err = p9_client_rpc(clnt, tc, &rc);
946 if (err)
947 goto error;
948
949 n = rc->params.rread.count;
950 if (n == 0)
951 goto done;
952
953 fid->rdir_fcall = rc;
954 rc = NULL;
955 if (offset >= fid->rdir_fpos &&
956 offset < fid->rdir_fpos+n)
957 break;
958 }
959
960 fid->rdir_pos = 0;
961 }
962
963 m = offset - fid->rdir_fpos;
964 if (m < 0)
965 goto done;
966
967 n = p9_deserialize_stat(fid->rdir_fcall->params.rread.data + m,
968 fid->rdir_fcall->params.rread.count - m, &st, clnt->dotu);
969
970 if (!n) {
971 err = -EIO;
972 goto error;
973 }
974
975 fid->rdir_pos += n;
976 st.size = n;
977 ret = p9_clone_stat(&st, clnt->dotu);
978 if (IS_ERR(ret)) {
979 err = PTR_ERR(ret);
980 ret = NULL;
981 goto error;
982 }
983
984done:
985 kfree(tc);
986 kfree(rc);
987 return ret;
988
989error:
990 kfree(tc);
991 kfree(rc);
992 kfree(ret);
993 return ERR_PTR(err);
994}
995EXPORT_SYMBOL(p9_client_dirread);
996
997static struct p9_stat *p9_clone_stat(struct p9_stat *st, int dotu)
998{
999 int n;
1000 char *p;
1001 struct p9_stat *ret;
1002
1003 n = sizeof(struct p9_stat) + st->name.len + st->uid.len + st->gid.len +
1004 st->muid.len;
1005
1006 if (dotu)
1007 n += st->extension.len;
1008
1009 ret = kmalloc(n, GFP_KERNEL);
1010 if (!ret)
1011 return ERR_PTR(-ENOMEM);
1012
1013 memmove(ret, st, sizeof(struct p9_stat));
1014 p = ((char *) ret) + sizeof(struct p9_stat);
1015 memmove(p, st->name.str, st->name.len);
1016 ret->name.str = p;
1017 p += st->name.len;
1018 memmove(p, st->uid.str, st->uid.len);
1019 ret->uid.str = p;
1020 p += st->uid.len;
1021 memmove(p, st->gid.str, st->gid.len);
1022 ret->gid.str = p;
1023 p += st->gid.len;
1024 memmove(p, st->muid.str, st->muid.len);
1025 ret->muid.str = p;
1026 p += st->muid.len;
1027
1028 if (dotu) {
1029 memmove(p, st->extension.str, st->extension.len);
1030 ret->extension.str = p;
1031 p += st->extension.len;
1032 }
1033
1034 return ret;
1035}
1036
1037static struct p9_fid *p9_fid_create(struct p9_client *clnt)
1038{
1039 int err;
1040 struct p9_fid *fid;
1041
1042 P9_DPRINTK(P9_DEBUG_9P, "clnt %p\n", clnt);
1043 fid = kmalloc(sizeof(struct p9_fid), GFP_KERNEL);
1044 if (!fid)
1045 return ERR_PTR(-ENOMEM);
1046
1047 fid->fid = p9_idpool_get(clnt->fidpool);
1048 if (fid->fid < 0) {
1049 err = -ENOSPC;
1050 goto error; 1268 goto error;
1051 } 1269 }
1052 1270
1053 memset(&fid->qid, 0, sizeof(struct p9_qid)); 1271 P9_DPRINTK(P9_DEBUG_9P, "<<< RWSTAT fid %d\n", fid->fid);
1054 fid->mode = -1;
1055 fid->rdir_fpos = 0;
1056 fid->rdir_pos = 0;
1057 fid->rdir_fcall = NULL;
1058 fid->uid = current->fsuid;
1059 fid->clnt = clnt;
1060 fid->aux = NULL;
1061
1062 spin_lock(&clnt->lock);
1063 list_add(&fid->flist, &clnt->fidlist);
1064 spin_unlock(&clnt->lock);
1065
1066 return fid;
1067 1272
1273 p9_free_req(clnt, req);
1068error: 1274error:
1069 kfree(fid); 1275 return err;
1070 return ERR_PTR(err);
1071}
1072
1073static void p9_fid_destroy(struct p9_fid *fid)
1074{
1075 struct p9_client *clnt;
1076
1077 P9_DPRINTK(P9_DEBUG_9P, "fid %d\n", fid->fid);
1078 clnt = fid->clnt;
1079 p9_idpool_put(fid->fid, clnt->fidpool);
1080 spin_lock(&clnt->lock);
1081 list_del(&fid->flist);
1082 spin_unlock(&clnt->lock);
1083 kfree(fid->rdir_fcall);
1084 kfree(fid);
1085} 1276}
1277EXPORT_SYMBOL(p9_client_wstat);
diff --git a/net/9p/conv.c b/net/9p/conv.c
deleted file mode 100644
index 5ad3a3bd73b2..000000000000
--- a/net/9p/conv.c
+++ /dev/null
@@ -1,1054 +0,0 @@
1/*
2 * net/9p/conv.c
3 *
4 * 9P protocol conversion functions
5 *
6 * Copyright (C) 2004, 2005 by Latchesar Ionkov <lucho@ionkov.net>
7 * Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com>
8 * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2
12 * as published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to:
21 * Free Software Foundation
22 * 51 Franklin Street, Fifth Floor
23 * Boston, MA 02111-1301 USA
24 *
25 */
26
27#include <linux/module.h>
28#include <linux/errno.h>
29#include <linux/fs.h>
30#include <linux/sched.h>
31#include <linux/idr.h>
32#include <linux/uaccess.h>
33#include <net/9p/9p.h>
34
35/*
36 * Buffer to help with string parsing
37 */
38struct cbuf {
39 unsigned char *sp;
40 unsigned char *p;
41 unsigned char *ep;
42};
43
44static inline void buf_init(struct cbuf *buf, void *data, int datalen)
45{
46 buf->sp = buf->p = data;
47 buf->ep = data + datalen;
48}
49
50static inline int buf_check_overflow(struct cbuf *buf)
51{
52 return buf->p > buf->ep;
53}
54
55static int buf_check_size(struct cbuf *buf, int len)
56{
57 if (buf->p + len > buf->ep) {
58 if (buf->p < buf->ep) {
59 P9_EPRINTK(KERN_ERR,
60 "buffer overflow: want %d has %d\n", len,
61 (int)(buf->ep - buf->p));
62 dump_stack();
63 buf->p = buf->ep + 1;
64 }
65
66 return 0;
67 }
68
69 return 1;
70}
71
72static void *buf_alloc(struct cbuf *buf, int len)
73{
74 void *ret = NULL;
75
76 if (buf_check_size(buf, len)) {
77 ret = buf->p;
78 buf->p += len;
79 }
80
81 return ret;
82}
83
84static void buf_put_int8(struct cbuf *buf, u8 val)
85{
86 if (buf_check_size(buf, 1)) {
87 buf->p[0] = val;
88 buf->p++;
89 }
90}
91
92static void buf_put_int16(struct cbuf *buf, u16 val)
93{
94 if (buf_check_size(buf, 2)) {
95 *(__le16 *) buf->p = cpu_to_le16(val);
96 buf->p += 2;
97 }
98}
99
100static void buf_put_int32(struct cbuf *buf, u32 val)
101{
102 if (buf_check_size(buf, 4)) {
103 *(__le32 *)buf->p = cpu_to_le32(val);
104 buf->p += 4;
105 }
106}
107
108static void buf_put_int64(struct cbuf *buf, u64 val)
109{
110 if (buf_check_size(buf, 8)) {
111 *(__le64 *)buf->p = cpu_to_le64(val);
112 buf->p += 8;
113 }
114}
115
116static char *buf_put_stringn(struct cbuf *buf, const char *s, u16 slen)
117{
118 char *ret;
119
120 ret = NULL;
121 if (buf_check_size(buf, slen + 2)) {
122 buf_put_int16(buf, slen);
123 ret = buf->p;
124 memcpy(buf->p, s, slen);
125 buf->p += slen;
126 }
127
128 return ret;
129}
130
131static u8 buf_get_int8(struct cbuf *buf)
132{
133 u8 ret = 0;
134
135 if (buf_check_size(buf, 1)) {
136 ret = buf->p[0];
137 buf->p++;
138 }
139
140 return ret;
141}
142
143static u16 buf_get_int16(struct cbuf *buf)
144{
145 u16 ret = 0;
146
147 if (buf_check_size(buf, 2)) {
148 ret = le16_to_cpu(*(__le16 *)buf->p);
149 buf->p += 2;
150 }
151
152 return ret;
153}
154
155static u32 buf_get_int32(struct cbuf *buf)
156{
157 u32 ret = 0;
158
159 if (buf_check_size(buf, 4)) {
160 ret = le32_to_cpu(*(__le32 *)buf->p);
161 buf->p += 4;
162 }
163
164 return ret;
165}
166
167static u64 buf_get_int64(struct cbuf *buf)
168{
169 u64 ret = 0;
170
171 if (buf_check_size(buf, 8)) {
172 ret = le64_to_cpu(*(__le64 *)buf->p);
173 buf->p += 8;
174 }
175
176 return ret;
177}
178
179static void buf_get_str(struct cbuf *buf, struct p9_str *vstr)
180{
181 vstr->len = buf_get_int16(buf);
182 if (!buf_check_overflow(buf) && buf_check_size(buf, vstr->len)) {
183 vstr->str = buf->p;
184 buf->p += vstr->len;
185 } else {
186 vstr->len = 0;
187 vstr->str = NULL;
188 }
189}
190
191static void buf_get_qid(struct cbuf *bufp, struct p9_qid *qid)
192{
193 qid->type = buf_get_int8(bufp);
194 qid->version = buf_get_int32(bufp);
195 qid->path = buf_get_int64(bufp);
196}
197
198/**
199 * p9_size_wstat - calculate the size of a variable length stat struct
200 * @wstat: metadata (stat) structure
201 * @dotu: non-zero if 9P2000.u
202 *
203 */
204
205static int p9_size_wstat(struct p9_wstat *wstat, int dotu)
206{
207 int size = 0;
208
209 if (wstat == NULL) {
210 P9_EPRINTK(KERN_ERR, "p9_size_stat: got a NULL stat pointer\n");
211 return 0;
212 }
213
214 size = /* 2 + *//* size[2] */
215 2 + /* type[2] */
216 4 + /* dev[4] */
217 1 + /* qid.type[1] */
218 4 + /* qid.vers[4] */
219 8 + /* qid.path[8] */
220 4 + /* mode[4] */
221 4 + /* atime[4] */
222 4 + /* mtime[4] */
223 8 + /* length[8] */
224 8; /* minimum sum of string lengths */
225
226 if (wstat->name)
227 size += strlen(wstat->name);
228 if (wstat->uid)
229 size += strlen(wstat->uid);
230 if (wstat->gid)
231 size += strlen(wstat->gid);
232 if (wstat->muid)
233 size += strlen(wstat->muid);
234
235 if (dotu) {
236 size += 4 + /* n_uid[4] */
237 4 + /* n_gid[4] */
238 4 + /* n_muid[4] */
239 2; /* string length of extension[4] */
240 if (wstat->extension)
241 size += strlen(wstat->extension);
242 }
243
244 return size;
245}
246
247/**
248 * buf_get_stat - safely decode a recieved metadata (stat) structure
249 * @bufp: buffer to deserialize
250 * @stat: metadata (stat) structure
251 * @dotu: non-zero if 9P2000.u
252 *
253 */
254
255static void
256buf_get_stat(struct cbuf *bufp, struct p9_stat *stat, int dotu)
257{
258 stat->size = buf_get_int16(bufp);
259 stat->type = buf_get_int16(bufp);
260 stat->dev = buf_get_int32(bufp);
261 stat->qid.type = buf_get_int8(bufp);
262 stat->qid.version = buf_get_int32(bufp);
263 stat->qid.path = buf_get_int64(bufp);
264 stat->mode = buf_get_int32(bufp);
265 stat->atime = buf_get_int32(bufp);
266 stat->mtime = buf_get_int32(bufp);
267 stat->length = buf_get_int64(bufp);
268 buf_get_str(bufp, &stat->name);
269 buf_get_str(bufp, &stat->uid);
270 buf_get_str(bufp, &stat->gid);
271 buf_get_str(bufp, &stat->muid);
272
273 if (dotu) {
274 buf_get_str(bufp, &stat->extension);
275 stat->n_uid = buf_get_int32(bufp);
276 stat->n_gid = buf_get_int32(bufp);
277 stat->n_muid = buf_get_int32(bufp);
278 }
279}
280
281/**
282 * p9_deserialize_stat - decode a received metadata structure
283 * @buf: buffer to deserialize
284 * @buflen: length of received buffer
285 * @stat: metadata structure to decode into
286 * @dotu: non-zero if 9P2000.u
287 *
288 * Note: stat will point to the buf region.
289 */
290
291int
292p9_deserialize_stat(void *buf, u32 buflen, struct p9_stat *stat,
293 int dotu)
294{
295 struct cbuf buffer;
296 struct cbuf *bufp = &buffer;
297 unsigned char *p;
298
299 buf_init(bufp, buf, buflen);
300 p = bufp->p;
301 buf_get_stat(bufp, stat, dotu);
302
303 if (buf_check_overflow(bufp))
304 return 0;
305 else
306 return bufp->p - p;
307}
308EXPORT_SYMBOL(p9_deserialize_stat);
309
310/**
311 * deserialize_fcall - unmarshal a response
312 * @buf: recieved buffer
313 * @buflen: length of received buffer
314 * @rcall: fcall structure to populate
315 * @rcalllen: length of fcall structure to populate
316 * @dotu: non-zero if 9P2000.u
317 *
318 */
319
320int
321p9_deserialize_fcall(void *buf, u32 buflen, struct p9_fcall *rcall,
322 int dotu)
323{
324
325 struct cbuf buffer;
326 struct cbuf *bufp = &buffer;
327 int i = 0;
328
329 buf_init(bufp, buf, buflen);
330
331 rcall->size = buf_get_int32(bufp);
332 rcall->id = buf_get_int8(bufp);
333 rcall->tag = buf_get_int16(bufp);
334
335 P9_DPRINTK(P9_DEBUG_CONV, "size %d id %d tag %d\n", rcall->size,
336 rcall->id, rcall->tag);
337
338 switch (rcall->id) {
339 default:
340 P9_EPRINTK(KERN_ERR, "unknown message type: %d\n", rcall->id);
341 return -EPROTO;
342 case P9_RVERSION:
343 rcall->params.rversion.msize = buf_get_int32(bufp);
344 buf_get_str(bufp, &rcall->params.rversion.version);
345 break;
346 case P9_RFLUSH:
347 break;
348 case P9_RATTACH:
349 rcall->params.rattach.qid.type = buf_get_int8(bufp);
350 rcall->params.rattach.qid.version = buf_get_int32(bufp);
351 rcall->params.rattach.qid.path = buf_get_int64(bufp);
352 break;
353 case P9_RWALK:
354 rcall->params.rwalk.nwqid = buf_get_int16(bufp);
355 if (rcall->params.rwalk.nwqid > P9_MAXWELEM) {
356 P9_EPRINTK(KERN_ERR,
357 "Rwalk with more than %d qids: %d\n",
358 P9_MAXWELEM, rcall->params.rwalk.nwqid);
359 return -EPROTO;
360 }
361
362 for (i = 0; i < rcall->params.rwalk.nwqid; i++)
363 buf_get_qid(bufp, &rcall->params.rwalk.wqids[i]);
364 break;
365 case P9_ROPEN:
366 buf_get_qid(bufp, &rcall->params.ropen.qid);
367 rcall->params.ropen.iounit = buf_get_int32(bufp);
368 break;
369 case P9_RCREATE:
370 buf_get_qid(bufp, &rcall->params.rcreate.qid);
371 rcall->params.rcreate.iounit = buf_get_int32(bufp);
372 break;
373 case P9_RREAD:
374 rcall->params.rread.count = buf_get_int32(bufp);
375 rcall->params.rread.data = bufp->p;
376 buf_check_size(bufp, rcall->params.rread.count);
377 break;
378 case P9_RWRITE:
379 rcall->params.rwrite.count = buf_get_int32(bufp);
380 break;
381 case P9_RCLUNK:
382 break;
383 case P9_RREMOVE:
384 break;
385 case P9_RSTAT:
386 buf_get_int16(bufp);
387 buf_get_stat(bufp, &rcall->params.rstat.stat, dotu);
388 break;
389 case P9_RWSTAT:
390 break;
391 case P9_RERROR:
392 buf_get_str(bufp, &rcall->params.rerror.error);
393 if (dotu)
394 rcall->params.rerror.errno = buf_get_int16(bufp);
395 break;
396 }
397
398 if (buf_check_overflow(bufp)) {
399 P9_DPRINTK(P9_DEBUG_ERROR, "buffer overflow\n");
400 return -EIO;
401 }
402
403 return bufp->p - bufp->sp;
404}
405EXPORT_SYMBOL(p9_deserialize_fcall);
406
407static inline void p9_put_int8(struct cbuf *bufp, u8 val, u8 * p)
408{
409 *p = val;
410 buf_put_int8(bufp, val);
411}
412
413static inline void p9_put_int16(struct cbuf *bufp, u16 val, u16 * p)
414{
415 *p = val;
416 buf_put_int16(bufp, val);
417}
418
419static inline void p9_put_int32(struct cbuf *bufp, u32 val, u32 * p)
420{
421 *p = val;
422 buf_put_int32(bufp, val);
423}
424
425static inline void p9_put_int64(struct cbuf *bufp, u64 val, u64 * p)
426{
427 *p = val;
428 buf_put_int64(bufp, val);
429}
430
431static void
432p9_put_str(struct cbuf *bufp, char *data, struct p9_str *str)
433{
434 int len;
435 char *s;
436
437 if (data)
438 len = strlen(data);
439 else
440 len = 0;
441
442 s = buf_put_stringn(bufp, data, len);
443 if (str) {
444 str->len = len;
445 str->str = s;
446 }
447}
448
449static int
450p9_put_data(struct cbuf *bufp, const char *data, int count,
451 unsigned char **pdata)
452{
453 *pdata = buf_alloc(bufp, count);
454 if (*pdata == NULL)
455 return -ENOMEM;
456 memmove(*pdata, data, count);
457 return 0;
458}
459
460static int
461p9_put_user_data(struct cbuf *bufp, const char __user *data, int count,
462 unsigned char **pdata)
463{
464 *pdata = buf_alloc(bufp, count);
465 if (*pdata == NULL)
466 return -ENOMEM;
467 return copy_from_user(*pdata, data, count);
468}
469
470static void
471p9_put_wstat(struct cbuf *bufp, struct p9_wstat *wstat,
472 struct p9_stat *stat, int statsz, int dotu)
473{
474 p9_put_int16(bufp, statsz, &stat->size);
475 p9_put_int16(bufp, wstat->type, &stat->type);
476 p9_put_int32(bufp, wstat->dev, &stat->dev);
477 p9_put_int8(bufp, wstat->qid.type, &stat->qid.type);
478 p9_put_int32(bufp, wstat->qid.version, &stat->qid.version);
479 p9_put_int64(bufp, wstat->qid.path, &stat->qid.path);
480 p9_put_int32(bufp, wstat->mode, &stat->mode);
481 p9_put_int32(bufp, wstat->atime, &stat->atime);
482 p9_put_int32(bufp, wstat->mtime, &stat->mtime);
483 p9_put_int64(bufp, wstat->length, &stat->length);
484
485 p9_put_str(bufp, wstat->name, &stat->name);
486 p9_put_str(bufp, wstat->uid, &stat->uid);
487 p9_put_str(bufp, wstat->gid, &stat->gid);
488 p9_put_str(bufp, wstat->muid, &stat->muid);
489
490 if (dotu) {
491 p9_put_str(bufp, wstat->extension, &stat->extension);
492 p9_put_int32(bufp, wstat->n_uid, &stat->n_uid);
493 p9_put_int32(bufp, wstat->n_gid, &stat->n_gid);
494 p9_put_int32(bufp, wstat->n_muid, &stat->n_muid);
495 }
496}
497
498static struct p9_fcall *
499p9_create_common(struct cbuf *bufp, u32 size, u8 id)
500{
501 struct p9_fcall *fc;
502
503 size += 4 + 1 + 2; /* size[4] id[1] tag[2] */
504 fc = kmalloc(sizeof(struct p9_fcall) + size, GFP_KERNEL);
505 if (!fc)
506 return ERR_PTR(-ENOMEM);
507
508 fc->sdata = (char *)fc + sizeof(*fc);
509
510 buf_init(bufp, (char *)fc->sdata, size);
511 p9_put_int32(bufp, size, &fc->size);
512 p9_put_int8(bufp, id, &fc->id);
513 p9_put_int16(bufp, P9_NOTAG, &fc->tag);
514
515 return fc;
516}
517
518/**
519 * p9_set_tag - set the tag field of an &p9_fcall structure
520 * @fc: fcall structure to set tag within
521 * @tag: tag id to set
522 */
523
524void p9_set_tag(struct p9_fcall *fc, u16 tag)
525{
526 fc->tag = tag;
527 *(__le16 *) (fc->sdata + 5) = cpu_to_le16(tag);
528}
529EXPORT_SYMBOL(p9_set_tag);
530
531/**
532 * p9_create_tversion - allocates and creates a T_VERSION request
533 * @msize: requested maximum data size
534 * @version: version string to negotiate
535 *
536 */
537struct p9_fcall *p9_create_tversion(u32 msize, char *version)
538{
539 int size;
540 struct p9_fcall *fc;
541 struct cbuf buffer;
542 struct cbuf *bufp = &buffer;
543
544 size = 4 + 2 + strlen(version); /* msize[4] version[s] */
545 fc = p9_create_common(bufp, size, P9_TVERSION);
546 if (IS_ERR(fc))
547 goto error;
548
549 p9_put_int32(bufp, msize, &fc->params.tversion.msize);
550 p9_put_str(bufp, version, &fc->params.tversion.version);
551
552 if (buf_check_overflow(bufp)) {
553 kfree(fc);
554 fc = ERR_PTR(-ENOMEM);
555 }
556error:
557 return fc;
558}
559EXPORT_SYMBOL(p9_create_tversion);
560
561/**
562 * p9_create_tauth - allocates and creates a T_AUTH request
563 * @afid: handle to use for authentication protocol
564 * @uname: user name attempting to authenticate
565 * @aname: mount specifier for remote server
566 * @n_uname: numeric id for user attempting to authneticate
567 * @dotu: 9P2000.u extension flag
568 *
569 */
570
571struct p9_fcall *p9_create_tauth(u32 afid, char *uname, char *aname,
572 u32 n_uname, int dotu)
573{
574 int size;
575 struct p9_fcall *fc;
576 struct cbuf buffer;
577 struct cbuf *bufp = &buffer;
578
579 /* afid[4] uname[s] aname[s] */
580 size = 4 + 2 + 2;
581 if (uname)
582 size += strlen(uname);
583
584 if (aname)
585 size += strlen(aname);
586
587 if (dotu)
588 size += 4; /* n_uname */
589
590 fc = p9_create_common(bufp, size, P9_TAUTH);
591 if (IS_ERR(fc))
592 goto error;
593
594 p9_put_int32(bufp, afid, &fc->params.tauth.afid);
595 p9_put_str(bufp, uname, &fc->params.tauth.uname);
596 p9_put_str(bufp, aname, &fc->params.tauth.aname);
597 if (dotu)
598 p9_put_int32(bufp, n_uname, &fc->params.tauth.n_uname);
599
600 if (buf_check_overflow(bufp)) {
601 kfree(fc);
602 fc = ERR_PTR(-ENOMEM);
603 }
604error:
605 return fc;
606}
607EXPORT_SYMBOL(p9_create_tauth);
608
609/**
610 * p9_create_tattach - allocates and creates a T_ATTACH request
611 * @fid: handle to use for the new mount point
612 * @afid: handle to use for authentication protocol
613 * @uname: user name attempting to attach
614 * @aname: mount specifier for remote server
615 * @n_uname: numeric id for user attempting to attach
616 * @n_uname: numeric id for user attempting to attach
617 * @dotu: 9P2000.u extension flag
618 *
619 */
620
621struct p9_fcall *
622p9_create_tattach(u32 fid, u32 afid, char *uname, char *aname,
623 u32 n_uname, int dotu)
624{
625 int size;
626 struct p9_fcall *fc;
627 struct cbuf buffer;
628 struct cbuf *bufp = &buffer;
629
630 /* fid[4] afid[4] uname[s] aname[s] */
631 size = 4 + 4 + 2 + 2;
632 if (uname)
633 size += strlen(uname);
634
635 if (aname)
636 size += strlen(aname);
637
638 if (dotu)
639 size += 4; /* n_uname */
640
641 fc = p9_create_common(bufp, size, P9_TATTACH);
642 if (IS_ERR(fc))
643 goto error;
644
645 p9_put_int32(bufp, fid, &fc->params.tattach.fid);
646 p9_put_int32(bufp, afid, &fc->params.tattach.afid);
647 p9_put_str(bufp, uname, &fc->params.tattach.uname);
648 p9_put_str(bufp, aname, &fc->params.tattach.aname);
649 if (dotu)
650 p9_put_int32(bufp, n_uname, &fc->params.tattach.n_uname);
651
652error:
653 return fc;
654}
655EXPORT_SYMBOL(p9_create_tattach);
656
657/**
658 * p9_create_tflush - allocates and creates a T_FLUSH request
659 * @oldtag: tag id for the transaction we are attempting to cancel
660 *
661 */
662
663struct p9_fcall *p9_create_tflush(u16 oldtag)
664{
665 int size;
666 struct p9_fcall *fc;
667 struct cbuf buffer;
668 struct cbuf *bufp = &buffer;
669
670 size = 2; /* oldtag[2] */
671 fc = p9_create_common(bufp, size, P9_TFLUSH);
672 if (IS_ERR(fc))
673 goto error;
674
675 p9_put_int16(bufp, oldtag, &fc->params.tflush.oldtag);
676
677 if (buf_check_overflow(bufp)) {
678 kfree(fc);
679 fc = ERR_PTR(-ENOMEM);
680 }
681error:
682 return fc;
683}
684EXPORT_SYMBOL(p9_create_tflush);
685
686/**
687 * p9_create_twalk - allocates and creates a T_FLUSH request
688 * @fid: handle we are traversing from
689 * @newfid: a new handle for this transaction
690 * @nwname: number of path elements to traverse
691 * @wnames: array of path elements
692 *
693 */
694
695struct p9_fcall *p9_create_twalk(u32 fid, u32 newfid, u16 nwname,
696 char **wnames)
697{
698 int i, size;
699 struct p9_fcall *fc;
700 struct cbuf buffer;
701 struct cbuf *bufp = &buffer;
702
703 if (nwname > P9_MAXWELEM) {
704 P9_DPRINTK(P9_DEBUG_ERROR, "nwname > %d\n", P9_MAXWELEM);
705 return NULL;
706 }
707
708 size = 4 + 4 + 2; /* fid[4] newfid[4] nwname[2] ... */
709 for (i = 0; i < nwname; i++) {
710 size += 2 + strlen(wnames[i]); /* wname[s] */
711 }
712
713 fc = p9_create_common(bufp, size, P9_TWALK);
714 if (IS_ERR(fc))
715 goto error;
716
717 p9_put_int32(bufp, fid, &fc->params.twalk.fid);
718 p9_put_int32(bufp, newfid, &fc->params.twalk.newfid);
719 p9_put_int16(bufp, nwname, &fc->params.twalk.nwname);
720 for (i = 0; i < nwname; i++) {
721 p9_put_str(bufp, wnames[i], &fc->params.twalk.wnames[i]);
722 }
723
724 if (buf_check_overflow(bufp)) {
725 kfree(fc);
726 fc = ERR_PTR(-ENOMEM);
727 }
728error:
729 return fc;
730}
731EXPORT_SYMBOL(p9_create_twalk);
732
733/**
734 * p9_create_topen - allocates and creates a T_OPEN request
735 * @fid: handle we are trying to open
736 * @mode: what mode we are trying to open the file in
737 *
738 */
739
740struct p9_fcall *p9_create_topen(u32 fid, u8 mode)
741{
742 int size;
743 struct p9_fcall *fc;
744 struct cbuf buffer;
745 struct cbuf *bufp = &buffer;
746
747 size = 4 + 1; /* fid[4] mode[1] */
748 fc = p9_create_common(bufp, size, P9_TOPEN);
749 if (IS_ERR(fc))
750 goto error;
751
752 p9_put_int32(bufp, fid, &fc->params.topen.fid);
753 p9_put_int8(bufp, mode, &fc->params.topen.mode);
754
755 if (buf_check_overflow(bufp)) {
756 kfree(fc);
757 fc = ERR_PTR(-ENOMEM);
758 }
759error:
760 return fc;
761}
762EXPORT_SYMBOL(p9_create_topen);
763
764/**
765 * p9_create_tcreate - allocates and creates a T_CREATE request
766 * @fid: handle of directory we are trying to create in
767 * @name: name of the file we are trying to create
768 * @perm: permissions for the file we are trying to create
769 * @mode: what mode we are trying to open the file in
770 * @extension: 9p2000.u extension string (for special files)
771 * @dotu: 9p2000.u enabled flag
772 *
773 * Note: Plan 9 create semantics include opening the resulting file
774 * which is why mode is included.
775 */
776
777struct p9_fcall *p9_create_tcreate(u32 fid, char *name, u32 perm, u8 mode,
778 char *extension, int dotu)
779{
780 int size;
781 struct p9_fcall *fc;
782 struct cbuf buffer;
783 struct cbuf *bufp = &buffer;
784
785 /* fid[4] name[s] perm[4] mode[1] */
786 size = 4 + 2 + strlen(name) + 4 + 1;
787 if (dotu) {
788 size += 2 + /* extension[s] */
789 (extension == NULL ? 0 : strlen(extension));
790 }
791
792 fc = p9_create_common(bufp, size, P9_TCREATE);
793 if (IS_ERR(fc))
794 goto error;
795
796 p9_put_int32(bufp, fid, &fc->params.tcreate.fid);
797 p9_put_str(bufp, name, &fc->params.tcreate.name);
798 p9_put_int32(bufp, perm, &fc->params.tcreate.perm);
799 p9_put_int8(bufp, mode, &fc->params.tcreate.mode);
800 if (dotu)
801 p9_put_str(bufp, extension, &fc->params.tcreate.extension);
802
803 if (buf_check_overflow(bufp)) {
804 kfree(fc);
805 fc = ERR_PTR(-ENOMEM);
806 }
807error:
808 return fc;
809}
810EXPORT_SYMBOL(p9_create_tcreate);
811
812/**
813 * p9_create_tread - allocates and creates a T_READ request
814 * @fid: handle of the file we are trying to read
815 * @offset: offset to start reading from
816 * @count: how many bytes to read
817 */
818
819struct p9_fcall *p9_create_tread(u32 fid, u64 offset, u32 count)
820{
821 int size;
822 struct p9_fcall *fc;
823 struct cbuf buffer;
824 struct cbuf *bufp = &buffer;
825
826 size = 4 + 8 + 4; /* fid[4] offset[8] count[4] */
827 fc = p9_create_common(bufp, size, P9_TREAD);
828 if (IS_ERR(fc))
829 goto error;
830
831 p9_put_int32(bufp, fid, &fc->params.tread.fid);
832 p9_put_int64(bufp, offset, &fc->params.tread.offset);
833 p9_put_int32(bufp, count, &fc->params.tread.count);
834
835 if (buf_check_overflow(bufp)) {
836 kfree(fc);
837 fc = ERR_PTR(-ENOMEM);
838 }
839error:
840 return fc;
841}
842EXPORT_SYMBOL(p9_create_tread);
843
844/**
845 * p9_create_twrite - allocates and creates a T_WRITE request from the kernel
846 * @fid: handle of the file we are trying to write
847 * @offset: offset to start writing at
848 * @count: how many bytes to write
849 * @data: data to write
850 *
851 * This function will create a requst with data buffers from the kernel
852 * such as the page cache.
853 */
854
855struct p9_fcall *p9_create_twrite(u32 fid, u64 offset, u32 count,
856 const char *data)
857{
858 int size, err;
859 struct p9_fcall *fc;
860 struct cbuf buffer;
861 struct cbuf *bufp = &buffer;
862
863 /* fid[4] offset[8] count[4] data[count] */
864 size = 4 + 8 + 4 + count;
865 fc = p9_create_common(bufp, size, P9_TWRITE);
866 if (IS_ERR(fc))
867 goto error;
868
869 p9_put_int32(bufp, fid, &fc->params.twrite.fid);
870 p9_put_int64(bufp, offset, &fc->params.twrite.offset);
871 p9_put_int32(bufp, count, &fc->params.twrite.count);
872 err = p9_put_data(bufp, data, count, &fc->params.twrite.data);
873 if (err) {
874 kfree(fc);
875 fc = ERR_PTR(err);
876 goto error;
877 }
878
879 if (buf_check_overflow(bufp)) {
880 kfree(fc);
881 fc = ERR_PTR(-ENOMEM);
882 }
883error:
884 return fc;
885}
886EXPORT_SYMBOL(p9_create_twrite);
887
888/**
889 * p9_create_twrite_u - allocates and creates a T_WRITE request from userspace
890 * @fid: handle of the file we are trying to write
891 * @offset: offset to start writing at
892 * @count: how many bytes to write
893 * @data: data to write
894 *
895 * This function will create a request with data buffers from userspace
896 */
897
898struct p9_fcall *p9_create_twrite_u(u32 fid, u64 offset, u32 count,
899 const char __user *data)
900{
901 int size, err;
902 struct p9_fcall *fc;
903 struct cbuf buffer;
904 struct cbuf *bufp = &buffer;
905
906 /* fid[4] offset[8] count[4] data[count] */
907 size = 4 + 8 + 4 + count;
908 fc = p9_create_common(bufp, size, P9_TWRITE);
909 if (IS_ERR(fc))
910 goto error;
911
912 p9_put_int32(bufp, fid, &fc->params.twrite.fid);
913 p9_put_int64(bufp, offset, &fc->params.twrite.offset);
914 p9_put_int32(bufp, count, &fc->params.twrite.count);
915 err = p9_put_user_data(bufp, data, count, &fc->params.twrite.data);
916 if (err) {
917 kfree(fc);
918 fc = ERR_PTR(err);
919 goto error;
920 }
921
922 if (buf_check_overflow(bufp)) {
923 kfree(fc);
924 fc = ERR_PTR(-ENOMEM);
925 }
926error:
927 return fc;
928}
929EXPORT_SYMBOL(p9_create_twrite_u);
930
931/**
932 * p9_create_tclunk - allocate a request to forget about a file handle
933 * @fid: handle of the file we closing or forgetting about
934 *
935 * clunk is used both to close open files and to discard transient handles
936 * which may be created during meta-data operations and hierarchy traversal.
937 */
938
939struct p9_fcall *p9_create_tclunk(u32 fid)
940{
941 int size;
942 struct p9_fcall *fc;
943 struct cbuf buffer;
944 struct cbuf *bufp = &buffer;
945
946 size = 4; /* fid[4] */
947 fc = p9_create_common(bufp, size, P9_TCLUNK);
948 if (IS_ERR(fc))
949 goto error;
950
951 p9_put_int32(bufp, fid, &fc->params.tclunk.fid);
952
953 if (buf_check_overflow(bufp)) {
954 kfree(fc);
955 fc = ERR_PTR(-ENOMEM);
956 }
957error:
958 return fc;
959}
960EXPORT_SYMBOL(p9_create_tclunk);
961
962/**
963 * p9_create_tremove - allocate and create a request to remove a file
964 * @fid: handle of the file or directory we are removing
965 *
966 */
967
968struct p9_fcall *p9_create_tremove(u32 fid)
969{
970 int size;
971 struct p9_fcall *fc;
972 struct cbuf buffer;
973 struct cbuf *bufp = &buffer;
974
975 size = 4; /* fid[4] */
976 fc = p9_create_common(bufp, size, P9_TREMOVE);
977 if (IS_ERR(fc))
978 goto error;
979
980 p9_put_int32(bufp, fid, &fc->params.tremove.fid);
981
982 if (buf_check_overflow(bufp)) {
983 kfree(fc);
984 fc = ERR_PTR(-ENOMEM);
985 }
986error:
987 return fc;
988}
989EXPORT_SYMBOL(p9_create_tremove);
990
991/**
992 * p9_create_tstat - allocate and populate a request for attributes
993 * @fid: handle of the file or directory we are trying to get the attributes of
994 *
995 */
996
997struct p9_fcall *p9_create_tstat(u32 fid)
998{
999 int size;
1000 struct p9_fcall *fc;
1001 struct cbuf buffer;
1002 struct cbuf *bufp = &buffer;
1003
1004 size = 4; /* fid[4] */
1005 fc = p9_create_common(bufp, size, P9_TSTAT);
1006 if (IS_ERR(fc))
1007 goto error;
1008
1009 p9_put_int32(bufp, fid, &fc->params.tstat.fid);
1010
1011 if (buf_check_overflow(bufp)) {
1012 kfree(fc);
1013 fc = ERR_PTR(-ENOMEM);
1014 }
1015error:
1016 return fc;
1017}
1018EXPORT_SYMBOL(p9_create_tstat);
1019
1020/**
1021 * p9_create_tstat - allocate and populate a request to change attributes
1022 * @fid: handle of the file or directory we are trying to change
1023 * @wstat: &p9_stat structure with attributes we wish to set
1024 * @dotu: 9p2000.u enabled flag
1025 *
1026 */
1027
1028struct p9_fcall *p9_create_twstat(u32 fid, struct p9_wstat *wstat,
1029 int dotu)
1030{
1031 int size, statsz;
1032 struct p9_fcall *fc;
1033 struct cbuf buffer;
1034 struct cbuf *bufp = &buffer;
1035
1036 statsz = p9_size_wstat(wstat, dotu);
1037 size = 4 + 2 + 2 + statsz; /* fid[4] stat[n] */
1038 fc = p9_create_common(bufp, size, P9_TWSTAT);
1039 if (IS_ERR(fc))
1040 goto error;
1041
1042 p9_put_int32(bufp, fid, &fc->params.twstat.fid);
1043 buf_put_int16(bufp, statsz + 2);
1044 p9_put_wstat(bufp, wstat, &fc->params.twstat.stat, statsz, dotu);
1045
1046 if (buf_check_overflow(bufp)) {
1047 kfree(fc);
1048 fc = ERR_PTR(-ENOMEM);
1049 }
1050error:
1051 return fc;
1052}
1053EXPORT_SYMBOL(p9_create_twstat);
1054
diff --git a/net/9p/fcprint.c b/net/9p/fcprint.c
deleted file mode 100644
index 53dd8e28dd8a..000000000000
--- a/net/9p/fcprint.c
+++ /dev/null
@@ -1,366 +0,0 @@
1/*
2 * net/9p/fcprint.c
3 *
4 * Print 9P call.
5 *
6 * Copyright (C) 2005 by Latchesar Ionkov <lucho@ionkov.net>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2
10 * as published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to:
19 * Free Software Foundation
20 * 51 Franklin Street, Fifth Floor
21 * Boston, MA 02111-1301 USA
22 *
23 */
24#include <linux/module.h>
25#include <linux/errno.h>
26#include <linux/fs.h>
27#include <linux/idr.h>
28#include <net/9p/9p.h>
29
30#ifdef CONFIG_NET_9P_DEBUG
31
32static int
33p9_printqid(char *buf, int buflen, struct p9_qid *q)
34{
35 int n;
36 char b[10];
37
38 n = 0;
39 if (q->type & P9_QTDIR)
40 b[n++] = 'd';
41 if (q->type & P9_QTAPPEND)
42 b[n++] = 'a';
43 if (q->type & P9_QTAUTH)
44 b[n++] = 'A';
45 if (q->type & P9_QTEXCL)
46 b[n++] = 'l';
47 if (q->type & P9_QTTMP)
48 b[n++] = 't';
49 if (q->type & P9_QTSYMLINK)
50 b[n++] = 'L';
51 b[n] = '\0';
52
53 return scnprintf(buf, buflen, "(%.16llx %x %s)",
54 (long long int) q->path, q->version, b);
55}
56
57static int
58p9_printperm(char *buf, int buflen, int perm)
59{
60 int n;
61 char b[15];
62
63 n = 0;
64 if (perm & P9_DMDIR)
65 b[n++] = 'd';
66 if (perm & P9_DMAPPEND)
67 b[n++] = 'a';
68 if (perm & P9_DMAUTH)
69 b[n++] = 'A';
70 if (perm & P9_DMEXCL)
71 b[n++] = 'l';
72 if (perm & P9_DMTMP)
73 b[n++] = 't';
74 if (perm & P9_DMDEVICE)
75 b[n++] = 'D';
76 if (perm & P9_DMSOCKET)
77 b[n++] = 'S';
78 if (perm & P9_DMNAMEDPIPE)
79 b[n++] = 'P';
80 if (perm & P9_DMSYMLINK)
81 b[n++] = 'L';
82 b[n] = '\0';
83
84 return scnprintf(buf, buflen, "%s%03o", b, perm&077);
85}
86
87static int
88p9_printstat(char *buf, int buflen, struct p9_stat *st, int extended)
89{
90 int n;
91
92 n = scnprintf(buf, buflen, "'%.*s' '%.*s'", st->name.len,
93 st->name.str, st->uid.len, st->uid.str);
94 if (extended)
95 n += scnprintf(buf+n, buflen-n, "(%d)", st->n_uid);
96
97 n += scnprintf(buf+n, buflen-n, " '%.*s'", st->gid.len, st->gid.str);
98 if (extended)
99 n += scnprintf(buf+n, buflen-n, "(%d)", st->n_gid);
100
101 n += scnprintf(buf+n, buflen-n, " '%.*s'", st->muid.len, st->muid.str);
102 if (extended)
103 n += scnprintf(buf+n, buflen-n, "(%d)", st->n_muid);
104
105 n += scnprintf(buf+n, buflen-n, " q ");
106 n += p9_printqid(buf+n, buflen-n, &st->qid);
107 n += scnprintf(buf+n, buflen-n, " m ");
108 n += p9_printperm(buf+n, buflen-n, st->mode);
109 n += scnprintf(buf+n, buflen-n, " at %d mt %d l %lld",
110 st->atime, st->mtime, (long long int) st->length);
111
112 if (extended)
113 n += scnprintf(buf+n, buflen-n, " ext '%.*s'",
114 st->extension.len, st->extension.str);
115
116 return n;
117}
118
119static int
120p9_dumpdata(char *buf, int buflen, u8 *data, int datalen)
121{
122 int i, n;
123
124 i = n = 0;
125 while (i < datalen) {
126 n += scnprintf(buf + n, buflen - n, "%02x", data[i]);
127 if (i%4 == 3)
128 n += scnprintf(buf + n, buflen - n, " ");
129 if (i%32 == 31)
130 n += scnprintf(buf + n, buflen - n, "\n");
131
132 i++;
133 }
134 n += scnprintf(buf + n, buflen - n, "\n");
135
136 return n;
137}
138
139static int
140p9_printdata(char *buf, int buflen, u8 *data, int datalen)
141{
142 return p9_dumpdata(buf, buflen, data, datalen < 16?datalen:16);
143}
144
145/**
146 * p9_printfcall - decode and print a protocol structure into a buffer
147 * @buf: buffer to deposit decoded structure into
148 * @buflen: available space in buffer
149 * @fc: protocol rpc structure of type &p9_fcall
150 * @extended: whether or not session is operating with extended protocol
151 */
152
153int
154p9_printfcall(char *buf, int buflen, struct p9_fcall *fc, int extended)
155{
156 int i, ret, type, tag;
157
158 if (!fc)
159 return scnprintf(buf, buflen, "<NULL>");
160
161 type = fc->id;
162 tag = fc->tag;
163
164 ret = 0;
165 switch (type) {
166 case P9_TVERSION:
167 ret += scnprintf(buf+ret, buflen-ret,
168 "Tversion tag %u msize %u version '%.*s'", tag,
169 fc->params.tversion.msize,
170 fc->params.tversion.version.len,
171 fc->params.tversion.version.str);
172 break;
173
174 case P9_RVERSION:
175 ret += scnprintf(buf+ret, buflen-ret,
176 "Rversion tag %u msize %u version '%.*s'", tag,
177 fc->params.rversion.msize,
178 fc->params.rversion.version.len,
179 fc->params.rversion.version.str);
180 break;
181
182 case P9_TAUTH:
183 ret += scnprintf(buf+ret, buflen-ret,
184 "Tauth tag %u afid %d uname '%.*s' aname '%.*s'", tag,
185 fc->params.tauth.afid, fc->params.tauth.uname.len,
186 fc->params.tauth.uname.str, fc->params.tauth.aname.len,
187 fc->params.tauth.aname.str);
188 break;
189
190 case P9_RAUTH:
191 ret += scnprintf(buf+ret, buflen-ret, "Rauth tag %u qid ", tag);
192 p9_printqid(buf+ret, buflen-ret, &fc->params.rauth.qid);
193 break;
194
195 case P9_TATTACH:
196 ret += scnprintf(buf+ret, buflen-ret,
197 "Tattach tag %u fid %d afid %d uname '%.*s' aname '%.*s'", tag,
198 fc->params.tattach.fid, fc->params.tattach.afid,
199 fc->params.tattach.uname.len, fc->params.tattach.uname.str,
200 fc->params.tattach.aname.len, fc->params.tattach.aname.str);
201 break;
202
203 case P9_RATTACH:
204 ret += scnprintf(buf+ret, buflen-ret, "Rattach tag %u qid ",
205 tag);
206 p9_printqid(buf+ret, buflen-ret, &fc->params.rattach.qid);
207 break;
208
209 case P9_RERROR:
210 ret += scnprintf(buf+ret, buflen-ret,
211 "Rerror tag %u ename '%.*s'", tag,
212 fc->params.rerror.error.len,
213 fc->params.rerror.error.str);
214 if (extended)
215 ret += scnprintf(buf+ret, buflen-ret, " ecode %d\n",
216 fc->params.rerror.errno);
217 break;
218
219 case P9_TFLUSH:
220 ret += scnprintf(buf+ret, buflen-ret, "Tflush tag %u oldtag %u",
221 tag, fc->params.tflush.oldtag);
222 break;
223
224 case P9_RFLUSH:
225 ret += scnprintf(buf+ret, buflen-ret, "Rflush tag %u", tag);
226 break;
227
228 case P9_TWALK:
229 ret += scnprintf(buf+ret, buflen-ret,
230 "Twalk tag %u fid %d newfid %d nwname %d", tag,
231 fc->params.twalk.fid, fc->params.twalk.newfid,
232 fc->params.twalk.nwname);
233 for (i = 0; i < fc->params.twalk.nwname; i++)
234 ret += scnprintf(buf+ret, buflen-ret, " '%.*s'",
235 fc->params.twalk.wnames[i].len,
236 fc->params.twalk.wnames[i].str);
237 break;
238
239 case P9_RWALK:
240 ret += scnprintf(buf+ret, buflen-ret, "Rwalk tag %u nwqid %d",
241 tag, fc->params.rwalk.nwqid);
242 for (i = 0; i < fc->params.rwalk.nwqid; i++)
243 ret += p9_printqid(buf+ret, buflen-ret,
244 &fc->params.rwalk.wqids[i]);
245 break;
246
247 case P9_TOPEN:
248 ret += scnprintf(buf+ret, buflen-ret,
249 "Topen tag %u fid %d mode %d", tag,
250 fc->params.topen.fid, fc->params.topen.mode);
251 break;
252
253 case P9_ROPEN:
254 ret += scnprintf(buf+ret, buflen-ret, "Ropen tag %u", tag);
255 ret += p9_printqid(buf+ret, buflen-ret, &fc->params.ropen.qid);
256 ret += scnprintf(buf+ret, buflen-ret, " iounit %d",
257 fc->params.ropen.iounit);
258 break;
259
260 case P9_TCREATE:
261 ret += scnprintf(buf+ret, buflen-ret,
262 "Tcreate tag %u fid %d name '%.*s' perm ", tag,
263 fc->params.tcreate.fid, fc->params.tcreate.name.len,
264 fc->params.tcreate.name.str);
265
266 ret += p9_printperm(buf+ret, buflen-ret,
267 fc->params.tcreate.perm);
268 ret += scnprintf(buf+ret, buflen-ret, " mode %d",
269 fc->params.tcreate.mode);
270 break;
271
272 case P9_RCREATE:
273 ret += scnprintf(buf+ret, buflen-ret, "Rcreate tag %u", tag);
274 ret += p9_printqid(buf+ret, buflen-ret,
275 &fc->params.rcreate.qid);
276 ret += scnprintf(buf+ret, buflen-ret, " iounit %d",
277 fc->params.rcreate.iounit);
278 break;
279
280 case P9_TREAD:
281 ret += scnprintf(buf+ret, buflen-ret,
282 "Tread tag %u fid %d offset %lld count %u", tag,
283 fc->params.tread.fid,
284 (long long int) fc->params.tread.offset,
285 fc->params.tread.count);
286 break;
287
288 case P9_RREAD:
289 ret += scnprintf(buf+ret, buflen-ret,
290 "Rread tag %u count %u data ", tag,
291 fc->params.rread.count);
292 ret += p9_printdata(buf+ret, buflen-ret, fc->params.rread.data,
293 fc->params.rread.count);
294 break;
295
296 case P9_TWRITE:
297 ret += scnprintf(buf+ret, buflen-ret,
298 "Twrite tag %u fid %d offset %lld count %u data ",
299 tag, fc->params.twrite.fid,
300 (long long int) fc->params.twrite.offset,
301 fc->params.twrite.count);
302 ret += p9_printdata(buf+ret, buflen-ret, fc->params.twrite.data,
303 fc->params.twrite.count);
304 break;
305
306 case P9_RWRITE:
307 ret += scnprintf(buf+ret, buflen-ret, "Rwrite tag %u count %u",
308 tag, fc->params.rwrite.count);
309 break;
310
311 case P9_TCLUNK:
312 ret += scnprintf(buf+ret, buflen-ret, "Tclunk tag %u fid %d",
313 tag, fc->params.tclunk.fid);
314 break;
315
316 case P9_RCLUNK:
317 ret += scnprintf(buf+ret, buflen-ret, "Rclunk tag %u", tag);
318 break;
319
320 case P9_TREMOVE:
321 ret += scnprintf(buf+ret, buflen-ret, "Tremove tag %u fid %d",
322 tag, fc->params.tremove.fid);
323 break;
324
325 case P9_RREMOVE:
326 ret += scnprintf(buf+ret, buflen-ret, "Rremove tag %u", tag);
327 break;
328
329 case P9_TSTAT:
330 ret += scnprintf(buf+ret, buflen-ret, "Tstat tag %u fid %d",
331 tag, fc->params.tstat.fid);
332 break;
333
334 case P9_RSTAT:
335 ret += scnprintf(buf+ret, buflen-ret, "Rstat tag %u ", tag);
336 ret += p9_printstat(buf+ret, buflen-ret, &fc->params.rstat.stat,
337 extended);
338 break;
339
340 case P9_TWSTAT:
341 ret += scnprintf(buf+ret, buflen-ret, "Twstat tag %u fid %d ",
342 tag, fc->params.twstat.fid);
343 ret += p9_printstat(buf+ret, buflen-ret,
344 &fc->params.twstat.stat, extended);
345 break;
346
347 case P9_RWSTAT:
348 ret += scnprintf(buf+ret, buflen-ret, "Rwstat tag %u", tag);
349 break;
350
351 default:
352 ret += scnprintf(buf+ret, buflen-ret, "unknown type %d", type);
353 break;
354 }
355
356 return ret;
357}
358#else
359int
360p9_printfcall(char *buf, int buflen, struct p9_fcall *fc, int extended)
361{
362 return 0;
363}
364#endif /* CONFIG_NET_9P_DEBUG */
365EXPORT_SYMBOL(p9_printfcall);
366
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/protocol.c b/net/9p/protocol.c
new file mode 100644
index 000000000000..dcd7666824ba
--- /dev/null
+++ b/net/9p/protocol.c
@@ -0,0 +1,567 @@
1/*
2 * net/9p/protocol.c
3 *
4 * 9P Protocol Support Code
5 *
6 * Copyright (C) 2008 by Eric Van Hensbergen <ericvh@gmail.com>
7 *
8 * Base on code from Anthony Liguori <aliguori@us.ibm.com>
9 * Copyright (C) 2008 by IBM, Corp.
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2
13 * as published by the Free Software Foundation.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to:
22 * Free Software Foundation
23 * 51 Franklin Street, Fifth Floor
24 * Boston, MA 02111-1301 USA
25 *
26 */
27
28#include <linux/module.h>
29#include <linux/errno.h>
30#include <linux/uaccess.h>
31#include <linux/sched.h>
32#include <net/9p/9p.h>
33#include <net/9p/client.h>
34#include "protocol.h"
35
36#ifndef MIN
37#define MIN(a, b) (((a) < (b)) ? (a) : (b))
38#endif
39
40#ifndef MAX
41#define MAX(a, b) (((a) > (b)) ? (a) : (b))
42#endif
43
44#ifndef offset_of
45#define offset_of(type, memb) \
46 ((unsigned long)(&((type *)0)->memb))
47#endif
48#ifndef container_of
49#define container_of(obj, type, memb) \
50 ((type *)(((char *)obj) - offset_of(type, memb)))
51#endif
52
53static int
54p9pdu_writef(struct p9_fcall *pdu, int optional, const char *fmt, ...);
55
56#ifdef CONFIG_NET_9P_DEBUG
57void
58p9pdu_dump(int way, struct p9_fcall *pdu)
59{
60 int i, n;
61 u8 *data = pdu->sdata;
62 int datalen = pdu->size;
63 char buf[255];
64 int buflen = 255;
65
66 i = n = 0;
67 if (datalen > (buflen-16))
68 datalen = buflen-16;
69 while (i < datalen) {
70 n += scnprintf(buf + n, buflen - n, "%02x ", data[i]);
71 if (i%4 == 3)
72 n += scnprintf(buf + n, buflen - n, " ");
73 if (i%32 == 31)
74 n += scnprintf(buf + n, buflen - n, "\n");
75
76 i++;
77 }
78 n += scnprintf(buf + n, buflen - n, "\n");
79
80 if (way)
81 P9_DPRINTK(P9_DEBUG_PKT, "[[[(%d) %s\n", datalen, buf);
82 else
83 P9_DPRINTK(P9_DEBUG_PKT, "]]](%d) %s\n", datalen, buf);
84}
85#else
86void
87p9pdu_dump(int way, struct p9_fcall *pdu)
88{
89}
90#endif
91EXPORT_SYMBOL(p9pdu_dump);
92
93void p9stat_free(struct p9_wstat *stbuf)
94{
95 kfree(stbuf->name);
96 kfree(stbuf->uid);
97 kfree(stbuf->gid);
98 kfree(stbuf->muid);
99 kfree(stbuf->extension);
100}
101EXPORT_SYMBOL(p9stat_free);
102
103static size_t pdu_read(struct p9_fcall *pdu, void *data, size_t size)
104{
105 size_t len = MIN(pdu->size - pdu->offset, size);
106 memcpy(data, &pdu->sdata[pdu->offset], len);
107 pdu->offset += len;
108 return size - len;
109}
110
111static size_t pdu_write(struct p9_fcall *pdu, const void *data, size_t size)
112{
113 size_t len = MIN(pdu->capacity - pdu->size, size);
114 memcpy(&pdu->sdata[pdu->size], data, len);
115 pdu->size += len;
116 return size - len;
117}
118
119static size_t
120pdu_write_u(struct p9_fcall *pdu, const char __user *udata, size_t size)
121{
122 size_t len = MIN(pdu->capacity - pdu->size, size);
123 int err = copy_from_user(&pdu->sdata[pdu->size], udata, len);
124 if (err)
125 printk(KERN_WARNING "pdu_write_u returning: %d\n", err);
126
127 pdu->size += len;
128 return size - len;
129}
130
131/*
132 b - int8_t
133 w - int16_t
134 d - int32_t
135 q - int64_t
136 s - string
137 S - stat
138 Q - qid
139 D - data blob (int32_t size followed by void *, results are not freed)
140 T - array of strings (int16_t count, followed by strings)
141 R - array of qids (int16_t count, followed by qids)
142 ? - if optional = 1, continue parsing
143*/
144
145static int
146p9pdu_vreadf(struct p9_fcall *pdu, int optional, const char *fmt, va_list ap)
147{
148 const char *ptr;
149 int errcode = 0;
150
151 for (ptr = fmt; *ptr; ptr++) {
152 switch (*ptr) {
153 case 'b':{
154 int8_t *val = va_arg(ap, int8_t *);
155 if (pdu_read(pdu, val, sizeof(*val))) {
156 errcode = -EFAULT;
157 break;
158 }
159 }
160 break;
161 case 'w':{
162 int16_t *val = va_arg(ap, int16_t *);
163 if (pdu_read(pdu, val, sizeof(*val))) {
164 errcode = -EFAULT;
165 break;
166 }
167 *val = cpu_to_le16(*val);
168 }
169 break;
170 case 'd':{
171 int32_t *val = va_arg(ap, int32_t *);
172 if (pdu_read(pdu, val, sizeof(*val))) {
173 errcode = -EFAULT;
174 break;
175 }
176 *val = cpu_to_le32(*val);
177 }
178 break;
179 case 'q':{
180 int64_t *val = va_arg(ap, int64_t *);
181 if (pdu_read(pdu, val, sizeof(*val))) {
182 errcode = -EFAULT;
183 break;
184 }
185 *val = cpu_to_le64(*val);
186 }
187 break;
188 case 's':{
189 char **sptr = va_arg(ap, char **);
190 int16_t len;
191 int size;
192
193 errcode = p9pdu_readf(pdu, optional, "w", &len);
194 if (errcode)
195 break;
196
197 size = MAX(len, 0);
198
199 *sptr = kmalloc(size + 1, GFP_KERNEL);
200 if (*sptr == NULL) {
201 errcode = -EFAULT;
202 break;
203 }
204 if (pdu_read(pdu, *sptr, size)) {
205 errcode = -EFAULT;
206 kfree(*sptr);
207 *sptr = NULL;
208 } else
209 (*sptr)[size] = 0;
210 }
211 break;
212 case 'Q':{
213 struct p9_qid *qid =
214 va_arg(ap, struct p9_qid *);
215
216 errcode = p9pdu_readf(pdu, optional, "bdq",
217 &qid->type, &qid->version,
218 &qid->path);
219 }
220 break;
221 case 'S':{
222 struct p9_wstat *stbuf =
223 va_arg(ap, struct p9_wstat *);
224
225 memset(stbuf, 0, sizeof(struct p9_wstat));
226 stbuf->n_uid = stbuf->n_gid = stbuf->n_muid =
227 -1;
228 errcode =
229 p9pdu_readf(pdu, optional,
230 "wwdQdddqssss?sddd",
231 &stbuf->size, &stbuf->type,
232 &stbuf->dev, &stbuf->qid,
233 &stbuf->mode, &stbuf->atime,
234 &stbuf->mtime, &stbuf->length,
235 &stbuf->name, &stbuf->uid,
236 &stbuf->gid, &stbuf->muid,
237 &stbuf->extension,
238 &stbuf->n_uid, &stbuf->n_gid,
239 &stbuf->n_muid);
240 if (errcode)
241 p9stat_free(stbuf);
242 }
243 break;
244 case 'D':{
245 int32_t *count = va_arg(ap, int32_t *);
246 void **data = va_arg(ap, void **);
247
248 errcode =
249 p9pdu_readf(pdu, optional, "d", count);
250 if (!errcode) {
251 *count =
252 MIN(*count,
253 pdu->size - pdu->offset);
254 *data = &pdu->sdata[pdu->offset];
255 }
256 }
257 break;
258 case 'T':{
259 int16_t *nwname = va_arg(ap, int16_t *);
260 char ***wnames = va_arg(ap, char ***);
261
262 errcode =
263 p9pdu_readf(pdu, optional, "w", nwname);
264 if (!errcode) {
265 *wnames =
266 kmalloc(sizeof(char *) * *nwname,
267 GFP_KERNEL);
268 if (!*wnames)
269 errcode = -ENOMEM;
270 }
271
272 if (!errcode) {
273 int i;
274
275 for (i = 0; i < *nwname; i++) {
276 errcode =
277 p9pdu_readf(pdu, optional,
278 "s",
279 &(*wnames)[i]);
280 if (errcode)
281 break;
282 }
283 }
284
285 if (errcode) {
286 if (*wnames) {
287 int i;
288
289 for (i = 0; i < *nwname; i++)
290 kfree((*wnames)[i]);
291 }
292 kfree(*wnames);
293 *wnames = NULL;
294 }
295 }
296 break;
297 case 'R':{
298 int16_t *nwqid = va_arg(ap, int16_t *);
299 struct p9_qid **wqids =
300 va_arg(ap, struct p9_qid **);
301
302 *wqids = NULL;
303
304 errcode =
305 p9pdu_readf(pdu, optional, "w", nwqid);
306 if (!errcode) {
307 *wqids =
308 kmalloc(*nwqid *
309 sizeof(struct p9_qid),
310 GFP_KERNEL);
311 if (*wqids == NULL)
312 errcode = -ENOMEM;
313 }
314
315 if (!errcode) {
316 int i;
317
318 for (i = 0; i < *nwqid; i++) {
319 errcode =
320 p9pdu_readf(pdu, optional,
321 "Q",
322 &(*wqids)[i]);
323 if (errcode)
324 break;
325 }
326 }
327
328 if (errcode) {
329 kfree(*wqids);
330 *wqids = NULL;
331 }
332 }
333 break;
334 case '?':
335 if (!optional)
336 return 0;
337 break;
338 default:
339 BUG();
340 break;
341 }
342
343 if (errcode)
344 break;
345 }
346
347 return errcode;
348}
349
350int
351p9pdu_vwritef(struct p9_fcall *pdu, int optional, const char *fmt, va_list ap)
352{
353 const char *ptr;
354 int errcode = 0;
355
356 for (ptr = fmt; *ptr; ptr++) {
357 switch (*ptr) {
358 case 'b':{
359 int8_t val = va_arg(ap, int);
360 if (pdu_write(pdu, &val, sizeof(val)))
361 errcode = -EFAULT;
362 }
363 break;
364 case 'w':{
365 int16_t val = va_arg(ap, int);
366 if (pdu_write(pdu, &val, sizeof(val)))
367 errcode = -EFAULT;
368 }
369 break;
370 case 'd':{
371 int32_t val = va_arg(ap, int32_t);
372 if (pdu_write(pdu, &val, sizeof(val)))
373 errcode = -EFAULT;
374 }
375 break;
376 case 'q':{
377 int64_t val = va_arg(ap, int64_t);
378 if (pdu_write(pdu, &val, sizeof(val)))
379 errcode = -EFAULT;
380 }
381 break;
382 case 's':{
383 const char *sptr = va_arg(ap, const char *);
384 int16_t len = 0;
385 if (sptr)
386 len = MIN(strlen(sptr), USHORT_MAX);
387
388 errcode = p9pdu_writef(pdu, optional, "w", len);
389 if (!errcode && pdu_write(pdu, sptr, len))
390 errcode = -EFAULT;
391 }
392 break;
393 case 'Q':{
394 const struct p9_qid *qid =
395 va_arg(ap, const struct p9_qid *);
396 errcode =
397 p9pdu_writef(pdu, optional, "bdq",
398 qid->type, qid->version,
399 qid->path);
400 } break;
401 case 'S':{
402 const struct p9_wstat *stbuf =
403 va_arg(ap, const struct p9_wstat *);
404 errcode =
405 p9pdu_writef(pdu, optional,
406 "wwdQdddqssss?sddd",
407 stbuf->size, stbuf->type,
408 stbuf->dev, &stbuf->qid,
409 stbuf->mode, stbuf->atime,
410 stbuf->mtime, stbuf->length,
411 stbuf->name, stbuf->uid,
412 stbuf->gid, stbuf->muid,
413 stbuf->extension, stbuf->n_uid,
414 stbuf->n_gid, stbuf->n_muid);
415 } break;
416 case 'D':{
417 int32_t count = va_arg(ap, int32_t);
418 const void *data = va_arg(ap, const void *);
419
420 errcode =
421 p9pdu_writef(pdu, optional, "d", count);
422 if (!errcode && pdu_write(pdu, data, count))
423 errcode = -EFAULT;
424 }
425 break;
426 case 'U':{
427 int32_t count = va_arg(ap, int32_t);
428 const char __user *udata =
429 va_arg(ap, const void __user *);
430 errcode =
431 p9pdu_writef(pdu, optional, "d", count);
432 if (!errcode && pdu_write_u(pdu, udata, count))
433 errcode = -EFAULT;
434 }
435 break;
436 case 'T':{
437 int16_t nwname = va_arg(ap, int);
438 const char **wnames = va_arg(ap, const char **);
439
440 errcode =
441 p9pdu_writef(pdu, optional, "w", nwname);
442 if (!errcode) {
443 int i;
444
445 for (i = 0; i < nwname; i++) {
446 errcode =
447 p9pdu_writef(pdu, optional,
448 "s",
449 wnames[i]);
450 if (errcode)
451 break;
452 }
453 }
454 }
455 break;
456 case 'R':{
457 int16_t nwqid = va_arg(ap, int);
458 struct p9_qid *wqids =
459 va_arg(ap, struct p9_qid *);
460
461 errcode =
462 p9pdu_writef(pdu, optional, "w", nwqid);
463 if (!errcode) {
464 int i;
465
466 for (i = 0; i < nwqid; i++) {
467 errcode =
468 p9pdu_writef(pdu, optional,
469 "Q",
470 &wqids[i]);
471 if (errcode)
472 break;
473 }
474 }
475 }
476 break;
477 case '?':
478 if (!optional)
479 return 0;
480 break;
481 default:
482 BUG();
483 break;
484 }
485
486 if (errcode)
487 break;
488 }
489
490 return errcode;
491}
492
493int p9pdu_readf(struct p9_fcall *pdu, int optional, const char *fmt, ...)
494{
495 va_list ap;
496 int ret;
497
498 va_start(ap, fmt);
499 ret = p9pdu_vreadf(pdu, optional, fmt, ap);
500 va_end(ap);
501
502 return ret;
503}
504
505static int
506p9pdu_writef(struct p9_fcall *pdu, int optional, const char *fmt, ...)
507{
508 va_list ap;
509 int ret;
510
511 va_start(ap, fmt);
512 ret = p9pdu_vwritef(pdu, optional, fmt, ap);
513 va_end(ap);
514
515 return ret;
516}
517
518int p9stat_read(char *buf, int len, struct p9_wstat *st, int dotu)
519{
520 struct p9_fcall fake_pdu;
521 int ret;
522
523 fake_pdu.size = len;
524 fake_pdu.capacity = len;
525 fake_pdu.sdata = buf;
526 fake_pdu.offset = 0;
527
528 ret = p9pdu_readf(&fake_pdu, dotu, "S", st);
529 if (ret) {
530 P9_DPRINTK(P9_DEBUG_9P, "<<< p9stat_read failed: %d\n", ret);
531 p9pdu_dump(1, &fake_pdu);
532 }
533
534 return ret;
535}
536EXPORT_SYMBOL(p9stat_read);
537
538int p9pdu_prepare(struct p9_fcall *pdu, int16_t tag, int8_t type)
539{
540 return p9pdu_writef(pdu, 0, "dbw", 0, type, tag);
541}
542
543int p9pdu_finalize(struct p9_fcall *pdu)
544{
545 int size = pdu->size;
546 int err;
547
548 pdu->size = 0;
549 err = p9pdu_writef(pdu, 0, "d", size);
550 pdu->size = size;
551
552#ifdef CONFIG_NET_9P_DEBUG
553 if ((p9_debug_level & P9_DEBUG_PKT) == P9_DEBUG_PKT)
554 p9pdu_dump(0, pdu);
555#endif
556
557 P9_DPRINTK(P9_DEBUG_9P, ">>> size=%d type: %d tag: %d\n", pdu->size,
558 pdu->id, pdu->tag);
559
560 return err;
561}
562
563void p9pdu_reset(struct p9_fcall *pdu)
564{
565 pdu->offset = 0;
566 pdu->size = 0;
567}
diff --git a/net/9p/protocol.h b/net/9p/protocol.h
new file mode 100644
index 000000000000..ccde462e7ac5
--- /dev/null
+++ b/net/9p/protocol.h
@@ -0,0 +1,34 @@
1/*
2 * net/9p/protocol.h
3 *
4 * 9P Protocol Support Code
5 *
6 * Copyright (C) 2008 by Eric Van Hensbergen <ericvh@gmail.com>
7 *
8 * Base on code from Anthony Liguori <aliguori@us.ibm.com>
9 * Copyright (C) 2008 by IBM, Corp.
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2
13 * as published by the Free Software Foundation.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to:
22 * Free Software Foundation
23 * 51 Franklin Street, Fifth Floor
24 * Boston, MA 02111-1301 USA
25 *
26 */
27
28int
29p9pdu_vwritef(struct p9_fcall *pdu, int optional, const char *fmt, va_list ap);
30int p9pdu_readf(struct p9_fcall *pdu, int optional, const char *fmt, ...);
31int p9pdu_prepare(struct p9_fcall *pdu, int16_t tag, int8_t type);
32int p9pdu_finalize(struct p9_fcall *pdu);
33void p9pdu_dump(int, struct p9_fcall *);
34void p9pdu_reset(struct p9_fcall *pdu);
diff --git a/net/9p/trans_fd.c b/net/9p/trans_fd.c
index 6dabbdb66651..1df0356f242b 100644
--- a/net/9p/trans_fd.c
+++ b/net/9p/trans_fd.c
@@ -39,12 +39,11 @@
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
45#define MAX_SOCK_BUF (64*1024) 46#define MAX_SOCK_BUF (64*1024)
46#define ERREQFLUSH 1
47#define SCHED_TIMEOUT 10
48#define MAXPOLLWADDR 2 47#define MAXPOLLWADDR 2
49 48
50/** 49/**
@@ -61,7 +60,6 @@ struct p9_fd_opts {
61 u16 port; 60 u16 port;
62}; 61};
63 62
64
65/** 63/**
66 * struct p9_trans_fd - transport state 64 * struct p9_trans_fd - transport state
67 * @rd: reference to file to read from 65 * @rd: reference to file to read from
@@ -100,60 +98,22 @@ enum {
100 Wpending = 8, /* can write */ 98 Wpending = 8, /* can write */
101}; 99};
102 100
103enum { 101struct p9_poll_wait {
104 None, 102 struct p9_conn *conn;
105 Flushing, 103 wait_queue_t wait;
106 Flushed, 104 wait_queue_head_t *wait_addr;
107};
108
109struct p9_req;
110typedef void (*p9_conn_req_callback)(struct p9_req *req, void *a);
111
112/**
113 * struct p9_req - fd mux encoding of an rpc transaction
114 * @lock: protects req_list
115 * @tag: numeric tag for rpc transaction
116 * @tcall: request &p9_fcall structure
117 * @rcall: response &p9_fcall structure
118 * @err: error state
119 * @cb: callback for when response is received
120 * @cba: argument to pass to callback
121 * @flush: flag to indicate RPC has been flushed
122 * @req_list: list link for higher level objects to chain requests
123 *
124 */
125
126struct p9_req {
127 spinlock_t lock;
128 int tag;
129 struct p9_fcall *tcall;
130 struct p9_fcall *rcall;
131 int err;
132 p9_conn_req_callback cb;
133 void *cba;
134 int flush;
135 struct list_head req_list;
136};
137
138struct p9_mux_poll_task {
139 struct task_struct *task;
140 struct list_head mux_list;
141 int muxnum;
142}; 105};
143 106
144/** 107/**
145 * struct p9_conn - fd mux connection state information 108 * struct p9_conn - fd mux connection state information
146 * @lock: protects mux_list (?)
147 * @mux_list: list link for mux to manage multiple connections (?) 109 * @mux_list: list link for mux to manage multiple connections (?)
148 * @poll_task: task polling on this connection 110 * @client: reference to client instance for this connection
149 * @msize: maximum size for connection (dup)
150 * @extended: 9p2000.u flag (dup)
151 * @trans: reference to transport instance for this connection
152 * @tagpool: id accounting for transactions
153 * @err: error state 111 * @err: error state
154 * @req_list: accounting for requests which have been sent 112 * @req_list: accounting for requests which have been sent
155 * @unsent_req_list: accounting for requests that haven't been sent 113 * @unsent_req_list: accounting for requests that haven't been sent
156 * @rcall: current response &p9_fcall structure 114 * @req: current request being processed (if any)
115 * @tmp_buf: temporary buffer to read in header
116 * @rsize: amount to read for current frame
157 * @rpos: read position in current frame 117 * @rpos: read position in current frame
158 * @rbuf: current read buffer 118 * @rbuf: current read buffer
159 * @wpos: write position for current frame 119 * @wpos: write position for current frame
@@ -169,409 +129,300 @@ struct p9_mux_poll_task {
169 */ 129 */
170 130
171struct p9_conn { 131struct p9_conn {
172 spinlock_t lock; /* protect lock structure */
173 struct list_head mux_list; 132 struct list_head mux_list;
174 struct p9_mux_poll_task *poll_task; 133 struct p9_client *client;
175 int msize;
176 unsigned char extended;
177 struct p9_trans *trans;
178 struct p9_idpool *tagpool;
179 int err; 134 int err;
180 struct list_head req_list; 135 struct list_head req_list;
181 struct list_head unsent_req_list; 136 struct list_head unsent_req_list;
182 struct p9_fcall *rcall; 137 struct p9_req_t *req;
138 char tmp_buf[7];
139 int rsize;
183 int rpos; 140 int rpos;
184 char *rbuf; 141 char *rbuf;
185 int wpos; 142 int wpos;
186 int wsize; 143 int wsize;
187 char *wbuf; 144 char *wbuf;
188 wait_queue_t poll_wait[MAXPOLLWADDR]; 145 struct list_head poll_pending_link;
189 wait_queue_head_t *poll_waddr[MAXPOLLWADDR]; 146 struct p9_poll_wait poll_wait[MAXPOLLWADDR];
190 poll_table pt; 147 poll_table pt;
191 struct work_struct rq; 148 struct work_struct rq;
192 struct work_struct wq; 149 struct work_struct wq;
193 unsigned long wsched; 150 unsigned long wsched;
194}; 151};
195 152
196/** 153static DEFINE_SPINLOCK(p9_poll_lock);
197 * struct p9_mux_rpc - fd mux rpc accounting structure 154static LIST_HEAD(p9_poll_pending_list);
198 * @m: connection this request was issued on
199 * @err: error state
200 * @tcall: request &p9_fcall
201 * @rcall: response &p9_fcall
202 * @wqueue: wait queue that client is blocked on for this rpc
203 *
204 * Bug: isn't this information duplicated elsewhere like &p9_req
205 */
206
207struct p9_mux_rpc {
208 struct p9_conn *m;
209 int err;
210 struct p9_fcall *tcall;
211 struct p9_fcall *rcall;
212 wait_queue_head_t wqueue;
213};
214
215static int p9_poll_proc(void *);
216static void p9_read_work(struct work_struct *work);
217static void p9_write_work(struct work_struct *work);
218static void p9_pollwait(struct file *filp, wait_queue_head_t *wait_address,
219 poll_table *p);
220static int p9_fd_write(struct p9_trans *trans, void *v, int len);
221static int p9_fd_read(struct p9_trans *trans, void *v, int len);
222
223static DEFINE_MUTEX(p9_mux_task_lock);
224static struct workqueue_struct *p9_mux_wq; 155static struct workqueue_struct *p9_mux_wq;
156static struct task_struct *p9_poll_task;
225 157
226static int p9_mux_num; 158static void p9_mux_poll_stop(struct p9_conn *m)
227static int p9_mux_poll_task_num;
228static struct p9_mux_poll_task p9_mux_poll_tasks[100];
229
230static void p9_conn_destroy(struct p9_conn *);
231static unsigned int p9_fd_poll(struct p9_trans *trans,
232 struct poll_table_struct *pt);
233
234#ifdef P9_NONBLOCK
235static int p9_conn_rpcnb(struct p9_conn *m, struct p9_fcall *tc,
236 p9_conn_req_callback cb, void *a);
237#endif /* P9_NONBLOCK */
238
239static void p9_conn_cancel(struct p9_conn *m, int err);
240
241static u16 p9_mux_get_tag(struct p9_conn *m)
242{ 159{
243 int tag; 160 unsigned long flags;
161 int i;
244 162
245 tag = p9_idpool_get(m->tagpool); 163 for (i = 0; i < ARRAY_SIZE(m->poll_wait); i++) {
246 if (tag < 0) 164 struct p9_poll_wait *pwait = &m->poll_wait[i];
247 return P9_NOTAG;
248 else
249 return (u16) tag;
250}
251 165
252static void p9_mux_put_tag(struct p9_conn *m, u16 tag) 166 if (pwait->wait_addr) {
253{ 167 remove_wait_queue(pwait->wait_addr, &pwait->wait);
254 if (tag != P9_NOTAG && p9_idpool_check(tag, m->tagpool)) 168 pwait->wait_addr = NULL;
255 p9_idpool_put(tag, m->tagpool); 169 }
170 }
171
172 spin_lock_irqsave(&p9_poll_lock, flags);
173 list_del_init(&m->poll_pending_link);
174 spin_unlock_irqrestore(&p9_poll_lock, flags);
256} 175}
257 176
258/** 177/**
259 * p9_mux_calc_poll_procs - calculates the number of polling procs 178 * p9_conn_cancel - cancel all pending requests with error
260 * @muxnum: number of mounts 179 * @m: mux data
180 * @err: error code
261 * 181 *
262 * Calculation is based on the number of mounted v9fs filesystems.
263 * The current implementation returns sqrt of the number of mounts.
264 */ 182 */
265 183
266static int p9_mux_calc_poll_procs(int muxnum) 184static void p9_conn_cancel(struct p9_conn *m, int err)
267{ 185{
268 int n; 186 struct p9_req_t *req, *rtmp;
269 187 unsigned long flags;
270 if (p9_mux_poll_task_num) 188 LIST_HEAD(cancel_list);
271 n = muxnum / p9_mux_poll_task_num +
272 (muxnum % p9_mux_poll_task_num ? 1 : 0);
273 else
274 n = 1;
275
276 if (n > ARRAY_SIZE(p9_mux_poll_tasks))
277 n = ARRAY_SIZE(p9_mux_poll_tasks);
278
279 return n;
280}
281 189
282static int p9_mux_poll_start(struct p9_conn *m) 190 P9_DPRINTK(P9_DEBUG_ERROR, "mux %p err %d\n", m, err);
283{
284 int i, n;
285 struct p9_mux_poll_task *vpt, *vptlast;
286 struct task_struct *pproc;
287
288 P9_DPRINTK(P9_DEBUG_MUX, "mux %p muxnum %d procnum %d\n", m, p9_mux_num,
289 p9_mux_poll_task_num);
290 mutex_lock(&p9_mux_task_lock);
291
292 n = p9_mux_calc_poll_procs(p9_mux_num + 1);
293 if (n > p9_mux_poll_task_num) {
294 for (i = 0; i < ARRAY_SIZE(p9_mux_poll_tasks); i++) {
295 if (p9_mux_poll_tasks[i].task == NULL) {
296 vpt = &p9_mux_poll_tasks[i];
297 P9_DPRINTK(P9_DEBUG_MUX, "create proc %p\n",
298 vpt);
299 pproc = kthread_create(p9_poll_proc, vpt,
300 "v9fs-poll");
301
302 if (!IS_ERR(pproc)) {
303 vpt->task = pproc;
304 INIT_LIST_HEAD(&vpt->mux_list);
305 vpt->muxnum = 0;
306 p9_mux_poll_task_num++;
307 wake_up_process(vpt->task);
308 }
309 break;
310 }
311 }
312 191
313 if (i >= ARRAY_SIZE(p9_mux_poll_tasks)) 192 spin_lock_irqsave(&m->client->lock, flags);
314 P9_DPRINTK(P9_DEBUG_ERROR,
315 "warning: no free poll slots\n");
316 }
317 193
318 n = (p9_mux_num + 1) / p9_mux_poll_task_num + 194 if (m->err) {
319 ((p9_mux_num + 1) % p9_mux_poll_task_num ? 1 : 0); 195 spin_unlock_irqrestore(&m->client->lock, flags);
320 196 return;
321 vptlast = NULL;
322 for (i = 0; i < ARRAY_SIZE(p9_mux_poll_tasks); i++) {
323 vpt = &p9_mux_poll_tasks[i];
324 if (vpt->task != NULL) {
325 vptlast = vpt;
326 if (vpt->muxnum < n) {
327 P9_DPRINTK(P9_DEBUG_MUX, "put in proc %d\n", i);
328 list_add(&m->mux_list, &vpt->mux_list);
329 vpt->muxnum++;
330 m->poll_task = vpt;
331 memset(&m->poll_waddr, 0,
332 sizeof(m->poll_waddr));
333 init_poll_funcptr(&m->pt, p9_pollwait);
334 break;
335 }
336 }
337 } 197 }
338 198
339 if (i >= ARRAY_SIZE(p9_mux_poll_tasks)) { 199 m->err = err;
340 if (vptlast == NULL) {
341 mutex_unlock(&p9_mux_task_lock);
342 return -ENOMEM;
343 }
344 200
345 P9_DPRINTK(P9_DEBUG_MUX, "put in proc %d\n", i); 201 list_for_each_entry_safe(req, rtmp, &m->req_list, req_list) {
346 list_add(&m->mux_list, &vptlast->mux_list); 202 req->status = REQ_STATUS_ERROR;
347 vptlast->muxnum++; 203 if (!req->t_err)
348 m->poll_task = vptlast; 204 req->t_err = err;
349 memset(&m->poll_waddr, 0, sizeof(m->poll_waddr)); 205 list_move(&req->req_list, &cancel_list);
350 init_poll_funcptr(&m->pt, p9_pollwait);
351 } 206 }
352 207 list_for_each_entry_safe(req, rtmp, &m->unsent_req_list, req_list) {
353 p9_mux_num++; 208 req->status = REQ_STATUS_ERROR;
354 mutex_unlock(&p9_mux_task_lock); 209 if (!req->t_err)
355 210 req->t_err = err;
356 return 0; 211 list_move(&req->req_list, &cancel_list);
357}
358
359static void p9_mux_poll_stop(struct p9_conn *m)
360{
361 int i;
362 struct p9_mux_poll_task *vpt;
363
364 mutex_lock(&p9_mux_task_lock);
365 vpt = m->poll_task;
366 list_del(&m->mux_list);
367 for (i = 0; i < ARRAY_SIZE(m->poll_waddr); i++) {
368 if (m->poll_waddr[i] != NULL) {
369 remove_wait_queue(m->poll_waddr[i], &m->poll_wait[i]);
370 m->poll_waddr[i] = NULL;
371 }
372 } 212 }
373 vpt->muxnum--; 213 spin_unlock_irqrestore(&m->client->lock, flags);
374 if (!vpt->muxnum) { 214
375 P9_DPRINTK(P9_DEBUG_MUX, "destroy proc %p\n", vpt); 215 list_for_each_entry_safe(req, rtmp, &cancel_list, req_list) {
376 kthread_stop(vpt->task); 216 list_del(&req->req_list);
377 vpt->task = NULL; 217 P9_DPRINTK(P9_DEBUG_ERROR, "call back req %p\n", req);
378 p9_mux_poll_task_num--; 218 p9_client_cb(m->client, req);
379 } 219 }
380 p9_mux_num--;
381 mutex_unlock(&p9_mux_task_lock);
382} 220}
383 221
384/** 222static unsigned int
385 * p9_conn_create - allocate and initialize the per-session mux data 223p9_fd_poll(struct p9_client *client, struct poll_table_struct *pt)
386 * @trans: transport structure
387 *
388 * Note: Creates the polling task if this is the first session.
389 */
390
391static struct p9_conn *p9_conn_create(struct p9_trans *trans)
392{ 224{
393 int i, n; 225 int ret, n;
394 struct p9_conn *m; 226 struct p9_trans_fd *ts = NULL;
395 227
396 P9_DPRINTK(P9_DEBUG_MUX, "transport %p msize %d\n", trans, 228 if (client && client->status == Connected)
397 trans->msize); 229 ts = client->trans;
398 m = kzalloc(sizeof(struct p9_conn), GFP_KERNEL);
399 if (!m)
400 return ERR_PTR(-ENOMEM);
401 230
402 spin_lock_init(&m->lock); 231 if (!ts)
403 INIT_LIST_HEAD(&m->mux_list); 232 return -EREMOTEIO;
404 m->msize = trans->msize;
405 m->extended = trans->extended;
406 m->trans = trans;
407 m->tagpool = p9_idpool_create();
408 if (IS_ERR(m->tagpool)) {
409 kfree(m);
410 return ERR_PTR(-ENOMEM);
411 }
412 233
413 INIT_LIST_HEAD(&m->req_list); 234 if (!ts->rd->f_op || !ts->rd->f_op->poll)
414 INIT_LIST_HEAD(&m->unsent_req_list); 235 return -EIO;
415 INIT_WORK(&m->rq, p9_read_work);
416 INIT_WORK(&m->wq, p9_write_work);
417 n = p9_mux_poll_start(m);
418 if (n) {
419 kfree(m);
420 return ERR_PTR(n);
421 }
422 236
423 n = p9_fd_poll(trans, &m->pt); 237 if (!ts->wr->f_op || !ts->wr->f_op->poll)
424 if (n & POLLIN) { 238 return -EIO;
425 P9_DPRINTK(P9_DEBUG_MUX, "mux %p can read\n", m);
426 set_bit(Rpending, &m->wsched);
427 }
428 239
429 if (n & POLLOUT) { 240 ret = ts->rd->f_op->poll(ts->rd, pt);
430 P9_DPRINTK(P9_DEBUG_MUX, "mux %p can write\n", m); 241 if (ret < 0)
431 set_bit(Wpending, &m->wsched); 242 return ret;
432 }
433 243
434 for (i = 0; i < ARRAY_SIZE(m->poll_waddr); i++) { 244 if (ts->rd != ts->wr) {
435 if (IS_ERR(m->poll_waddr[i])) { 245 n = ts->wr->f_op->poll(ts->wr, pt);
436 p9_mux_poll_stop(m); 246 if (n < 0)
437 kfree(m); 247 return n;
438 return (void *)m->poll_waddr; /* the error code */ 248 ret = (ret & ~POLLOUT) | (n & ~POLLIN);
439 }
440 } 249 }
441 250
442 return m; 251 return ret;
443} 252}
444 253
445/** 254/**
446 * p9_mux_destroy - cancels all pending requests and frees mux resources 255 * p9_fd_read- read from a fd
447 * @m: mux to destroy 256 * @client: client instance
257 * @v: buffer to receive data into
258 * @len: size of receive buffer
448 * 259 *
449 */ 260 */
450 261
451static void p9_conn_destroy(struct p9_conn *m) 262static int p9_fd_read(struct p9_client *client, void *v, int len)
452{ 263{
453 P9_DPRINTK(P9_DEBUG_MUX, "mux %p prev %p next %p\n", m, 264 int ret;
454 m->mux_list.prev, m->mux_list.next); 265 struct p9_trans_fd *ts = NULL;
455 266
456 p9_mux_poll_stop(m); 267 if (client && client->status != Disconnected)
457 cancel_work_sync(&m->rq); 268 ts = client->trans;
458 cancel_work_sync(&m->wq);
459 269
460 p9_conn_cancel(m, -ECONNRESET); 270 if (!ts)
271 return -EREMOTEIO;
461 272
462 m->trans = NULL; 273 if (!(ts->rd->f_flags & O_NONBLOCK))
463 p9_idpool_destroy(m->tagpool); 274 P9_DPRINTK(P9_DEBUG_ERROR, "blocking read ...\n");
464 kfree(m); 275
276 ret = kernel_read(ts->rd, ts->rd->f_pos, v, len);
277 if (ret <= 0 && ret != -ERESTARTSYS && ret != -EAGAIN)
278 client->status = Disconnected;
279 return ret;
465} 280}
466 281
467/** 282/**
468 * p9_pollwait - add poll task to the wait queue 283 * p9_read_work - called when there is some data to be read from a transport
469 * @filp: file pointer being polled 284 * @work: container of work to be done
470 * @wait_address: wait_q to block on
471 * @p: poll state
472 * 285 *
473 * called by files poll operation to add v9fs-poll task to files wait queue
474 */ 286 */
475 287
476static void 288static void p9_read_work(struct work_struct *work)
477p9_pollwait(struct file *filp, wait_queue_head_t *wait_address, poll_table *p)
478{ 289{
479 int i; 290 int n, err;
480 struct p9_conn *m; 291 struct p9_conn *m;
481 292
482 m = container_of(p, struct p9_conn, pt); 293 m = container_of(work, struct p9_conn, rq);
483 for (i = 0; i < ARRAY_SIZE(m->poll_waddr); i++)
484 if (m->poll_waddr[i] == NULL)
485 break;
486 294
487 if (i >= ARRAY_SIZE(m->poll_waddr)) { 295 if (m->err < 0)
488 P9_DPRINTK(P9_DEBUG_ERROR, "not enough wait_address slots\n");
489 return; 296 return;
490 }
491 297
492 m->poll_waddr[i] = wait_address; 298 P9_DPRINTK(P9_DEBUG_TRANS, "start mux %p pos %d\n", m, m->rpos);
493 299
494 if (!wait_address) { 300 if (!m->rbuf) {
495 P9_DPRINTK(P9_DEBUG_ERROR, "no wait_address\n"); 301 m->rbuf = m->tmp_buf;
496 m->poll_waddr[i] = ERR_PTR(-EIO); 302 m->rpos = 0;
303 m->rsize = 7; /* start by reading header */
304 }
305
306 clear_bit(Rpending, &m->wsched);
307 P9_DPRINTK(P9_DEBUG_TRANS, "read mux %p pos %d size: %d = %d\n", m,
308 m->rpos, m->rsize, m->rsize-m->rpos);
309 err = p9_fd_read(m->client, m->rbuf + m->rpos,
310 m->rsize - m->rpos);
311 P9_DPRINTK(P9_DEBUG_TRANS, "mux %p got %d bytes\n", m, err);
312 if (err == -EAGAIN) {
313 clear_bit(Rworksched, &m->wsched);
497 return; 314 return;
498 } 315 }
499 316
500 init_waitqueue_entry(&m->poll_wait[i], m->poll_task->task); 317 if (err <= 0)
501 add_wait_queue(wait_address, &m->poll_wait[i]); 318 goto error;
502}
503 319
504/** 320 m->rpos += err;
505 * p9_poll_mux - polls a mux and schedules read or write works if necessary
506 * @m: connection to poll
507 *
508 */
509 321
510static void p9_poll_mux(struct p9_conn *m) 322 if ((!m->req) && (m->rpos == m->rsize)) { /* header read in */
511{ 323 u16 tag;
512 int n; 324 P9_DPRINTK(P9_DEBUG_TRANS, "got new header\n");
513 325
514 if (m->err < 0) 326 n = le32_to_cpu(*(__le32 *) m->rbuf); /* read packet size */
515 return; 327 if (n >= m->client->msize) {
328 P9_DPRINTK(P9_DEBUG_ERROR,
329 "requested packet size too big: %d\n", n);
330 err = -EIO;
331 goto error;
332 }
516 333
517 n = p9_fd_poll(m->trans, NULL); 334 tag = le16_to_cpu(*(__le16 *) (m->rbuf+5)); /* read tag */
518 if (n < 0 || n & (POLLERR | POLLHUP | POLLNVAL)) { 335 P9_DPRINTK(P9_DEBUG_TRANS,
519 P9_DPRINTK(P9_DEBUG_MUX, "error mux %p err %d\n", m, n); 336 "mux %p pkt: size: %d bytes tag: %d\n", m, n, tag);
520 if (n >= 0)
521 n = -ECONNRESET;
522 p9_conn_cancel(m, n);
523 }
524 337
525 if (n & POLLIN) { 338 m->req = p9_tag_lookup(m->client, tag);
526 set_bit(Rpending, &m->wsched); 339 if (!m->req) {
527 P9_DPRINTK(P9_DEBUG_MUX, "mux %p can read\n", m); 340 P9_DPRINTK(P9_DEBUG_ERROR, "Unexpected packet tag %d\n",
528 if (!test_and_set_bit(Rworksched, &m->wsched)) { 341 tag);
529 P9_DPRINTK(P9_DEBUG_MUX, "schedule read work %p\n", m); 342 err = -EIO;
530 queue_work(p9_mux_wq, &m->rq); 343 goto error;
531 } 344 }
532 }
533 345
534 if (n & POLLOUT) { 346 if (m->req->rc == NULL) {
535 set_bit(Wpending, &m->wsched); 347 m->req->rc = kmalloc(sizeof(struct p9_fcall) +
536 P9_DPRINTK(P9_DEBUG_MUX, "mux %p can write\n", m); 348 m->client->msize, GFP_KERNEL);
537 if ((m->wsize || !list_empty(&m->unsent_req_list)) 349 if (!m->req->rc) {
538 && !test_and_set_bit(Wworksched, &m->wsched)) { 350 m->req = NULL;
539 P9_DPRINTK(P9_DEBUG_MUX, "schedule write work %p\n", m); 351 err = -ENOMEM;
540 queue_work(p9_mux_wq, &m->wq); 352 goto error;
353 }
541 } 354 }
355 m->rbuf = (char *)m->req->rc + sizeof(struct p9_fcall);
356 memcpy(m->rbuf, m->tmp_buf, m->rsize);
357 m->rsize = n;
542 } 358 }
359
360 /* not an else because some packets (like clunk) have no payload */
361 if ((m->req) && (m->rpos == m->rsize)) { /* packet is read in */
362 P9_DPRINTK(P9_DEBUG_TRANS, "got new packet\n");
363 spin_lock(&m->client->lock);
364 list_del(&m->req->req_list);
365 spin_unlock(&m->client->lock);
366 p9_client_cb(m->client, m->req);
367
368 m->rbuf = NULL;
369 m->rpos = 0;
370 m->rsize = 0;
371 m->req = NULL;
372 }
373
374 if (!list_empty(&m->req_list)) {
375 if (test_and_clear_bit(Rpending, &m->wsched))
376 n = POLLIN;
377 else
378 n = p9_fd_poll(m->client, NULL);
379
380 if (n & POLLIN) {
381 P9_DPRINTK(P9_DEBUG_TRANS, "sched read work %p\n", m);
382 queue_work(p9_mux_wq, &m->rq);
383 } else
384 clear_bit(Rworksched, &m->wsched);
385 } else
386 clear_bit(Rworksched, &m->wsched);
387
388 return;
389error:
390 p9_conn_cancel(m, err);
391 clear_bit(Rworksched, &m->wsched);
543} 392}
544 393
545/** 394/**
546 * p9_poll_proc - poll worker thread 395 * p9_fd_write - write to a socket
547 * @a: thread state and arguments 396 * @client: client instance
548 * 397 * @v: buffer to send data from
549 * polls all v9fs transports for new events and queues the appropriate 398 * @len: size of send buffer
550 * work to the work queue
551 * 399 *
552 */ 400 */
553 401
554static int p9_poll_proc(void *a) 402static int p9_fd_write(struct p9_client *client, void *v, int len)
555{ 403{
556 struct p9_conn *m, *mtmp; 404 int ret;
557 struct p9_mux_poll_task *vpt; 405 mm_segment_t oldfs;
406 struct p9_trans_fd *ts = NULL;
558 407
559 vpt = a; 408 if (client && client->status != Disconnected)
560 P9_DPRINTK(P9_DEBUG_MUX, "start %p %p\n", current, vpt); 409 ts = client->trans;
561 while (!kthread_should_stop()) {
562 set_current_state(TASK_INTERRUPTIBLE);
563 410
564 list_for_each_entry_safe(m, mtmp, &vpt->mux_list, mux_list) { 411 if (!ts)
565 p9_poll_mux(m); 412 return -EREMOTEIO;
566 }
567 413
568 P9_DPRINTK(P9_DEBUG_MUX, "sleeping...\n"); 414 if (!(ts->wr->f_flags & O_NONBLOCK))
569 schedule_timeout(SCHED_TIMEOUT * HZ); 415 P9_DPRINTK(P9_DEBUG_ERROR, "blocking write ...\n");
570 }
571 416
572 __set_current_state(TASK_RUNNING); 417 oldfs = get_fs();
573 P9_DPRINTK(P9_DEBUG_MUX, "finish\n"); 418 set_fs(get_ds());
574 return 0; 419 /* The cast to a user pointer is valid due to the set_fs() */
420 ret = vfs_write(ts->wr, (void __user *)v, len, &ts->wr->f_pos);
421 set_fs(oldfs);
422
423 if (ret <= 0 && ret != -ERESTARTSYS && ret != -EAGAIN)
424 client->status = Disconnected;
425 return ret;
575} 426}
576 427
577/** 428/**
@@ -584,7 +435,7 @@ static void p9_write_work(struct work_struct *work)
584{ 435{
585 int n, err; 436 int n, err;
586 struct p9_conn *m; 437 struct p9_conn *m;
587 struct p9_req *req; 438 struct p9_req_t *req;
588 439
589 m = container_of(work, struct p9_conn, wq); 440 m = container_of(work, struct p9_conn, wq);
590 441
@@ -599,25 +450,23 @@ static void p9_write_work(struct work_struct *work)
599 return; 450 return;
600 } 451 }
601 452
602 spin_lock(&m->lock); 453 spin_lock(&m->client->lock);
603again: 454 req = list_entry(m->unsent_req_list.next, struct p9_req_t,
604 req = list_entry(m->unsent_req_list.next, struct p9_req,
605 req_list); 455 req_list);
456 req->status = REQ_STATUS_SENT;
606 list_move_tail(&req->req_list, &m->req_list); 457 list_move_tail(&req->req_list, &m->req_list);
607 if (req->err == ERREQFLUSH)
608 goto again;
609 458
610 m->wbuf = req->tcall->sdata; 459 m->wbuf = req->tc->sdata;
611 m->wsize = req->tcall->size; 460 m->wsize = req->tc->size;
612 m->wpos = 0; 461 m->wpos = 0;
613 spin_unlock(&m->lock); 462 spin_unlock(&m->client->lock);
614 } 463 }
615 464
616 P9_DPRINTK(P9_DEBUG_MUX, "mux %p pos %d size %d\n", m, m->wpos, 465 P9_DPRINTK(P9_DEBUG_TRANS, "mux %p pos %d size %d\n", m, m->wpos,
617 m->wsize); 466 m->wsize);
618 clear_bit(Wpending, &m->wsched); 467 clear_bit(Wpending, &m->wsched);
619 err = p9_fd_write(m->trans, m->wbuf + m->wpos, m->wsize - m->wpos); 468 err = p9_fd_write(m->client, m->wbuf + m->wpos, m->wsize - m->wpos);
620 P9_DPRINTK(P9_DEBUG_MUX, "mux %p sent %d bytes\n", m, err); 469 P9_DPRINTK(P9_DEBUG_TRANS, "mux %p sent %d bytes\n", m, err);
621 if (err == -EAGAIN) { 470 if (err == -EAGAIN) {
622 clear_bit(Wworksched, &m->wsched); 471 clear_bit(Wworksched, &m->wsched);
623 return; 472 return;
@@ -638,10 +487,10 @@ again:
638 if (test_and_clear_bit(Wpending, &m->wsched)) 487 if (test_and_clear_bit(Wpending, &m->wsched))
639 n = POLLOUT; 488 n = POLLOUT;
640 else 489 else
641 n = p9_fd_poll(m->trans, NULL); 490 n = p9_fd_poll(m->client, NULL);
642 491
643 if (n & POLLOUT) { 492 if (n & POLLOUT) {
644 P9_DPRINTK(P9_DEBUG_MUX, "schedule write work %p\n", m); 493 P9_DPRINTK(P9_DEBUG_TRANS, "sched write work %p\n", m);
645 queue_work(p9_mux_wq, &m->wq); 494 queue_work(p9_mux_wq, &m->wq);
646 } else 495 } else
647 clear_bit(Wworksched, &m->wsched); 496 clear_bit(Wworksched, &m->wsched);
@@ -655,504 +504,195 @@ error:
655 clear_bit(Wworksched, &m->wsched); 504 clear_bit(Wworksched, &m->wsched);
656} 505}
657 506
658static void process_request(struct p9_conn *m, struct p9_req *req) 507static int p9_pollwake(wait_queue_t *wait, unsigned mode, int sync, void *key)
659{ 508{
660 int ecode; 509 struct p9_poll_wait *pwait =
661 struct p9_str *ename; 510 container_of(wait, struct p9_poll_wait, wait);
662 511 struct p9_conn *m = pwait->conn;
663 if (!req->err && req->rcall->id == P9_RERROR) { 512 unsigned long flags;
664 ecode = req->rcall->params.rerror.errno; 513 DECLARE_WAITQUEUE(dummy_wait, p9_poll_task);
665 ename = &req->rcall->params.rerror.error;
666
667 P9_DPRINTK(P9_DEBUG_MUX, "Rerror %.*s\n", ename->len,
668 ename->str);
669
670 if (m->extended)
671 req->err = -ecode;
672 514
673 if (!req->err) { 515 spin_lock_irqsave(&p9_poll_lock, flags);
674 req->err = p9_errstr2errno(ename->str, ename->len); 516 if (list_empty(&m->poll_pending_link))
517 list_add_tail(&m->poll_pending_link, &p9_poll_pending_list);
518 spin_unlock_irqrestore(&p9_poll_lock, flags);
675 519
676 /* string match failed */ 520 /* perform the default wake up operation */
677 if (!req->err) { 521 return default_wake_function(&dummy_wait, mode, sync, key);
678 PRINT_FCALL_ERROR("unknown error", req->rcall);
679 req->err = -ESERVERFAULT;
680 }
681 }
682 } else if (req->tcall && req->rcall->id != req->tcall->id + 1) {
683 P9_DPRINTK(P9_DEBUG_ERROR,
684 "fcall mismatch: expected %d, got %d\n",
685 req->tcall->id + 1, req->rcall->id);
686 if (!req->err)
687 req->err = -EIO;
688 }
689} 522}
690 523
691/** 524/**
692 * p9_read_work - called when there is some data to be read from a transport 525 * p9_pollwait - add poll task to the wait queue
693 * @work: container of work to be done 526 * @filp: file pointer being polled
527 * @wait_address: wait_q to block on
528 * @p: poll state
694 * 529 *
530 * called by files poll operation to add v9fs-poll task to files wait queue
695 */ 531 */
696 532
697static void p9_read_work(struct work_struct *work) 533static void
534p9_pollwait(struct file *filp, wait_queue_head_t *wait_address, poll_table *p)
698{ 535{
699 int n, err; 536 struct p9_conn *m = container_of(p, struct p9_conn, pt);
700 struct p9_conn *m; 537 struct p9_poll_wait *pwait = NULL;
701 struct p9_req *req, *rptr, *rreq; 538 int i;
702 struct p9_fcall *rcall;
703 char *rbuf;
704
705 m = container_of(work, struct p9_conn, rq);
706
707 if (m->err < 0)
708 return;
709
710 rcall = NULL;
711 P9_DPRINTK(P9_DEBUG_MUX, "start mux %p pos %d\n", m, m->rpos);
712 539
713 if (!m->rcall) { 540 for (i = 0; i < ARRAY_SIZE(m->poll_wait); i++) {
714 m->rcall = 541 if (m->poll_wait[i].wait_addr == NULL) {
715 kmalloc(sizeof(struct p9_fcall) + m->msize, GFP_KERNEL); 542 pwait = &m->poll_wait[i];
716 if (!m->rcall) { 543 break;
717 err = -ENOMEM;
718 goto error;
719 } 544 }
720
721 m->rbuf = (char *)m->rcall + sizeof(struct p9_fcall);
722 m->rpos = 0;
723 } 545 }
724 546
725 clear_bit(Rpending, &m->wsched); 547 if (!pwait) {
726 err = p9_fd_read(m->trans, m->rbuf + m->rpos, m->msize - m->rpos); 548 P9_DPRINTK(P9_DEBUG_ERROR, "not enough wait_address slots\n");
727 P9_DPRINTK(P9_DEBUG_MUX, "mux %p got %d bytes\n", m, err);
728 if (err == -EAGAIN) {
729 clear_bit(Rworksched, &m->wsched);
730 return; 549 return;
731 } 550 }
732 551
733 if (err <= 0) 552 pwait->conn = m;
734 goto error; 553 pwait->wait_addr = wait_address;
735 554 init_waitqueue_func_entry(&pwait->wait, p9_pollwake);
736 m->rpos += err; 555 add_wait_queue(wait_address, &pwait->wait);
737 while (m->rpos > 4) {
738 n = le32_to_cpu(*(__le32 *) m->rbuf);
739 if (n >= m->msize) {
740 P9_DPRINTK(P9_DEBUG_ERROR,
741 "requested packet size too big: %d\n", n);
742 err = -EIO;
743 goto error;
744 }
745
746 if (m->rpos < n)
747 break;
748
749 err =
750 p9_deserialize_fcall(m->rbuf, n, m->rcall, m->extended);
751 if (err < 0)
752 goto error;
753
754#ifdef CONFIG_NET_9P_DEBUG
755 if ((p9_debug_level&P9_DEBUG_FCALL) == P9_DEBUG_FCALL) {
756 char buf[150];
757
758 p9_printfcall(buf, sizeof(buf), m->rcall,
759 m->extended);
760 printk(KERN_NOTICE ">>> %p %s\n", m, buf);
761 }
762#endif
763
764 rcall = m->rcall;
765 rbuf = m->rbuf;
766 if (m->rpos > n) {
767 m->rcall = kmalloc(sizeof(struct p9_fcall) + m->msize,
768 GFP_KERNEL);
769 if (!m->rcall) {
770 err = -ENOMEM;
771 goto error;
772 }
773
774 m->rbuf = (char *)m->rcall + sizeof(struct p9_fcall);
775 memmove(m->rbuf, rbuf + n, m->rpos - n);
776 m->rpos -= n;
777 } else {
778 m->rcall = NULL;
779 m->rbuf = NULL;
780 m->rpos = 0;
781 }
782
783 P9_DPRINTK(P9_DEBUG_MUX, "mux %p fcall id %d tag %d\n", m,
784 rcall->id, rcall->tag);
785
786 req = NULL;
787 spin_lock(&m->lock);
788 list_for_each_entry_safe(rreq, rptr, &m->req_list, req_list) {
789 if (rreq->tag == rcall->tag) {
790 req = rreq;
791 if (req->flush != Flushing)
792 list_del(&req->req_list);
793 break;
794 }
795 }
796 spin_unlock(&m->lock);
797
798 if (req) {
799 req->rcall = rcall;
800 process_request(m, req);
801
802 if (req->flush != Flushing) {
803 if (req->cb)
804 (*req->cb) (req, req->cba);
805 else
806 kfree(req->rcall);
807 }
808 } else {
809 if (err >= 0 && rcall->id != P9_RFLUSH)
810 P9_DPRINTK(P9_DEBUG_ERROR,
811 "unexpected response mux %p id %d tag %d\n",
812 m, rcall->id, rcall->tag);
813 kfree(rcall);
814 }
815 }
816
817 if (!list_empty(&m->req_list)) {
818 if (test_and_clear_bit(Rpending, &m->wsched))
819 n = POLLIN;
820 else
821 n = p9_fd_poll(m->trans, NULL);
822
823 if (n & POLLIN) {
824 P9_DPRINTK(P9_DEBUG_MUX, "schedule read work %p\n", m);
825 queue_work(p9_mux_wq, &m->rq);
826 } else
827 clear_bit(Rworksched, &m->wsched);
828 } else
829 clear_bit(Rworksched, &m->wsched);
830
831 return;
832
833error:
834 p9_conn_cancel(m, err);
835 clear_bit(Rworksched, &m->wsched);
836} 556}
837 557
838/** 558/**
839 * p9_send_request - send 9P request 559 * p9_conn_create - allocate and initialize the per-session mux data
840 * The function can sleep until the request is scheduled for sending. 560 * @client: client instance
841 * The function can be interrupted. Return from the function is not
842 * a guarantee that the request is sent successfully. Can return errors
843 * that can be retrieved by PTR_ERR macros.
844 *
845 * @m: mux data
846 * @tc: request to be sent
847 * @cb: callback function to call when response is received
848 * @cba: parameter to pass to the callback function
849 * 561 *
562 * Note: Creates the polling task if this is the first session.
850 */ 563 */
851 564
852static struct p9_req *p9_send_request(struct p9_conn *m, 565static struct p9_conn *p9_conn_create(struct p9_client *client)
853 struct p9_fcall *tc,
854 p9_conn_req_callback cb, void *cba)
855{ 566{
856 int n; 567 int n;
857 struct p9_req *req; 568 struct p9_conn *m;
858
859 P9_DPRINTK(P9_DEBUG_MUX, "mux %p task %p tcall %p id %d\n", m, current,
860 tc, tc->id);
861 if (m->err < 0)
862 return ERR_PTR(m->err);
863
864 req = kmalloc(sizeof(struct p9_req), GFP_KERNEL);
865 if (!req)
866 return ERR_PTR(-ENOMEM);
867
868 if (tc->id == P9_TVERSION)
869 n = P9_NOTAG;
870 else
871 n = p9_mux_get_tag(m);
872 569
873 if (n < 0) { 570 P9_DPRINTK(P9_DEBUG_TRANS, "client %p msize %d\n", client,
874 kfree(req); 571 client->msize);
572 m = kzalloc(sizeof(struct p9_conn), GFP_KERNEL);
573 if (!m)
875 return ERR_PTR(-ENOMEM); 574 return ERR_PTR(-ENOMEM);
876 }
877 575
878 p9_set_tag(tc, n); 576 INIT_LIST_HEAD(&m->mux_list);
577 m->client = client;
879 578
880#ifdef CONFIG_NET_9P_DEBUG 579 INIT_LIST_HEAD(&m->req_list);
881 if ((p9_debug_level&P9_DEBUG_FCALL) == P9_DEBUG_FCALL) { 580 INIT_LIST_HEAD(&m->unsent_req_list);
882 char buf[150]; 581 INIT_WORK(&m->rq, p9_read_work);
582 INIT_WORK(&m->wq, p9_write_work);
583 INIT_LIST_HEAD(&m->poll_pending_link);
584 init_poll_funcptr(&m->pt, p9_pollwait);
883 585
884 p9_printfcall(buf, sizeof(buf), tc, m->extended); 586 n = p9_fd_poll(client, &m->pt);
885 printk(KERN_NOTICE "<<< %p %s\n", m, buf); 587 if (n & POLLIN) {
588 P9_DPRINTK(P9_DEBUG_TRANS, "mux %p can read\n", m);
589 set_bit(Rpending, &m->wsched);
886 } 590 }
887#endif
888
889 spin_lock_init(&req->lock);
890 req->tag = n;
891 req->tcall = tc;
892 req->rcall = NULL;
893 req->err = 0;
894 req->cb = cb;
895 req->cba = cba;
896 req->flush = None;
897
898 spin_lock(&m->lock);
899 list_add_tail(&req->req_list, &m->unsent_req_list);
900 spin_unlock(&m->lock);
901
902 if (test_and_clear_bit(Wpending, &m->wsched))
903 n = POLLOUT;
904 else
905 n = p9_fd_poll(m->trans, NULL);
906 591
907 if (n & POLLOUT && !test_and_set_bit(Wworksched, &m->wsched)) 592 if (n & POLLOUT) {
908 queue_work(p9_mux_wq, &m->wq); 593 P9_DPRINTK(P9_DEBUG_TRANS, "mux %p can write\n", m);
594 set_bit(Wpending, &m->wsched);
595 }
909 596
910 return req; 597 return m;
911} 598}
912 599
913static void p9_mux_free_request(struct p9_conn *m, struct p9_req *req) 600/**
914{ 601 * p9_poll_mux - polls a mux and schedules read or write works if necessary
915 p9_mux_put_tag(m, req->tag); 602 * @m: connection to poll
916 kfree(req); 603 *
917} 604 */
918 605
919static void p9_mux_flush_cb(struct p9_req *freq, void *a) 606static void p9_poll_mux(struct p9_conn *m)
920{ 607{
921 int tag; 608 int n;
922 struct p9_conn *m;
923 struct p9_req *req, *rreq, *rptr;
924
925 m = a;
926 P9_DPRINTK(P9_DEBUG_MUX, "mux %p tc %p rc %p err %d oldtag %d\n", m,
927 freq->tcall, freq->rcall, freq->err,
928 freq->tcall->params.tflush.oldtag);
929
930 spin_lock(&m->lock);
931 tag = freq->tcall->params.tflush.oldtag;
932 req = NULL;
933 list_for_each_entry_safe(rreq, rptr, &m->req_list, req_list) {
934 if (rreq->tag == tag) {
935 req = rreq;
936 list_del(&req->req_list);
937 break;
938 }
939 }
940 spin_unlock(&m->lock);
941 609
942 if (req) { 610 if (m->err < 0)
943 spin_lock(&req->lock); 611 return;
944 req->flush = Flushed;
945 spin_unlock(&req->lock);
946 612
947 if (req->cb) 613 n = p9_fd_poll(m->client, NULL);
948 (*req->cb) (req, req->cba); 614 if (n < 0 || n & (POLLERR | POLLHUP | POLLNVAL)) {
949 else 615 P9_DPRINTK(P9_DEBUG_TRANS, "error mux %p err %d\n", m, n);
950 kfree(req->rcall); 616 if (n >= 0)
617 n = -ECONNRESET;
618 p9_conn_cancel(m, n);
951 } 619 }
952 620
953 kfree(freq->tcall); 621 if (n & POLLIN) {
954 kfree(freq->rcall); 622 set_bit(Rpending, &m->wsched);
955 p9_mux_free_request(m, freq); 623 P9_DPRINTK(P9_DEBUG_TRANS, "mux %p can read\n", m);
956} 624 if (!test_and_set_bit(Rworksched, &m->wsched)) {
957 625 P9_DPRINTK(P9_DEBUG_TRANS, "sched read work %p\n", m);
958static int 626 queue_work(p9_mux_wq, &m->rq);
959p9_mux_flush_request(struct p9_conn *m, struct p9_req *req) 627 }
960{
961 struct p9_fcall *fc;
962 struct p9_req *rreq, *rptr;
963
964 P9_DPRINTK(P9_DEBUG_MUX, "mux %p req %p tag %d\n", m, req, req->tag);
965
966 /* if a response was received for a request, do nothing */
967 spin_lock(&req->lock);
968 if (req->rcall || req->err) {
969 spin_unlock(&req->lock);
970 P9_DPRINTK(P9_DEBUG_MUX,
971 "mux %p req %p response already received\n", m, req);
972 return 0;
973 } 628 }
974 629
975 req->flush = Flushing; 630 if (n & POLLOUT) {
976 spin_unlock(&req->lock); 631 set_bit(Wpending, &m->wsched);
977 632 P9_DPRINTK(P9_DEBUG_TRANS, "mux %p can write\n", m);
978 spin_lock(&m->lock); 633 if ((m->wsize || !list_empty(&m->unsent_req_list))
979 /* if the request is not sent yet, just remove it from the list */ 634 && !test_and_set_bit(Wworksched, &m->wsched)) {
980 list_for_each_entry_safe(rreq, rptr, &m->unsent_req_list, req_list) { 635 P9_DPRINTK(P9_DEBUG_TRANS, "sched write work %p\n", m);
981 if (rreq->tag == req->tag) { 636 queue_work(p9_mux_wq, &m->wq);
982 P9_DPRINTK(P9_DEBUG_MUX,
983 "mux %p req %p request is not sent yet\n", m, req);
984 list_del(&rreq->req_list);
985 req->flush = Flushed;
986 spin_unlock(&m->lock);
987 if (req->cb)
988 (*req->cb) (req, req->cba);
989 return 0;
990 } 637 }
991 } 638 }
992 spin_unlock(&m->lock);
993
994 clear_thread_flag(TIF_SIGPENDING);
995 fc = p9_create_tflush(req->tag);
996 p9_send_request(m, fc, p9_mux_flush_cb, m);
997 return 1;
998}
999
1000static void
1001p9_conn_rpc_cb(struct p9_req *req, void *a)
1002{
1003 struct p9_mux_rpc *r;
1004
1005 P9_DPRINTK(P9_DEBUG_MUX, "req %p r %p\n", req, a);
1006 r = a;
1007 r->rcall = req->rcall;
1008 r->err = req->err;
1009
1010 if (req->flush != None && !req->err)
1011 r->err = -ERESTARTSYS;
1012
1013 wake_up(&r->wqueue);
1014} 639}
1015 640
1016/** 641/**
1017 * p9_fd_rpc- sends 9P request and waits until a response is available. 642 * p9_fd_request - send 9P request
1018 * The function can be interrupted. 643 * The function can sleep until the request is scheduled for sending.
1019 * @t: transport data 644 * The function can be interrupted. Return from the function is not
1020 * @tc: request to be sent 645 * a guarantee that the request is sent successfully.
1021 * @rc: pointer where a pointer to the response is stored 646 *
647 * @client: client instance
648 * @req: request to be sent
1022 * 649 *
1023 */ 650 */
1024 651
1025int 652static int p9_fd_request(struct p9_client *client, struct p9_req_t *req)
1026p9_fd_rpc(struct p9_trans *t, struct p9_fcall *tc, struct p9_fcall **rc)
1027{ 653{
1028 struct p9_trans_fd *p = t->priv; 654 int n;
1029 struct p9_conn *m = p->conn; 655 struct p9_trans_fd *ts = client->trans;
1030 int err, sigpending; 656 struct p9_conn *m = ts->conn;
1031 unsigned long flags;
1032 struct p9_req *req;
1033 struct p9_mux_rpc r;
1034
1035 r.err = 0;
1036 r.tcall = tc;
1037 r.rcall = NULL;
1038 r.m = m;
1039 init_waitqueue_head(&r.wqueue);
1040
1041 if (rc)
1042 *rc = NULL;
1043
1044 sigpending = 0;
1045 if (signal_pending(current)) {
1046 sigpending = 1;
1047 clear_thread_flag(TIF_SIGPENDING);
1048 }
1049
1050 req = p9_send_request(m, tc, p9_conn_rpc_cb, &r);
1051 if (IS_ERR(req)) {
1052 err = PTR_ERR(req);
1053 P9_DPRINTK(P9_DEBUG_MUX, "error %d\n", err);
1054 return err;
1055 }
1056 657
1057 err = wait_event_interruptible(r.wqueue, r.rcall != NULL || r.err < 0); 658 P9_DPRINTK(P9_DEBUG_TRANS, "mux %p task %p tcall %p id %d\n", m,
1058 if (r.err < 0) 659 current, req->tc, req->tc->id);
1059 err = r.err; 660 if (m->err < 0)
1060 661 return m->err;
1061 if (err == -ERESTARTSYS && m->trans->status == Connected
1062 && m->err == 0) {
1063 if (p9_mux_flush_request(m, req)) {
1064 /* wait until we get response of the flush message */
1065 do {
1066 clear_thread_flag(TIF_SIGPENDING);
1067 err = wait_event_interruptible(r.wqueue,
1068 r.rcall || r.err);
1069 } while (!r.rcall && !r.err && err == -ERESTARTSYS &&
1070 m->trans->status == Connected && !m->err);
1071
1072 err = -ERESTARTSYS;
1073 }
1074 sigpending = 1;
1075 }
1076 662
1077 if (sigpending) { 663 spin_lock(&client->lock);
1078 spin_lock_irqsave(&current->sighand->siglock, flags); 664 req->status = REQ_STATUS_UNSENT;
1079 recalc_sigpending(); 665 list_add_tail(&req->req_list, &m->unsent_req_list);
1080 spin_unlock_irqrestore(&current->sighand->siglock, flags); 666 spin_unlock(&client->lock);
1081 }
1082 667
1083 if (rc) 668 if (test_and_clear_bit(Wpending, &m->wsched))
1084 *rc = r.rcall; 669 n = POLLOUT;
1085 else 670 else
1086 kfree(r.rcall); 671 n = p9_fd_poll(m->client, NULL);
1087 672
1088 p9_mux_free_request(m, req); 673 if (n & POLLOUT && !test_and_set_bit(Wworksched, &m->wsched))
1089 if (err > 0) 674 queue_work(p9_mux_wq, &m->wq);
1090 err = -EIO;
1091 675
1092 return err; 676 return 0;
1093} 677}
1094 678
1095#ifdef P9_NONBLOCK 679static int p9_fd_cancel(struct p9_client *client, struct p9_req_t *req)
1096/**
1097 * p9_conn_rpcnb - sends 9P request without waiting for response.
1098 * @m: mux data
1099 * @tc: request to be sent
1100 * @cb: callback function to be called when response arrives
1101 * @a: value to pass to the callback function
1102 *
1103 */
1104
1105int p9_conn_rpcnb(struct p9_conn *m, struct p9_fcall *tc,
1106 p9_conn_req_callback cb, void *a)
1107{ 680{
1108 int err; 681 int ret = 1;
1109 struct p9_req *req;
1110 682
1111 req = p9_send_request(m, tc, cb, a); 683 P9_DPRINTK(P9_DEBUG_TRANS, "client %p req %p\n", client, req);
1112 if (IS_ERR(req)) {
1113 err = PTR_ERR(req);
1114 P9_DPRINTK(P9_DEBUG_MUX, "error %d\n", err);
1115 return PTR_ERR(req);
1116 }
1117 684
1118 P9_DPRINTK(P9_DEBUG_MUX, "mux %p tc %p tag %d\n", m, tc, req->tag); 685 spin_lock(&client->lock);
1119 return 0; 686 list_del(&req->req_list);
1120}
1121#endif /* P9_NONBLOCK */
1122 687
1123/** 688 if (req->status == REQ_STATUS_UNSENT) {
1124 * p9_conn_cancel - cancel all pending requests with error 689 req->status = REQ_STATUS_FLSHD;
1125 * @m: mux data 690 ret = 0;
1126 * @err: error code
1127 *
1128 */
1129
1130void p9_conn_cancel(struct p9_conn *m, int err)
1131{
1132 struct p9_req *req, *rtmp;
1133 LIST_HEAD(cancel_list);
1134
1135 P9_DPRINTK(P9_DEBUG_ERROR, "mux %p err %d\n", m, err);
1136 m->err = err;
1137 spin_lock(&m->lock);
1138 list_for_each_entry_safe(req, rtmp, &m->req_list, req_list) {
1139 list_move(&req->req_list, &cancel_list);
1140 } 691 }
1141 list_for_each_entry_safe(req, rtmp, &m->unsent_req_list, req_list) {
1142 list_move(&req->req_list, &cancel_list);
1143 }
1144 spin_unlock(&m->lock);
1145 692
1146 list_for_each_entry_safe(req, rtmp, &cancel_list, req_list) { 693 spin_unlock(&client->lock);
1147 list_del(&req->req_list);
1148 if (!req->err)
1149 req->err = err;
1150 694
1151 if (req->cb) 695 return ret;
1152 (*req->cb) (req, req->cba);
1153 else
1154 kfree(req->rcall);
1155 }
1156} 696}
1157 697
1158/** 698/**
@@ -1216,7 +756,7 @@ static int parse_opts(char *params, struct p9_fd_opts *opts)
1216 return 0; 756 return 0;
1217} 757}
1218 758
1219static int p9_fd_open(struct p9_trans *trans, int rfd, int wfd) 759static int p9_fd_open(struct p9_client *client, int rfd, int wfd)
1220{ 760{
1221 struct p9_trans_fd *ts = kmalloc(sizeof(struct p9_trans_fd), 761 struct p9_trans_fd *ts = kmalloc(sizeof(struct p9_trans_fd),
1222 GFP_KERNEL); 762 GFP_KERNEL);
@@ -1234,13 +774,13 @@ static int p9_fd_open(struct p9_trans *trans, int rfd, int wfd)
1234 return -EIO; 774 return -EIO;
1235 } 775 }
1236 776
1237 trans->priv = ts; 777 client->trans = ts;
1238 trans->status = Connected; 778 client->status = Connected;
1239 779
1240 return 0; 780 return 0;
1241} 781}
1242 782
1243static int p9_socket_open(struct p9_trans *trans, struct socket *csocket) 783static int p9_socket_open(struct p9_client *client, struct socket *csocket)
1244{ 784{
1245 int fd, ret; 785 int fd, ret;
1246 786
@@ -1251,137 +791,65 @@ static int p9_socket_open(struct p9_trans *trans, struct socket *csocket)
1251 return fd; 791 return fd;
1252 } 792 }
1253 793
1254 ret = p9_fd_open(trans, fd, fd); 794 ret = p9_fd_open(client, fd, fd);
1255 if (ret < 0) { 795 if (ret < 0) {
1256 P9_EPRINTK(KERN_ERR, "p9_socket_open: failed to open fd\n"); 796 P9_EPRINTK(KERN_ERR, "p9_socket_open: failed to open fd\n");
1257 sockfd_put(csocket); 797 sockfd_put(csocket);
1258 return ret; 798 return ret;
1259 } 799 }
1260 800
1261 ((struct p9_trans_fd *)trans->priv)->rd->f_flags |= O_NONBLOCK; 801 ((struct p9_trans_fd *)client->trans)->rd->f_flags |= O_NONBLOCK;
1262 802
1263 return 0; 803 return 0;
1264} 804}
1265 805
1266/** 806/**
1267 * p9_fd_read- read from a fd 807 * p9_mux_destroy - cancels all pending requests and frees mux resources
1268 * @trans: transport instance state 808 * @m: mux to destroy
1269 * @v: buffer to receive data into
1270 * @len: size of receive buffer
1271 *
1272 */
1273
1274static int p9_fd_read(struct p9_trans *trans, void *v, int len)
1275{
1276 int ret;
1277 struct p9_trans_fd *ts = NULL;
1278
1279 if (trans && trans->status != Disconnected)
1280 ts = trans->priv;
1281
1282 if (!ts)
1283 return -EREMOTEIO;
1284
1285 if (!(ts->rd->f_flags & O_NONBLOCK))
1286 P9_DPRINTK(P9_DEBUG_ERROR, "blocking read ...\n");
1287
1288 ret = kernel_read(ts->rd, ts->rd->f_pos, v, len);
1289 if (ret <= 0 && ret != -ERESTARTSYS && ret != -EAGAIN)
1290 trans->status = Disconnected;
1291 return ret;
1292}
1293
1294/**
1295 * p9_fd_write - write to a socket
1296 * @trans: transport instance state
1297 * @v: buffer to send data from
1298 * @len: size of send buffer
1299 * 809 *
1300 */ 810 */
1301 811
1302static int p9_fd_write(struct p9_trans *trans, void *v, int len) 812static void p9_conn_destroy(struct p9_conn *m)
1303{
1304 int ret;
1305 mm_segment_t oldfs;
1306 struct p9_trans_fd *ts = NULL;
1307
1308 if (trans && trans->status != Disconnected)
1309 ts = trans->priv;
1310
1311 if (!ts)
1312 return -EREMOTEIO;
1313
1314 if (!(ts->wr->f_flags & O_NONBLOCK))
1315 P9_DPRINTK(P9_DEBUG_ERROR, "blocking write ...\n");
1316
1317 oldfs = get_fs();
1318 set_fs(get_ds());
1319 /* The cast to a user pointer is valid due to the set_fs() */
1320 ret = vfs_write(ts->wr, (void __user *)v, len, &ts->wr->f_pos);
1321 set_fs(oldfs);
1322
1323 if (ret <= 0 && ret != -ERESTARTSYS && ret != -EAGAIN)
1324 trans->status = Disconnected;
1325 return ret;
1326}
1327
1328static unsigned int
1329p9_fd_poll(struct p9_trans *trans, struct poll_table_struct *pt)
1330{ 813{
1331 int ret, n; 814 P9_DPRINTK(P9_DEBUG_TRANS, "mux %p prev %p next %p\n", m,
1332 struct p9_trans_fd *ts = NULL; 815 m->mux_list.prev, m->mux_list.next);
1333
1334 if (trans && trans->status == Connected)
1335 ts = trans->priv;
1336
1337 if (!ts)
1338 return -EREMOTEIO;
1339
1340 if (!ts->rd->f_op || !ts->rd->f_op->poll)
1341 return -EIO;
1342
1343 if (!ts->wr->f_op || !ts->wr->f_op->poll)
1344 return -EIO;
1345 816
1346 ret = ts->rd->f_op->poll(ts->rd, pt); 817 p9_mux_poll_stop(m);
1347 if (ret < 0) 818 cancel_work_sync(&m->rq);
1348 return ret; 819 cancel_work_sync(&m->wq);
1349 820
1350 if (ts->rd != ts->wr) { 821 p9_conn_cancel(m, -ECONNRESET);
1351 n = ts->wr->f_op->poll(ts->wr, pt);
1352 if (n < 0)
1353 return n;
1354 ret = (ret & ~POLLOUT) | (n & ~POLLIN);
1355 }
1356 822
1357 return ret; 823 m->client = NULL;
824 kfree(m);
1358} 825}
1359 826
1360/** 827/**
1361 * p9_fd_close - shutdown socket 828 * p9_fd_close - shutdown file descriptor transport
1362 * @trans: private socket structure 829 * @client: client instance
1363 * 830 *
1364 */ 831 */
1365 832
1366static void p9_fd_close(struct p9_trans *trans) 833static void p9_fd_close(struct p9_client *client)
1367{ 834{
1368 struct p9_trans_fd *ts; 835 struct p9_trans_fd *ts;
1369 836
1370 if (!trans) 837 if (!client)
1371 return; 838 return;
1372 839
1373 ts = xchg(&trans->priv, NULL); 840 ts = client->trans;
1374
1375 if (!ts) 841 if (!ts)
1376 return; 842 return;
1377 843
844 client->status = Disconnected;
845
1378 p9_conn_destroy(ts->conn); 846 p9_conn_destroy(ts->conn);
1379 847
1380 trans->status = Disconnected;
1381 if (ts->rd) 848 if (ts->rd)
1382 fput(ts->rd); 849 fput(ts->rd);
1383 if (ts->wr) 850 if (ts->wr)
1384 fput(ts->wr); 851 fput(ts->wr);
852
1385 kfree(ts); 853 kfree(ts);
1386} 854}
1387 855
@@ -1402,31 +870,23 @@ static inline int valid_ipaddr4(const char *buf)
1402 return 0; 870 return 0;
1403} 871}
1404 872
1405static struct p9_trans * 873static int
1406p9_trans_create_tcp(const char *addr, char *args, int msize, unsigned char dotu) 874p9_fd_create_tcp(struct p9_client *client, const char *addr, char *args)
1407{ 875{
1408 int err; 876 int err;
1409 struct p9_trans *trans;
1410 struct socket *csocket; 877 struct socket *csocket;
1411 struct sockaddr_in sin_server; 878 struct sockaddr_in sin_server;
1412 struct p9_fd_opts opts; 879 struct p9_fd_opts opts;
1413 struct p9_trans_fd *p; 880 struct p9_trans_fd *p = NULL; /* this gets allocated in p9_fd_open */
1414 881
1415 err = parse_opts(args, &opts); 882 err = parse_opts(args, &opts);
1416 if (err < 0) 883 if (err < 0)
1417 return ERR_PTR(err); 884 return err;
1418 885
1419 if (valid_ipaddr4(addr) < 0) 886 if (valid_ipaddr4(addr) < 0)
1420 return ERR_PTR(-EINVAL); 887 return -EINVAL;
1421 888
1422 csocket = NULL; 889 csocket = NULL;
1423 trans = kmalloc(sizeof(struct p9_trans), GFP_KERNEL);
1424 if (!trans)
1425 return ERR_PTR(-ENOMEM);
1426 trans->msize = msize;
1427 trans->extended = dotu;
1428 trans->rpc = p9_fd_rpc;
1429 trans->close = p9_fd_close;
1430 890
1431 sin_server.sin_family = AF_INET; 891 sin_server.sin_family = AF_INET;
1432 sin_server.sin_addr.s_addr = in_aton(addr); 892 sin_server.sin_addr.s_addr = in_aton(addr);
@@ -1449,45 +909,38 @@ p9_trans_create_tcp(const char *addr, char *args, int msize, unsigned char dotu)
1449 goto error; 909 goto error;
1450 } 910 }
1451 911
1452 err = p9_socket_open(trans, csocket); 912 err = p9_socket_open(client, csocket);
1453 if (err < 0) 913 if (err < 0)
1454 goto error; 914 goto error;
1455 915
1456 p = (struct p9_trans_fd *) trans->priv; 916 p = (struct p9_trans_fd *) client->trans;
1457 p->conn = p9_conn_create(trans); 917 p->conn = p9_conn_create(client);
1458 if (IS_ERR(p->conn)) { 918 if (IS_ERR(p->conn)) {
1459 err = PTR_ERR(p->conn); 919 err = PTR_ERR(p->conn);
1460 p->conn = NULL; 920 p->conn = NULL;
1461 goto error; 921 goto error;
1462 } 922 }
1463 923
1464 return trans; 924 return 0;
1465 925
1466error: 926error:
1467 if (csocket) 927 if (csocket)
1468 sock_release(csocket); 928 sock_release(csocket);
1469 929
1470 kfree(trans); 930 kfree(p);
1471 return ERR_PTR(err); 931
932 return err;
1472} 933}
1473 934
1474static struct p9_trans * 935static int
1475p9_trans_create_unix(const char *addr, char *args, int msize, 936p9_fd_create_unix(struct p9_client *client, const char *addr, char *args)
1476 unsigned char dotu)
1477{ 937{
1478 int err; 938 int err;
1479 struct socket *csocket; 939 struct socket *csocket;
1480 struct sockaddr_un sun_server; 940 struct sockaddr_un sun_server;
1481 struct p9_trans *trans; 941 struct p9_trans_fd *p = NULL; /* this gets allocated in p9_fd_open */
1482 struct p9_trans_fd *p;
1483 942
1484 csocket = NULL; 943 csocket = NULL;
1485 trans = kmalloc(sizeof(struct p9_trans), GFP_KERNEL);
1486 if (!trans)
1487 return ERR_PTR(-ENOMEM);
1488
1489 trans->rpc = p9_fd_rpc;
1490 trans->close = p9_fd_close;
1491 944
1492 if (strlen(addr) > UNIX_PATH_MAX) { 945 if (strlen(addr) > UNIX_PATH_MAX) {
1493 P9_EPRINTK(KERN_ERR, "p9_trans_unix: address too long: %s\n", 946 P9_EPRINTK(KERN_ERR, "p9_trans_unix: address too long: %s\n",
@@ -1508,79 +961,69 @@ p9_trans_create_unix(const char *addr, char *args, int msize,
1508 goto error; 961 goto error;
1509 } 962 }
1510 963
1511 err = p9_socket_open(trans, csocket); 964 err = p9_socket_open(client, csocket);
1512 if (err < 0) 965 if (err < 0)
1513 goto error; 966 goto error;
1514 967
1515 trans->msize = msize; 968 p = (struct p9_trans_fd *) client->trans;
1516 trans->extended = dotu; 969 p->conn = p9_conn_create(client);
1517 p = (struct p9_trans_fd *) trans->priv;
1518 p->conn = p9_conn_create(trans);
1519 if (IS_ERR(p->conn)) { 970 if (IS_ERR(p->conn)) {
1520 err = PTR_ERR(p->conn); 971 err = PTR_ERR(p->conn);
1521 p->conn = NULL; 972 p->conn = NULL;
1522 goto error; 973 goto error;
1523 } 974 }
1524 975
1525 return trans; 976 return 0;
1526 977
1527error: 978error:
1528 if (csocket) 979 if (csocket)
1529 sock_release(csocket); 980 sock_release(csocket);
1530 981
1531 kfree(trans); 982 kfree(p);
1532 return ERR_PTR(err); 983 return err;
1533} 984}
1534 985
1535static struct p9_trans * 986static int
1536p9_trans_create_fd(const char *name, char *args, int msize, 987p9_fd_create(struct p9_client *client, const char *addr, char *args)
1537 unsigned char extended)
1538{ 988{
1539 int err; 989 int err;
1540 struct p9_trans *trans;
1541 struct p9_fd_opts opts; 990 struct p9_fd_opts opts;
1542 struct p9_trans_fd *p; 991 struct p9_trans_fd *p = NULL; /* this get allocated in p9_fd_open */
1543 992
1544 parse_opts(args, &opts); 993 parse_opts(args, &opts);
1545 994
1546 if (opts.rfd == ~0 || opts.wfd == ~0) { 995 if (opts.rfd == ~0 || opts.wfd == ~0) {
1547 printk(KERN_ERR "v9fs: Insufficient options for proto=fd\n"); 996 printk(KERN_ERR "v9fs: Insufficient options for proto=fd\n");
1548 return ERR_PTR(-ENOPROTOOPT); 997 return -ENOPROTOOPT;
1549 } 998 }
1550 999
1551 trans = kmalloc(sizeof(struct p9_trans), GFP_KERNEL); 1000 err = p9_fd_open(client, opts.rfd, opts.wfd);
1552 if (!trans)
1553 return ERR_PTR(-ENOMEM);
1554
1555 trans->rpc = p9_fd_rpc;
1556 trans->close = p9_fd_close;
1557
1558 err = p9_fd_open(trans, opts.rfd, opts.wfd);
1559 if (err < 0) 1001 if (err < 0)
1560 goto error; 1002 goto error;
1561 1003
1562 trans->msize = msize; 1004 p = (struct p9_trans_fd *) client->trans;
1563 trans->extended = extended; 1005 p->conn = p9_conn_create(client);
1564 p = (struct p9_trans_fd *) trans->priv;
1565 p->conn = p9_conn_create(trans);
1566 if (IS_ERR(p->conn)) { 1006 if (IS_ERR(p->conn)) {
1567 err = PTR_ERR(p->conn); 1007 err = PTR_ERR(p->conn);
1568 p->conn = NULL; 1008 p->conn = NULL;
1569 goto error; 1009 goto error;
1570 } 1010 }
1571 1011
1572 return trans; 1012 return 0;
1573 1013
1574error: 1014error:
1575 kfree(trans); 1015 kfree(p);
1576 return ERR_PTR(err); 1016 return err;
1577} 1017}
1578 1018
1579static struct p9_trans_module p9_tcp_trans = { 1019static struct p9_trans_module p9_tcp_trans = {
1580 .name = "tcp", 1020 .name = "tcp",
1581 .maxsize = MAX_SOCK_BUF, 1021 .maxsize = MAX_SOCK_BUF,
1582 .def = 1, 1022 .def = 1,
1583 .create = p9_trans_create_tcp, 1023 .create = p9_fd_create_tcp,
1024 .close = p9_fd_close,
1025 .request = p9_fd_request,
1026 .cancel = p9_fd_cancel,
1584 .owner = THIS_MODULE, 1027 .owner = THIS_MODULE,
1585}; 1028};
1586 1029
@@ -1588,7 +1031,10 @@ static struct p9_trans_module p9_unix_trans = {
1588 .name = "unix", 1031 .name = "unix",
1589 .maxsize = MAX_SOCK_BUF, 1032 .maxsize = MAX_SOCK_BUF,
1590 .def = 0, 1033 .def = 0,
1591 .create = p9_trans_create_unix, 1034 .create = p9_fd_create_unix,
1035 .close = p9_fd_close,
1036 .request = p9_fd_request,
1037 .cancel = p9_fd_cancel,
1592 .owner = THIS_MODULE, 1038 .owner = THIS_MODULE,
1593}; 1039};
1594 1040
@@ -1596,23 +1042,71 @@ static struct p9_trans_module p9_fd_trans = {
1596 .name = "fd", 1042 .name = "fd",
1597 .maxsize = MAX_SOCK_BUF, 1043 .maxsize = MAX_SOCK_BUF,
1598 .def = 0, 1044 .def = 0,
1599 .create = p9_trans_create_fd, 1045 .create = p9_fd_create,
1046 .close = p9_fd_close,
1047 .request = p9_fd_request,
1048 .cancel = p9_fd_cancel,
1600 .owner = THIS_MODULE, 1049 .owner = THIS_MODULE,
1601}; 1050};
1602 1051
1603int p9_trans_fd_init(void) 1052/**
1053 * p9_poll_proc - poll worker thread
1054 * @a: thread state and arguments
1055 *
1056 * polls all v9fs transports for new events and queues the appropriate
1057 * work to the work queue
1058 *
1059 */
1060
1061static int p9_poll_proc(void *a)
1604{ 1062{
1605 int i; 1063 unsigned long flags;
1064
1065 P9_DPRINTK(P9_DEBUG_TRANS, "start %p\n", current);
1066 repeat:
1067 spin_lock_irqsave(&p9_poll_lock, flags);
1068 while (!list_empty(&p9_poll_pending_list)) {
1069 struct p9_conn *conn = list_first_entry(&p9_poll_pending_list,
1070 struct p9_conn,
1071 poll_pending_link);
1072 list_del_init(&conn->poll_pending_link);
1073 spin_unlock_irqrestore(&p9_poll_lock, flags);
1074
1075 p9_poll_mux(conn);
1076
1077 spin_lock_irqsave(&p9_poll_lock, flags);
1078 }
1079 spin_unlock_irqrestore(&p9_poll_lock, flags);
1080
1081 set_current_state(TASK_INTERRUPTIBLE);
1082 if (list_empty(&p9_poll_pending_list)) {
1083 P9_DPRINTK(P9_DEBUG_TRANS, "sleeping...\n");
1084 schedule();
1085 }
1086 __set_current_state(TASK_RUNNING);
1087
1088 if (!kthread_should_stop())
1089 goto repeat;
1606 1090
1607 for (i = 0; i < ARRAY_SIZE(p9_mux_poll_tasks); i++) 1091 P9_DPRINTK(P9_DEBUG_TRANS, "finish\n");
1608 p9_mux_poll_tasks[i].task = NULL; 1092 return 0;
1093}
1609 1094
1095int p9_trans_fd_init(void)
1096{
1610 p9_mux_wq = create_workqueue("v9fs"); 1097 p9_mux_wq = create_workqueue("v9fs");
1611 if (!p9_mux_wq) { 1098 if (!p9_mux_wq) {
1612 printk(KERN_WARNING "v9fs: mux: creating workqueue failed\n"); 1099 printk(KERN_WARNING "v9fs: mux: creating workqueue failed\n");
1613 return -ENOMEM; 1100 return -ENOMEM;
1614 } 1101 }
1615 1102
1103 p9_poll_task = kthread_run(p9_poll_proc, NULL, "v9fs-poll");
1104 if (IS_ERR(p9_poll_task)) {
1105 destroy_workqueue(p9_mux_wq);
1106 printk(KERN_WARNING "v9fs: mux: creating poll task failed\n");
1107 return PTR_ERR(p9_poll_task);
1108 }
1109
1616 v9fs_register_trans(&p9_tcp_trans); 1110 v9fs_register_trans(&p9_tcp_trans);
1617 v9fs_register_trans(&p9_unix_trans); 1111 v9fs_register_trans(&p9_unix_trans);
1618 v9fs_register_trans(&p9_fd_trans); 1112 v9fs_register_trans(&p9_fd_trans);
@@ -1622,6 +1116,7 @@ int p9_trans_fd_init(void)
1622 1116
1623void p9_trans_fd_exit(void) 1117void p9_trans_fd_exit(void)
1624{ 1118{
1119 kthread_stop(p9_poll_task);
1625 v9fs_unregister_trans(&p9_tcp_trans); 1120 v9fs_unregister_trans(&p9_tcp_trans);
1626 v9fs_unregister_trans(&p9_unix_trans); 1121 v9fs_unregister_trans(&p9_unix_trans);
1627 v9fs_unregister_trans(&p9_fd_trans); 1122 v9fs_unregister_trans(&p9_fd_trans);
diff --git a/net/9p/trans_rdma.c b/net/9p/trans_rdma.c
new file mode 100644
index 000000000000..8d6cc4777aae
--- /dev/null
+++ b/net/9p/trans_rdma.c
@@ -0,0 +1,712 @@
1/*
2 * linux/fs/9p/trans_rdma.c
3 *
4 * RDMA transport layer based on the trans_fd.c implementation.
5 *
6 * Copyright (C) 2008 by Tom Tucker <tom@opengridcomputing.com>
7 * Copyright (C) 2006 by Russ Cox <rsc@swtch.com>
8 * Copyright (C) 2004-2005 by Latchesar Ionkov <lucho@ionkov.net>
9 * Copyright (C) 2004-2008 by Eric Van Hensbergen <ericvh@gmail.com>
10 * Copyright (C) 1997-2002 by Ron Minnich <rminnich@sarnoff.com>
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2
14 * as published by the Free Software Foundation.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to:
23 * Free Software Foundation
24 * 51 Franklin Street, Fifth Floor
25 * Boston, MA 02111-1301 USA
26 *
27 */
28
29#include <linux/in.h>
30#include <linux/module.h>
31#include <linux/net.h>
32#include <linux/ipv6.h>
33#include <linux/kthread.h>
34#include <linux/errno.h>
35#include <linux/kernel.h>
36#include <linux/un.h>
37#include <linux/uaccess.h>
38#include <linux/inet.h>
39#include <linux/idr.h>
40#include <linux/file.h>
41#include <linux/parser.h>
42#include <linux/semaphore.h>
43#include <net/9p/9p.h>
44#include <net/9p/client.h>
45#include <net/9p/transport.h>
46#include <rdma/ib_verbs.h>
47#include <rdma/rdma_cm.h>
48#include <rdma/ib_verbs.h>
49
50#define P9_PORT 5640
51#define P9_RDMA_SQ_DEPTH 32
52#define P9_RDMA_RQ_DEPTH 32
53#define P9_RDMA_SEND_SGE 4
54#define P9_RDMA_RECV_SGE 4
55#define P9_RDMA_IRD 0
56#define P9_RDMA_ORD 0
57#define P9_RDMA_TIMEOUT 30000 /* 30 seconds */
58#define P9_RDMA_MAXSIZE (4*4096) /* Min SGE is 4, so we can
59 * safely advertise a maxsize
60 * of 64k */
61
62#define P9_RDMA_MAX_SGE (P9_RDMA_MAXSIZE >> PAGE_SHIFT)
63/**
64 * struct p9_trans_rdma - RDMA transport instance
65 *
66 * @state: tracks the transport state machine for connection setup and tear down
67 * @cm_id: The RDMA CM ID
68 * @pd: Protection Domain pointer
69 * @qp: Queue Pair pointer
70 * @cq: Completion Queue pointer
71 * @lkey: The local access only memory region key
72 * @timeout: Number of uSecs to wait for connection management events
73 * @sq_depth: The depth of the Send Queue
74 * @sq_sem: Semaphore for the SQ
75 * @rq_depth: The depth of the Receive Queue.
76 * @addr: The remote peer's address
77 * @req_lock: Protects the active request list
78 * @send_wait: Wait list when the SQ fills up
79 * @cm_done: Completion event for connection management tracking
80 */
81struct p9_trans_rdma {
82 enum {
83 P9_RDMA_INIT,
84 P9_RDMA_ADDR_RESOLVED,
85 P9_RDMA_ROUTE_RESOLVED,
86 P9_RDMA_CONNECTED,
87 P9_RDMA_FLUSHING,
88 P9_RDMA_CLOSING,
89 P9_RDMA_CLOSED,
90 } state;
91 struct rdma_cm_id *cm_id;
92 struct ib_pd *pd;
93 struct ib_qp *qp;
94 struct ib_cq *cq;
95 struct ib_mr *dma_mr;
96 u32 lkey;
97 long timeout;
98 int sq_depth;
99 struct semaphore sq_sem;
100 int rq_depth;
101 atomic_t rq_count;
102 struct sockaddr_in addr;
103 spinlock_t req_lock;
104
105 struct completion cm_done;
106};
107
108/**
109 * p9_rdma_context - Keeps track of in-process WR
110 *
111 * @wc_op: The original WR op for when the CQE completes in error.
112 * @busa: Bus address to unmap when the WR completes
113 * @req: Keeps track of requests (send)
114 * @rc: Keepts track of replies (receive)
115 */
116struct p9_rdma_req;
117struct p9_rdma_context {
118 enum ib_wc_opcode wc_op;
119 dma_addr_t busa;
120 union {
121 struct p9_req_t *req;
122 struct p9_fcall *rc;
123 };
124};
125
126/**
127 * p9_rdma_opts - Collection of mount options
128 * @port: port of connection
129 * @sq_depth: The requested depth of the SQ. This really doesn't need
130 * to be any deeper than the number of threads used in the client
131 * @rq_depth: The depth of the RQ. Should be greater than or equal to SQ depth
132 * @timeout: Time to wait in msecs for CM events
133 */
134struct p9_rdma_opts {
135 short port;
136 int sq_depth;
137 int rq_depth;
138 long timeout;
139};
140
141/*
142 * Option Parsing (code inspired by NFS code)
143 */
144enum {
145 /* Options that take integer arguments */
146 Opt_port, Opt_rq_depth, Opt_sq_depth, Opt_timeout, Opt_err,
147};
148
149static match_table_t tokens = {
150 {Opt_port, "port=%u"},
151 {Opt_sq_depth, "sq=%u"},
152 {Opt_rq_depth, "rq=%u"},
153 {Opt_timeout, "timeout=%u"},
154 {Opt_err, NULL},
155};
156
157/**
158 * parse_options - parse mount options into session structure
159 * @options: options string passed from mount
160 * @opts: transport-specific structure to parse options into
161 *
162 * Returns 0 upon success, -ERRNO upon failure
163 */
164static int parse_opts(char *params, struct p9_rdma_opts *opts)
165{
166 char *p;
167 substring_t args[MAX_OPT_ARGS];
168 int option;
169 char *options;
170 int ret;
171
172 opts->port = P9_PORT;
173 opts->sq_depth = P9_RDMA_SQ_DEPTH;
174 opts->rq_depth = P9_RDMA_RQ_DEPTH;
175 opts->timeout = P9_RDMA_TIMEOUT;
176
177 if (!params)
178 return 0;
179
180 options = kstrdup(params, GFP_KERNEL);
181 if (!options) {
182 P9_DPRINTK(P9_DEBUG_ERROR,
183 "failed to allocate copy of option string\n");
184 return -ENOMEM;
185 }
186
187 while ((p = strsep(&options, ",")) != NULL) {
188 int token;
189 int r;
190 if (!*p)
191 continue;
192 token = match_token(p, tokens, args);
193 r = match_int(&args[0], &option);
194 if (r < 0) {
195 P9_DPRINTK(P9_DEBUG_ERROR,
196 "integer field, but no integer?\n");
197 ret = r;
198 continue;
199 }
200 switch (token) {
201 case Opt_port:
202 opts->port = option;
203 break;
204 case Opt_sq_depth:
205 opts->sq_depth = option;
206 break;
207 case Opt_rq_depth:
208 opts->rq_depth = option;
209 break;
210 case Opt_timeout:
211 opts->timeout = option;
212 break;
213 default:
214 continue;
215 }
216 }
217 /* RQ must be at least as large as the SQ */
218 opts->rq_depth = max(opts->rq_depth, opts->sq_depth);
219 kfree(options);
220 return 0;
221}
222
223static int
224p9_cm_event_handler(struct rdma_cm_id *id, struct rdma_cm_event *event)
225{
226 struct p9_client *c = id->context;
227 struct p9_trans_rdma *rdma = c->trans;
228 switch (event->event) {
229 case RDMA_CM_EVENT_ADDR_RESOLVED:
230 BUG_ON(rdma->state != P9_RDMA_INIT);
231 rdma->state = P9_RDMA_ADDR_RESOLVED;
232 break;
233
234 case RDMA_CM_EVENT_ROUTE_RESOLVED:
235 BUG_ON(rdma->state != P9_RDMA_ADDR_RESOLVED);
236 rdma->state = P9_RDMA_ROUTE_RESOLVED;
237 break;
238
239 case RDMA_CM_EVENT_ESTABLISHED:
240 BUG_ON(rdma->state != P9_RDMA_ROUTE_RESOLVED);
241 rdma->state = P9_RDMA_CONNECTED;
242 break;
243
244 case RDMA_CM_EVENT_DISCONNECTED:
245 if (rdma)
246 rdma->state = P9_RDMA_CLOSED;
247 if (c)
248 c->status = Disconnected;
249 break;
250
251 case RDMA_CM_EVENT_TIMEWAIT_EXIT:
252 break;
253
254 case RDMA_CM_EVENT_ADDR_CHANGE:
255 case RDMA_CM_EVENT_ROUTE_ERROR:
256 case RDMA_CM_EVENT_DEVICE_REMOVAL:
257 case RDMA_CM_EVENT_MULTICAST_JOIN:
258 case RDMA_CM_EVENT_MULTICAST_ERROR:
259 case RDMA_CM_EVENT_REJECTED:
260 case RDMA_CM_EVENT_CONNECT_REQUEST:
261 case RDMA_CM_EVENT_CONNECT_RESPONSE:
262 case RDMA_CM_EVENT_CONNECT_ERROR:
263 case RDMA_CM_EVENT_ADDR_ERROR:
264 case RDMA_CM_EVENT_UNREACHABLE:
265 c->status = Disconnected;
266 rdma_disconnect(rdma->cm_id);
267 break;
268 default:
269 BUG();
270 }
271 complete(&rdma->cm_done);
272 return 0;
273}
274
275static void
276handle_recv(struct p9_client *client, struct p9_trans_rdma *rdma,
277 struct p9_rdma_context *c, enum ib_wc_status status, u32 byte_len)
278{
279 struct p9_req_t *req;
280 int err = 0;
281 int16_t tag;
282
283 req = NULL;
284 ib_dma_unmap_single(rdma->cm_id->device, c->busa, client->msize,
285 DMA_FROM_DEVICE);
286
287 if (status != IB_WC_SUCCESS)
288 goto err_out;
289
290 err = p9_parse_header(c->rc, NULL, NULL, &tag, 1);
291 if (err)
292 goto err_out;
293
294 req = p9_tag_lookup(client, tag);
295 if (!req)
296 goto err_out;
297
298 req->rc = c->rc;
299 p9_client_cb(client, req);
300
301 return;
302
303 err_out:
304 P9_DPRINTK(P9_DEBUG_ERROR, "req %p err %d status %d\n",
305 req, err, status);
306 rdma->state = P9_RDMA_FLUSHING;
307 client->status = Disconnected;
308 return;
309}
310
311static void
312handle_send(struct p9_client *client, struct p9_trans_rdma *rdma,
313 struct p9_rdma_context *c, enum ib_wc_status status, u32 byte_len)
314{
315 ib_dma_unmap_single(rdma->cm_id->device,
316 c->busa, c->req->tc->size,
317 DMA_TO_DEVICE);
318}
319
320static void qp_event_handler(struct ib_event *event, void *context)
321{
322 P9_DPRINTK(P9_DEBUG_ERROR, "QP event %d context %p\n", event->event,
323 context);
324}
325
326static void cq_comp_handler(struct ib_cq *cq, void *cq_context)
327{
328 struct p9_client *client = cq_context;
329 struct p9_trans_rdma *rdma = client->trans;
330 int ret;
331 struct ib_wc wc;
332
333 ib_req_notify_cq(rdma->cq, IB_CQ_NEXT_COMP);
334 while ((ret = ib_poll_cq(cq, 1, &wc)) > 0) {
335 struct p9_rdma_context *c = (void *) (unsigned long) wc.wr_id;
336
337 switch (c->wc_op) {
338 case IB_WC_RECV:
339 atomic_dec(&rdma->rq_count);
340 handle_recv(client, rdma, c, wc.status, wc.byte_len);
341 break;
342
343 case IB_WC_SEND:
344 handle_send(client, rdma, c, wc.status, wc.byte_len);
345 up(&rdma->sq_sem);
346 break;
347
348 default:
349 printk(KERN_ERR "9prdma: unexpected completion type, "
350 "c->wc_op=%d, wc.opcode=%d, status=%d\n",
351 c->wc_op, wc.opcode, wc.status);
352 break;
353 }
354 kfree(c);
355 }
356}
357
358static void cq_event_handler(struct ib_event *e, void *v)
359{
360 P9_DPRINTK(P9_DEBUG_ERROR, "CQ event %d context %p\n", e->event, v);
361}
362
363static void rdma_destroy_trans(struct p9_trans_rdma *rdma)
364{
365 if (!rdma)
366 return;
367
368 if (rdma->dma_mr && !IS_ERR(rdma->dma_mr))
369 ib_dereg_mr(rdma->dma_mr);
370
371 if (rdma->qp && !IS_ERR(rdma->qp))
372 ib_destroy_qp(rdma->qp);
373
374 if (rdma->pd && !IS_ERR(rdma->pd))
375 ib_dealloc_pd(rdma->pd);
376
377 if (rdma->cq && !IS_ERR(rdma->cq))
378 ib_destroy_cq(rdma->cq);
379
380 if (rdma->cm_id && !IS_ERR(rdma->cm_id))
381 rdma_destroy_id(rdma->cm_id);
382
383 kfree(rdma);
384}
385
386static int
387post_recv(struct p9_client *client, struct p9_rdma_context *c)
388{
389 struct p9_trans_rdma *rdma = client->trans;
390 struct ib_recv_wr wr, *bad_wr;
391 struct ib_sge sge;
392
393 c->busa = ib_dma_map_single(rdma->cm_id->device,
394 c->rc->sdata, client->msize,
395 DMA_FROM_DEVICE);
396 if (ib_dma_mapping_error(rdma->cm_id->device, c->busa))
397 goto error;
398
399 sge.addr = c->busa;
400 sge.length = client->msize;
401 sge.lkey = rdma->lkey;
402
403 wr.next = NULL;
404 c->wc_op = IB_WC_RECV;
405 wr.wr_id = (unsigned long) c;
406 wr.sg_list = &sge;
407 wr.num_sge = 1;
408 return ib_post_recv(rdma->qp, &wr, &bad_wr);
409
410 error:
411 P9_DPRINTK(P9_DEBUG_ERROR, "EIO\n");
412 return -EIO;
413}
414
415static int rdma_request(struct p9_client *client, struct p9_req_t *req)
416{
417 struct p9_trans_rdma *rdma = client->trans;
418 struct ib_send_wr wr, *bad_wr;
419 struct ib_sge sge;
420 int err = 0;
421 unsigned long flags;
422 struct p9_rdma_context *c = NULL;
423 struct p9_rdma_context *rpl_context = NULL;
424
425 /* Allocate an fcall for the reply */
426 rpl_context = kmalloc(sizeof *rpl_context, GFP_KERNEL);
427 if (!rpl_context)
428 goto err_close;
429
430 /*
431 * If the request has a buffer, steal it, otherwise
432 * allocate a new one. Typically, requests should already
433 * have receive buffers allocated and just swap them around
434 */
435 if (!req->rc) {
436 req->rc = kmalloc(sizeof(struct p9_fcall)+client->msize,
437 GFP_KERNEL);
438 if (req->rc) {
439 req->rc->sdata = (char *) req->rc +
440 sizeof(struct p9_fcall);
441 req->rc->capacity = client->msize;
442 }
443 }
444 rpl_context->rc = req->rc;
445 if (!rpl_context->rc) {
446 kfree(rpl_context);
447 goto err_close;
448 }
449
450 /*
451 * Post a receive buffer for this request. We need to ensure
452 * there is a reply buffer available for every outstanding
453 * request. A flushed request can result in no reply for an
454 * outstanding request, so we must keep a count to avoid
455 * overflowing the RQ.
456 */
457 if (atomic_inc_return(&rdma->rq_count) <= rdma->rq_depth) {
458 err = post_recv(client, rpl_context);
459 if (err) {
460 kfree(rpl_context->rc);
461 kfree(rpl_context);
462 goto err_close;
463 }
464 } else
465 atomic_dec(&rdma->rq_count);
466
467 /* remove posted receive buffer from request structure */
468 req->rc = NULL;
469
470 /* Post the request */
471 c = kmalloc(sizeof *c, GFP_KERNEL);
472 if (!c)
473 goto err_close;
474 c->req = req;
475
476 c->busa = ib_dma_map_single(rdma->cm_id->device,
477 c->req->tc->sdata, c->req->tc->size,
478 DMA_TO_DEVICE);
479 if (ib_dma_mapping_error(rdma->cm_id->device, c->busa))
480 goto error;
481
482 sge.addr = c->busa;
483 sge.length = c->req->tc->size;
484 sge.lkey = rdma->lkey;
485
486 wr.next = NULL;
487 c->wc_op = IB_WC_SEND;
488 wr.wr_id = (unsigned long) c;
489 wr.opcode = IB_WR_SEND;
490 wr.send_flags = IB_SEND_SIGNALED;
491 wr.sg_list = &sge;
492 wr.num_sge = 1;
493
494 if (down_interruptible(&rdma->sq_sem))
495 goto error;
496
497 return ib_post_send(rdma->qp, &wr, &bad_wr);
498
499 error:
500 P9_DPRINTK(P9_DEBUG_ERROR, "EIO\n");
501 return -EIO;
502
503 err_close:
504 spin_lock_irqsave(&rdma->req_lock, flags);
505 if (rdma->state < P9_RDMA_CLOSING) {
506 rdma->state = P9_RDMA_CLOSING;
507 spin_unlock_irqrestore(&rdma->req_lock, flags);
508 rdma_disconnect(rdma->cm_id);
509 } else
510 spin_unlock_irqrestore(&rdma->req_lock, flags);
511 return err;
512}
513
514static void rdma_close(struct p9_client *client)
515{
516 struct p9_trans_rdma *rdma;
517
518 if (!client)
519 return;
520
521 rdma = client->trans;
522 if (!rdma)
523 return;
524
525 client->status = Disconnected;
526 rdma_disconnect(rdma->cm_id);
527 rdma_destroy_trans(rdma);
528}
529
530/**
531 * alloc_rdma - Allocate and initialize the rdma transport structure
532 * @msize: MTU
533 * @dotu: Extension attribute
534 * @opts: Mount options structure
535 */
536static struct p9_trans_rdma *alloc_rdma(struct p9_rdma_opts *opts)
537{
538 struct p9_trans_rdma *rdma;
539
540 rdma = kzalloc(sizeof(struct p9_trans_rdma), GFP_KERNEL);
541 if (!rdma)
542 return NULL;
543
544 rdma->sq_depth = opts->sq_depth;
545 rdma->rq_depth = opts->rq_depth;
546 rdma->timeout = opts->timeout;
547 spin_lock_init(&rdma->req_lock);
548 init_completion(&rdma->cm_done);
549 sema_init(&rdma->sq_sem, rdma->sq_depth);
550 atomic_set(&rdma->rq_count, 0);
551
552 return rdma;
553}
554
555/* its not clear to me we can do anything after send has been posted */
556static int rdma_cancel(struct p9_client *client, struct p9_req_t *req)
557{
558 return 1;
559}
560
561/**
562 * trans_create_rdma - Transport method for creating atransport instance
563 * @client: client instance
564 * @addr: IP address string
565 * @args: Mount options string
566 */
567static int
568rdma_create_trans(struct p9_client *client, const char *addr, char *args)
569{
570 int err;
571 struct p9_rdma_opts opts;
572 struct p9_trans_rdma *rdma;
573 struct rdma_conn_param conn_param;
574 struct ib_qp_init_attr qp_attr;
575 struct ib_device_attr devattr;
576
577 /* Parse the transport specific mount options */
578 err = parse_opts(args, &opts);
579 if (err < 0)
580 return err;
581
582 /* Create and initialize the RDMA transport structure */
583 rdma = alloc_rdma(&opts);
584 if (!rdma)
585 return -ENOMEM;
586
587 /* Create the RDMA CM ID */
588 rdma->cm_id = rdma_create_id(p9_cm_event_handler, client, RDMA_PS_TCP);
589 if (IS_ERR(rdma->cm_id))
590 goto error;
591
592 /* Resolve the server's address */
593 rdma->addr.sin_family = AF_INET;
594 rdma->addr.sin_addr.s_addr = in_aton(addr);
595 rdma->addr.sin_port = htons(opts.port);
596 err = rdma_resolve_addr(rdma->cm_id, NULL,
597 (struct sockaddr *)&rdma->addr,
598 rdma->timeout);
599 if (err)
600 goto error;
601 err = wait_for_completion_interruptible(&rdma->cm_done);
602 if (err || (rdma->state != P9_RDMA_ADDR_RESOLVED))
603 goto error;
604
605 /* Resolve the route to the server */
606 err = rdma_resolve_route(rdma->cm_id, rdma->timeout);
607 if (err)
608 goto error;
609 err = wait_for_completion_interruptible(&rdma->cm_done);
610 if (err || (rdma->state != P9_RDMA_ROUTE_RESOLVED))
611 goto error;
612
613 /* Query the device attributes */
614 err = ib_query_device(rdma->cm_id->device, &devattr);
615 if (err)
616 goto error;
617
618 /* Create the Completion Queue */
619 rdma->cq = ib_create_cq(rdma->cm_id->device, cq_comp_handler,
620 cq_event_handler, client,
621 opts.sq_depth + opts.rq_depth + 1, 0);
622 if (IS_ERR(rdma->cq))
623 goto error;
624 ib_req_notify_cq(rdma->cq, IB_CQ_NEXT_COMP);
625
626 /* Create the Protection Domain */
627 rdma->pd = ib_alloc_pd(rdma->cm_id->device);
628 if (IS_ERR(rdma->pd))
629 goto error;
630
631 /* Cache the DMA lkey in the transport */
632 rdma->dma_mr = NULL;
633 if (devattr.device_cap_flags & IB_DEVICE_LOCAL_DMA_LKEY)
634 rdma->lkey = rdma->cm_id->device->local_dma_lkey;
635 else {
636 rdma->dma_mr = ib_get_dma_mr(rdma->pd, IB_ACCESS_LOCAL_WRITE);
637 if (IS_ERR(rdma->dma_mr))
638 goto error;
639 rdma->lkey = rdma->dma_mr->lkey;
640 }
641
642 /* Create the Queue Pair */
643 memset(&qp_attr, 0, sizeof qp_attr);
644 qp_attr.event_handler = qp_event_handler;
645 qp_attr.qp_context = client;
646 qp_attr.cap.max_send_wr = opts.sq_depth;
647 qp_attr.cap.max_recv_wr = opts.rq_depth;
648 qp_attr.cap.max_send_sge = P9_RDMA_SEND_SGE;
649 qp_attr.cap.max_recv_sge = P9_RDMA_RECV_SGE;
650 qp_attr.sq_sig_type = IB_SIGNAL_REQ_WR;
651 qp_attr.qp_type = IB_QPT_RC;
652 qp_attr.send_cq = rdma->cq;
653 qp_attr.recv_cq = rdma->cq;
654 err = rdma_create_qp(rdma->cm_id, rdma->pd, &qp_attr);
655 if (err)
656 goto error;
657 rdma->qp = rdma->cm_id->qp;
658
659 /* Request a connection */
660 memset(&conn_param, 0, sizeof(conn_param));
661 conn_param.private_data = NULL;
662 conn_param.private_data_len = 0;
663 conn_param.responder_resources = P9_RDMA_IRD;
664 conn_param.initiator_depth = P9_RDMA_ORD;
665 err = rdma_connect(rdma->cm_id, &conn_param);
666 if (err)
667 goto error;
668 err = wait_for_completion_interruptible(&rdma->cm_done);
669 if (err || (rdma->state != P9_RDMA_CONNECTED))
670 goto error;
671
672 client->trans = rdma;
673 client->status = Connected;
674
675 return 0;
676
677error:
678 rdma_destroy_trans(rdma);
679 return -ENOTCONN;
680}
681
682static struct p9_trans_module p9_rdma_trans = {
683 .name = "rdma",
684 .maxsize = P9_RDMA_MAXSIZE,
685 .def = 0,
686 .owner = THIS_MODULE,
687 .create = rdma_create_trans,
688 .close = rdma_close,
689 .request = rdma_request,
690 .cancel = rdma_cancel,
691};
692
693/**
694 * p9_trans_rdma_init - Register the 9P RDMA transport driver
695 */
696static int __init p9_trans_rdma_init(void)
697{
698 v9fs_register_trans(&p9_rdma_trans);
699 return 0;
700}
701
702static void __exit p9_trans_rdma_exit(void)
703{
704 v9fs_unregister_trans(&p9_rdma_trans);
705}
706
707module_init(p9_trans_rdma_init);
708module_exit(p9_trans_rdma_exit);
709
710MODULE_AUTHOR("Tom Tucker <tom@opengridcomputing.com>");
711MODULE_DESCRIPTION("RDMA Transport for 9P");
712MODULE_LICENSE("Dual BSD/GPL");
diff --git a/net/9p/trans_virtio.c b/net/9p/trans_virtio.c
index 94912e077a55..2d7781ec663b 100644
--- a/net/9p/trans_virtio.c
+++ b/net/9p/trans_virtio.c
@@ -1,12 +1,10 @@
1/* 1/*
2 * The Guest 9p transport driver 2 * The Virtio 9p transport driver
3 * 3 *
4 * This is a block based transport driver based on the lguest block driver 4 * This is a block based transport driver based on the lguest block driver
5 * code. 5 * code.
6 * 6 *
7 */ 7 * Copyright (C) 2007, 2008 Eric Van Hensbergen, IBM Corporation
8/*
9 * Copyright (C) 2007 Eric Van Hensbergen, IBM Corporation
10 * 8 *
11 * Based on virtio console driver 9 * Based on virtio console driver
12 * Copyright (C) 2006, 2007 Rusty Russell, IBM Corporation 10 * Copyright (C) 2006, 2007 Rusty Russell, IBM Corporation
@@ -41,6 +39,7 @@
41#include <linux/file.h> 39#include <linux/file.h>
42#include <net/9p/9p.h> 40#include <net/9p/9p.h>
43#include <linux/parser.h> 41#include <linux/parser.h>
42#include <net/9p/client.h>
44#include <net/9p/transport.h> 43#include <net/9p/transport.h>
45#include <linux/scatterlist.h> 44#include <linux/scatterlist.h>
46#include <linux/virtio.h> 45#include <linux/virtio.h>
@@ -53,50 +52,6 @@ static DEFINE_MUTEX(virtio_9p_lock);
53/* global which tracks highest initialized channel */ 52/* global which tracks highest initialized channel */
54static int chan_index; 53static int chan_index;
55 54
56#define P9_INIT_MAXTAG 16
57
58
59/**
60 * enum p9_req_status_t - virtio request status
61 * @REQ_STATUS_IDLE: request slot unused
62 * @REQ_STATUS_SENT: request sent to server
63 * @REQ_STATUS_RCVD: response received from server
64 * @REQ_STATUS_FLSH: request has been flushed
65 *
66 * The @REQ_STATUS_IDLE state is used to mark a request slot as unused
67 * but use is actually tracked by the idpool structure which handles tag
68 * id allocation.
69 *
70 */
71
72enum p9_req_status_t {
73 REQ_STATUS_IDLE,
74 REQ_STATUS_SENT,
75 REQ_STATUS_RCVD,
76 REQ_STATUS_FLSH,
77};
78
79/**
80 * struct p9_req_t - virtio request slots
81 * @status: status of this request slot
82 * @wq: wait_queue for the client to block on for this request
83 *
84 * The virtio transport uses an array to track outstanding requests
85 * instead of a list. While this may incurr overhead during initial
86 * allocation or expansion, it makes request lookup much easier as the
87 * tag id is a index into an array. (We use tag+1 so that we can accomodate
88 * the -1 tag for the T_VERSION request).
89 * This also has the nice effect of only having to allocate wait_queues
90 * once, instead of constantly allocating and freeing them. Its possible
91 * other resources could benefit from this scheme as well.
92 *
93 */
94
95struct p9_req_t {
96 int status;
97 wait_queue_head_t *wq;
98};
99
100/** 55/**
101 * struct virtio_chan - per-instance transport information 56 * struct virtio_chan - per-instance transport information
102 * @initialized: whether the channel is initialized 57 * @initialized: whether the channel is initialized
@@ -121,67 +76,14 @@ static struct virtio_chan {
121 76
122 spinlock_t lock; 77 spinlock_t lock;
123 78
79 struct p9_client *client;
124 struct virtio_device *vdev; 80 struct virtio_device *vdev;
125 struct virtqueue *vq; 81 struct virtqueue *vq;
126 82
127 struct p9_idpool *tagpool;
128 struct p9_req_t *reqs;
129 int max_tag;
130
131 /* Scatterlist: can be too big for stack. */ 83 /* Scatterlist: can be too big for stack. */
132 struct scatterlist sg[VIRTQUEUE_NUM]; 84 struct scatterlist sg[VIRTQUEUE_NUM];
133} channels[MAX_9P_CHAN]; 85} channels[MAX_9P_CHAN];
134 86
135/**
136 * p9_lookup_tag - Lookup requests by tag
137 * @c: virtio channel to lookup tag within
138 * @tag: numeric id for transaction
139 *
140 * this is a simple array lookup, but will grow the
141 * request_slots as necessary to accomodate transaction
142 * ids which did not previously have a slot.
143 *
144 * Bugs: there is currently no upper limit on request slots set
145 * here, but that should be constrained by the id accounting.
146 */
147
148static struct p9_req_t *p9_lookup_tag(struct virtio_chan *c, u16 tag)
149{
150 /* This looks up the original request by tag so we know which
151 * buffer to read the data into */
152 tag++;
153
154 while (tag >= c->max_tag) {
155 int old_max = c->max_tag;
156 int count;
157
158 if (c->max_tag)
159 c->max_tag *= 2;
160 else
161 c->max_tag = P9_INIT_MAXTAG;
162
163 c->reqs = krealloc(c->reqs, sizeof(struct p9_req_t)*c->max_tag,
164 GFP_ATOMIC);
165 if (!c->reqs) {
166 printk(KERN_ERR "Couldn't grow tag array\n");
167 BUG();
168 }
169 for (count = old_max; count < c->max_tag; count++) {
170 c->reqs[count].status = REQ_STATUS_IDLE;
171 c->reqs[count].wq = kmalloc(sizeof(wait_queue_head_t),
172 GFP_ATOMIC);
173 if (!c->reqs[count].wq) {
174 printk(KERN_ERR "Couldn't grow tag array\n");
175 BUG();
176 }
177 init_waitqueue_head(c->reqs[count].wq);
178 }
179 }
180
181 return &c->reqs[tag];
182}
183
184
185/* How many bytes left in this page. */ 87/* How many bytes left in this page. */
186static unsigned int rest_of_page(void *data) 88static unsigned int rest_of_page(void *data)
187{ 89{
@@ -197,25 +99,13 @@ static unsigned int rest_of_page(void *data)
197 * 99 *
198 */ 100 */
199 101
200static void p9_virtio_close(struct p9_trans *trans) 102static void p9_virtio_close(struct p9_client *client)
201{ 103{
202 struct virtio_chan *chan = trans->priv; 104 struct virtio_chan *chan = client->trans;
203 int count;
204 unsigned long flags;
205
206 spin_lock_irqsave(&chan->lock, flags);
207 p9_idpool_destroy(chan->tagpool);
208 for (count = 0; count < chan->max_tag; count++)
209 kfree(chan->reqs[count].wq);
210 kfree(chan->reqs);
211 chan->max_tag = 0;
212 spin_unlock_irqrestore(&chan->lock, flags);
213 105
214 mutex_lock(&virtio_9p_lock); 106 mutex_lock(&virtio_9p_lock);
215 chan->inuse = false; 107 chan->inuse = false;
216 mutex_unlock(&virtio_9p_lock); 108 mutex_unlock(&virtio_9p_lock);
217
218 kfree(trans);
219} 109}
220 110
221/** 111/**
@@ -236,17 +126,16 @@ static void req_done(struct virtqueue *vq)
236 struct virtio_chan *chan = vq->vdev->priv; 126 struct virtio_chan *chan = vq->vdev->priv;
237 struct p9_fcall *rc; 127 struct p9_fcall *rc;
238 unsigned int len; 128 unsigned int len;
239 unsigned long flags;
240 struct p9_req_t *req; 129 struct p9_req_t *req;
241 130
242 spin_lock_irqsave(&chan->lock, flags); 131 P9_DPRINTK(P9_DEBUG_TRANS, ": request done\n");
132
243 while ((rc = chan->vq->vq_ops->get_buf(chan->vq, &len)) != NULL) { 133 while ((rc = chan->vq->vq_ops->get_buf(chan->vq, &len)) != NULL) {
244 req = p9_lookup_tag(chan, rc->tag); 134 P9_DPRINTK(P9_DEBUG_TRANS, ": rc %p\n", rc);
245 req->status = REQ_STATUS_RCVD; 135 P9_DPRINTK(P9_DEBUG_TRANS, ": lookup tag %d\n", rc->tag);
246 wake_up(req->wq); 136 req = p9_tag_lookup(chan->client, rc->tag);
137 p9_client_cb(chan->client, req);
247 } 138 }
248 /* In case queue is stopped waiting for more buffers. */
249 spin_unlock_irqrestore(&chan->lock, flags);
250} 139}
251 140
252/** 141/**
@@ -283,8 +172,14 @@ pack_sg_list(struct scatterlist *sg, int start, int limit, char *data,
283 return index-start; 172 return index-start;
284} 173}
285 174
175/* We don't currently allow canceling of virtio requests */
176static int p9_virtio_cancel(struct p9_client *client, struct p9_req_t *req)
177{
178 return 1;
179}
180
286/** 181/**
287 * p9_virtio_rpc - issue a request and wait for a response 182 * p9_virtio_request - issue a request
288 * @t: transport state 183 * @t: transport state
289 * @tc: &p9_fcall request to transmit 184 * @tc: &p9_fcall request to transmit
290 * @rc: &p9_fcall to put reponse into 185 * @rc: &p9_fcall to put reponse into
@@ -292,44 +187,22 @@ pack_sg_list(struct scatterlist *sg, int start, int limit, char *data,
292 */ 187 */
293 188
294static int 189static int
295p9_virtio_rpc(struct p9_trans *t, struct p9_fcall *tc, struct p9_fcall **rc) 190p9_virtio_request(struct p9_client *client, struct p9_req_t *req)
296{ 191{
297 int in, out; 192 int in, out;
298 int n, err, size; 193 struct virtio_chan *chan = client->trans;
299 struct virtio_chan *chan = t->priv; 194 char *rdata = (char *)req->rc+sizeof(struct p9_fcall);
300 char *rdata;
301 struct p9_req_t *req;
302 unsigned long flags;
303
304 if (*rc == NULL) {
305 *rc = kmalloc(sizeof(struct p9_fcall) + t->msize, GFP_KERNEL);
306 if (!*rc)
307 return -ENOMEM;
308 }
309
310 rdata = (char *)*rc+sizeof(struct p9_fcall);
311
312 n = P9_NOTAG;
313 if (tc->id != P9_TVERSION) {
314 n = p9_idpool_get(chan->tagpool);
315 if (n < 0)
316 return -ENOMEM;
317 }
318
319 spin_lock_irqsave(&chan->lock, flags);
320 req = p9_lookup_tag(chan, n);
321 spin_unlock_irqrestore(&chan->lock, flags);
322 195
323 p9_set_tag(tc, n); 196 P9_DPRINTK(P9_DEBUG_TRANS, "9p debug: virtio request\n");
324 197
325 P9_DPRINTK(P9_DEBUG_TRANS, "9p debug: virtio rpc tag %d\n", n); 198 out = pack_sg_list(chan->sg, 0, VIRTQUEUE_NUM, req->tc->sdata,
326 199 req->tc->size);
327 out = pack_sg_list(chan->sg, 0, VIRTQUEUE_NUM, tc->sdata, tc->size); 200 in = pack_sg_list(chan->sg, out, VIRTQUEUE_NUM-out, rdata,
328 in = pack_sg_list(chan->sg, out, VIRTQUEUE_NUM-out, rdata, t->msize); 201 client->msize);
329 202
330 req->status = REQ_STATUS_SENT; 203 req->status = REQ_STATUS_SENT;
331 204
332 if (chan->vq->vq_ops->add_buf(chan->vq, chan->sg, out, in, tc)) { 205 if (chan->vq->vq_ops->add_buf(chan->vq, chan->sg, out, in, req->tc)) {
333 P9_DPRINTK(P9_DEBUG_TRANS, 206 P9_DPRINTK(P9_DEBUG_TRANS,
334 "9p debug: virtio rpc add_buf returned failure"); 207 "9p debug: virtio rpc add_buf returned failure");
335 return -EIO; 208 return -EIO;
@@ -337,31 +210,7 @@ p9_virtio_rpc(struct p9_trans *t, struct p9_fcall *tc, struct p9_fcall **rc)
337 210
338 chan->vq->vq_ops->kick(chan->vq); 211 chan->vq->vq_ops->kick(chan->vq);
339 212
340 wait_event(*req->wq, req->status == REQ_STATUS_RCVD); 213 P9_DPRINTK(P9_DEBUG_TRANS, "9p debug: virtio request kicked\n");
341
342 size = le32_to_cpu(*(__le32 *) rdata);
343
344 err = p9_deserialize_fcall(rdata, size, *rc, t->extended);
345 if (err < 0) {
346 P9_DPRINTK(P9_DEBUG_TRANS,
347 "9p debug: virtio rpc deserialize returned %d\n", err);
348 return err;
349 }
350
351#ifdef CONFIG_NET_9P_DEBUG
352 if ((p9_debug_level&P9_DEBUG_FCALL) == P9_DEBUG_FCALL) {
353 char buf[150];
354
355 p9_printfcall(buf, sizeof(buf), *rc, t->extended);
356 printk(KERN_NOTICE ">>> %p %s\n", t, buf);
357 }
358#endif
359
360 if (n != P9_NOTAG && p9_idpool_check(n, chan->tagpool))
361 p9_idpool_put(n, chan->tagpool);
362
363 req->status = REQ_STATUS_IDLE;
364
365 return 0; 214 return 0;
366} 215}
367 216
@@ -422,10 +271,9 @@ fail:
422 271
423/** 272/**
424 * p9_virtio_create - allocate a new virtio channel 273 * p9_virtio_create - allocate a new virtio channel
274 * @client: client instance invoking this transport
425 * @devname: string identifying the channel to connect to (unused) 275 * @devname: string identifying the channel to connect to (unused)
426 * @args: args passed from sys_mount() for per-transport options (unused) 276 * @args: args passed from sys_mount() for per-transport options (unused)
427 * @msize: requested maximum packet size
428 * @extended: 9p2000.u enabled flag
429 * 277 *
430 * This sets up a transport channel for 9p communication. Right now 278 * This sets up a transport channel for 9p communication. Right now
431 * we only match the first available channel, but eventually we couldlook up 279 * we only match the first available channel, but eventually we couldlook up
@@ -441,11 +289,9 @@ fail:
441 * 289 *
442 */ 290 */
443 291
444static struct p9_trans * 292static int
445p9_virtio_create(const char *devname, char *args, int msize, 293p9_virtio_create(struct p9_client *client, const char *devname, char *args)
446 unsigned char extended)
447{ 294{
448 struct p9_trans *trans;
449 struct virtio_chan *chan = channels; 295 struct virtio_chan *chan = channels;
450 int index = 0; 296 int index = 0;
451 297
@@ -463,30 +309,13 @@ p9_virtio_create(const char *devname, char *args, int msize,
463 309
464 if (index >= MAX_9P_CHAN) { 310 if (index >= MAX_9P_CHAN) {
465 printk(KERN_ERR "9p: no channels available\n"); 311 printk(KERN_ERR "9p: no channels available\n");
466 return ERR_PTR(-ENODEV); 312 return -ENODEV;
467 } 313 }
468 314
469 chan->tagpool = p9_idpool_create(); 315 client->trans = (void *)chan;
470 if (IS_ERR(chan->tagpool)) { 316 chan->client = client;
471 printk(KERN_ERR "9p: couldn't allocate tagpool\n");
472 return ERR_PTR(-ENOMEM);
473 }
474 p9_idpool_get(chan->tagpool); /* reserve tag 0 */
475 chan->max_tag = 0;
476 chan->reqs = NULL;
477
478 trans = kmalloc(sizeof(struct p9_trans), GFP_KERNEL);
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 317
489 return trans; 318 return 0;
490} 319}
491 320
492/** 321/**
@@ -526,6 +355,9 @@ static struct virtio_driver p9_virtio_drv = {
526static struct p9_trans_module p9_virtio_trans = { 355static struct p9_trans_module p9_virtio_trans = {
527 .name = "virtio", 356 .name = "virtio",
528 .create = p9_virtio_create, 357 .create = p9_virtio_create,
358 .close = p9_virtio_close,
359 .request = p9_virtio_request,
360 .cancel = p9_virtio_cancel,
529 .maxsize = PAGE_SIZE*16, 361 .maxsize = PAGE_SIZE*16,
530 .def = 0, 362 .def = 0,
531 .owner = THIS_MODULE, 363 .owner = THIS_MODULE,
diff --git a/net/9p/util.c b/net/9p/util.c
index 958fc58cd1ff..dc4ec05ad93d 100644
--- a/net/9p/util.c
+++ b/net/9p/util.c
@@ -105,6 +105,7 @@ retry:
105 else if (error) 105 else if (error)
106 return -1; 106 return -1;
107 107
108 P9_DPRINTK(P9_DEBUG_MUX, " id %d pool %p\n", i, p);
108 return i; 109 return i;
109} 110}
110EXPORT_SYMBOL(p9_idpool_get); 111EXPORT_SYMBOL(p9_idpool_get);
@@ -121,6 +122,9 @@ EXPORT_SYMBOL(p9_idpool_get);
121void p9_idpool_put(int id, struct p9_idpool *p) 122void p9_idpool_put(int id, struct p9_idpool *p)
122{ 123{
123 unsigned long flags; 124 unsigned long flags;
125
126 P9_DPRINTK(P9_DEBUG_MUX, " id %d pool %p\n", id, p);
127
124 spin_lock_irqsave(&p->lock, flags); 128 spin_lock_irqsave(&p->lock, flags);
125 idr_remove(&p->pool, id); 129 idr_remove(&p->pool, id);
126 spin_unlock_irqrestore(&p->lock, flags); 130 spin_unlock_irqrestore(&p->lock, flags);
diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c
index f6348e078aa4..8f9431a12c6f 100644
--- a/net/bluetooth/af_bluetooth.c
+++ b/net/bluetooth/af_bluetooth.c
@@ -37,10 +37,7 @@
37#include <linux/poll.h> 37#include <linux/poll.h>
38#include <net/sock.h> 38#include <net/sock.h>
39#include <asm/ioctls.h> 39#include <asm/ioctls.h>
40
41#if defined(CONFIG_KMOD)
42#include <linux/kmod.h> 40#include <linux/kmod.h>
43#endif
44 41
45#include <net/bluetooth/bluetooth.h> 42#include <net/bluetooth/bluetooth.h>
46 43
@@ -145,11 +142,8 @@ static int bt_sock_create(struct net *net, struct socket *sock, int proto)
145 if (proto < 0 || proto >= BT_MAX_PROTO) 142 if (proto < 0 || proto >= BT_MAX_PROTO)
146 return -EINVAL; 143 return -EINVAL;
147 144
148#if defined(CONFIG_KMOD) 145 if (!bt_proto[proto])
149 if (!bt_proto[proto]) {
150 request_module("bt-proto-%d", proto); 146 request_module("bt-proto-%d", proto);
151 }
152#endif
153 147
154 err = -EPROTONOSUPPORT; 148 err = -EPROTONOSUPPORT;
155 149
diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c
index 22ba8632196f..6c023f0f8252 100644
--- a/net/bridge/br_device.c
+++ b/net/bridge/br_device.c
@@ -179,5 +179,5 @@ void br_dev_setup(struct net_device *dev)
179 179
180 dev->features = NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_HIGHDMA | 180 dev->features = NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_HIGHDMA |
181 NETIF_F_GSO_MASK | NETIF_F_NO_CSUM | NETIF_F_LLTX | 181 NETIF_F_GSO_MASK | NETIF_F_NO_CSUM | NETIF_F_LLTX |
182 NETIF_F_NETNS_LOCAL; 182 NETIF_F_NETNS_LOCAL | NETIF_F_GSO;
183} 183}
diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c
index 573e20f7dba4..0a09ccf68c1c 100644
--- a/net/bridge/br_if.c
+++ b/net/bridge/br_if.c
@@ -347,15 +347,21 @@ int br_min_mtu(const struct net_bridge *br)
347void br_features_recompute(struct net_bridge *br) 347void br_features_recompute(struct net_bridge *br)
348{ 348{
349 struct net_bridge_port *p; 349 struct net_bridge_port *p;
350 unsigned long features; 350 unsigned long features, mask;
351 351
352 features = br->feature_mask; 352 features = mask = br->feature_mask;
353 if (list_empty(&br->port_list))
354 goto done;
355
356 features &= ~NETIF_F_ONE_FOR_ALL;
353 357
354 list_for_each_entry(p, &br->port_list, list) { 358 list_for_each_entry(p, &br->port_list, list) {
355 features = netdev_compute_features(features, p->dev->features); 359 features = netdev_increment_features(features,
360 p->dev->features, mask);
356 } 361 }
357 362
358 br->dev->features = features; 363done:
364 br->dev->features = netdev_fix_features(features, NULL);
359} 365}
360 366
361/* called with RTNL */ 367/* called with RTNL */
diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c
index a4abed5b4c44..fa5cda4e552a 100644
--- a/net/bridge/br_netfilter.c
+++ b/net/bridge/br_netfilter.c
@@ -719,7 +719,7 @@ static unsigned int br_nf_forward_arp(unsigned int hook, struct sk_buff *skb,
719 return NF_ACCEPT; 719 return NF_ACCEPT;
720 } 720 }
721 *d = (struct net_device *)in; 721 *d = (struct net_device *)in;
722 NF_HOOK(NF_ARP, NF_ARP_FORWARD, skb, (struct net_device *)in, 722 NF_HOOK(NFPROTO_ARP, NF_ARP_FORWARD, skb, (struct net_device *)in,
723 (struct net_device *)out, br_nf_forward_finish); 723 (struct net_device *)out, br_nf_forward_finish);
724 724
725 return NF_STOLEN; 725 return NF_STOLEN;
diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c
index 5bb88eb0aad4..0fa208e86405 100644
--- a/net/bridge/netfilter/ebtables.c
+++ b/net/bridge/netfilter/ebtables.c
@@ -305,23 +305,14 @@ find_inlist_lock_noload(struct list_head *head, const char *name, int *error,
305 return NULL; 305 return NULL;
306} 306}
307 307
308#ifndef CONFIG_KMOD
309#define find_inlist_lock(h,n,p,e,m) find_inlist_lock_noload((h),(n),(e),(m))
310#else
311static void * 308static void *
312find_inlist_lock(struct list_head *head, const char *name, const char *prefix, 309find_inlist_lock(struct list_head *head, const char *name, const char *prefix,
313 int *error, struct mutex *mutex) 310 int *error, struct mutex *mutex)
314{ 311{
315 void *ret; 312 return try_then_request_module(
316 313 find_inlist_lock_noload(head, name, error, mutex),
317 ret = find_inlist_lock_noload(head, name, error, mutex); 314 "%s%s", prefix, name);
318 if (!ret) {
319 request_module("%s%s", prefix, name);
320 ret = find_inlist_lock_noload(head, name, error, mutex);
321 }
322 return ret;
323} 315}
324#endif
325 316
326static inline struct ebt_table * 317static inline struct ebt_table *
327find_table_lock(const char *name, int *error, struct mutex *mutex) 318find_table_lock(const char *name, int *error, struct mutex *mutex)
diff --git a/net/can/af_can.c b/net/can/af_can.c
index 8035fbf526ae..7d4d2b3c137e 100644
--- a/net/can/af_can.c
+++ b/net/can/af_can.c
@@ -128,8 +128,8 @@ static int can_create(struct net *net, struct socket *sock, int protocol)
128 if (net != &init_net) 128 if (net != &init_net)
129 return -EAFNOSUPPORT; 129 return -EAFNOSUPPORT;
130 130
131#ifdef CONFIG_KMOD 131#ifdef CONFIG_MODULES
132 /* try to load protocol module, when CONFIG_KMOD is defined */ 132 /* try to load protocol module kernel is modular */
133 if (!proto_tab[protocol]) { 133 if (!proto_tab[protocol]) {
134 err = request_module("can-proto-%d", protocol); 134 err = request_module("can-proto-%d", protocol);
135 135
diff --git a/net/core/dev.c b/net/core/dev.c
index 1408a083fe4e..d9038e328cc1 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -924,10 +924,10 @@ int dev_change_name(struct net_device *dev, const char *newname)
924 strlcpy(dev->name, newname, IFNAMSIZ); 924 strlcpy(dev->name, newname, IFNAMSIZ);
925 925
926rollback: 926rollback:
927 err = device_rename(&dev->dev, dev->name); 927 ret = device_rename(&dev->dev, dev->name);
928 if (err) { 928 if (ret) {
929 memcpy(dev->name, oldname, IFNAMSIZ); 929 memcpy(dev->name, oldname, IFNAMSIZ);
930 return err; 930 return ret;
931 } 931 }
932 932
933 write_lock_bh(&dev_base_lock); 933 write_lock_bh(&dev_base_lock);
@@ -3947,6 +3947,46 @@ static void netdev_init_queue_locks(struct net_device *dev)
3947 __netdev_init_queue_locks_one(dev, &dev->rx_queue, NULL); 3947 __netdev_init_queue_locks_one(dev, &dev->rx_queue, NULL);
3948} 3948}
3949 3949
3950unsigned long netdev_fix_features(unsigned long features, const char *name)
3951{
3952 /* Fix illegal SG+CSUM combinations. */
3953 if ((features & NETIF_F_SG) &&
3954 !(features & NETIF_F_ALL_CSUM)) {
3955 if (name)
3956 printk(KERN_NOTICE "%s: Dropping NETIF_F_SG since no "
3957 "checksum feature.\n", name);
3958 features &= ~NETIF_F_SG;
3959 }
3960
3961 /* TSO requires that SG is present as well. */
3962 if ((features & NETIF_F_TSO) && !(features & NETIF_F_SG)) {
3963 if (name)
3964 printk(KERN_NOTICE "%s: Dropping NETIF_F_TSO since no "
3965 "SG feature.\n", name);
3966 features &= ~NETIF_F_TSO;
3967 }
3968
3969 if (features & NETIF_F_UFO) {
3970 if (!(features & NETIF_F_GEN_CSUM)) {
3971 if (name)
3972 printk(KERN_ERR "%s: Dropping NETIF_F_UFO "
3973 "since no NETIF_F_HW_CSUM feature.\n",
3974 name);
3975 features &= ~NETIF_F_UFO;
3976 }
3977
3978 if (!(features & NETIF_F_SG)) {
3979 if (name)
3980 printk(KERN_ERR "%s: Dropping NETIF_F_UFO "
3981 "since no NETIF_F_SG feature.\n", name);
3982 features &= ~NETIF_F_UFO;
3983 }
3984 }
3985
3986 return features;
3987}
3988EXPORT_SYMBOL(netdev_fix_features);
3989
3950/** 3990/**
3951 * register_netdevice - register a network device 3991 * register_netdevice - register a network device
3952 * @dev: device to register 3992 * @dev: device to register
@@ -4032,36 +4072,7 @@ int register_netdevice(struct net_device *dev)
4032 dev->features &= ~(NETIF_F_IP_CSUM|NETIF_F_IPV6_CSUM|NETIF_F_HW_CSUM); 4072 dev->features &= ~(NETIF_F_IP_CSUM|NETIF_F_IPV6_CSUM|NETIF_F_HW_CSUM);
4033 } 4073 }
4034 4074
4035 4075 dev->features = netdev_fix_features(dev->features, dev->name);
4036 /* Fix illegal SG+CSUM combinations. */
4037 if ((dev->features & NETIF_F_SG) &&
4038 !(dev->features & NETIF_F_ALL_CSUM)) {
4039 printk(KERN_NOTICE "%s: Dropping NETIF_F_SG since no checksum feature.\n",
4040 dev->name);
4041 dev->features &= ~NETIF_F_SG;
4042 }
4043
4044 /* TSO requires that SG is present as well. */
4045 if ((dev->features & NETIF_F_TSO) &&
4046 !(dev->features & NETIF_F_SG)) {
4047 printk(KERN_NOTICE "%s: Dropping NETIF_F_TSO since no SG feature.\n",
4048 dev->name);
4049 dev->features &= ~NETIF_F_TSO;
4050 }
4051 if (dev->features & NETIF_F_UFO) {
4052 if (!(dev->features & NETIF_F_HW_CSUM)) {
4053 printk(KERN_ERR "%s: Dropping NETIF_F_UFO since no "
4054 "NETIF_F_HW_CSUM feature.\n",
4055 dev->name);
4056 dev->features &= ~NETIF_F_UFO;
4057 }
4058 if (!(dev->features & NETIF_F_SG)) {
4059 printk(KERN_ERR "%s: Dropping NETIF_F_UFO since no "
4060 "NETIF_F_SG feature.\n",
4061 dev->name);
4062 dev->features &= ~NETIF_F_UFO;
4063 }
4064 }
4065 4076
4066 /* Enable software GSO if SG is supported. */ 4077 /* Enable software GSO if SG is supported. */
4067 if (dev->features & NETIF_F_SG) 4078 if (dev->features & NETIF_F_SG)
@@ -4700,49 +4711,45 @@ static int __init netdev_dma_register(void) { return -ENODEV; }
4700#endif /* CONFIG_NET_DMA */ 4711#endif /* CONFIG_NET_DMA */
4701 4712
4702/** 4713/**
4703 * netdev_compute_feature - compute conjunction of two feature sets 4714 * netdev_increment_features - increment feature set by one
4704 * @all: first feature set 4715 * @all: current feature set
4705 * @one: second feature set 4716 * @one: new feature set
4717 * @mask: mask feature set
4706 * 4718 *
4707 * Computes a new feature set after adding a device with feature set 4719 * Computes a new feature set after adding a device with feature set
4708 * @one to the master device with current feature set @all. Returns 4720 * @one to the master device with current feature set @all. Will not
4709 * the new feature set. 4721 * enable anything that is off in @mask. Returns the new feature set.
4710 */ 4722 */
4711int netdev_compute_features(unsigned long all, unsigned long one) 4723unsigned long netdev_increment_features(unsigned long all, unsigned long one,
4712{ 4724 unsigned long mask)
4713 /* if device needs checksumming, downgrade to hw checksumming */ 4725{
4714 if (all & NETIF_F_NO_CSUM && !(one & NETIF_F_NO_CSUM)) 4726 /* If device needs checksumming, downgrade to it. */
4715 all ^= NETIF_F_NO_CSUM | NETIF_F_HW_CSUM; 4727 if (all & NETIF_F_NO_CSUM && !(one & NETIF_F_NO_CSUM))
4716 4728 all ^= NETIF_F_NO_CSUM | (one & NETIF_F_ALL_CSUM);
4717 /* if device can't do all checksum, downgrade to ipv4/ipv6 */ 4729 else if (mask & NETIF_F_ALL_CSUM) {
4718 if (all & NETIF_F_HW_CSUM && !(one & NETIF_F_HW_CSUM)) 4730 /* If one device supports v4/v6 checksumming, set for all. */
4719 all ^= NETIF_F_HW_CSUM 4731 if (one & (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM) &&
4720 | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM; 4732 !(all & NETIF_F_GEN_CSUM)) {
4721 4733 all &= ~NETIF_F_ALL_CSUM;
4722 if (one & NETIF_F_GSO) 4734 all |= one & (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM);
4723 one |= NETIF_F_GSO_SOFTWARE; 4735 }
4724 one |= NETIF_F_GSO;
4725
4726 /*
4727 * If even one device supports a GSO protocol with software fallback,
4728 * enable it for all.
4729 */
4730 all |= one & NETIF_F_GSO_SOFTWARE;
4731 4736
4732 /* If even one device supports robust GSO, enable it for all. */ 4737 /* If one device supports hw checksumming, set for all. */
4733 if (one & NETIF_F_GSO_ROBUST) 4738 if (one & NETIF_F_GEN_CSUM && !(all & NETIF_F_GEN_CSUM)) {
4734 all |= NETIF_F_GSO_ROBUST; 4739 all &= ~NETIF_F_ALL_CSUM;
4740 all |= NETIF_F_HW_CSUM;
4741 }
4742 }
4735 4743
4736 all &= one | NETIF_F_LLTX; 4744 one |= NETIF_F_ALL_CSUM;
4737 4745
4738 if (!(all & NETIF_F_ALL_CSUM)) 4746 one |= all & NETIF_F_ONE_FOR_ALL;
4739 all &= ~NETIF_F_SG; 4747 all &= one | NETIF_F_LLTX | NETIF_F_GSO;
4740 if (!(all & NETIF_F_SG)) 4748 all |= one & mask & NETIF_F_ONE_FOR_ALL;
4741 all &= ~NETIF_F_GSO_MASK;
4742 4749
4743 return all; 4750 return all;
4744} 4751}
4745EXPORT_SYMBOL(netdev_compute_features); 4752EXPORT_SYMBOL(netdev_increment_features);
4746 4753
4747static struct hlist_head *netdev_create_hash(void) 4754static struct hlist_head *netdev_create_hash(void)
4748{ 4755{
@@ -4956,8 +4963,6 @@ EXPORT_SYMBOL(br_fdb_get_hook);
4956EXPORT_SYMBOL(br_fdb_put_hook); 4963EXPORT_SYMBOL(br_fdb_put_hook);
4957#endif 4964#endif
4958 4965
4959#ifdef CONFIG_KMOD
4960EXPORT_SYMBOL(dev_load); 4966EXPORT_SYMBOL(dev_load);
4961#endif
4962 4967
4963EXPORT_PER_CPU_SYMBOL(softnet_data); 4968EXPORT_PER_CPU_SYMBOL(softnet_data);
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 3630131fa1fa..31f29d2989fd 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -1040,7 +1040,7 @@ static int rtnl_newlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
1040 struct nlattr *linkinfo[IFLA_INFO_MAX+1]; 1040 struct nlattr *linkinfo[IFLA_INFO_MAX+1];
1041 int err; 1041 int err;
1042 1042
1043#ifdef CONFIG_KMOD 1043#ifdef CONFIG_MODULES
1044replay: 1044replay:
1045#endif 1045#endif
1046 err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFLA_MAX, ifla_policy); 1046 err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFLA_MAX, ifla_policy);
@@ -1129,7 +1129,7 @@ replay:
1129 return -EOPNOTSUPP; 1129 return -EOPNOTSUPP;
1130 1130
1131 if (!ops) { 1131 if (!ops) {
1132#ifdef CONFIG_KMOD 1132#ifdef CONFIG_MODULES
1133 if (kind[0]) { 1133 if (kind[0]) {
1134 __rtnl_unlock(); 1134 __rtnl_unlock();
1135 request_module("rtnl-link-%s", kind); 1135 request_module("rtnl-link-%s", kind);
diff --git a/net/dccp/ccid.c b/net/dccp/ccid.c
index 4809753d12ae..8fe931a3d7a1 100644
--- a/net/dccp/ccid.c
+++ b/net/dccp/ccid.c
@@ -154,7 +154,7 @@ struct ccid *ccid_new(unsigned char id, struct sock *sk, int rx, gfp_t gfp)
154 struct ccid *ccid = NULL; 154 struct ccid *ccid = NULL;
155 155
156 ccids_read_lock(); 156 ccids_read_lock();
157#ifdef CONFIG_KMOD 157#ifdef CONFIG_MODULES
158 if (ccids[id] == NULL) { 158 if (ccids[id] == NULL) {
159 /* We only try to load if in process context */ 159 /* We only try to load if in process context */
160 ccids_read_unlock(); 160 ccids_read_unlock();
diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c
index 11062780bb02..d4ce1224e008 100644
--- a/net/dccp/ipv6.c
+++ b/net/dccp/ipv6.c
@@ -259,7 +259,7 @@ static int dccp_v6_send_response(struct sock *sk, struct request_sock *req)
259 fl.fl6_flowlabel = 0; 259 fl.fl6_flowlabel = 0;
260 fl.oif = ireq6->iif; 260 fl.oif = ireq6->iif;
261 fl.fl_ip_dport = inet_rsk(req)->rmt_port; 261 fl.fl_ip_dport = inet_rsk(req)->rmt_port;
262 fl.fl_ip_sport = inet_sk(sk)->sport; 262 fl.fl_ip_sport = inet_rsk(req)->loc_port;
263 security_req_classify_flow(req, &fl); 263 security_req_classify_flow(req, &fl);
264 264
265 opt = np->opt; 265 opt = np->opt;
@@ -558,7 +558,7 @@ static struct sock *dccp_v6_request_recv_sock(struct sock *sk,
558 ipv6_addr_copy(&fl.fl6_src, &ireq6->loc_addr); 558 ipv6_addr_copy(&fl.fl6_src, &ireq6->loc_addr);
559 fl.oif = sk->sk_bound_dev_if; 559 fl.oif = sk->sk_bound_dev_if;
560 fl.fl_ip_dport = inet_rsk(req)->rmt_port; 560 fl.fl_ip_dport = inet_rsk(req)->rmt_port;
561 fl.fl_ip_sport = inet_sk(sk)->sport; 561 fl.fl_ip_sport = inet_rsk(req)->loc_port;
562 security_sk_classify_flow(sk, &fl); 562 security_sk_classify_flow(sk, &fl);
563 563
564 if (ip6_dst_lookup(sk, &dst, &fl)) 564 if (ip6_dst_lookup(sk, &dst, &fl))
diff --git a/net/dccp/minisocks.c b/net/dccp/minisocks.c
index b2804e2d1b8c..e6bf99e3e41a 100644
--- a/net/dccp/minisocks.c
+++ b/net/dccp/minisocks.c
@@ -309,6 +309,7 @@ void dccp_reqsk_init(struct request_sock *req, struct sk_buff *skb)
309 struct dccp_request_sock *dreq = dccp_rsk(req); 309 struct dccp_request_sock *dreq = dccp_rsk(req);
310 310
311 inet_rsk(req)->rmt_port = dccp_hdr(skb)->dccph_sport; 311 inet_rsk(req)->rmt_port = dccp_hdr(skb)->dccph_sport;
312 inet_rsk(req)->loc_port = dccp_hdr(skb)->dccph_dport;
312 inet_rsk(req)->acked = 0; 313 inet_rsk(req)->acked = 0;
313 req->rcv_wnd = sysctl_dccp_feat_sequence_window; 314 req->rcv_wnd = sysctl_dccp_feat_sequence_window;
314 dreq->dreq_timestamp_echo = 0; 315 dreq->dreq_timestamp_echo = 0;
diff --git a/net/dccp/output.c b/net/dccp/output.c
index d06945c7d3df..809d803d5006 100644
--- a/net/dccp/output.c
+++ b/net/dccp/output.c
@@ -347,7 +347,7 @@ struct sk_buff *dccp_make_response(struct sock *sk, struct dst_entry *dst,
347 /* Build and checksum header */ 347 /* Build and checksum header */
348 dh = dccp_zeroed_hdr(skb, dccp_header_size); 348 dh = dccp_zeroed_hdr(skb, dccp_header_size);
349 349
350 dh->dccph_sport = inet_sk(sk)->sport; 350 dh->dccph_sport = inet_rsk(req)->loc_port;
351 dh->dccph_dport = inet_rsk(req)->rmt_port; 351 dh->dccph_dport = inet_rsk(req)->rmt_port;
352 dh->dccph_doff = (dccp_header_size + 352 dh->dccph_doff = (dccp_header_size +
353 DCCP_SKB_CB(skb)->dccpd_opt_len) / 4; 353 DCCP_SKB_CB(skb)->dccpd_opt_len) / 4;
diff --git a/net/decnet/dn_dev.c b/net/decnet/dn_dev.c
index 8008c8613027..28e26bd08e24 100644
--- a/net/decnet/dn_dev.c
+++ b/net/decnet/dn_dev.c
@@ -490,9 +490,7 @@ int dn_dev_ioctl(unsigned int cmd, void __user *arg)
490 return -EFAULT; 490 return -EFAULT;
491 ifr->ifr_name[IFNAMSIZ-1] = 0; 491 ifr->ifr_name[IFNAMSIZ-1] = 0;
492 492
493#ifdef CONFIG_KMOD
494 dev_load(&init_net, ifr->ifr_name); 493 dev_load(&init_net, ifr->ifr_name);
495#endif
496 494
497 switch(cmd) { 495 switch(cmd) {
498 case SIOCGIFADDR: 496 case SIOCGIFADDR:
diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c
index b043eda60b04..1a9dd66511fc 100644
--- a/net/ipv4/arp.c
+++ b/net/ipv4/arp.c
@@ -663,7 +663,7 @@ out:
663void arp_xmit(struct sk_buff *skb) 663void arp_xmit(struct sk_buff *skb)
664{ 664{
665 /* Send it off, maybe filter it using firewalling first. */ 665 /* Send it off, maybe filter it using firewalling first. */
666 NF_HOOK(NF_ARP, NF_ARP_OUT, skb, NULL, skb->dev, dev_queue_xmit); 666 NF_HOOK(NFPROTO_ARP, NF_ARP_OUT, skb, NULL, skb->dev, dev_queue_xmit);
667} 667}
668 668
669/* 669/*
@@ -928,7 +928,7 @@ static int arp_rcv(struct sk_buff *skb, struct net_device *dev,
928 928
929 memset(NEIGH_CB(skb), 0, sizeof(struct neighbour_cb)); 929 memset(NEIGH_CB(skb), 0, sizeof(struct neighbour_cb));
930 930
931 return NF_HOOK(NF_ARP, NF_ARP_IN, skb, dev, NULL, arp_process); 931 return NF_HOOK(NFPROTO_ARP, NF_ARP_IN, skb, dev, NULL, arp_process);
932 932
933freeskb: 933freeskb:
934 kfree_skb(skb); 934 kfree_skb(skb);
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
index 5154e729cf16..56fce3ab6c55 100644
--- a/net/ipv4/devinet.c
+++ b/net/ipv4/devinet.c
@@ -613,9 +613,7 @@ int devinet_ioctl(struct net *net, unsigned int cmd, void __user *arg)
613 if (colon) 613 if (colon)
614 *colon = 0; 614 *colon = 0;
615 615
616#ifdef CONFIG_KMOD
617 dev_load(net, ifr.ifr_name); 616 dev_load(net, ifr.ifr_name);
618#endif
619 617
620 switch (cmd) { 618 switch (cmd) {
621 case SIOCGIFADDR: /* Get interface address */ 619 case SIOCGIFADDR: /* Get interface address */
diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c
index 89cb047ab314..564230dabcb8 100644
--- a/net/ipv4/inet_diag.c
+++ b/net/ipv4/inet_diag.c
@@ -53,11 +53,9 @@ static DEFINE_MUTEX(inet_diag_table_mutex);
53 53
54static const struct inet_diag_handler *inet_diag_lock_handler(int type) 54static const struct inet_diag_handler *inet_diag_lock_handler(int type)
55{ 55{
56#ifdef CONFIG_KMOD
57 if (!inet_diag_table[type]) 56 if (!inet_diag_table[type])
58 request_module("net-pf-%d-proto-%d-type-%d", PF_NETLINK, 57 request_module("net-pf-%d-proto-%d-type-%d", PF_NETLINK,
59 NETLINK_INET_DIAG, type); 58 NETLINK_INET_DIAG, type);
60#endif
61 59
62 mutex_lock(&inet_diag_table_mutex); 60 mutex_lock(&inet_diag_table_mutex);
63 if (!inet_diag_table[type]) 61 if (!inet_diag_table[type])
diff --git a/net/ipv4/netfilter/nf_nat_snmp_basic.c b/net/ipv4/netfilter/nf_nat_snmp_basic.c
index ffeaffc3fffe..8303e4b406c0 100644
--- a/net/ipv4/netfilter/nf_nat_snmp_basic.c
+++ b/net/ipv4/netfilter/nf_nat_snmp_basic.c
@@ -742,6 +742,7 @@ static unsigned char snmp_object_decode(struct asn1_ctx *ctx,
742 *obj = kmalloc(sizeof(struct snmp_object) + len, 742 *obj = kmalloc(sizeof(struct snmp_object) + len,
743 GFP_ATOMIC); 743 GFP_ATOMIC);
744 if (*obj == NULL) { 744 if (*obj == NULL) {
745 kfree(p);
745 kfree(id); 746 kfree(id);
746 if (net_ratelimit()) 747 if (net_ratelimit())
747 printk("OOM in bsalg (%d)\n", __LINE__); 748 printk("OOM in bsalg (%d)\n", __LINE__);
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index 942be04e7955..2ea6dcc3e2cc 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -1109,7 +1109,12 @@ restart:
1109 printk("\n"); 1109 printk("\n");
1110 } 1110 }
1111#endif 1111#endif
1112 rt_hash_table[hash].chain = rt; 1112 /*
1113 * Since lookup is lockfree, we must make sure
1114 * previous writes to rt are comitted to memory
1115 * before making rt visible to other CPUS.
1116 */
1117 rcu_assign_pointer(rt_hash_table[hash].chain, rt);
1113 spin_unlock_bh(rt_hash_lock_addr(hash)); 1118 spin_unlock_bh(rt_hash_lock_addr(hash));
1114 *rp = rt; 1119 *rp = rt;
1115 return 0; 1120 return 0;
diff --git a/net/ipv4/tcp_cong.c b/net/ipv4/tcp_cong.c
index 6a250828b767..4ec5b4e97c4e 100644
--- a/net/ipv4/tcp_cong.c
+++ b/net/ipv4/tcp_cong.c
@@ -115,7 +115,7 @@ int tcp_set_default_congestion_control(const char *name)
115 115
116 spin_lock(&tcp_cong_list_lock); 116 spin_lock(&tcp_cong_list_lock);
117 ca = tcp_ca_find(name); 117 ca = tcp_ca_find(name);
118#ifdef CONFIG_KMOD 118#ifdef CONFIG_MODULES
119 if (!ca && capable(CAP_SYS_MODULE)) { 119 if (!ca && capable(CAP_SYS_MODULE)) {
120 spin_unlock(&tcp_cong_list_lock); 120 spin_unlock(&tcp_cong_list_lock);
121 121
@@ -244,7 +244,7 @@ int tcp_set_congestion_control(struct sock *sk, const char *name)
244 if (ca == icsk->icsk_ca_ops) 244 if (ca == icsk->icsk_ca_ops)
245 goto out; 245 goto out;
246 246
247#ifdef CONFIG_KMOD 247#ifdef CONFIG_MODULES
248 /* not found attempt to autoload module */ 248 /* not found attempt to autoload module */
249 if (!ca && capable(CAP_SYS_MODULE)) { 249 if (!ca && capable(CAP_SYS_MODULE)) {
250 rcu_read_unlock(); 250 rcu_read_unlock();
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index 990a58493235..e4c5ac9fe89b 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -362,6 +362,17 @@ struct tcp_out_options {
362 __u32 tsval, tsecr; /* need to include OPTION_TS */ 362 __u32 tsval, tsecr; /* need to include OPTION_TS */
363}; 363};
364 364
365/* Beware: Something in the Internet is very sensitive to the ordering of
366 * TCP options, we learned this through the hard way, so be careful here.
367 * Luckily we can at least blame others for their non-compliance but from
368 * inter-operatibility perspective it seems that we're somewhat stuck with
369 * the ordering which we have been using if we want to keep working with
370 * those broken things (not that it currently hurts anybody as there isn't
371 * particular reason why the ordering would need to be changed).
372 *
373 * At least SACK_PERM as the first option is known to lead to a disaster
374 * (but it may well be that other scenarios fail similarly).
375 */
365static void tcp_options_write(__be32 *ptr, struct tcp_sock *tp, 376static void tcp_options_write(__be32 *ptr, struct tcp_sock *tp,
366 const struct tcp_out_options *opts, 377 const struct tcp_out_options *opts,
367 __u8 **md5_hash) { 378 __u8 **md5_hash) {
@@ -376,6 +387,12 @@ static void tcp_options_write(__be32 *ptr, struct tcp_sock *tp,
376 *md5_hash = NULL; 387 *md5_hash = NULL;
377 } 388 }
378 389
390 if (unlikely(opts->mss)) {
391 *ptr++ = htonl((TCPOPT_MSS << 24) |
392 (TCPOLEN_MSS << 16) |
393 opts->mss);
394 }
395
379 if (likely(OPTION_TS & opts->options)) { 396 if (likely(OPTION_TS & opts->options)) {
380 if (unlikely(OPTION_SACK_ADVERTISE & opts->options)) { 397 if (unlikely(OPTION_SACK_ADVERTISE & opts->options)) {
381 *ptr++ = htonl((TCPOPT_SACK_PERM << 24) | 398 *ptr++ = htonl((TCPOPT_SACK_PERM << 24) |
@@ -392,12 +409,6 @@ static void tcp_options_write(__be32 *ptr, struct tcp_sock *tp,
392 *ptr++ = htonl(opts->tsecr); 409 *ptr++ = htonl(opts->tsecr);
393 } 410 }
394 411
395 if (unlikely(opts->mss)) {
396 *ptr++ = htonl((TCPOPT_MSS << 24) |
397 (TCPOLEN_MSS << 16) |
398 opts->mss);
399 }
400
401 if (unlikely(OPTION_SACK_ADVERTISE & opts->options && 412 if (unlikely(OPTION_SACK_ADVERTISE & opts->options &&
402 !(OPTION_TS & opts->options))) { 413 !(OPTION_TS & opts->options))) {
403 *ptr++ = htonl((TCPOPT_NOP << 24) | 414 *ptr++ = htonl((TCPOPT_NOP << 24) |
@@ -432,7 +443,7 @@ static void tcp_options_write(__be32 *ptr, struct tcp_sock *tp,
432 443
433 if (tp->rx_opt.dsack) { 444 if (tp->rx_opt.dsack) {
434 tp->rx_opt.dsack = 0; 445 tp->rx_opt.dsack = 0;
435 tp->rx_opt.eff_sacks--; 446 tp->rx_opt.eff_sacks = tp->rx_opt.num_sacks;
436 } 447 }
437 } 448 }
438} 449}
diff --git a/net/ipv6/syncookies.c b/net/ipv6/syncookies.c
index ec394cf5a19b..676c80b5b14b 100644
--- a/net/ipv6/syncookies.c
+++ b/net/ipv6/syncookies.c
@@ -204,6 +204,7 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb)
204 204
205 req->mss = mss; 205 req->mss = mss;
206 ireq->rmt_port = th->source; 206 ireq->rmt_port = th->source;
207 ireq->loc_port = th->dest;
207 ipv6_addr_copy(&ireq6->rmt_addr, &ipv6_hdr(skb)->saddr); 208 ipv6_addr_copy(&ireq6->rmt_addr, &ipv6_hdr(skb)->saddr);
208 ipv6_addr_copy(&ireq6->loc_addr, &ipv6_hdr(skb)->daddr); 209 ipv6_addr_copy(&ireq6->loc_addr, &ipv6_hdr(skb)->daddr);
209 if (ipv6_opt_accepted(sk, skb) || 210 if (ipv6_opt_accepted(sk, skb) ||
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index e5310c9b84dc..b6b356b7912a 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -476,7 +476,7 @@ static int tcp_v6_send_synack(struct sock *sk, struct request_sock *req)
476 fl.fl6_flowlabel = 0; 476 fl.fl6_flowlabel = 0;
477 fl.oif = treq->iif; 477 fl.oif = treq->iif;
478 fl.fl_ip_dport = inet_rsk(req)->rmt_port; 478 fl.fl_ip_dport = inet_rsk(req)->rmt_port;
479 fl.fl_ip_sport = inet_sk(sk)->sport; 479 fl.fl_ip_sport = inet_rsk(req)->loc_port;
480 security_req_classify_flow(req, &fl); 480 security_req_classify_flow(req, &fl);
481 481
482 opt = np->opt; 482 opt = np->opt;
@@ -1309,7 +1309,7 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
1309 ipv6_addr_copy(&fl.fl6_src, &treq->loc_addr); 1309 ipv6_addr_copy(&fl.fl6_src, &treq->loc_addr);
1310 fl.oif = sk->sk_bound_dev_if; 1310 fl.oif = sk->sk_bound_dev_if;
1311 fl.fl_ip_dport = inet_rsk(req)->rmt_port; 1311 fl.fl_ip_dport = inet_rsk(req)->rmt_port;
1312 fl.fl_ip_sport = inet_sk(sk)->sport; 1312 fl.fl_ip_sport = inet_rsk(req)->loc_port;
1313 security_req_classify_flow(req, &fl); 1313 security_req_classify_flow(req, &fl);
1314 1314
1315 if (ip6_dst_lookup(sk, &dst, &fl)) 1315 if (ip6_dst_lookup(sk, &dst, &fl))
@@ -1865,7 +1865,7 @@ static void get_openreq6(struct seq_file *seq,
1865 i, 1865 i,
1866 src->s6_addr32[0], src->s6_addr32[1], 1866 src->s6_addr32[0], src->s6_addr32[1],
1867 src->s6_addr32[2], src->s6_addr32[3], 1867 src->s6_addr32[2], src->s6_addr32[3],
1868 ntohs(inet_sk(sk)->sport), 1868 ntohs(inet_rsk(req)->loc_port),
1869 dest->s6_addr32[0], dest->s6_addr32[1], 1869 dest->s6_addr32[0], dest->s6_addr32[1],
1870 dest->s6_addr32[2], dest->s6_addr32[3], 1870 dest->s6_addr32[2], dest->s6_addr32[3],
1871 ntohs(inet_rsk(req)->rmt_port), 1871 ntohs(inet_rsk(req)->rmt_port),
diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig
index 78892cf2b021..25dcef9f2194 100644
--- a/net/netfilter/Kconfig
+++ b/net/netfilter/Kconfig
@@ -271,7 +271,6 @@ config NF_CONNTRACK_TFTP
271config NF_CT_NETLINK 271config NF_CT_NETLINK
272 tristate 'Connection tracking netlink interface' 272 tristate 'Connection tracking netlink interface'
273 select NETFILTER_NETLINK 273 select NETFILTER_NETLINK
274 depends on NF_NAT=n || NF_NAT
275 default m if NETFILTER_ADVANCED=n 274 default m if NETFILTER_ADVANCED=n
276 help 275 help
277 This option enables support for a netlink-based userspace interface 276 This option enables support for a netlink-based userspace interface
diff --git a/net/netfilter/ipvs/Kconfig b/net/netfilter/ipvs/Kconfig
index 05048e403266..79a698052218 100644
--- a/net/netfilter/ipvs/Kconfig
+++ b/net/netfilter/ipvs/Kconfig
@@ -25,11 +25,13 @@ menuconfig IP_VS
25if IP_VS 25if IP_VS
26 26
27config IP_VS_IPV6 27config IP_VS_IPV6
28 bool "IPv6 support for IPVS (DANGEROUS)" 28 bool "IPv6 support for IPVS"
29 depends on EXPERIMENTAL && (IPV6 = y || IP_VS = IPV6) 29 depends on EXPERIMENTAL && (IPV6 = y || IP_VS = IPV6)
30 ---help--- 30 ---help---
31 Add IPv6 support to IPVS. This is incomplete and might be dangerous. 31 Add IPv6 support to IPVS. This is incomplete and might be dangerous.
32 32
33 See http://www.mindbasket.com/ipvs for more information.
34
33 Say N if unsure. 35 Say N if unsure.
34 36
35config IP_VS_DEBUG 37config IP_VS_DEBUG
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c
index 08e82d64eb6f..a040d46f85d6 100644
--- a/net/netfilter/nf_conntrack_netlink.c
+++ b/net/netfilter/nf_conntrack_netlink.c
@@ -813,6 +813,7 @@ out:
813 return err; 813 return err;
814} 814}
815 815
816#ifdef CONFIG_NF_NAT_NEEDED
816static int 817static int
817ctnetlink_parse_nat_setup(struct nf_conn *ct, 818ctnetlink_parse_nat_setup(struct nf_conn *ct,
818 enum nf_nat_manip_type manip, 819 enum nf_nat_manip_type manip,
@@ -822,7 +823,7 @@ ctnetlink_parse_nat_setup(struct nf_conn *ct,
822 823
823 parse_nat_setup = rcu_dereference(nfnetlink_parse_nat_setup_hook); 824 parse_nat_setup = rcu_dereference(nfnetlink_parse_nat_setup_hook);
824 if (!parse_nat_setup) { 825 if (!parse_nat_setup) {
825#ifdef CONFIG_KMOD 826#ifdef CONFIG_MODULES
826 rcu_read_unlock(); 827 rcu_read_unlock();
827 nfnl_unlock(); 828 nfnl_unlock();
828 if (request_module("nf-nat-ipv4") < 0) { 829 if (request_module("nf-nat-ipv4") < 0) {
@@ -840,6 +841,7 @@ ctnetlink_parse_nat_setup(struct nf_conn *ct,
840 841
841 return parse_nat_setup(ct, manip, attr); 842 return parse_nat_setup(ct, manip, attr);
842} 843}
844#endif
843 845
844static int 846static int
845ctnetlink_change_status(struct nf_conn *ct, struct nlattr *cda[]) 847ctnetlink_change_status(struct nf_conn *ct, struct nlattr *cda[])
diff --git a/net/netfilter/nfnetlink.c b/net/netfilter/nfnetlink.c
index 4739f9f961d8..9c0ba17a1ddb 100644
--- a/net/netfilter/nfnetlink.c
+++ b/net/netfilter/nfnetlink.c
@@ -137,7 +137,7 @@ static int nfnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
137replay: 137replay:
138 ss = nfnetlink_get_subsys(type); 138 ss = nfnetlink_get_subsys(type);
139 if (!ss) { 139 if (!ss) {
140#ifdef CONFIG_KMOD 140#ifdef CONFIG_MODULES
141 nfnl_unlock(); 141 nfnl_unlock();
142 request_module("nfnetlink-subsys-%d", NFNL_SUBSYS_ID(type)); 142 request_module("nfnetlink-subsys-%d", NFNL_SUBSYS_ID(type));
143 nfnl_lock(); 143 nfnl_lock();
diff --git a/net/netfilter/xt_NFQUEUE.c b/net/netfilter/xt_NFQUEUE.c
index 2cc1fff49307..f9977b3311f7 100644
--- a/net/netfilter/xt_NFQUEUE.c
+++ b/net/netfilter/xt_NFQUEUE.c
@@ -48,7 +48,7 @@ static struct xt_target nfqueue_tg_reg[] __read_mostly = {
48 }, 48 },
49 { 49 {
50 .name = "NFQUEUE", 50 .name = "NFQUEUE",
51 .family = NF_ARP, 51 .family = NFPROTO_ARP,
52 .target = nfqueue_tg, 52 .target = nfqueue_tg,
53 .targetsize = sizeof(struct xt_NFQ_info), 53 .targetsize = sizeof(struct xt_NFQ_info),
54 .me = THIS_MODULE, 54 .me = THIS_MODULE,
diff --git a/net/netfilter/xt_iprange.c b/net/netfilter/xt_iprange.c
index 6f62c36948d9..7ac54eab0b00 100644
--- a/net/netfilter/xt_iprange.c
+++ b/net/netfilter/xt_iprange.c
@@ -61,7 +61,7 @@ iprange_mt4(const struct sk_buff *skb, const struct xt_match_param *par)
61 if (info->flags & IPRANGE_SRC) { 61 if (info->flags & IPRANGE_SRC) {
62 m = ntohl(iph->saddr) < ntohl(info->src_min.ip); 62 m = ntohl(iph->saddr) < ntohl(info->src_min.ip);
63 m |= ntohl(iph->saddr) > ntohl(info->src_max.ip); 63 m |= ntohl(iph->saddr) > ntohl(info->src_max.ip);
64 m ^= info->flags & IPRANGE_SRC_INV; 64 m ^= !!(info->flags & IPRANGE_SRC_INV);
65 if (m) { 65 if (m) {
66 pr_debug("src IP " NIPQUAD_FMT " NOT in range %s" 66 pr_debug("src IP " NIPQUAD_FMT " NOT in range %s"
67 NIPQUAD_FMT "-" NIPQUAD_FMT "\n", 67 NIPQUAD_FMT "-" NIPQUAD_FMT "\n",
@@ -75,7 +75,7 @@ iprange_mt4(const struct sk_buff *skb, const struct xt_match_param *par)
75 if (info->flags & IPRANGE_DST) { 75 if (info->flags & IPRANGE_DST) {
76 m = ntohl(iph->daddr) < ntohl(info->dst_min.ip); 76 m = ntohl(iph->daddr) < ntohl(info->dst_min.ip);
77 m |= ntohl(iph->daddr) > ntohl(info->dst_max.ip); 77 m |= ntohl(iph->daddr) > ntohl(info->dst_max.ip);
78 m ^= info->flags & IPRANGE_DST_INV; 78 m ^= !!(info->flags & IPRANGE_DST_INV);
79 if (m) { 79 if (m) {
80 pr_debug("dst IP " NIPQUAD_FMT " NOT in range %s" 80 pr_debug("dst IP " NIPQUAD_FMT " NOT in range %s"
81 NIPQUAD_FMT "-" NIPQUAD_FMT "\n", 81 NIPQUAD_FMT "-" NIPQUAD_FMT "\n",
@@ -114,14 +114,14 @@ iprange_mt6(const struct sk_buff *skb, const struct xt_match_param *par)
114 if (info->flags & IPRANGE_SRC) { 114 if (info->flags & IPRANGE_SRC) {
115 m = iprange_ipv6_sub(&iph->saddr, &info->src_min.in6) < 0; 115 m = iprange_ipv6_sub(&iph->saddr, &info->src_min.in6) < 0;
116 m |= iprange_ipv6_sub(&iph->saddr, &info->src_max.in6) > 0; 116 m |= iprange_ipv6_sub(&iph->saddr, &info->src_max.in6) > 0;
117 m ^= info->flags & IPRANGE_SRC_INV; 117 m ^= !!(info->flags & IPRANGE_SRC_INV);
118 if (m) 118 if (m)
119 return false; 119 return false;
120 } 120 }
121 if (info->flags & IPRANGE_DST) { 121 if (info->flags & IPRANGE_DST) {
122 m = iprange_ipv6_sub(&iph->daddr, &info->dst_min.in6) < 0; 122 m = iprange_ipv6_sub(&iph->daddr, &info->dst_min.in6) < 0;
123 m |= iprange_ipv6_sub(&iph->daddr, &info->dst_max.in6) > 0; 123 m |= iprange_ipv6_sub(&iph->daddr, &info->dst_max.in6) > 0;
124 m ^= info->flags & IPRANGE_DST_INV; 124 m ^= !!(info->flags & IPRANGE_DST_INV);
125 if (m) 125 if (m)
126 return false; 126 return false;
127 } 127 }
diff --git a/net/netfilter/xt_recent.c b/net/netfilter/xt_recent.c
index 4ebd4ca9a991..280c471bcdf4 100644
--- a/net/netfilter/xt_recent.c
+++ b/net/netfilter/xt_recent.c
@@ -318,15 +318,15 @@ static bool recent_mt_check(const struct xt_mtchk_param *par)
318 for (i = 0; i < ip_list_hash_size; i++) 318 for (i = 0; i < ip_list_hash_size; i++)
319 INIT_LIST_HEAD(&t->iphash[i]); 319 INIT_LIST_HEAD(&t->iphash[i]);
320#ifdef CONFIG_PROC_FS 320#ifdef CONFIG_PROC_FS
321 t->proc = proc_create(t->name, ip_list_perms, recent_proc_dir, 321 t->proc = proc_create_data(t->name, ip_list_perms, recent_proc_dir,
322 &recent_mt_fops); 322 &recent_mt_fops, t);
323 if (t->proc == NULL) { 323 if (t->proc == NULL) {
324 kfree(t); 324 kfree(t);
325 goto out; 325 goto out;
326 } 326 }
327#ifdef CONFIG_NETFILTER_XT_MATCH_RECENT_PROC_COMPAT 327#ifdef CONFIG_NETFILTER_XT_MATCH_RECENT_PROC_COMPAT
328 t->proc_old = proc_create(t->name, ip_list_perms, proc_old_dir, 328 t->proc_old = proc_create_data(t->name, ip_list_perms, proc_old_dir,
329 &recent_old_fops); 329 &recent_old_fops, t);
330 if (t->proc_old == NULL) { 330 if (t->proc_old == NULL) {
331 remove_proc_entry(t->name, proc_old_dir); 331 remove_proc_entry(t->name, proc_old_dir);
332 kfree(t); 332 kfree(t);
@@ -334,11 +334,9 @@ static bool recent_mt_check(const struct xt_mtchk_param *par)
334 } 334 }
335 t->proc_old->uid = ip_list_uid; 335 t->proc_old->uid = ip_list_uid;
336 t->proc_old->gid = ip_list_gid; 336 t->proc_old->gid = ip_list_gid;
337 t->proc_old->data = t;
338#endif 337#endif
339 t->proc->uid = ip_list_uid; 338 t->proc->uid = ip_list_uid;
340 t->proc->gid = ip_list_gid; 339 t->proc->gid = ip_list_gid;
341 t->proc->data = t;
342#endif 340#endif
343 spin_lock_bh(&recent_lock); 341 spin_lock_bh(&recent_lock);
344 list_add_tail(&t->list, &tables); 342 list_add_tail(&t->list, &tables);
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index 2fd8afac5f71..480184a857d2 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -435,7 +435,7 @@ static int netlink_create(struct net *net, struct socket *sock, int protocol)
435 return -EPROTONOSUPPORT; 435 return -EPROTONOSUPPORT;
436 436
437 netlink_lock_table(); 437 netlink_lock_table();
438#ifdef CONFIG_KMOD 438#ifdef CONFIG_MODULES
439 if (!nl_table[protocol].registered) { 439 if (!nl_table[protocol].registered) {
440 netlink_unlock_table(); 440 netlink_unlock_table();
441 request_module("net-pf-%d-proto-%d", PF_NETLINK, protocol); 441 request_module("net-pf-%d-proto-%d", PF_NETLINK, protocol);
diff --git a/net/phonet/af_phonet.c b/net/phonet/af_phonet.c
index 9e9c6fce11aa..b9d97effebe3 100644
--- a/net/phonet/af_phonet.c
+++ b/net/phonet/af_phonet.c
@@ -67,11 +67,10 @@ static int pn_socket_create(struct net *net, struct socket *sock, int protocol)
67 } 67 }
68 68
69 pnp = phonet_proto_get(protocol); 69 pnp = phonet_proto_get(protocol);
70#ifdef CONFIG_KMOD
71 if (pnp == NULL && 70 if (pnp == NULL &&
72 request_module("net-pf-%d-proto-%d", PF_PHONET, protocol) == 0) 71 request_module("net-pf-%d-proto-%d", PF_PHONET, protocol) == 0)
73 pnp = phonet_proto_get(protocol); 72 pnp = phonet_proto_get(protocol);
74#endif 73
75 if (pnp == NULL) 74 if (pnp == NULL)
76 return -EPROTONOSUPPORT; 75 return -EPROTONOSUPPORT;
77 if (sock->type != pnp->sock_type) { 76 if (sock->type != pnp->sock_type) {
diff --git a/net/sched/act_api.c b/net/sched/act_api.c
index 9974b3f04f05..8f457f1e0acf 100644
--- a/net/sched/act_api.c
+++ b/net/sched/act_api.c
@@ -494,7 +494,7 @@ struct tc_action *tcf_action_init_1(struct nlattr *nla, struct nlattr *est,
494 494
495 a_o = tc_lookup_action_n(act_name); 495 a_o = tc_lookup_action_n(act_name);
496 if (a_o == NULL) { 496 if (a_o == NULL) {
497#ifdef CONFIG_KMOD 497#ifdef CONFIG_MODULES
498 rtnl_unlock(); 498 rtnl_unlock();
499 request_module("act_%s", act_name); 499 request_module("act_%s", act_name);
500 rtnl_lock(); 500 rtnl_lock();
diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c
index 8eb79e92e94c..16e7ac9774e5 100644
--- a/net/sched/cls_api.c
+++ b/net/sched/cls_api.c
@@ -227,7 +227,7 @@ replay:
227 err = -ENOENT; 227 err = -ENOENT;
228 tp_ops = tcf_proto_lookup_ops(tca[TCA_KIND]); 228 tp_ops = tcf_proto_lookup_ops(tca[TCA_KIND]);
229 if (tp_ops == NULL) { 229 if (tp_ops == NULL) {
230#ifdef CONFIG_KMOD 230#ifdef CONFIG_MODULES
231 struct nlattr *kind = tca[TCA_KIND]; 231 struct nlattr *kind = tca[TCA_KIND];
232 char name[IFNAMSIZ]; 232 char name[IFNAMSIZ];
233 233
diff --git a/net/sched/ematch.c b/net/sched/ematch.c
index 5e6f82e0e6f3..e82519e548d7 100644
--- a/net/sched/ematch.c
+++ b/net/sched/ematch.c
@@ -224,7 +224,7 @@ static int tcf_em_validate(struct tcf_proto *tp,
224 224
225 if (em->ops == NULL) { 225 if (em->ops == NULL) {
226 err = -ENOENT; 226 err = -ENOENT;
227#ifdef CONFIG_KMOD 227#ifdef CONFIG_MODULES
228 __rtnl_unlock(); 228 __rtnl_unlock();
229 request_module("ematch-kind-%u", em_hdr->kind); 229 request_module("ematch-kind-%u", em_hdr->kind);
230 rtnl_lock(); 230 rtnl_lock();
diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c
index 1122c952aa99..b16ad2972c6b 100644
--- a/net/sched/sch_api.c
+++ b/net/sched/sch_api.c
@@ -764,7 +764,7 @@ qdisc_create(struct net_device *dev, struct netdev_queue *dev_queue,
764 struct qdisc_size_table *stab; 764 struct qdisc_size_table *stab;
765 765
766 ops = qdisc_lookup_ops(kind); 766 ops = qdisc_lookup_ops(kind);
767#ifdef CONFIG_KMOD 767#ifdef CONFIG_MODULES
768 if (ops == NULL && kind != NULL) { 768 if (ops == NULL && kind != NULL) {
769 char name[IFNAMSIZ]; 769 char name[IFNAMSIZ];
770 if (nla_strlcpy(name, kind, IFNAMSIZ) < IFNAMSIZ) { 770 if (nla_strlcpy(name, kind, IFNAMSIZ) < IFNAMSIZ) {
diff --git a/net/sched/sch_cbq.c b/net/sched/sch_cbq.c
index 8b06fa900482..03e389e8d945 100644
--- a/net/sched/sch_cbq.c
+++ b/net/sched/sch_cbq.c
@@ -545,9 +545,10 @@ static void cbq_ovl_delay(struct cbq_class *cl)
545 expires = ktime_set(0, 0); 545 expires = ktime_set(0, 0);
546 expires = ktime_add_ns(expires, PSCHED_US2NS(sched)); 546 expires = ktime_add_ns(expires, PSCHED_US2NS(sched));
547 if (hrtimer_try_to_cancel(&q->delay_timer) && 547 if (hrtimer_try_to_cancel(&q->delay_timer) &&
548 ktime_to_ns(ktime_sub(q->delay_timer.expires, 548 ktime_to_ns(ktime_sub(
549 expires)) > 0) 549 hrtimer_get_expires(&q->delay_timer),
550 q->delay_timer.expires = expires; 550 expires)) > 0)
551 hrtimer_set_expires(&q->delay_timer, expires);
551 hrtimer_restart(&q->delay_timer); 552 hrtimer_restart(&q->delay_timer);
552 cl->delayed = 1; 553 cl->delayed = 1;
553 cl->xstats.overactions++; 554 cl->xstats.overactions++;
diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c
index 7b5572d6beb5..93cd30ce6501 100644
--- a/net/sched/sch_generic.c
+++ b/net/sched/sch_generic.c
@@ -326,6 +326,7 @@ struct Qdisc_ops noop_qdisc_ops __read_mostly = {
326 326
327static struct netdev_queue noop_netdev_queue = { 327static struct netdev_queue noop_netdev_queue = {
328 .qdisc = &noop_qdisc, 328 .qdisc = &noop_qdisc,
329 .qdisc_sleeping = &noop_qdisc,
329}; 330};
330 331
331struct Qdisc noop_qdisc = { 332struct Qdisc noop_qdisc = {
@@ -352,6 +353,7 @@ static struct Qdisc_ops noqueue_qdisc_ops __read_mostly = {
352static struct Qdisc noqueue_qdisc; 353static struct Qdisc noqueue_qdisc;
353static struct netdev_queue noqueue_netdev_queue = { 354static struct netdev_queue noqueue_netdev_queue = {
354 .qdisc = &noqueue_qdisc, 355 .qdisc = &noqueue_qdisc,
356 .qdisc_sleeping = &noqueue_qdisc,
355}; 357};
356 358
357static struct Qdisc noqueue_qdisc = { 359static struct Qdisc noqueue_qdisc = {
diff --git a/net/sctp/input.c b/net/sctp/input.c
index a49fa80b57b9..bf612d954d41 100644
--- a/net/sctp/input.c
+++ b/net/sctp/input.c
@@ -369,7 +369,7 @@ static void sctp_add_backlog(struct sock *sk, struct sk_buff *skb)
369void sctp_icmp_frag_needed(struct sock *sk, struct sctp_association *asoc, 369void sctp_icmp_frag_needed(struct sock *sk, struct sctp_association *asoc,
370 struct sctp_transport *t, __u32 pmtu) 370 struct sctp_transport *t, __u32 pmtu)
371{ 371{
372 if (!t || (t->pathmtu == pmtu)) 372 if (!t || (t->pathmtu <= pmtu))
373 return; 373 return;
374 374
375 if (sock_owned_by_user(sk)) { 375 if (sock_owned_by_user(sk)) {
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c
index d4c3fbc4671e..a6a0ea71ae93 100644
--- a/net/sctp/sm_statefuns.c
+++ b/net/sctp/sm_statefuns.c
@@ -2544,6 +2544,7 @@ sctp_disposition_t sctp_sf_do_9_2_shutdown(const struct sctp_endpoint *ep,
2544 sctp_shutdownhdr_t *sdh; 2544 sctp_shutdownhdr_t *sdh;
2545 sctp_disposition_t disposition; 2545 sctp_disposition_t disposition;
2546 struct sctp_ulpevent *ev; 2546 struct sctp_ulpevent *ev;
2547 __u32 ctsn;
2547 2548
2548 if (!sctp_vtag_verify(chunk, asoc)) 2549 if (!sctp_vtag_verify(chunk, asoc))
2549 return sctp_sf_pdiscard(ep, asoc, type, arg, commands); 2550 return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
@@ -2558,6 +2559,14 @@ sctp_disposition_t sctp_sf_do_9_2_shutdown(const struct sctp_endpoint *ep,
2558 sdh = (sctp_shutdownhdr_t *)chunk->skb->data; 2559 sdh = (sctp_shutdownhdr_t *)chunk->skb->data;
2559 skb_pull(chunk->skb, sizeof(sctp_shutdownhdr_t)); 2560 skb_pull(chunk->skb, sizeof(sctp_shutdownhdr_t));
2560 chunk->subh.shutdown_hdr = sdh; 2561 chunk->subh.shutdown_hdr = sdh;
2562 ctsn = ntohl(sdh->cum_tsn_ack);
2563
2564 /* If Cumulative TSN Ack beyond the max tsn currently
2565 * send, terminating the association and respond to the
2566 * sender with an ABORT.
2567 */
2568 if (!TSN_lt(ctsn, asoc->next_tsn))
2569 return sctp_sf_violation_ctsn(ep, asoc, type, arg, commands);
2561 2570
2562 /* API 5.3.1.5 SCTP_SHUTDOWN_EVENT 2571 /* API 5.3.1.5 SCTP_SHUTDOWN_EVENT
2563 * When a peer sends a SHUTDOWN, SCTP delivers this notification to 2572 * When a peer sends a SHUTDOWN, SCTP delivers this notification to
@@ -2599,6 +2608,51 @@ out:
2599 return disposition; 2608 return disposition;
2600} 2609}
2601 2610
2611/*
2612 * sctp_sf_do_9_2_shut_ctsn
2613 *
2614 * Once an endpoint has reached the SHUTDOWN-RECEIVED state,
2615 * it MUST NOT send a SHUTDOWN in response to a ULP request.
2616 * The Cumulative TSN Ack of the received SHUTDOWN chunk
2617 * MUST be processed.
2618 */
2619sctp_disposition_t sctp_sf_do_9_2_shut_ctsn(const struct sctp_endpoint *ep,
2620 const struct sctp_association *asoc,
2621 const sctp_subtype_t type,
2622 void *arg,
2623 sctp_cmd_seq_t *commands)
2624{
2625 struct sctp_chunk *chunk = arg;
2626 sctp_shutdownhdr_t *sdh;
2627
2628 if (!sctp_vtag_verify(chunk, asoc))
2629 return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
2630
2631 /* Make sure that the SHUTDOWN chunk has a valid length. */
2632 if (!sctp_chunk_length_valid(chunk,
2633 sizeof(struct sctp_shutdown_chunk_t)))
2634 return sctp_sf_violation_chunklen(ep, asoc, type, arg,
2635 commands);
2636
2637 sdh = (sctp_shutdownhdr_t *)chunk->skb->data;
2638
2639 /* If Cumulative TSN Ack beyond the max tsn currently
2640 * send, terminating the association and respond to the
2641 * sender with an ABORT.
2642 */
2643 if (!TSN_lt(ntohl(sdh->cum_tsn_ack), asoc->next_tsn))
2644 return sctp_sf_violation_ctsn(ep, asoc, type, arg, commands);
2645
2646 /* verify, by checking the Cumulative TSN Ack field of the
2647 * chunk, that all its outstanding DATA chunks have been
2648 * received by the SHUTDOWN sender.
2649 */
2650 sctp_add_cmd_sf(commands, SCTP_CMD_PROCESS_CTSN,
2651 SCTP_BE32(sdh->cum_tsn_ack));
2652
2653 return SCTP_DISPOSITION_CONSUME;
2654}
2655
2602/* RFC 2960 9.2 2656/* RFC 2960 9.2
2603 * If an endpoint is in SHUTDOWN-ACK-SENT state and receives an INIT chunk 2657 * If an endpoint is in SHUTDOWN-ACK-SENT state and receives an INIT chunk
2604 * (e.g., if the SHUTDOWN COMPLETE was lost) with source and destination 2658 * (e.g., if the SHUTDOWN COMPLETE was lost) with source and destination
diff --git a/net/sctp/sm_statetable.c b/net/sctp/sm_statetable.c
index dd4ddc40c0ad..5c8186d88c61 100644
--- a/net/sctp/sm_statetable.c
+++ b/net/sctp/sm_statetable.c
@@ -266,11 +266,11 @@ const sctp_sm_table_entry_t *sctp_sm_lookup_event(sctp_event_t event_type,
266 /* SCTP_STATE_ESTABLISHED */ \ 266 /* SCTP_STATE_ESTABLISHED */ \
267 TYPE_SCTP_FUNC(sctp_sf_do_9_2_shutdown), \ 267 TYPE_SCTP_FUNC(sctp_sf_do_9_2_shutdown), \
268 /* SCTP_STATE_SHUTDOWN_PENDING */ \ 268 /* SCTP_STATE_SHUTDOWN_PENDING */ \
269 TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \ 269 TYPE_SCTP_FUNC(sctp_sf_do_9_2_shutdown), \
270 /* SCTP_STATE_SHUTDOWN_SENT */ \ 270 /* SCTP_STATE_SHUTDOWN_SENT */ \
271 TYPE_SCTP_FUNC(sctp_sf_do_9_2_shutdown_ack), \ 271 TYPE_SCTP_FUNC(sctp_sf_do_9_2_shutdown_ack), \
272 /* SCTP_STATE_SHUTDOWN_RECEIVED */ \ 272 /* SCTP_STATE_SHUTDOWN_RECEIVED */ \
273 TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \ 273 TYPE_SCTP_FUNC(sctp_sf_do_9_2_shut_ctsn), \
274 /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \ 274 /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
275 TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \ 275 TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
276} /* TYPE_SCTP_SHUTDOWN */ 276} /* TYPE_SCTP_SHUTDOWN */
diff --git a/net/socket.c b/net/socket.c
index 3e8d4e35c08f..2b7a4b5c9b72 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -1142,7 +1142,7 @@ static int __sock_create(struct net *net, int family, int type, int protocol,
1142 1142
1143 sock->type = type; 1143 sock->type = type;
1144 1144
1145#if defined(CONFIG_KMOD) 1145#ifdef CONFIG_MODULES
1146 /* Attempt to load a protocol module if the find failed. 1146 /* Attempt to load a protocol module if the find failed.
1147 * 1147 *
1148 * 12/09/1996 Marcin: But! this makes REALLY only sense, if the user 1148 * 12/09/1996 Marcin: But! this makes REALLY only sense, if the user
diff --git a/net/sunrpc/auth.c b/net/sunrpc/auth.c
index 6bfea9ed6869..436bf1b4b76c 100644
--- a/net/sunrpc/auth.c
+++ b/net/sunrpc/auth.c
@@ -83,10 +83,8 @@ rpcauth_create(rpc_authflavor_t pseudoflavor, struct rpc_clnt *clnt)
83 if (flavor >= RPC_AUTH_MAXFLAVOR) 83 if (flavor >= RPC_AUTH_MAXFLAVOR)
84 goto out; 84 goto out;
85 85
86#ifdef CONFIG_KMOD
87 if ((ops = auth_flavors[flavor]) == NULL) 86 if ((ops = auth_flavors[flavor]) == NULL)
88 request_module("rpc-auth-%u", flavor); 87 request_module("rpc-auth-%u", flavor);
89#endif
90 spin_lock(&rpc_authflavor_lock); 88 spin_lock(&rpc_authflavor_lock);
91 ops = auth_flavors[flavor]; 89 ops = auth_flavors[flavor];
92 if (ops == NULL || !try_module_get(ops->owner)) { 90 if (ops == NULL || !try_module_get(ops->owner)) {
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index c647aab8d418..dc504d308ec0 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -711,28 +711,30 @@ static struct sock *unix_find_other(struct net *net,
711 int type, unsigned hash, int *error) 711 int type, unsigned hash, int *error)
712{ 712{
713 struct sock *u; 713 struct sock *u;
714 struct nameidata nd; 714 struct path path;
715 int err = 0; 715 int err = 0;
716 716
717 if (sunname->sun_path[0]) { 717 if (sunname->sun_path[0]) {
718 err = path_lookup(sunname->sun_path, LOOKUP_FOLLOW, &nd); 718 struct inode *inode;
719 err = kern_path(sunname->sun_path, LOOKUP_FOLLOW, &path);
719 if (err) 720 if (err)
720 goto fail; 721 goto fail;
721 err = vfs_permission(&nd, MAY_WRITE); 722 inode = path.dentry->d_inode;
723 err = inode_permission(inode, MAY_WRITE);
722 if (err) 724 if (err)
723 goto put_fail; 725 goto put_fail;
724 726
725 err = -ECONNREFUSED; 727 err = -ECONNREFUSED;
726 if (!S_ISSOCK(nd.path.dentry->d_inode->i_mode)) 728 if (!S_ISSOCK(inode->i_mode))
727 goto put_fail; 729 goto put_fail;
728 u = unix_find_socket_byinode(net, nd.path.dentry->d_inode); 730 u = unix_find_socket_byinode(net, inode);
729 if (!u) 731 if (!u)
730 goto put_fail; 732 goto put_fail;
731 733
732 if (u->sk_type == type) 734 if (u->sk_type == type)
733 touch_atime(nd.path.mnt, nd.path.dentry); 735 touch_atime(path.mnt, path.dentry);
734 736
735 path_put(&nd.path); 737 path_put(&path);
736 738
737 err=-EPROTOTYPE; 739 err=-EPROTOTYPE;
738 if (u->sk_type != type) { 740 if (u->sk_type != type) {
@@ -753,7 +755,7 @@ static struct sock *unix_find_other(struct net *net,
753 return u; 755 return u;
754 756
755put_fail: 757put_fail:
756 path_put(&nd.path); 758 path_put(&path);
757fail: 759fail:
758 *error=err; 760 *error=err;
759 return NULL; 761 return NULL;