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.c391
1 files changed, 291 insertions, 100 deletions
diff --git a/net/9p/client.c b/net/9p/client.c
index 0505a03c374c..305a4e719b03 100644
--- a/net/9p/client.c
+++ b/net/9p/client.c
@@ -203,11 +203,12 @@ free_and_return:
203 * 203 *
204 */ 204 */
205 205
206static struct p9_req_t *p9_tag_alloc(struct p9_client *c, u16 tag) 206static struct p9_req_t *p9_tag_alloc(struct p9_client *c, u16 tag, int max_size)
207{ 207{
208 unsigned long flags; 208 unsigned long flags;
209 int row, col; 209 int row, col;
210 struct p9_req_t *req; 210 struct p9_req_t *req;
211 int alloc_msize = min(c->msize, max_size);
211 212
212 /* This looks up the original request by tag so we know which 213 /* This looks up the original request by tag so we know which
213 * buffer to read the data into */ 214 * buffer to read the data into */
@@ -245,23 +246,12 @@ static struct p9_req_t *p9_tag_alloc(struct p9_client *c, u16 tag)
245 return ERR_PTR(-ENOMEM); 246 return ERR_PTR(-ENOMEM);
246 } 247 }
247 init_waitqueue_head(req->wq); 248 init_waitqueue_head(req->wq);
248 if ((c->trans_mod->pref & P9_TRANS_PREF_PAYLOAD_MASK) == 249 req->tc = kmalloc(sizeof(struct p9_fcall) + alloc_msize,
249 P9_TRANS_PREF_PAYLOAD_SEP) { 250 GFP_NOFS);
250 int alloc_msize = min(c->msize, 4096); 251 req->tc->capacity = alloc_msize;
251 req->tc = kmalloc(sizeof(struct p9_fcall)+alloc_msize, 252 req->rc = kmalloc(sizeof(struct p9_fcall) + alloc_msize,
252 GFP_NOFS); 253 GFP_NOFS);
253 req->tc->capacity = alloc_msize; 254 req->rc->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);
@@ -485,27 +475,8 @@ static int p9_check_errors(struct p9_client *c, struct p9_req_t *req)
485 475
486 if (!p9_is_proto_dotl(c)) { 476 if (!p9_is_proto_dotl(c)) {
487 char *ename; 477 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", 478 err = p9pdu_readf(req->rc, c->proto_version, "s?d",
508 &ename, &ecode); 479 &ename, &ecode);
509 if (err) 480 if (err)
510 goto out_err; 481 goto out_err;
511 482
@@ -515,11 +486,10 @@ static int p9_check_errors(struct p9_client *c, struct p9_req_t *req)
515 if (!err || !IS_ERR_VALUE(err)) { 486 if (!err || !IS_ERR_VALUE(err)) {
516 err = p9_errstr2errno(ename, strlen(ename)); 487 err = p9_errstr2errno(ename, strlen(ename));
517 488
518 P9_DPRINTK(P9_DEBUG_9P, "<<< RERROR (%d) %s\n", -ecode, 489 P9_DPRINTK(P9_DEBUG_9P, "<<< RERROR (%d) %s\n",
519 ename); 490 -ecode, ename);
520
521 kfree(ename);
522 } 491 }
492 kfree(ename);
523 } else { 493 } else {
524 err = p9pdu_readf(req->rc, c->proto_version, "d", &ecode); 494 err = p9pdu_readf(req->rc, c->proto_version, "d", &ecode);
525 err = -ecode; 495 err = -ecode;
@@ -527,7 +497,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); 497 P9_DPRINTK(P9_DEBUG_9P, "<<< RLERROR (%d)\n", -ecode);
528 } 498 }
529 499
530
531 return err; 500 return err;
532 501
533out_err: 502out_err:
@@ -536,6 +505,110 @@ out_err:
536 return err; 505 return err;
537} 506}
538 507
508/**
509 * p9_check_zc_errors - check 9p packet for error return and process it
510 * @c: current client instance
511 * @req: request to parse and check for error conditions
512 * @in_hdrlen: Size of response protocol buffer.
513 *
514 * returns error code if one is discovered, otherwise returns 0
515 *
516 * this will have to be more complicated if we have multiple
517 * error packet types
518 */
519
520static int p9_check_zc_errors(struct p9_client *c, struct p9_req_t *req,
521 char *uidata, int in_hdrlen, int kern_buf)
522{
523 int err;
524 int ecode;
525 int8_t type;
526 char *ename = NULL;
527
528 err = p9_parse_header(req->rc, NULL, &type, NULL, 0);
529 if (err) {
530 P9_DPRINTK(P9_DEBUG_ERROR, "couldn't parse header %d\n", err);
531 return err;
532 }
533
534 if (type != P9_RERROR && type != P9_RLERROR)
535 return 0;
536
537 if (!p9_is_proto_dotl(c)) {
538 /* Error is reported in string format */
539 uint16_t len;
540 /* 7 = header size for RERROR, 2 is the size of string len; */
541 int inline_len = in_hdrlen - (7 + 2);
542
543 /* Read the size of error string */
544 err = p9pdu_readf(req->rc, c->proto_version, "w", &len);
545 if (err)
546 goto out_err;
547
548 ename = kmalloc(len + 1, GFP_NOFS);
549 if (!ename) {
550 err = -ENOMEM;
551 goto out_err;
552 }
553 if (len <= inline_len) {
554 /* We have error in protocol buffer itself */
555 if (pdu_read(req->rc, ename, len)) {
556 err = -EFAULT;
557 goto out_free;
558
559 }
560 } else {
561 /*
562 * Part of the data is in user space buffer.
563 */
564 if (pdu_read(req->rc, ename, inline_len)) {
565 err = -EFAULT;
566 goto out_free;
567
568 }
569 if (kern_buf) {
570 memcpy(ename + inline_len, uidata,
571 len - inline_len);
572 } else {
573 err = copy_from_user(ename + inline_len,
574 uidata, len - inline_len);
575 if (err) {
576 err = -EFAULT;
577 goto out_free;
578 }
579 }
580 }
581 ename[len] = 0;
582 if (p9_is_proto_dotu(c)) {
583 /* For dotu we also have error code */
584 err = p9pdu_readf(req->rc,
585 c->proto_version, "d", &ecode);
586 if (err)
587 goto out_free;
588 err = -ecode;
589 }
590 if (!err || !IS_ERR_VALUE(err)) {
591 err = p9_errstr2errno(ename, strlen(ename));
592
593 P9_DPRINTK(P9_DEBUG_9P, "<<< RERROR (%d) %s\n",
594 -ecode, ename);
595 }
596 kfree(ename);
597 } else {
598 err = p9pdu_readf(req->rc, c->proto_version, "d", &ecode);
599 err = -ecode;
600
601 P9_DPRINTK(P9_DEBUG_9P, "<<< RLERROR (%d)\n", -ecode);
602 }
603 return err;
604
605out_free:
606 kfree(ename);
607out_err:
608 P9_DPRINTK(P9_DEBUG_ERROR, "couldn't parse error%d\n", err);
609 return err;
610}
611
539static struct p9_req_t * 612static struct p9_req_t *
540p9_client_rpc(struct p9_client *c, int8_t type, const char *fmt, ...); 613p9_client_rpc(struct p9_client *c, int8_t type, const char *fmt, ...);
541 614
@@ -579,23 +652,12 @@ static int p9_client_flush(struct p9_client *c, struct p9_req_t *oldreq)
579 return 0; 652 return 0;
580} 653}
581 654
582/** 655static struct p9_req_t *p9_client_prepare_req(struct p9_client *c,
583 * p9_client_rpc - issue a request and wait for a response 656 int8_t type, int req_size,
584 * @c: client session 657 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{ 658{
594 va_list ap;
595 int tag, err; 659 int tag, err;
596 struct p9_req_t *req; 660 struct p9_req_t *req;
597 unsigned long flags;
598 int sigpending;
599 661
600 P9_DPRINTK(P9_DEBUG_MUX, "client %p op %d\n", c, type); 662 P9_DPRINTK(P9_DEBUG_MUX, "client %p op %d\n", c, type);
601 663
@@ -607,12 +669,6 @@ p9_client_rpc(struct p9_client *c, int8_t type, const char *fmt, ...)
607 if ((c->status == BeginDisconnect) && (type != P9_TCLUNK)) 669 if ((c->status == BeginDisconnect) && (type != P9_TCLUNK))
608 return ERR_PTR(-EIO); 670 return ERR_PTR(-EIO);
609 671
610 if (signal_pending(current)) {
611 sigpending = 1;
612 clear_thread_flag(TIF_SIGPENDING);
613 } else
614 sigpending = 0;
615
616 tag = P9_NOTAG; 672 tag = P9_NOTAG;
617 if (type != P9_TVERSION) { 673 if (type != P9_TVERSION) {
618 tag = p9_idpool_get(c->tagpool); 674 tag = p9_idpool_get(c->tagpool);
@@ -620,18 +676,50 @@ p9_client_rpc(struct p9_client *c, int8_t type, const char *fmt, ...)
620 return ERR_PTR(-ENOMEM); 676 return ERR_PTR(-ENOMEM);
621 } 677 }
622 678
623 req = p9_tag_alloc(c, tag); 679 req = p9_tag_alloc(c, tag, req_size);
624 if (IS_ERR(req)) 680 if (IS_ERR(req))
625 return req; 681 return req;
626 682
627 /* marshall the data */ 683 /* marshall the data */
628 p9pdu_prepare(req->tc, tag, type); 684 p9pdu_prepare(req->tc, tag, type);
629 va_start(ap, fmt);
630 err = p9pdu_vwritef(req->tc, c->proto_version, fmt, ap); 685 err = p9pdu_vwritef(req->tc, c->proto_version, fmt, ap);
631 va_end(ap);
632 if (err) 686 if (err)
633 goto reterr; 687 goto reterr;
634 p9pdu_finalize(req->tc); 688 p9pdu_finalize(req->tc);
689 return req;
690reterr:
691 p9_free_req(c, req);
692 return ERR_PTR(err);
693}
694
695/**
696 * p9_client_rpc - issue a request and wait for a response
697 * @c: client session
698 * @type: type of request
699 * @fmt: protocol format string (see protocol.c)
700 *
701 * Returns request structure (which client must free using p9_free_req)
702 */
703
704static struct p9_req_t *
705p9_client_rpc(struct p9_client *c, int8_t type, const char *fmt, ...)
706{
707 va_list ap;
708 int sigpending, err;
709 unsigned long flags;
710 struct p9_req_t *req;
711
712 va_start(ap, fmt);
713 req = p9_client_prepare_req(c, type, c->msize, fmt, ap);
714 va_end(ap);
715 if (IS_ERR(req))
716 return req;
717
718 if (signal_pending(current)) {
719 sigpending = 1;
720 clear_thread_flag(TIF_SIGPENDING);
721 } else
722 sigpending = 0;
635 723
636 err = c->trans_mod->request(c, req); 724 err = c->trans_mod->request(c, req);
637 if (err < 0) { 725 if (err < 0) {
@@ -639,18 +727,14 @@ p9_client_rpc(struct p9_client *c, int8_t type, const char *fmt, ...)
639 c->status = Disconnected; 727 c->status = Disconnected;
640 goto reterr; 728 goto reterr;
641 } 729 }
642 730 /* 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, 731 err = wait_event_interruptible(*req->wq,
645 req->status >= REQ_STATUS_RCVD); 732 req->status >= REQ_STATUS_RCVD);
646 P9_DPRINTK(P9_DEBUG_MUX, "wait %p tag: %d returned %d\n",
647 req->wq, tag, err);
648 733
649 if (req->status == REQ_STATUS_ERROR) { 734 if (req->status == REQ_STATUS_ERROR) {
650 P9_DPRINTK(P9_DEBUG_ERROR, "req_status error %d\n", req->t_err); 735 P9_DPRINTK(P9_DEBUG_ERROR, "req_status error %d\n", req->t_err);
651 err = req->t_err; 736 err = req->t_err;
652 } 737 }
653
654 if ((err == -ERESTARTSYS) && (c->status == Connected)) { 738 if ((err == -ERESTARTSYS) && (c->status == Connected)) {
655 P9_DPRINTK(P9_DEBUG_MUX, "flushing\n"); 739 P9_DPRINTK(P9_DEBUG_MUX, "flushing\n");
656 sigpending = 1; 740 sigpending = 1;
@@ -663,13 +747,11 @@ p9_client_rpc(struct p9_client *c, int8_t type, const char *fmt, ...)
663 if (req->status == REQ_STATUS_RCVD) 747 if (req->status == REQ_STATUS_RCVD)
664 err = 0; 748 err = 0;
665 } 749 }
666
667 if (sigpending) { 750 if (sigpending) {
668 spin_lock_irqsave(&current->sighand->siglock, flags); 751 spin_lock_irqsave(&current->sighand->siglock, flags);
669 recalc_sigpending(); 752 recalc_sigpending();
670 spin_unlock_irqrestore(&current->sighand->siglock, flags); 753 spin_unlock_irqrestore(&current->sighand->siglock, flags);
671 } 754 }
672
673 if (err < 0) 755 if (err < 0)
674 goto reterr; 756 goto reterr;
675 757
@@ -678,7 +760,92 @@ p9_client_rpc(struct p9_client *c, int8_t type, const char *fmt, ...)
678 P9_DPRINTK(P9_DEBUG_MUX, "exit: client %p op %d\n", c, type); 760 P9_DPRINTK(P9_DEBUG_MUX, "exit: client %p op %d\n", c, type);
679 return req; 761 return req;
680 } 762 }
763reterr:
764 P9_DPRINTK(P9_DEBUG_MUX,
765 "exit: client %p op %d error: %d\n", c, type, err);
766 p9_free_req(c, req);
767 return ERR_PTR(err);
768}
769
770/**
771 * p9_client_zc_rpc - issue a request and wait for a response
772 * @c: client session
773 * @type: type of request
774 * @uidata: user bffer that should be ued for zero copy read
775 * @uodata: user buffer that shoud be user for zero copy write
776 * @inlen: read buffer size
777 * @olen: write buffer size
778 * @hdrlen: reader header size, This is the size of response protocol data
779 * @fmt: protocol format string (see protocol.c)
780 *
781 * Returns request structure (which client must free using p9_free_req)
782 */
783static struct p9_req_t *p9_client_zc_rpc(struct p9_client *c, int8_t type,
784 char *uidata, char *uodata,
785 int inlen, int olen, int in_hdrlen,
786 int kern_buf, const char *fmt, ...)
787{
788 va_list ap;
789 int sigpending, err;
790 unsigned long flags;
791 struct p9_req_t *req;
792
793 va_start(ap, fmt);
794 /*
795 * We allocate a inline protocol data of only 4k bytes.
796 * The actual content is passed in zero-copy fashion.
797 */
798 req = p9_client_prepare_req(c, type, P9_ZC_HDR_SZ, fmt, ap);
799 va_end(ap);
800 if (IS_ERR(req))
801 return req;
802
803 if (signal_pending(current)) {
804 sigpending = 1;
805 clear_thread_flag(TIF_SIGPENDING);
806 } else
807 sigpending = 0;
808
809 /* If we are called with KERNEL_DS force kern_buf */
810 if (segment_eq(get_fs(), KERNEL_DS))
811 kern_buf = 1;
812
813 err = c->trans_mod->zc_request(c, req, uidata, uodata,
814 inlen, olen, in_hdrlen, kern_buf);
815 if (err < 0) {
816 if (err == -EIO)
817 c->status = Disconnected;
818 goto reterr;
819 }
820 if (req->status == REQ_STATUS_ERROR) {
821 P9_DPRINTK(P9_DEBUG_ERROR, "req_status error %d\n", req->t_err);
822 err = req->t_err;
823 }
824 if ((err == -ERESTARTSYS) && (c->status == Connected)) {
825 P9_DPRINTK(P9_DEBUG_MUX, "flushing\n");
826 sigpending = 1;
827 clear_thread_flag(TIF_SIGPENDING);
681 828
829 if (c->trans_mod->cancel(c, req))
830 p9_client_flush(c, req);
831
832 /* if we received the response anyway, don't signal error */
833 if (req->status == REQ_STATUS_RCVD)
834 err = 0;
835 }
836 if (sigpending) {
837 spin_lock_irqsave(&current->sighand->siglock, flags);
838 recalc_sigpending();
839 spin_unlock_irqrestore(&current->sighand->siglock, flags);
840 }
841 if (err < 0)
842 goto reterr;
843
844 err = p9_check_zc_errors(c, req, uidata, in_hdrlen, kern_buf);
845 if (!err) {
846 P9_DPRINTK(P9_DEBUG_MUX, "exit: client %p op %d\n", c, type);
847 return req;
848 }
682reterr: 849reterr:
683 P9_DPRINTK(P9_DEBUG_MUX, "exit: client %p op %d error: %d\n", c, type, 850 P9_DPRINTK(P9_DEBUG_MUX, "exit: client %p op %d error: %d\n", c, type,
684 err); 851 err);
@@ -1330,13 +1497,15 @@ int
1330p9_client_read(struct p9_fid *fid, char *data, char __user *udata, u64 offset, 1497p9_client_read(struct p9_fid *fid, char *data, char __user *udata, u64 offset,
1331 u32 count) 1498 u32 count)
1332{ 1499{
1333 int err, rsize;
1334 struct p9_client *clnt;
1335 struct p9_req_t *req;
1336 char *dataptr; 1500 char *dataptr;
1501 int kernel_buf = 0;
1502 struct p9_req_t *req;
1503 struct p9_client *clnt;
1504 int err, rsize, non_zc = 0;
1505
1337 1506
1338 P9_DPRINTK(P9_DEBUG_9P, ">>> TREAD fid %d offset %llu %d\n", fid->fid, 1507 P9_DPRINTK(P9_DEBUG_9P, ">>> TREAD fid %d offset %llu %d\n",
1339 (long long unsigned) offset, count); 1508 fid->fid, (long long unsigned) offset, count);
1340 err = 0; 1509 err = 0;
1341 clnt = fid->clnt; 1510 clnt = fid->clnt;
1342 1511
@@ -1348,13 +1517,24 @@ p9_client_read(struct p9_fid *fid, char *data, char __user *udata, u64 offset,
1348 rsize = count; 1517 rsize = count;
1349 1518
1350 /* Don't bother zerocopy for small IO (< 1024) */ 1519 /* Don't bother zerocopy for small IO (< 1024) */
1351 if (((clnt->trans_mod->pref & P9_TRANS_PREF_PAYLOAD_MASK) == 1520 if (clnt->trans_mod->zc_request && rsize > 1024) {
1352 P9_TRANS_PREF_PAYLOAD_SEP) && (rsize > 1024)) { 1521 char *indata;
1353 req = p9_client_rpc(clnt, P9_TREAD, "dqE", fid->fid, offset, 1522 if (data) {
1354 rsize, data, udata); 1523 kernel_buf = 1;
1524 indata = data;
1525 } else
1526 indata = (char *)udata;
1527 /*
1528 * response header len is 11
1529 * PDU Header(7) + IO Size (4)
1530 */
1531 req = p9_client_zc_rpc(clnt, P9_TREAD, indata, NULL, rsize, 0,
1532 11, kernel_buf, "dqd", fid->fid,
1533 offset, rsize);
1355 } else { 1534 } else {
1535 non_zc = 1;
1356 req = p9_client_rpc(clnt, P9_TREAD, "dqd", fid->fid, offset, 1536 req = p9_client_rpc(clnt, P9_TREAD, "dqd", fid->fid, offset,
1357 rsize); 1537 rsize);
1358 } 1538 }
1359 if (IS_ERR(req)) { 1539 if (IS_ERR(req)) {
1360 err = PTR_ERR(req); 1540 err = PTR_ERR(req);
@@ -1370,7 +1550,7 @@ p9_client_read(struct p9_fid *fid, char *data, char __user *udata, u64 offset,
1370 P9_DPRINTK(P9_DEBUG_9P, "<<< RREAD count %d\n", count); 1550 P9_DPRINTK(P9_DEBUG_9P, "<<< RREAD count %d\n", count);
1371 P9_DUMP_PKT(1, req->rc); 1551 P9_DUMP_PKT(1, req->rc);
1372 1552
1373 if (!req->tc->pbuf_size) { 1553 if (non_zc) {
1374 if (data) { 1554 if (data) {
1375 memmove(data, dataptr, count); 1555 memmove(data, dataptr, count);
1376 } else { 1556 } else {
@@ -1396,6 +1576,7 @@ p9_client_write(struct p9_fid *fid, char *data, const char __user *udata,
1396 u64 offset, u32 count) 1576 u64 offset, u32 count)
1397{ 1577{
1398 int err, rsize; 1578 int err, rsize;
1579 int kernel_buf = 0;
1399 struct p9_client *clnt; 1580 struct p9_client *clnt;
1400 struct p9_req_t *req; 1581 struct p9_req_t *req;
1401 1582
@@ -1411,19 +1592,24 @@ p9_client_write(struct p9_fid *fid, char *data, const char __user *udata,
1411 if (count < rsize) 1592 if (count < rsize)
1412 rsize = count; 1593 rsize = count;
1413 1594
1414 /* Don't bother zerocopy form small IO (< 1024) */ 1595 /* Don't bother zerocopy for small IO (< 1024) */
1415 if (((clnt->trans_mod->pref & P9_TRANS_PREF_PAYLOAD_MASK) == 1596 if (clnt->trans_mod->zc_request && rsize > 1024) {
1416 P9_TRANS_PREF_PAYLOAD_SEP) && (rsize > 1024)) { 1597 char *odata;
1417 req = p9_client_rpc(clnt, P9_TWRITE, "dqE", fid->fid, offset, 1598 if (data) {
1418 rsize, data, udata); 1599 kernel_buf = 1;
1600 odata = data;
1601 } else
1602 odata = (char *)udata;
1603 req = p9_client_zc_rpc(clnt, P9_TWRITE, NULL, odata, 0, rsize,
1604 P9_ZC_HDR_SZ, kernel_buf, "dqd",
1605 fid->fid, offset, rsize);
1419 } else { 1606 } else {
1420
1421 if (data) 1607 if (data)
1422 req = p9_client_rpc(clnt, P9_TWRITE, "dqD", fid->fid, 1608 req = p9_client_rpc(clnt, P9_TWRITE, "dqD", fid->fid,
1423 offset, rsize, data); 1609 offset, rsize, data);
1424 else 1610 else
1425 req = p9_client_rpc(clnt, P9_TWRITE, "dqU", fid->fid, 1611 req = p9_client_rpc(clnt, P9_TWRITE, "dqU", fid->fid,
1426 offset, rsize, udata); 1612 offset, rsize, udata);
1427 } 1613 }
1428 if (IS_ERR(req)) { 1614 if (IS_ERR(req)) {
1429 err = PTR_ERR(req); 1615 err = PTR_ERR(req);
@@ -1824,7 +2010,7 @@ EXPORT_SYMBOL_GPL(p9_client_xattrcreate);
1824 2010
1825int p9_client_readdir(struct p9_fid *fid, char *data, u32 count, u64 offset) 2011int p9_client_readdir(struct p9_fid *fid, char *data, u32 count, u64 offset)
1826{ 2012{
1827 int err, rsize; 2013 int err, rsize, non_zc = 0;
1828 struct p9_client *clnt; 2014 struct p9_client *clnt;
1829 struct p9_req_t *req; 2015 struct p9_req_t *req;
1830 char *dataptr; 2016 char *dataptr;
@@ -1842,13 +2028,18 @@ int p9_client_readdir(struct p9_fid *fid, char *data, u32 count, u64 offset)
1842 if (count < rsize) 2028 if (count < rsize)
1843 rsize = count; 2029 rsize = count;
1844 2030
1845 if ((clnt->trans_mod->pref & P9_TRANS_PREF_PAYLOAD_MASK) == 2031 /* Don't bother zerocopy for small IO (< 1024) */
1846 P9_TRANS_PREF_PAYLOAD_SEP) { 2032 if (clnt->trans_mod->zc_request && rsize > 1024) {
1847 req = p9_client_rpc(clnt, P9_TREADDIR, "dqF", fid->fid, 2033 /*
1848 offset, rsize, data); 2034 * response header len is 11
2035 * PDU Header(7) + IO Size (4)
2036 */
2037 req = p9_client_zc_rpc(clnt, P9_TREADDIR, data, NULL, rsize, 0,
2038 11, 1, "dqd", fid->fid, offset, rsize);
1849 } else { 2039 } else {
2040 non_zc = 1;
1850 req = p9_client_rpc(clnt, P9_TREADDIR, "dqd", fid->fid, 2041 req = p9_client_rpc(clnt, P9_TREADDIR, "dqd", fid->fid,
1851 offset, rsize); 2042 offset, rsize);
1852 } 2043 }
1853 if (IS_ERR(req)) { 2044 if (IS_ERR(req)) {
1854 err = PTR_ERR(req); 2045 err = PTR_ERR(req);
@@ -1863,7 +2054,7 @@ int p9_client_readdir(struct p9_fid *fid, char *data, u32 count, u64 offset)
1863 2054
1864 P9_DPRINTK(P9_DEBUG_9P, "<<< RREADDIR count %d\n", count); 2055 P9_DPRINTK(P9_DEBUG_9P, "<<< RREADDIR count %d\n", count);
1865 2056
1866 if (!req->tc->pbuf_size && data) 2057 if (non_zc)
1867 memmove(data, dataptr, count); 2058 memmove(data, dataptr, count);
1868 2059
1869 p9_free_req(clnt, req); 2060 p9_free_req(clnt, req);