aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-10-26 08:20:53 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-10-26 08:20:53 -0400
commite33bae14fd8da449d735552d78e6dd33ece0458c (patch)
tree048c062c47f7bfdb0ea8ad19c5b5849a58ff3022 /net
parent7670c7010c7b367ca40c3aba02afb36149764a6e (diff)
parent14211d026dad4641d4dffd7a4c520bcaa8fd4a65 (diff)
Merge branch 'for-linus' of git://github.com/ericvh/linux
* 'for-linus' of git://github.com/ericvh/linux: 9p: fix 9p.txt to advertise msize instead of maxdata net/9p: Convert net/9p protocol dumps to tracepoints fs/9p: change an int to unsigned int fs/9p: Cleanup option parsing in 9p 9p: move dereference after NULL check fs/9p: inode file operation is properly initialized init_special_inode fs/9p: Update zero-copy implementation in 9p
Diffstat (limited to 'net')
-rw-r--r--net/9p/client.c469
-rw-r--r--net/9p/protocol.c99
-rw-r--r--net/9p/protocol.h4
-rw-r--r--net/9p/trans_common.c53
-rw-r--r--net/9p/trans_common.h21
-rw-r--r--net/9p/trans_virtio.c319
6 files changed, 554 insertions, 411 deletions
diff --git a/net/9p/client.c b/net/9p/client.c
index 0505a03c374c..854ca7a911c4 100644
--- a/net/9p/client.c
+++ b/net/9p/client.c
@@ -38,6 +38,9 @@
38#include <net/9p/transport.h> 38#include <net/9p/transport.h>
39#include "protocol.h" 39#include "protocol.h"
40 40
41#define CREATE_TRACE_POINTS
42#include <trace/events/9p.h>
43
41/* 44/*
42 * Client Option Parsing (code inspired by NFS code) 45 * Client Option Parsing (code inspired by NFS code)
43 * - a little lazy - parse all client options 46 * - a little lazy - parse all client options
@@ -123,21 +126,19 @@ static int parse_opts(char *opts, struct p9_client *clnt)
123 options = tmp_options; 126 options = tmp_options;
124 127
125 while ((p = strsep(&options, ",")) != NULL) { 128 while ((p = strsep(&options, ",")) != NULL) {
126 int token; 129 int token, r;
127 if (!*p) 130 if (!*p)
128 continue; 131 continue;
129 token = match_token(p, tokens, args); 132 token = match_token(p, tokens, args);
130 if (token < Opt_trans) { 133 switch (token) {
131 int r = match_int(&args[0], &option); 134 case Opt_msize:
135 r = match_int(&args[0], &option);
132 if (r < 0) { 136 if (r < 0) {
133 P9_DPRINTK(P9_DEBUG_ERROR, 137 P9_DPRINTK(P9_DEBUG_ERROR,
134 "integer field, but no integer?\n"); 138 "integer field, but no integer?\n");
135 ret = r; 139 ret = r;
136 continue; 140 continue;
137 } 141 }
138 }
139 switch (token) {
140 case Opt_msize:
141 clnt->msize = option; 142 clnt->msize = option;
142 break; 143 break;
143 case Opt_trans: 144 case Opt_trans:
@@ -203,11 +204,13 @@ free_and_return:
203 * 204 *
204 */ 205 */
205 206
206static struct p9_req_t *p9_tag_alloc(struct p9_client *c, u16 tag) 207static struct p9_req_t *
208p9_tag_alloc(struct p9_client *c, u16 tag, unsigned int max_size)
207{ 209{
208 unsigned long flags; 210 unsigned long flags;
209 int row, col; 211 int row, col;
210 struct p9_req_t *req; 212 struct p9_req_t *req;
213 int alloc_msize = min(c->msize, max_size);
211 214
212 /* This looks up the original request by tag so we know which 215 /* This looks up the original request by tag so we know which
213 * buffer to read the data into */ 216 * buffer to read the data into */
@@ -245,23 +248,10 @@ static struct p9_req_t *p9_tag_alloc(struct p9_client *c, u16 tag)
245 return ERR_PTR(-ENOMEM); 248 return ERR_PTR(-ENOMEM);
246 } 249 }
247 init_waitqueue_head(req->wq); 250 init_waitqueue_head(req->wq);
248 if ((c->trans_mod->pref & P9_TRANS_PREF_PAYLOAD_MASK) == 251 req->tc = kmalloc(sizeof(struct p9_fcall) + alloc_msize,
249 P9_TRANS_PREF_PAYLOAD_SEP) { 252 GFP_NOFS);
250 int alloc_msize = min(c->msize, 4096); 253 req->rc = kmalloc(sizeof(struct p9_fcall) + alloc_msize,
251 req->tc = kmalloc(sizeof(struct p9_fcall)+alloc_msize, 254 GFP_NOFS);
252 GFP_NOFS);
253 req->tc->capacity = alloc_msize;
254 req->rc = kmalloc(sizeof(struct p9_fcall)+alloc_msize,
255 GFP_NOFS);
256 req->rc->capacity = alloc_msize;
257 } else {
258 req->tc = kmalloc(sizeof(struct p9_fcall)+c->msize,
259 GFP_NOFS);
260 req->tc->capacity = c->msize;
261 req->rc = kmalloc(sizeof(struct p9_fcall)+c->msize,
262 GFP_NOFS);
263 req->rc->capacity = c->msize;
264 }
265 if ((!req->tc) || (!req->rc)) { 255 if ((!req->tc) || (!req->rc)) {
266 printk(KERN_ERR "Couldn't grow tag array\n"); 256 printk(KERN_ERR "Couldn't grow tag array\n");
267 kfree(req->tc); 257 kfree(req->tc);
@@ -271,6 +261,8 @@ static struct p9_req_t *p9_tag_alloc(struct p9_client *c, u16 tag)
271 req->wq = NULL; 261 req->wq = NULL;
272 return ERR_PTR(-ENOMEM); 262 return ERR_PTR(-ENOMEM);
273 } 263 }
264 req->tc->capacity = alloc_msize;
265 req->rc->capacity = alloc_msize;
274 req->tc->sdata = (char *) req->tc + sizeof(struct p9_fcall); 266 req->tc->sdata = (char *) req->tc + sizeof(struct p9_fcall);
275 req->rc->sdata = (char *) req->rc + sizeof(struct p9_fcall); 267 req->rc->sdata = (char *) req->rc + sizeof(struct p9_fcall);
276 } 268 }
@@ -475,37 +467,22 @@ static int p9_check_errors(struct p9_client *c, struct p9_req_t *req)
475 int ecode; 467 int ecode;
476 468
477 err = p9_parse_header(req->rc, NULL, &type, NULL, 0); 469 err = p9_parse_header(req->rc, NULL, &type, NULL, 0);
470 /*
471 * dump the response from server
472 * This should be after check errors which poplulate pdu_fcall.
473 */
474 trace_9p_protocol_dump(c, req->rc);
478 if (err) { 475 if (err) {
479 P9_DPRINTK(P9_DEBUG_ERROR, "couldn't parse header %d\n", err); 476 P9_DPRINTK(P9_DEBUG_ERROR, "couldn't parse header %d\n", err);
480 return err; 477 return err;
481 } 478 }
482
483 if (type != P9_RERROR && type != P9_RLERROR) 479 if (type != P9_RERROR && type != P9_RLERROR)
484 return 0; 480 return 0;
485 481
486 if (!p9_is_proto_dotl(c)) { 482 if (!p9_is_proto_dotl(c)) {
487 char *ename; 483 char *ename;
488
489 if (req->tc->pbuf_size) {
490 /* Handle user buffers */
491 size_t len = req->rc->size - req->rc->offset;
492 if (req->tc->pubuf) {
493 /* User Buffer */
494 err = copy_from_user(
495 &req->rc->sdata[req->rc->offset],
496 req->tc->pubuf, len);
497 if (err) {
498 err = -EFAULT;
499 goto out_err;
500 }
501 } else {
502 /* Kernel Buffer */
503 memmove(&req->rc->sdata[req->rc->offset],
504 req->tc->pkbuf, len);
505 }
506 }
507 err = p9pdu_readf(req->rc, c->proto_version, "s?d", 484 err = p9pdu_readf(req->rc, c->proto_version, "s?d",
508 &ename, &ecode); 485 &ename, &ecode);
509 if (err) 486 if (err)
510 goto out_err; 487 goto out_err;
511 488
@@ -515,11 +492,10 @@ static int p9_check_errors(struct p9_client *c, struct p9_req_t *req)
515 if (!err || !IS_ERR_VALUE(err)) { 492 if (!err || !IS_ERR_VALUE(err)) {
516 err = p9_errstr2errno(ename, strlen(ename)); 493 err = p9_errstr2errno(ename, strlen(ename));
517 494
518 P9_DPRINTK(P9_DEBUG_9P, "<<< RERROR (%d) %s\n", -ecode, 495 P9_DPRINTK(P9_DEBUG_9P, "<<< RERROR (%d) %s\n",
519 ename); 496 -ecode, ename);
520
521 kfree(ename);
522 } 497 }
498 kfree(ename);
523 } else { 499 } else {
524 err = p9pdu_readf(req->rc, c->proto_version, "d", &ecode); 500 err = p9pdu_readf(req->rc, c->proto_version, "d", &ecode);
525 err = -ecode; 501 err = -ecode;
@@ -527,7 +503,6 @@ static int p9_check_errors(struct p9_client *c, struct p9_req_t *req)
527 P9_DPRINTK(P9_DEBUG_9P, "<<< RLERROR (%d)\n", -ecode); 503 P9_DPRINTK(P9_DEBUG_9P, "<<< RLERROR (%d)\n", -ecode);
528 } 504 }
529 505
530
531 return err; 506 return err;
532 507
533out_err: 508out_err:
@@ -536,6 +511,115 @@ out_err:
536 return err; 511 return err;
537} 512}
538 513
514/**
515 * p9_check_zc_errors - check 9p packet for error return and process it
516 * @c: current client instance
517 * @req: request to parse and check for error conditions
518 * @in_hdrlen: Size of response protocol buffer.
519 *
520 * returns error code if one is discovered, otherwise returns 0
521 *
522 * this will have to be more complicated if we have multiple
523 * error packet types
524 */
525
526static int p9_check_zc_errors(struct p9_client *c, struct p9_req_t *req,
527 char *uidata, int in_hdrlen, int kern_buf)
528{
529 int err;
530 int ecode;
531 int8_t type;
532 char *ename = NULL;
533
534 err = p9_parse_header(req->rc, NULL, &type, NULL, 0);
535 /*
536 * dump the response from server
537 * This should be after parse_header which poplulate pdu_fcall.
538 */
539 trace_9p_protocol_dump(c, req->rc);
540 if (err) {
541 P9_DPRINTK(P9_DEBUG_ERROR, "couldn't parse header %d\n", err);
542 return err;
543 }
544
545 if (type != P9_RERROR && type != P9_RLERROR)
546 return 0;
547
548 if (!p9_is_proto_dotl(c)) {
549 /* Error is reported in string format */
550 uint16_t len;
551 /* 7 = header size for RERROR, 2 is the size of string len; */
552 int inline_len = in_hdrlen - (7 + 2);
553
554 /* Read the size of error string */
555 err = p9pdu_readf(req->rc, c->proto_version, "w", &len);
556 if (err)
557 goto out_err;
558
559 ename = kmalloc(len + 1, GFP_NOFS);
560 if (!ename) {
561 err = -ENOMEM;
562 goto out_err;
563 }
564 if (len <= inline_len) {
565 /* We have error in protocol buffer itself */
566 if (pdu_read(req->rc, ename, len)) {
567 err = -EFAULT;
568 goto out_free;
569
570 }
571 } else {
572 /*
573 * Part of the data is in user space buffer.
574 */
575 if (pdu_read(req->rc, ename, inline_len)) {
576 err = -EFAULT;
577 goto out_free;
578
579 }
580 if (kern_buf) {
581 memcpy(ename + inline_len, uidata,
582 len - inline_len);
583 } else {
584 err = copy_from_user(ename + inline_len,
585 uidata, len - inline_len);
586 if (err) {
587 err = -EFAULT;
588 goto out_free;
589 }
590 }
591 }
592 ename[len] = 0;
593 if (p9_is_proto_dotu(c)) {
594 /* For dotu we also have error code */
595 err = p9pdu_readf(req->rc,
596 c->proto_version, "d", &ecode);
597 if (err)
598 goto out_free;
599 err = -ecode;
600 }
601 if (!err || !IS_ERR_VALUE(err)) {
602 err = p9_errstr2errno(ename, strlen(ename));
603
604 P9_DPRINTK(P9_DEBUG_9P, "<<< RERROR (%d) %s\n",
605 -ecode, ename);
606 }
607 kfree(ename);
608 } else {
609 err = p9pdu_readf(req->rc, c->proto_version, "d", &ecode);
610 err = -ecode;
611
612 P9_DPRINTK(P9_DEBUG_9P, "<<< RLERROR (%d)\n", -ecode);
613 }
614 return err;
615
616out_free:
617 kfree(ename);
618out_err:
619 P9_DPRINTK(P9_DEBUG_ERROR, "couldn't parse error%d\n", err);
620 return err;
621}
622
539static struct p9_req_t * 623static struct p9_req_t *
540p9_client_rpc(struct p9_client *c, int8_t type, const char *fmt, ...); 624p9_client_rpc(struct p9_client *c, int8_t type, const char *fmt, ...);
541 625
@@ -579,23 +663,12 @@ static int p9_client_flush(struct p9_client *c, struct p9_req_t *oldreq)
579 return 0; 663 return 0;
580} 664}
581 665
582/** 666static struct p9_req_t *p9_client_prepare_req(struct p9_client *c,
583 * p9_client_rpc - issue a request and wait for a response 667 int8_t type, int req_size,
584 * @c: client session 668 const char *fmt, va_list ap)
585 * @type: type of request
586 * @fmt: protocol format string (see protocol.c)
587 *
588 * Returns request structure (which client must free using p9_free_req)
589 */
590
591static struct p9_req_t *
592p9_client_rpc(struct p9_client *c, int8_t type, const char *fmt, ...)
593{ 669{
594 va_list ap;
595 int tag, err; 670 int tag, err;
596 struct p9_req_t *req; 671 struct p9_req_t *req;
597 unsigned long flags;
598 int sigpending;
599 672
600 P9_DPRINTK(P9_DEBUG_MUX, "client %p op %d\n", c, type); 673 P9_DPRINTK(P9_DEBUG_MUX, "client %p op %d\n", c, type);
601 674
@@ -607,12 +680,6 @@ p9_client_rpc(struct p9_client *c, int8_t type, const char *fmt, ...)
607 if ((c->status == BeginDisconnect) && (type != P9_TCLUNK)) 680 if ((c->status == BeginDisconnect) && (type != P9_TCLUNK))
608 return ERR_PTR(-EIO); 681 return ERR_PTR(-EIO);
609 682
610 if (signal_pending(current)) {
611 sigpending = 1;
612 clear_thread_flag(TIF_SIGPENDING);
613 } else
614 sigpending = 0;
615
616 tag = P9_NOTAG; 683 tag = P9_NOTAG;
617 if (type != P9_TVERSION) { 684 if (type != P9_TVERSION) {
618 tag = p9_idpool_get(c->tagpool); 685 tag = p9_idpool_get(c->tagpool);
@@ -620,18 +687,51 @@ p9_client_rpc(struct p9_client *c, int8_t type, const char *fmt, ...)
620 return ERR_PTR(-ENOMEM); 687 return ERR_PTR(-ENOMEM);
621 } 688 }
622 689
623 req = p9_tag_alloc(c, tag); 690 req = p9_tag_alloc(c, tag, req_size);
624 if (IS_ERR(req)) 691 if (IS_ERR(req))
625 return req; 692 return req;
626 693
627 /* marshall the data */ 694 /* marshall the data */
628 p9pdu_prepare(req->tc, tag, type); 695 p9pdu_prepare(req->tc, tag, type);
629 va_start(ap, fmt);
630 err = p9pdu_vwritef(req->tc, c->proto_version, fmt, ap); 696 err = p9pdu_vwritef(req->tc, c->proto_version, fmt, ap);
631 va_end(ap);
632 if (err) 697 if (err)
633 goto reterr; 698 goto reterr;
634 p9pdu_finalize(req->tc); 699 p9pdu_finalize(c, req->tc);
700 trace_9p_client_req(c, type, tag);
701 return req;
702reterr:
703 p9_free_req(c, req);
704 return ERR_PTR(err);
705}
706
707/**
708 * p9_client_rpc - issue a request and wait for a response
709 * @c: client session
710 * @type: type of request
711 * @fmt: protocol format string (see protocol.c)
712 *
713 * Returns request structure (which client must free using p9_free_req)
714 */
715
716static struct p9_req_t *
717p9_client_rpc(struct p9_client *c, int8_t type, const char *fmt, ...)
718{
719 va_list ap;
720 int sigpending, err;
721 unsigned long flags;
722 struct p9_req_t *req;
723
724 va_start(ap, fmt);
725 req = p9_client_prepare_req(c, type, c->msize, fmt, ap);
726 va_end(ap);
727 if (IS_ERR(req))
728 return req;
729
730 if (signal_pending(current)) {
731 sigpending = 1;
732 clear_thread_flag(TIF_SIGPENDING);
733 } else
734 sigpending = 0;
635 735
636 err = c->trans_mod->request(c, req); 736 err = c->trans_mod->request(c, req);
637 if (err < 0) { 737 if (err < 0) {
@@ -639,18 +739,14 @@ p9_client_rpc(struct p9_client *c, int8_t type, const char *fmt, ...)
639 c->status = Disconnected; 739 c->status = Disconnected;
640 goto reterr; 740 goto reterr;
641 } 741 }
642 742 /* Wait for the response */
643 P9_DPRINTK(P9_DEBUG_MUX, "wait %p tag: %d\n", req->wq, tag);
644 err = wait_event_interruptible(*req->wq, 743 err = wait_event_interruptible(*req->wq,
645 req->status >= REQ_STATUS_RCVD); 744 req->status >= REQ_STATUS_RCVD);
646 P9_DPRINTK(P9_DEBUG_MUX, "wait %p tag: %d returned %d\n",
647 req->wq, tag, err);
648 745
649 if (req->status == REQ_STATUS_ERROR) { 746 if (req->status == REQ_STATUS_ERROR) {
650 P9_DPRINTK(P9_DEBUG_ERROR, "req_status error %d\n", req->t_err); 747 P9_DPRINTK(P9_DEBUG_ERROR, "req_status error %d\n", req->t_err);
651 err = req->t_err; 748 err = req->t_err;
652 } 749 }
653
654 if ((err == -ERESTARTSYS) && (c->status == Connected)) { 750 if ((err == -ERESTARTSYS) && (c->status == Connected)) {
655 P9_DPRINTK(P9_DEBUG_MUX, "flushing\n"); 751 P9_DPRINTK(P9_DEBUG_MUX, "flushing\n");
656 sigpending = 1; 752 sigpending = 1;
@@ -663,25 +759,102 @@ p9_client_rpc(struct p9_client *c, int8_t type, const char *fmt, ...)
663 if (req->status == REQ_STATUS_RCVD) 759 if (req->status == REQ_STATUS_RCVD)
664 err = 0; 760 err = 0;
665 } 761 }
666
667 if (sigpending) { 762 if (sigpending) {
668 spin_lock_irqsave(&current->sighand->siglock, flags); 763 spin_lock_irqsave(&current->sighand->siglock, flags);
669 recalc_sigpending(); 764 recalc_sigpending();
670 spin_unlock_irqrestore(&current->sighand->siglock, flags); 765 spin_unlock_irqrestore(&current->sighand->siglock, flags);
671 } 766 }
672
673 if (err < 0) 767 if (err < 0)
674 goto reterr; 768 goto reterr;
675 769
676 err = p9_check_errors(c, req); 770 err = p9_check_errors(c, req);
677 if (!err) { 771 trace_9p_client_res(c, type, req->rc->tag, err);
678 P9_DPRINTK(P9_DEBUG_MUX, "exit: client %p op %d\n", c, type); 772 if (!err)
773 return req;
774reterr:
775 p9_free_req(c, req);
776 return ERR_PTR(err);
777}
778
779/**
780 * p9_client_zc_rpc - issue a request and wait for a response
781 * @c: client session
782 * @type: type of request
783 * @uidata: user bffer that should be ued for zero copy read
784 * @uodata: user buffer that shoud be user for zero copy write
785 * @inlen: read buffer size
786 * @olen: write buffer size
787 * @hdrlen: reader header size, This is the size of response protocol data
788 * @fmt: protocol format string (see protocol.c)
789 *
790 * Returns request structure (which client must free using p9_free_req)
791 */
792static struct p9_req_t *p9_client_zc_rpc(struct p9_client *c, int8_t type,
793 char *uidata, char *uodata,
794 int inlen, int olen, int in_hdrlen,
795 int kern_buf, const char *fmt, ...)
796{
797 va_list ap;
798 int sigpending, err;
799 unsigned long flags;
800 struct p9_req_t *req;
801
802 va_start(ap, fmt);
803 /*
804 * We allocate a inline protocol data of only 4k bytes.
805 * The actual content is passed in zero-copy fashion.
806 */
807 req = p9_client_prepare_req(c, type, P9_ZC_HDR_SZ, fmt, ap);
808 va_end(ap);
809 if (IS_ERR(req))
679 return req; 810 return req;
811
812 if (signal_pending(current)) {
813 sigpending = 1;
814 clear_thread_flag(TIF_SIGPENDING);
815 } else
816 sigpending = 0;
817
818 /* If we are called with KERNEL_DS force kern_buf */
819 if (segment_eq(get_fs(), KERNEL_DS))
820 kern_buf = 1;
821
822 err = c->trans_mod->zc_request(c, req, uidata, uodata,
823 inlen, olen, in_hdrlen, kern_buf);
824 if (err < 0) {
825 if (err == -EIO)
826 c->status = Disconnected;
827 goto reterr;
828 }
829 if (req->status == REQ_STATUS_ERROR) {
830 P9_DPRINTK(P9_DEBUG_ERROR, "req_status error %d\n", req->t_err);
831 err = req->t_err;
832 }
833 if ((err == -ERESTARTSYS) && (c->status == Connected)) {
834 P9_DPRINTK(P9_DEBUG_MUX, "flushing\n");
835 sigpending = 1;
836 clear_thread_flag(TIF_SIGPENDING);
837
838 if (c->trans_mod->cancel(c, req))
839 p9_client_flush(c, req);
840
841 /* if we received the response anyway, don't signal error */
842 if (req->status == REQ_STATUS_RCVD)
843 err = 0;
844 }
845 if (sigpending) {
846 spin_lock_irqsave(&current->sighand->siglock, flags);
847 recalc_sigpending();
848 spin_unlock_irqrestore(&current->sighand->siglock, flags);
680 } 849 }
850 if (err < 0)
851 goto reterr;
681 852
853 err = p9_check_zc_errors(c, req, uidata, in_hdrlen, kern_buf);
854 trace_9p_client_res(c, type, req->rc->tag, err);
855 if (!err)
856 return req;
682reterr: 857reterr:
683 P9_DPRINTK(P9_DEBUG_MUX, "exit: client %p op %d error: %d\n", c, type,
684 err);
685 p9_free_req(c, req); 858 p9_free_req(c, req);
686 return ERR_PTR(err); 859 return ERR_PTR(err);
687} 860}
@@ -769,7 +942,7 @@ static int p9_client_version(struct p9_client *c)
769 err = p9pdu_readf(req->rc, c->proto_version, "ds", &msize, &version); 942 err = p9pdu_readf(req->rc, c->proto_version, "ds", &msize, &version);
770 if (err) { 943 if (err) {
771 P9_DPRINTK(P9_DEBUG_9P, "version error %d\n", err); 944 P9_DPRINTK(P9_DEBUG_9P, "version error %d\n", err);
772 P9_DUMP_PKT(1, req->rc); 945 trace_9p_protocol_dump(c, req->rc);
773 goto error; 946 goto error;
774 } 947 }
775 948
@@ -906,15 +1079,14 @@ EXPORT_SYMBOL(p9_client_begin_disconnect);
906struct p9_fid *p9_client_attach(struct p9_client *clnt, struct p9_fid *afid, 1079struct p9_fid *p9_client_attach(struct p9_client *clnt, struct p9_fid *afid,
907 char *uname, u32 n_uname, char *aname) 1080 char *uname, u32 n_uname, char *aname)
908{ 1081{
909 int err; 1082 int err = 0;
910 struct p9_req_t *req; 1083 struct p9_req_t *req;
911 struct p9_fid *fid; 1084 struct p9_fid *fid;
912 struct p9_qid qid; 1085 struct p9_qid qid;
913 1086
914 P9_DPRINTK(P9_DEBUG_9P, ">>> TATTACH afid %d uname %s aname %s\n",
915 afid ? afid->fid : -1, uname, aname);
916 err = 0;
917 1087
1088 P9_DPRINTK(P9_DEBUG_9P, ">>> TATTACH afid %d uname %s aname %s\n",
1089 afid ? afid->fid : -1, uname, aname);
918 fid = p9_fid_create(clnt); 1090 fid = p9_fid_create(clnt);
919 if (IS_ERR(fid)) { 1091 if (IS_ERR(fid)) {
920 err = PTR_ERR(fid); 1092 err = PTR_ERR(fid);
@@ -931,7 +1103,7 @@ struct p9_fid *p9_client_attach(struct p9_client *clnt, struct p9_fid *afid,
931 1103
932 err = p9pdu_readf(req->rc, clnt->proto_version, "Q", &qid); 1104 err = p9pdu_readf(req->rc, clnt->proto_version, "Q", &qid);
933 if (err) { 1105 if (err) {
934 P9_DUMP_PKT(1, req->rc); 1106 trace_9p_protocol_dump(clnt, req->rc);
935 p9_free_req(clnt, req); 1107 p9_free_req(clnt, req);
936 goto error; 1108 goto error;
937 } 1109 }
@@ -991,7 +1163,7 @@ struct p9_fid *p9_client_walk(struct p9_fid *oldfid, uint16_t nwname,
991 1163
992 err = p9pdu_readf(req->rc, clnt->proto_version, "R", &nwqids, &wqids); 1164 err = p9pdu_readf(req->rc, clnt->proto_version, "R", &nwqids, &wqids);
993 if (err) { 1165 if (err) {
994 P9_DUMP_PKT(1, req->rc); 1166 trace_9p_protocol_dump(clnt, req->rc);
995 p9_free_req(clnt, req); 1167 p9_free_req(clnt, req);
996 goto clunk_fid; 1168 goto clunk_fid;
997 } 1169 }
@@ -1058,7 +1230,7 @@ int p9_client_open(struct p9_fid *fid, int mode)
1058 1230
1059 err = p9pdu_readf(req->rc, clnt->proto_version, "Qd", &qid, &iounit); 1231 err = p9pdu_readf(req->rc, clnt->proto_version, "Qd", &qid, &iounit);
1060 if (err) { 1232 if (err) {
1061 P9_DUMP_PKT(1, req->rc); 1233 trace_9p_protocol_dump(clnt, req->rc);
1062 goto free_and_error; 1234 goto free_and_error;
1063 } 1235 }
1064 1236
@@ -1101,7 +1273,7 @@ int p9_client_create_dotl(struct p9_fid *ofid, char *name, u32 flags, u32 mode,
1101 1273
1102 err = p9pdu_readf(req->rc, clnt->proto_version, "Qd", qid, &iounit); 1274 err = p9pdu_readf(req->rc, clnt->proto_version, "Qd", qid, &iounit);
1103 if (err) { 1275 if (err) {
1104 P9_DUMP_PKT(1, req->rc); 1276 trace_9p_protocol_dump(clnt, req->rc);
1105 goto free_and_error; 1277 goto free_and_error;
1106 } 1278 }
1107 1279
@@ -1146,7 +1318,7 @@ int p9_client_fcreate(struct p9_fid *fid, char *name, u32 perm, int mode,
1146 1318
1147 err = p9pdu_readf(req->rc, clnt->proto_version, "Qd", &qid, &iounit); 1319 err = p9pdu_readf(req->rc, clnt->proto_version, "Qd", &qid, &iounit);
1148 if (err) { 1320 if (err) {
1149 P9_DUMP_PKT(1, req->rc); 1321 trace_9p_protocol_dump(clnt, req->rc);
1150 goto free_and_error; 1322 goto free_and_error;
1151 } 1323 }
1152 1324
@@ -1185,7 +1357,7 @@ int p9_client_symlink(struct p9_fid *dfid, char *name, char *symtgt, gid_t gid,
1185 1357
1186 err = p9pdu_readf(req->rc, clnt->proto_version, "Q", qid); 1358 err = p9pdu_readf(req->rc, clnt->proto_version, "Q", qid);
1187 if (err) { 1359 if (err) {
1188 P9_DUMP_PKT(1, req->rc); 1360 trace_9p_protocol_dump(clnt, req->rc);
1189 goto free_and_error; 1361 goto free_and_error;
1190 } 1362 }
1191 1363
@@ -1330,13 +1502,15 @@ int
1330p9_client_read(struct p9_fid *fid, char *data, char __user *udata, u64 offset, 1502p9_client_read(struct p9_fid *fid, char *data, char __user *udata, u64 offset,
1331 u32 count) 1503 u32 count)
1332{ 1504{
1333 int err, rsize;
1334 struct p9_client *clnt;
1335 struct p9_req_t *req;
1336 char *dataptr; 1505 char *dataptr;
1506 int kernel_buf = 0;
1507 struct p9_req_t *req;
1508 struct p9_client *clnt;
1509 int err, rsize, non_zc = 0;
1510
1337 1511
1338 P9_DPRINTK(P9_DEBUG_9P, ">>> TREAD fid %d offset %llu %d\n", fid->fid, 1512 P9_DPRINTK(P9_DEBUG_9P, ">>> TREAD fid %d offset %llu %d\n",
1339 (long long unsigned) offset, count); 1513 fid->fid, (long long unsigned) offset, count);
1340 err = 0; 1514 err = 0;
1341 clnt = fid->clnt; 1515 clnt = fid->clnt;
1342 1516
@@ -1348,13 +1522,24 @@ p9_client_read(struct p9_fid *fid, char *data, char __user *udata, u64 offset,
1348 rsize = count; 1522 rsize = count;
1349 1523
1350 /* Don't bother zerocopy for small IO (< 1024) */ 1524 /* Don't bother zerocopy for small IO (< 1024) */
1351 if (((clnt->trans_mod->pref & P9_TRANS_PREF_PAYLOAD_MASK) == 1525 if (clnt->trans_mod->zc_request && rsize > 1024) {
1352 P9_TRANS_PREF_PAYLOAD_SEP) && (rsize > 1024)) { 1526 char *indata;
1353 req = p9_client_rpc(clnt, P9_TREAD, "dqE", fid->fid, offset, 1527 if (data) {
1354 rsize, data, udata); 1528 kernel_buf = 1;
1529 indata = data;
1530 } else
1531 indata = (char *)udata;
1532 /*
1533 * response header len is 11
1534 * PDU Header(7) + IO Size (4)
1535 */
1536 req = p9_client_zc_rpc(clnt, P9_TREAD, indata, NULL, rsize, 0,
1537 11, kernel_buf, "dqd", fid->fid,
1538 offset, rsize);
1355 } else { 1539 } else {
1540 non_zc = 1;
1356 req = p9_client_rpc(clnt, P9_TREAD, "dqd", fid->fid, offset, 1541 req = p9_client_rpc(clnt, P9_TREAD, "dqd", fid->fid, offset,
1357 rsize); 1542 rsize);
1358 } 1543 }
1359 if (IS_ERR(req)) { 1544 if (IS_ERR(req)) {
1360 err = PTR_ERR(req); 1545 err = PTR_ERR(req);
@@ -1363,14 +1548,13 @@ p9_client_read(struct p9_fid *fid, char *data, char __user *udata, u64 offset,
1363 1548
1364 err = p9pdu_readf(req->rc, clnt->proto_version, "D", &count, &dataptr); 1549 err = p9pdu_readf(req->rc, clnt->proto_version, "D", &count, &dataptr);
1365 if (err) { 1550 if (err) {
1366 P9_DUMP_PKT(1, req->rc); 1551 trace_9p_protocol_dump(clnt, req->rc);
1367 goto free_and_error; 1552 goto free_and_error;
1368 } 1553 }
1369 1554
1370 P9_DPRINTK(P9_DEBUG_9P, "<<< RREAD count %d\n", count); 1555 P9_DPRINTK(P9_DEBUG_9P, "<<< RREAD count %d\n", count);
1371 P9_DUMP_PKT(1, req->rc);
1372 1556
1373 if (!req->tc->pbuf_size) { 1557 if (non_zc) {
1374 if (data) { 1558 if (data) {
1375 memmove(data, dataptr, count); 1559 memmove(data, dataptr, count);
1376 } else { 1560 } else {
@@ -1396,6 +1580,7 @@ p9_client_write(struct p9_fid *fid, char *data, const char __user *udata,
1396 u64 offset, u32 count) 1580 u64 offset, u32 count)
1397{ 1581{
1398 int err, rsize; 1582 int err, rsize;
1583 int kernel_buf = 0;
1399 struct p9_client *clnt; 1584 struct p9_client *clnt;
1400 struct p9_req_t *req; 1585 struct p9_req_t *req;
1401 1586
@@ -1411,19 +1596,24 @@ p9_client_write(struct p9_fid *fid, char *data, const char __user *udata,
1411 if (count < rsize) 1596 if (count < rsize)
1412 rsize = count; 1597 rsize = count;
1413 1598
1414 /* Don't bother zerocopy form small IO (< 1024) */ 1599 /* Don't bother zerocopy for small IO (< 1024) */
1415 if (((clnt->trans_mod->pref & P9_TRANS_PREF_PAYLOAD_MASK) == 1600 if (clnt->trans_mod->zc_request && rsize > 1024) {
1416 P9_TRANS_PREF_PAYLOAD_SEP) && (rsize > 1024)) { 1601 char *odata;
1417 req = p9_client_rpc(clnt, P9_TWRITE, "dqE", fid->fid, offset, 1602 if (data) {
1418 rsize, data, udata); 1603 kernel_buf = 1;
1604 odata = data;
1605 } else
1606 odata = (char *)udata;
1607 req = p9_client_zc_rpc(clnt, P9_TWRITE, NULL, odata, 0, rsize,
1608 P9_ZC_HDR_SZ, kernel_buf, "dqd",
1609 fid->fid, offset, rsize);
1419 } else { 1610 } else {
1420
1421 if (data) 1611 if (data)
1422 req = p9_client_rpc(clnt, P9_TWRITE, "dqD", fid->fid, 1612 req = p9_client_rpc(clnt, P9_TWRITE, "dqD", fid->fid,
1423 offset, rsize, data); 1613 offset, rsize, data);
1424 else 1614 else
1425 req = p9_client_rpc(clnt, P9_TWRITE, "dqU", fid->fid, 1615 req = p9_client_rpc(clnt, P9_TWRITE, "dqU", fid->fid,
1426 offset, rsize, udata); 1616 offset, rsize, udata);
1427 } 1617 }
1428 if (IS_ERR(req)) { 1618 if (IS_ERR(req)) {
1429 err = PTR_ERR(req); 1619 err = PTR_ERR(req);
@@ -1432,7 +1622,7 @@ p9_client_write(struct p9_fid *fid, char *data, const char __user *udata,
1432 1622
1433 err = p9pdu_readf(req->rc, clnt->proto_version, "d", &count); 1623 err = p9pdu_readf(req->rc, clnt->proto_version, "d", &count);
1434 if (err) { 1624 if (err) {
1435 P9_DUMP_PKT(1, req->rc); 1625 trace_9p_protocol_dump(clnt, req->rc);
1436 goto free_and_error; 1626 goto free_and_error;
1437 } 1627 }
1438 1628
@@ -1472,7 +1662,7 @@ struct p9_wstat *p9_client_stat(struct p9_fid *fid)
1472 1662
1473 err = p9pdu_readf(req->rc, clnt->proto_version, "wS", &ignored, ret); 1663 err = p9pdu_readf(req->rc, clnt->proto_version, "wS", &ignored, ret);
1474 if (err) { 1664 if (err) {
1475 P9_DUMP_PKT(1, req->rc); 1665 trace_9p_protocol_dump(clnt, req->rc);
1476 p9_free_req(clnt, req); 1666 p9_free_req(clnt, req);
1477 goto error; 1667 goto error;
1478 } 1668 }
@@ -1523,7 +1713,7 @@ struct p9_stat_dotl *p9_client_getattr_dotl(struct p9_fid *fid,
1523 1713
1524 err = p9pdu_readf(req->rc, clnt->proto_version, "A", ret); 1714 err = p9pdu_readf(req->rc, clnt->proto_version, "A", ret);
1525 if (err) { 1715 if (err) {
1526 P9_DUMP_PKT(1, req->rc); 1716 trace_9p_protocol_dump(clnt, req->rc);
1527 p9_free_req(clnt, req); 1717 p9_free_req(clnt, req);
1528 goto error; 1718 goto error;
1529 } 1719 }
@@ -1671,7 +1861,7 @@ int p9_client_statfs(struct p9_fid *fid, struct p9_rstatfs *sb)
1671 &sb->bsize, &sb->blocks, &sb->bfree, &sb->bavail, 1861 &sb->bsize, &sb->blocks, &sb->bfree, &sb->bavail,
1672 &sb->files, &sb->ffree, &sb->fsid, &sb->namelen); 1862 &sb->files, &sb->ffree, &sb->fsid, &sb->namelen);
1673 if (err) { 1863 if (err) {
1674 P9_DUMP_PKT(1, req->rc); 1864 trace_9p_protocol_dump(clnt, req->rc);
1675 p9_free_req(clnt, req); 1865 p9_free_req(clnt, req);
1676 goto error; 1866 goto error;
1677 } 1867 }
@@ -1778,7 +1968,7 @@ struct p9_fid *p9_client_xattrwalk(struct p9_fid *file_fid,
1778 } 1968 }
1779 err = p9pdu_readf(req->rc, clnt->proto_version, "q", attr_size); 1969 err = p9pdu_readf(req->rc, clnt->proto_version, "q", attr_size);
1780 if (err) { 1970 if (err) {
1781 P9_DUMP_PKT(1, req->rc); 1971 trace_9p_protocol_dump(clnt, req->rc);
1782 p9_free_req(clnt, req); 1972 p9_free_req(clnt, req);
1783 goto clunk_fid; 1973 goto clunk_fid;
1784 } 1974 }
@@ -1824,7 +2014,7 @@ EXPORT_SYMBOL_GPL(p9_client_xattrcreate);
1824 2014
1825int p9_client_readdir(struct p9_fid *fid, char *data, u32 count, u64 offset) 2015int p9_client_readdir(struct p9_fid *fid, char *data, u32 count, u64 offset)
1826{ 2016{
1827 int err, rsize; 2017 int err, rsize, non_zc = 0;
1828 struct p9_client *clnt; 2018 struct p9_client *clnt;
1829 struct p9_req_t *req; 2019 struct p9_req_t *req;
1830 char *dataptr; 2020 char *dataptr;
@@ -1842,13 +2032,18 @@ int p9_client_readdir(struct p9_fid *fid, char *data, u32 count, u64 offset)
1842 if (count < rsize) 2032 if (count < rsize)
1843 rsize = count; 2033 rsize = count;
1844 2034
1845 if ((clnt->trans_mod->pref & P9_TRANS_PREF_PAYLOAD_MASK) == 2035 /* Don't bother zerocopy for small IO (< 1024) */
1846 P9_TRANS_PREF_PAYLOAD_SEP) { 2036 if (clnt->trans_mod->zc_request && rsize > 1024) {
1847 req = p9_client_rpc(clnt, P9_TREADDIR, "dqF", fid->fid, 2037 /*
1848 offset, rsize, data); 2038 * response header len is 11
2039 * PDU Header(7) + IO Size (4)
2040 */
2041 req = p9_client_zc_rpc(clnt, P9_TREADDIR, data, NULL, rsize, 0,
2042 11, 1, "dqd", fid->fid, offset, rsize);
1849 } else { 2043 } else {
2044 non_zc = 1;
1850 req = p9_client_rpc(clnt, P9_TREADDIR, "dqd", fid->fid, 2045 req = p9_client_rpc(clnt, P9_TREADDIR, "dqd", fid->fid,
1851 offset, rsize); 2046 offset, rsize);
1852 } 2047 }
1853 if (IS_ERR(req)) { 2048 if (IS_ERR(req)) {
1854 err = PTR_ERR(req); 2049 err = PTR_ERR(req);
@@ -1857,13 +2052,13 @@ int p9_client_readdir(struct p9_fid *fid, char *data, u32 count, u64 offset)
1857 2052
1858 err = p9pdu_readf(req->rc, clnt->proto_version, "D", &count, &dataptr); 2053 err = p9pdu_readf(req->rc, clnt->proto_version, "D", &count, &dataptr);
1859 if (err) { 2054 if (err) {
1860 P9_DUMP_PKT(1, req->rc); 2055 trace_9p_protocol_dump(clnt, req->rc);
1861 goto free_and_error; 2056 goto free_and_error;
1862 } 2057 }
1863 2058
1864 P9_DPRINTK(P9_DEBUG_9P, "<<< RREADDIR count %d\n", count); 2059 P9_DPRINTK(P9_DEBUG_9P, "<<< RREADDIR count %d\n", count);
1865 2060
1866 if (!req->tc->pbuf_size && data) 2061 if (non_zc)
1867 memmove(data, dataptr, count); 2062 memmove(data, dataptr, count);
1868 2063
1869 p9_free_req(clnt, req); 2064 p9_free_req(clnt, req);
@@ -1894,7 +2089,7 @@ int p9_client_mknod_dotl(struct p9_fid *fid, char *name, int mode,
1894 2089
1895 err = p9pdu_readf(req->rc, clnt->proto_version, "Q", qid); 2090 err = p9pdu_readf(req->rc, clnt->proto_version, "Q", qid);
1896 if (err) { 2091 if (err) {
1897 P9_DUMP_PKT(1, req->rc); 2092 trace_9p_protocol_dump(clnt, req->rc);
1898 goto error; 2093 goto error;
1899 } 2094 }
1900 P9_DPRINTK(P9_DEBUG_9P, "<<< RMKNOD qid %x.%llx.%x\n", qid->type, 2095 P9_DPRINTK(P9_DEBUG_9P, "<<< RMKNOD qid %x.%llx.%x\n", qid->type,
@@ -1925,7 +2120,7 @@ int p9_client_mkdir_dotl(struct p9_fid *fid, char *name, int mode,
1925 2120
1926 err = p9pdu_readf(req->rc, clnt->proto_version, "Q", qid); 2121 err = p9pdu_readf(req->rc, clnt->proto_version, "Q", qid);
1927 if (err) { 2122 if (err) {
1928 P9_DUMP_PKT(1, req->rc); 2123 trace_9p_protocol_dump(clnt, req->rc);
1929 goto error; 2124 goto error;
1930 } 2125 }
1931 P9_DPRINTK(P9_DEBUG_9P, "<<< RMKDIR qid %x.%llx.%x\n", qid->type, 2126 P9_DPRINTK(P9_DEBUG_9P, "<<< RMKDIR qid %x.%llx.%x\n", qid->type,
@@ -1960,7 +2155,7 @@ int p9_client_lock_dotl(struct p9_fid *fid, struct p9_flock *flock, u8 *status)
1960 2155
1961 err = p9pdu_readf(req->rc, clnt->proto_version, "b", status); 2156 err = p9pdu_readf(req->rc, clnt->proto_version, "b", status);
1962 if (err) { 2157 if (err) {
1963 P9_DUMP_PKT(1, req->rc); 2158 trace_9p_protocol_dump(clnt, req->rc);
1964 goto error; 2159 goto error;
1965 } 2160 }
1966 P9_DPRINTK(P9_DEBUG_9P, "<<< RLOCK status %i\n", *status); 2161 P9_DPRINTK(P9_DEBUG_9P, "<<< RLOCK status %i\n", *status);
@@ -1993,7 +2188,7 @@ int p9_client_getlock_dotl(struct p9_fid *fid, struct p9_getlock *glock)
1993 &glock->start, &glock->length, &glock->proc_id, 2188 &glock->start, &glock->length, &glock->proc_id,
1994 &glock->client_id); 2189 &glock->client_id);
1995 if (err) { 2190 if (err) {
1996 P9_DUMP_PKT(1, req->rc); 2191 trace_9p_protocol_dump(clnt, req->rc);
1997 goto error; 2192 goto error;
1998 } 2193 }
1999 P9_DPRINTK(P9_DEBUG_9P, "<<< RGETLOCK type %i start %lld length %lld " 2194 P9_DPRINTK(P9_DEBUG_9P, "<<< RGETLOCK type %i start %lld length %lld "
@@ -2021,7 +2216,7 @@ int p9_client_readlink(struct p9_fid *fid, char **target)
2021 2216
2022 err = p9pdu_readf(req->rc, clnt->proto_version, "s", target); 2217 err = p9pdu_readf(req->rc, clnt->proto_version, "s", target);
2023 if (err) { 2218 if (err) {
2024 P9_DUMP_PKT(1, req->rc); 2219 trace_9p_protocol_dump(clnt, req->rc);
2025 goto error; 2220 goto error;
2026 } 2221 }
2027 P9_DPRINTK(P9_DEBUG_9P, "<<< RREADLINK target %s\n", *target); 2222 P9_DPRINTK(P9_DEBUG_9P, "<<< RREADLINK target %s\n", *target);
diff --git a/net/9p/protocol.c b/net/9p/protocol.c
index df58375ea6b3..55e10a96c902 100644
--- a/net/9p/protocol.c
+++ b/net/9p/protocol.c
@@ -37,40 +37,11 @@
37#include <net/9p/client.h> 37#include <net/9p/client.h>
38#include "protocol.h" 38#include "protocol.h"
39 39
40#include <trace/events/9p.h>
41
40static int 42static int
41p9pdu_writef(struct p9_fcall *pdu, int proto_version, const char *fmt, ...); 43p9pdu_writef(struct p9_fcall *pdu, int proto_version, const char *fmt, ...);
42 44
43#ifdef CONFIG_NET_9P_DEBUG
44void
45p9pdu_dump(int way, struct p9_fcall *pdu)
46{
47 int len = pdu->size;
48
49 if ((p9_debug_level & P9_DEBUG_VPKT) != P9_DEBUG_VPKT) {
50 if ((p9_debug_level & P9_DEBUG_PKT) == P9_DEBUG_PKT) {
51 if (len > 32)
52 len = 32;
53 } else {
54 /* shouldn't happen */
55 return;
56 }
57 }
58
59 if (way)
60 print_hex_dump_bytes("[9P] ", DUMP_PREFIX_OFFSET, pdu->sdata,
61 len);
62 else
63 print_hex_dump_bytes("]9P[ ", DUMP_PREFIX_OFFSET, pdu->sdata,
64 len);
65}
66#else
67void
68p9pdu_dump(int way, struct p9_fcall *pdu)
69{
70}
71#endif
72EXPORT_SYMBOL(p9pdu_dump);
73
74void p9stat_free(struct p9_wstat *stbuf) 45void p9stat_free(struct p9_wstat *stbuf)
75{ 46{
76 kfree(stbuf->name); 47 kfree(stbuf->name);
@@ -81,7 +52,7 @@ void p9stat_free(struct p9_wstat *stbuf)
81} 52}
82EXPORT_SYMBOL(p9stat_free); 53EXPORT_SYMBOL(p9stat_free);
83 54
84static size_t pdu_read(struct p9_fcall *pdu, void *data, size_t size) 55size_t pdu_read(struct p9_fcall *pdu, void *data, size_t size)
85{ 56{
86 size_t len = min(pdu->size - pdu->offset, size); 57 size_t len = min(pdu->size - pdu->offset, size);
87 memcpy(data, &pdu->sdata[pdu->offset], len); 58 memcpy(data, &pdu->sdata[pdu->offset], len);
@@ -108,26 +79,6 @@ pdu_write_u(struct p9_fcall *pdu, const char __user *udata, size_t size)
108 return size - len; 79 return size - len;
109} 80}
110 81
111static size_t
112pdu_write_urw(struct p9_fcall *pdu, const char *kdata, const char __user *udata,
113 size_t size)
114{
115 BUG_ON(pdu->size > P9_IOHDRSZ);
116 pdu->pubuf = (char __user *)udata;
117 pdu->pkbuf = (char *)kdata;
118 pdu->pbuf_size = size;
119 return 0;
120}
121
122static size_t
123pdu_write_readdir(struct p9_fcall *pdu, const char *kdata, size_t size)
124{
125 BUG_ON(pdu->size > P9_READDIRHDRSZ);
126 pdu->pkbuf = (char *)kdata;
127 pdu->pbuf_size = size;
128 return 0;
129}
130
131/* 82/*
132 b - int8_t 83 b - int8_t
133 w - int16_t 84 w - int16_t
@@ -459,26 +410,6 @@ p9pdu_vwritef(struct p9_fcall *pdu, int proto_version, const char *fmt,
459 errcode = -EFAULT; 410 errcode = -EFAULT;
460 } 411 }
461 break; 412 break;
462 case 'E':{
463 int32_t cnt = va_arg(ap, int32_t);
464 const char *k = va_arg(ap, const void *);
465 const char __user *u = va_arg(ap,
466 const void __user *);
467 errcode = p9pdu_writef(pdu, proto_version, "d",
468 cnt);
469 if (!errcode && pdu_write_urw(pdu, k, u, cnt))
470 errcode = -EFAULT;
471 }
472 break;
473 case 'F':{
474 int32_t cnt = va_arg(ap, int32_t);
475 const char *k = va_arg(ap, const void *);
476 errcode = p9pdu_writef(pdu, proto_version, "d",
477 cnt);
478 if (!errcode && pdu_write_readdir(pdu, k, cnt))
479 errcode = -EFAULT;
480 }
481 break;
482 case 'U':{ 413 case 'U':{
483 int32_t count = va_arg(ap, int32_t); 414 int32_t count = va_arg(ap, int32_t);
484 const char __user *udata = 415 const char __user *udata =
@@ -591,7 +522,7 @@ p9pdu_writef(struct p9_fcall *pdu, int proto_version, const char *fmt, ...)
591 return ret; 522 return ret;
592} 523}
593 524
594int p9stat_read(char *buf, int len, struct p9_wstat *st, int proto_version) 525int p9stat_read(struct p9_client *clnt, char *buf, int len, struct p9_wstat *st)
595{ 526{
596 struct p9_fcall fake_pdu; 527 struct p9_fcall fake_pdu;
597 int ret; 528 int ret;
@@ -601,10 +532,10 @@ int p9stat_read(char *buf, int len, struct p9_wstat *st, int proto_version)
601 fake_pdu.sdata = buf; 532 fake_pdu.sdata = buf;
602 fake_pdu.offset = 0; 533 fake_pdu.offset = 0;
603 534
604 ret = p9pdu_readf(&fake_pdu, proto_version, "S", st); 535 ret = p9pdu_readf(&fake_pdu, clnt->proto_version, "S", st);
605 if (ret) { 536 if (ret) {
606 P9_DPRINTK(P9_DEBUG_9P, "<<< p9stat_read failed: %d\n", ret); 537 P9_DPRINTK(P9_DEBUG_9P, "<<< p9stat_read failed: %d\n", ret);
607 P9_DUMP_PKT(0, &fake_pdu); 538 trace_9p_protocol_dump(clnt, &fake_pdu);
608 } 539 }
609 540
610 return ret; 541 return ret;
@@ -617,7 +548,7 @@ int p9pdu_prepare(struct p9_fcall *pdu, int16_t tag, int8_t type)
617 return p9pdu_writef(pdu, 0, "dbw", 0, type, tag); 548 return p9pdu_writef(pdu, 0, "dbw", 0, type, tag);
618} 549}
619 550
620int p9pdu_finalize(struct p9_fcall *pdu) 551int p9pdu_finalize(struct p9_client *clnt, struct p9_fcall *pdu)
621{ 552{
622 int size = pdu->size; 553 int size = pdu->size;
623 int err; 554 int err;
@@ -626,7 +557,7 @@ int p9pdu_finalize(struct p9_fcall *pdu)
626 err = p9pdu_writef(pdu, 0, "d", size); 557 err = p9pdu_writef(pdu, 0, "d", size);
627 pdu->size = size; 558 pdu->size = size;
628 559
629 P9_DUMP_PKT(0, pdu); 560 trace_9p_protocol_dump(clnt, pdu);
630 P9_DPRINTK(P9_DEBUG_9P, ">>> size=%d type: %d tag: %d\n", pdu->size, 561 P9_DPRINTK(P9_DEBUG_9P, ">>> size=%d type: %d tag: %d\n", pdu->size,
631 pdu->id, pdu->tag); 562 pdu->id, pdu->tag);
632 563
@@ -637,14 +568,10 @@ void p9pdu_reset(struct p9_fcall *pdu)
637{ 568{
638 pdu->offset = 0; 569 pdu->offset = 0;
639 pdu->size = 0; 570 pdu->size = 0;
640 pdu->private = NULL;
641 pdu->pubuf = NULL;
642 pdu->pkbuf = NULL;
643 pdu->pbuf_size = 0;
644} 571}
645 572
646int p9dirent_read(char *buf, int len, struct p9_dirent *dirent, 573int p9dirent_read(struct p9_client *clnt, char *buf, int len,
647 int proto_version) 574 struct p9_dirent *dirent)
648{ 575{
649 struct p9_fcall fake_pdu; 576 struct p9_fcall fake_pdu;
650 int ret; 577 int ret;
@@ -655,11 +582,11 @@ int p9dirent_read(char *buf, int len, struct p9_dirent *dirent,
655 fake_pdu.sdata = buf; 582 fake_pdu.sdata = buf;
656 fake_pdu.offset = 0; 583 fake_pdu.offset = 0;
657 584
658 ret = p9pdu_readf(&fake_pdu, proto_version, "Qqbs", &dirent->qid, 585 ret = p9pdu_readf(&fake_pdu, clnt->proto_version, "Qqbs", &dirent->qid,
659 &dirent->d_off, &dirent->d_type, &nameptr); 586 &dirent->d_off, &dirent->d_type, &nameptr);
660 if (ret) { 587 if (ret) {
661 P9_DPRINTK(P9_DEBUG_9P, "<<< p9dirent_read failed: %d\n", ret); 588 P9_DPRINTK(P9_DEBUG_9P, "<<< p9dirent_read failed: %d\n", ret);
662 P9_DUMP_PKT(1, &fake_pdu); 589 trace_9p_protocol_dump(clnt, &fake_pdu);
663 goto out; 590 goto out;
664 } 591 }
665 592
diff --git a/net/9p/protocol.h b/net/9p/protocol.h
index 2431c0f38d56..2cc525fa49fa 100644
--- a/net/9p/protocol.h
+++ b/net/9p/protocol.h
@@ -29,6 +29,6 @@ int p9pdu_vwritef(struct p9_fcall *pdu, int proto_version, const char *fmt,
29 va_list ap); 29 va_list ap);
30int p9pdu_readf(struct p9_fcall *pdu, int proto_version, const char *fmt, ...); 30int p9pdu_readf(struct p9_fcall *pdu, int proto_version, const char *fmt, ...);
31int p9pdu_prepare(struct p9_fcall *pdu, int16_t tag, int8_t type); 31int p9pdu_prepare(struct p9_fcall *pdu, int16_t tag, int8_t type);
32int p9pdu_finalize(struct p9_fcall *pdu); 32int p9pdu_finalize(struct p9_client *clnt, struct p9_fcall *pdu);
33void p9pdu_dump(int, struct p9_fcall *);
34void p9pdu_reset(struct p9_fcall *pdu); 33void p9pdu_reset(struct p9_fcall *pdu);
34size_t pdu_read(struct p9_fcall *pdu, void *data, size_t size);
diff --git a/net/9p/trans_common.c b/net/9p/trans_common.c
index 9a70ebdec56e..de8df957867d 100644
--- a/net/9p/trans_common.c
+++ b/net/9p/trans_common.c
@@ -21,30 +21,25 @@
21 21
22/** 22/**
23 * p9_release_req_pages - Release pages after the transaction. 23 * p9_release_req_pages - Release pages after the transaction.
24 * @*private: PDU's private page of struct trans_rpage_info
25 */ 24 */
26void 25void p9_release_pages(struct page **pages, int nr_pages)
27p9_release_req_pages(struct trans_rpage_info *rpinfo)
28{ 26{
29 int i = 0; 27 int i = 0;
30 28 while (pages[i] && nr_pages--) {
31 while (rpinfo->rp_data[i] && rpinfo->rp_nr_pages--) { 29 put_page(pages[i]);
32 put_page(rpinfo->rp_data[i]);
33 i++; 30 i++;
34 } 31 }
35} 32}
36EXPORT_SYMBOL(p9_release_req_pages); 33EXPORT_SYMBOL(p9_release_pages);
37 34
38/** 35/**
39 * p9_nr_pages - Return number of pages needed to accommodate the payload. 36 * p9_nr_pages - Return number of pages needed to accommodate the payload.
40 */ 37 */
41int 38int p9_nr_pages(char *data, int len)
42p9_nr_pages(struct p9_req_t *req)
43{ 39{
44 unsigned long start_page, end_page; 40 unsigned long start_page, end_page;
45 start_page = (unsigned long)req->tc->pubuf >> PAGE_SHIFT; 41 start_page = (unsigned long)data >> PAGE_SHIFT;
46 end_page = ((unsigned long)req->tc->pubuf + req->tc->pbuf_size + 42 end_page = ((unsigned long)data + len + PAGE_SIZE - 1) >> PAGE_SHIFT;
47 PAGE_SIZE - 1) >> PAGE_SHIFT;
48 return end_page - start_page; 43 return end_page - start_page;
49} 44}
50EXPORT_SYMBOL(p9_nr_pages); 45EXPORT_SYMBOL(p9_nr_pages);
@@ -58,35 +53,17 @@ EXPORT_SYMBOL(p9_nr_pages);
58 * @nr_pages: number of pages to accommodate the payload 53 * @nr_pages: number of pages to accommodate the payload
59 * @rw: Indicates if the pages are for read or write. 54 * @rw: Indicates if the pages are for read or write.
60 */ 55 */
61int
62p9_payload_gup(struct p9_req_t *req, size_t *pdata_off, int *pdata_len,
63 int nr_pages, u8 rw)
64{
65 uint32_t first_page_bytes = 0;
66 int32_t pdata_mapped_pages;
67 struct trans_rpage_info *rpinfo;
68
69 *pdata_off = (__force size_t)req->tc->pubuf & (PAGE_SIZE-1);
70 56
71 if (*pdata_off) 57int p9_payload_gup(char *data, int *nr_pages, struct page **pages, int write)
72 first_page_bytes = min(((size_t)PAGE_SIZE - *pdata_off), 58{
73 req->tc->pbuf_size); 59 int nr_mapped_pages;
74 60
75 rpinfo = req->tc->private; 61 nr_mapped_pages = get_user_pages_fast((unsigned long)data,
76 pdata_mapped_pages = get_user_pages_fast((unsigned long)req->tc->pubuf, 62 *nr_pages, write, pages);
77 nr_pages, rw, &rpinfo->rp_data[0]); 63 if (nr_mapped_pages <= 0)
78 if (pdata_mapped_pages <= 0) 64 return nr_mapped_pages;
79 return pdata_mapped_pages;
80 65
81 rpinfo->rp_nr_pages = pdata_mapped_pages; 66 *nr_pages = nr_mapped_pages;
82 if (*pdata_off) {
83 *pdata_len = first_page_bytes;
84 *pdata_len += min((req->tc->pbuf_size - *pdata_len),
85 ((size_t)pdata_mapped_pages - 1) << PAGE_SHIFT);
86 } else {
87 *pdata_len = min(req->tc->pbuf_size,
88 (size_t)pdata_mapped_pages << PAGE_SHIFT);
89 }
90 return 0; 67 return 0;
91} 68}
92EXPORT_SYMBOL(p9_payload_gup); 69EXPORT_SYMBOL(p9_payload_gup);
diff --git a/net/9p/trans_common.h b/net/9p/trans_common.h
index 76309223bb02..173bb550a9eb 100644
--- a/net/9p/trans_common.h
+++ b/net/9p/trans_common.h
@@ -12,21 +12,6 @@
12 * 12 *
13 */ 13 */
14 14
15/* TRUE if it is user context */ 15void p9_release_pages(struct page **, int);
16#define P9_IS_USER_CONTEXT (!segment_eq(get_fs(), KERNEL_DS)) 16int p9_payload_gup(char *, int *, struct page **, int);
17 17int p9_nr_pages(char *, int);
18/**
19 * struct trans_rpage_info - To store mapped page information in PDU.
20 * @rp_alloc:Set if this structure is allocd, not a reuse unused space in pdu.
21 * @rp_nr_pages: Number of mapped pages
22 * @rp_data: Array of page pointers
23 */
24struct trans_rpage_info {
25 u8 rp_alloc;
26 int rp_nr_pages;
27 struct page *rp_data[0];
28};
29
30void p9_release_req_pages(struct trans_rpage_info *);
31int p9_payload_gup(struct p9_req_t *, size_t *, int *, int, u8);
32int p9_nr_pages(struct p9_req_t *);
diff --git a/net/9p/trans_virtio.c b/net/9p/trans_virtio.c
index e317583fcc73..32aa9834229c 100644
--- a/net/9p/trans_virtio.c
+++ b/net/9p/trans_virtio.c
@@ -150,12 +150,10 @@ static void req_done(struct virtqueue *vq)
150 while (1) { 150 while (1) {
151 spin_lock_irqsave(&chan->lock, flags); 151 spin_lock_irqsave(&chan->lock, flags);
152 rc = virtqueue_get_buf(chan->vq, &len); 152 rc = virtqueue_get_buf(chan->vq, &len);
153
154 if (rc == NULL) { 153 if (rc == NULL) {
155 spin_unlock_irqrestore(&chan->lock, flags); 154 spin_unlock_irqrestore(&chan->lock, flags);
156 break; 155 break;
157 } 156 }
158
159 chan->ring_bufs_avail = 1; 157 chan->ring_bufs_avail = 1;
160 spin_unlock_irqrestore(&chan->lock, flags); 158 spin_unlock_irqrestore(&chan->lock, flags);
161 /* Wakeup if anyone waiting for VirtIO ring space. */ 159 /* Wakeup if anyone waiting for VirtIO ring space. */
@@ -163,17 +161,6 @@ static void req_done(struct virtqueue *vq)
163 P9_DPRINTK(P9_DEBUG_TRANS, ": rc %p\n", rc); 161 P9_DPRINTK(P9_DEBUG_TRANS, ": rc %p\n", rc);
164 P9_DPRINTK(P9_DEBUG_TRANS, ": lookup tag %d\n", rc->tag); 162 P9_DPRINTK(P9_DEBUG_TRANS, ": lookup tag %d\n", rc->tag);
165 req = p9_tag_lookup(chan->client, rc->tag); 163 req = p9_tag_lookup(chan->client, rc->tag);
166 if (req->tc->private) {
167 struct trans_rpage_info *rp = req->tc->private;
168 int p = rp->rp_nr_pages;
169 /*Release pages */
170 p9_release_req_pages(rp);
171 atomic_sub(p, &vp_pinned);
172 wake_up(&vp_wq);
173 if (rp->rp_alloc)
174 kfree(rp);
175 req->tc->private = NULL;
176 }
177 req->status = REQ_STATUS_RCVD; 164 req->status = REQ_STATUS_RCVD;
178 p9_client_cb(chan->client, req); 165 p9_client_cb(chan->client, req);
179 } 166 }
@@ -193,9 +180,8 @@ static void req_done(struct virtqueue *vq)
193 * 180 *
194 */ 181 */
195 182
196static int 183static int pack_sg_list(struct scatterlist *sg, int start,
197pack_sg_list(struct scatterlist *sg, int start, int limit, char *data, 184 int limit, char *data, int count)
198 int count)
199{ 185{
200 int s; 186 int s;
201 int index = start; 187 int index = start;
@@ -224,31 +210,36 @@ static int p9_virtio_cancel(struct p9_client *client, struct p9_req_t *req)
224 * this takes a list of pages. 210 * this takes a list of pages.
225 * @sg: scatter/gather list to pack into 211 * @sg: scatter/gather list to pack into
226 * @start: which segment of the sg_list to start at 212 * @start: which segment of the sg_list to start at
227 * @pdata_off: Offset into the first page
228 * @**pdata: a list of pages to add into sg. 213 * @**pdata: a list of pages to add into sg.
214 * @nr_pages: number of pages to pack into the scatter/gather list
215 * @data: data to pack into scatter/gather list
229 * @count: amount of data to pack into the scatter/gather list 216 * @count: amount of data to pack into the scatter/gather list
230 */ 217 */
231static int 218static int
232pack_sg_list_p(struct scatterlist *sg, int start, int limit, size_t pdata_off, 219pack_sg_list_p(struct scatterlist *sg, int start, int limit,
233 struct page **pdata, int count) 220 struct page **pdata, int nr_pages, char *data, int count)
234{ 221{
235 int s; 222 int i = 0, s;
236 int i = 0; 223 int data_off;
237 int index = start; 224 int index = start;
238 225
239 if (pdata_off) { 226 BUG_ON(nr_pages > (limit - start));
240 s = min((int)(PAGE_SIZE - pdata_off), count); 227 /*
241 sg_set_page(&sg[index++], pdata[i++], s, pdata_off); 228 * if the first page doesn't start at
242 count -= s; 229 * page boundary find the offset
243 } 230 */
244 231 data_off = offset_in_page(data);
245 while (count) { 232 while (nr_pages) {
246 BUG_ON(index > limit); 233 s = rest_of_page(data);
247 s = min((int)PAGE_SIZE, count); 234 if (s > count)
248 sg_set_page(&sg[index++], pdata[i++], s, 0); 235 s = count;
236 sg_set_page(&sg[index++], pdata[i++], s, data_off);
237 data_off = 0;
238 data += s;
249 count -= s; 239 count -= s;
240 nr_pages--;
250 } 241 }
251 return index-start; 242 return index - start;
252} 243}
253 244
254/** 245/**
@@ -261,114 +252,166 @@ pack_sg_list_p(struct scatterlist *sg, int start, int limit, size_t pdata_off,
261static int 252static int
262p9_virtio_request(struct p9_client *client, struct p9_req_t *req) 253p9_virtio_request(struct p9_client *client, struct p9_req_t *req)
263{ 254{
264 int in, out, inp, outp; 255 int err;
265 struct virtio_chan *chan = client->trans; 256 int in, out;
266 unsigned long flags; 257 unsigned long flags;
267 size_t pdata_off = 0; 258 struct virtio_chan *chan = client->trans;
268 struct trans_rpage_info *rpinfo = NULL;
269 int err, pdata_len = 0;
270 259
271 P9_DPRINTK(P9_DEBUG_TRANS, "9p debug: virtio request\n"); 260 P9_DPRINTK(P9_DEBUG_TRANS, "9p debug: virtio request\n");
272 261
273 req->status = REQ_STATUS_SENT; 262 req->status = REQ_STATUS_SENT;
263req_retry:
264 spin_lock_irqsave(&chan->lock, flags);
265
266 /* Handle out VirtIO ring buffers */
267 out = pack_sg_list(chan->sg, 0,
268 VIRTQUEUE_NUM, req->tc->sdata, req->tc->size);
274 269
275 if (req->tc->pbuf_size && (req->tc->pubuf && P9_IS_USER_CONTEXT)) { 270 in = pack_sg_list(chan->sg, out,
276 int nr_pages = p9_nr_pages(req); 271 VIRTQUEUE_NUM, req->rc->sdata, req->rc->capacity);
277 int rpinfo_size = sizeof(struct trans_rpage_info) +
278 sizeof(struct page *) * nr_pages;
279 272
280 if (atomic_read(&vp_pinned) >= chan->p9_max_pages) { 273 err = virtqueue_add_buf(chan->vq, chan->sg, out, in, req->tc);
281 err = wait_event_interruptible(vp_wq, 274 if (err < 0) {
282 atomic_read(&vp_pinned) < chan->p9_max_pages); 275 if (err == -ENOSPC) {
276 chan->ring_bufs_avail = 0;
277 spin_unlock_irqrestore(&chan->lock, flags);
278 err = wait_event_interruptible(*chan->vc_wq,
279 chan->ring_bufs_avail);
283 if (err == -ERESTARTSYS) 280 if (err == -ERESTARTSYS)
284 return err; 281 return err;
285 P9_DPRINTK(P9_DEBUG_TRANS, "9p: May gup pages now.\n");
286 }
287 282
288 if (rpinfo_size <= (req->tc->capacity - req->tc->size)) { 283 P9_DPRINTK(P9_DEBUG_TRANS, "9p:Retry virtio request\n");
289 /* We can use sdata */ 284 goto req_retry;
290 req->tc->private = req->tc->sdata + req->tc->size;
291 rpinfo = (struct trans_rpage_info *)req->tc->private;
292 rpinfo->rp_alloc = 0;
293 } else { 285 } else {
294 req->tc->private = kmalloc(rpinfo_size, GFP_NOFS); 286 spin_unlock_irqrestore(&chan->lock, flags);
295 if (!req->tc->private) { 287 P9_DPRINTK(P9_DEBUG_TRANS,
296 P9_DPRINTK(P9_DEBUG_TRANS, "9p debug: " 288 "9p debug: "
297 "private kmalloc returned NULL"); 289 "virtio rpc add_buf returned failure");
298 return -ENOMEM; 290 return -EIO;
299 }
300 rpinfo = (struct trans_rpage_info *)req->tc->private;
301 rpinfo->rp_alloc = 1;
302 } 291 }
292 }
293 virtqueue_kick(chan->vq);
294 spin_unlock_irqrestore(&chan->lock, flags);
303 295
304 err = p9_payload_gup(req, &pdata_off, &pdata_len, nr_pages, 296 P9_DPRINTK(P9_DEBUG_TRANS, "9p debug: virtio request kicked\n");
305 req->tc->id == P9_TREAD ? 1 : 0); 297 return 0;
306 if (err < 0) { 298}
307 if (rpinfo->rp_alloc) 299
308 kfree(rpinfo); 300static int p9_get_mapped_pages(struct virtio_chan *chan,
301 struct page **pages, char *data,
302 int nr_pages, int write, int kern_buf)
303{
304 int err;
305 if (!kern_buf) {
306 /*
307 * We allow only p9_max_pages pinned. We wait for the
308 * Other zc request to finish here
309 */
310 if (atomic_read(&vp_pinned) >= chan->p9_max_pages) {
311 err = wait_event_interruptible(vp_wq,
312 (atomic_read(&vp_pinned) < chan->p9_max_pages));
313 if (err == -ERESTARTSYS)
314 return err;
315 }
316 err = p9_payload_gup(data, &nr_pages, pages, write);
317 if (err < 0)
309 return err; 318 return err;
310 } else { 319 atomic_add(nr_pages, &vp_pinned);
311 atomic_add(rpinfo->rp_nr_pages, &vp_pinned); 320 } else {
321 /* kernel buffer, no need to pin pages */
322 int s, index = 0;
323 int count = nr_pages;
324 while (nr_pages) {
325 s = rest_of_page(data);
326 pages[index++] = virt_to_page(data);
327 data += s;
328 nr_pages--;
312 } 329 }
330 nr_pages = count;
313 } 331 }
332 return nr_pages;
333}
314 334
315req_retry_pinned: 335/**
316 spin_lock_irqsave(&chan->lock, flags); 336 * p9_virtio_zc_request - issue a zero copy request
337 * @client: client instance issuing the request
338 * @req: request to be issued
339 * @uidata: user bffer that should be ued for zero copy read
340 * @uodata: user buffer that shoud be user for zero copy write
341 * @inlen: read buffer size
342 * @olen: write buffer size
343 * @hdrlen: reader header size, This is the size of response protocol data
344 *
345 */
346static int
347p9_virtio_zc_request(struct p9_client *client, struct p9_req_t *req,
348 char *uidata, char *uodata, int inlen,
349 int outlen, int in_hdr_len, int kern_buf)
350{
351 int in, out, err;
352 unsigned long flags;
353 int in_nr_pages = 0, out_nr_pages = 0;
354 struct page **in_pages = NULL, **out_pages = NULL;
355 struct virtio_chan *chan = client->trans;
317 356
318 /* Handle out VirtIO ring buffers */ 357 P9_DPRINTK(P9_DEBUG_TRANS, "9p debug: virtio request\n");
319 out = pack_sg_list(chan->sg, 0, VIRTQUEUE_NUM, req->tc->sdata, 358
320 req->tc->size); 359 if (uodata) {
321 360 out_nr_pages = p9_nr_pages(uodata, outlen);
322 if (req->tc->pbuf_size && (req->tc->id == P9_TWRITE)) { 361 out_pages = kmalloc(sizeof(struct page *) * out_nr_pages,
323 /* We have additional write payload buffer to take care */ 362 GFP_NOFS);
324 if (req->tc->pubuf && P9_IS_USER_CONTEXT) { 363 if (!out_pages) {
325 outp = pack_sg_list_p(chan->sg, out, VIRTQUEUE_NUM, 364 err = -ENOMEM;
326 pdata_off, rpinfo->rp_data, pdata_len); 365 goto err_out;
327 } else { 366 }
328 char *pbuf; 367 out_nr_pages = p9_get_mapped_pages(chan, out_pages, uodata,
329 if (req->tc->pubuf) 368 out_nr_pages, 0, kern_buf);
330 pbuf = (__force char *) req->tc->pubuf; 369 if (out_nr_pages < 0) {
331 else 370 err = out_nr_pages;
332 pbuf = req->tc->pkbuf; 371 kfree(out_pages);
333 outp = pack_sg_list(chan->sg, out, VIRTQUEUE_NUM, pbuf, 372 out_pages = NULL;
334 req->tc->pbuf_size); 373 goto err_out;
335 } 374 }
336 out += outp;
337 } 375 }
338 376 if (uidata) {
339 /* Handle in VirtIO ring buffers */ 377 in_nr_pages = p9_nr_pages(uidata, inlen);
340 if (req->tc->pbuf_size && 378 in_pages = kmalloc(sizeof(struct page *) * in_nr_pages,
341 ((req->tc->id == P9_TREAD) || (req->tc->id == P9_TREADDIR))) { 379 GFP_NOFS);
342 /* 380 if (!in_pages) {
343 * Take care of additional Read payload. 381 err = -ENOMEM;
344 * 11 is the read/write header = PDU Header(7) + IO Size (4). 382 goto err_out;
345 * Arrange in such a way that server places header in the 383 }
346 * alloced memory and payload onto the user buffer. 384 in_nr_pages = p9_get_mapped_pages(chan, in_pages, uidata,
347 */ 385 in_nr_pages, 1, kern_buf);
348 inp = pack_sg_list(chan->sg, out, 386 if (in_nr_pages < 0) {
349 VIRTQUEUE_NUM, req->rc->sdata, 11); 387 err = in_nr_pages;
350 /* 388 kfree(in_pages);
351 * Running executables in the filesystem may result in 389 in_pages = NULL;
352 * a read request with kernel buffer as opposed to user buffer. 390 goto err_out;
353 */
354 if (req->tc->pubuf && P9_IS_USER_CONTEXT) {
355 in = pack_sg_list_p(chan->sg, out+inp, VIRTQUEUE_NUM,
356 pdata_off, rpinfo->rp_data, pdata_len);
357 } else {
358 char *pbuf;
359 if (req->tc->pubuf)
360 pbuf = (__force char *) req->tc->pubuf;
361 else
362 pbuf = req->tc->pkbuf;
363
364 in = pack_sg_list(chan->sg, out+inp, VIRTQUEUE_NUM,
365 pbuf, req->tc->pbuf_size);
366 } 391 }
367 in += inp;
368 } else {
369 in = pack_sg_list(chan->sg, out, VIRTQUEUE_NUM,
370 req->rc->sdata, req->rc->capacity);
371 } 392 }
393 req->status = REQ_STATUS_SENT;
394req_retry_pinned:
395 spin_lock_irqsave(&chan->lock, flags);
396 /* out data */
397 out = pack_sg_list(chan->sg, 0,
398 VIRTQUEUE_NUM, req->tc->sdata, req->tc->size);
399
400 if (out_pages)
401 out += pack_sg_list_p(chan->sg, out, VIRTQUEUE_NUM,
402 out_pages, out_nr_pages, uodata, outlen);
403 /*
404 * Take care of in data
405 * For example TREAD have 11.
406 * 11 is the read/write header = PDU Header(7) + IO Size (4).
407 * Arrange in such a way that server places header in the
408 * alloced memory and payload onto the user buffer.
409 */
410 in = pack_sg_list(chan->sg, out,
411 VIRTQUEUE_NUM, req->rc->sdata, in_hdr_len);
412 if (in_pages)
413 in += pack_sg_list_p(chan->sg, out + in, VIRTQUEUE_NUM,
414 in_pages, in_nr_pages, uidata, inlen);
372 415
373 err = virtqueue_add_buf(chan->vq, chan->sg, out, in, req->tc); 416 err = virtqueue_add_buf(chan->vq, chan->sg, out, in, req->tc);
374 if (err < 0) { 417 if (err < 0) {
@@ -376,28 +419,45 @@ req_retry_pinned:
376 chan->ring_bufs_avail = 0; 419 chan->ring_bufs_avail = 0;
377 spin_unlock_irqrestore(&chan->lock, flags); 420 spin_unlock_irqrestore(&chan->lock, flags);
378 err = wait_event_interruptible(*chan->vc_wq, 421 err = wait_event_interruptible(*chan->vc_wq,
379 chan->ring_bufs_avail); 422 chan->ring_bufs_avail);
380 if (err == -ERESTARTSYS) 423 if (err == -ERESTARTSYS)
381 return err; 424 goto err_out;
382 425
383 P9_DPRINTK(P9_DEBUG_TRANS, "9p:Retry virtio request\n"); 426 P9_DPRINTK(P9_DEBUG_TRANS, "9p:Retry virtio request\n");
384 goto req_retry_pinned; 427 goto req_retry_pinned;
385 } else { 428 } else {
386 spin_unlock_irqrestore(&chan->lock, flags); 429 spin_unlock_irqrestore(&chan->lock, flags);
387 P9_DPRINTK(P9_DEBUG_TRANS, 430 P9_DPRINTK(P9_DEBUG_TRANS,
388 "9p debug: " 431 "9p debug: "
389 "virtio rpc add_buf returned failure"); 432 "virtio rpc add_buf returned failure");
390 if (rpinfo && rpinfo->rp_alloc) 433 err = -EIO;
391 kfree(rpinfo); 434 goto err_out;
392 return -EIO;
393 } 435 }
394 } 436 }
395
396 virtqueue_kick(chan->vq); 437 virtqueue_kick(chan->vq);
397 spin_unlock_irqrestore(&chan->lock, flags); 438 spin_unlock_irqrestore(&chan->lock, flags);
398
399 P9_DPRINTK(P9_DEBUG_TRANS, "9p debug: virtio request kicked\n"); 439 P9_DPRINTK(P9_DEBUG_TRANS, "9p debug: virtio request kicked\n");
400 return 0; 440 err = wait_event_interruptible(*req->wq,
441 req->status >= REQ_STATUS_RCVD);
442 /*
443 * Non kernel buffers are pinned, unpin them
444 */
445err_out:
446 if (!kern_buf) {
447 if (in_pages) {
448 p9_release_pages(in_pages, in_nr_pages);
449 atomic_sub(in_nr_pages, &vp_pinned);
450 }
451 if (out_pages) {
452 p9_release_pages(out_pages, out_nr_pages);
453 atomic_sub(out_nr_pages, &vp_pinned);
454 }
455 /* wakeup anybody waiting for slots to pin pages */
456 wake_up(&vp_wq);
457 }
458 kfree(in_pages);
459 kfree(out_pages);
460 return err;
401} 461}
402 462
403static ssize_t p9_mount_tag_show(struct device *dev, 463static ssize_t p9_mount_tag_show(struct device *dev,
@@ -591,8 +651,8 @@ static struct p9_trans_module p9_virtio_trans = {
591 .create = p9_virtio_create, 651 .create = p9_virtio_create,
592 .close = p9_virtio_close, 652 .close = p9_virtio_close,
593 .request = p9_virtio_request, 653 .request = p9_virtio_request,
654 .zc_request = p9_virtio_zc_request,
594 .cancel = p9_virtio_cancel, 655 .cancel = p9_virtio_cancel,
595
596 /* 656 /*
597 * We leave one entry for input and one entry for response 657 * We leave one entry for input and one entry for response
598 * headers. We also skip one more entry to accomodate, address 658 * headers. We also skip one more entry to accomodate, address
@@ -600,7 +660,6 @@ static struct p9_trans_module p9_virtio_trans = {
600 * page in zero copy. 660 * page in zero copy.
601 */ 661 */
602 .maxsize = PAGE_SIZE * (VIRTQUEUE_NUM - 3), 662 .maxsize = PAGE_SIZE * (VIRTQUEUE_NUM - 3),
603 .pref = P9_TRANS_PREF_PAYLOAD_SEP,
604 .def = 0, 663 .def = 0,
605 .owner = THIS_MODULE, 664 .owner = THIS_MODULE,
606}; 665};