aboutsummaryrefslogtreecommitdiffstats
path: root/net/9p/client.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/9p/client.c')
-rw-r--r--net/9p/client.c469
1 files changed, 332 insertions, 137 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);