43
43
#include <linux/sunrpc/debug.h>
44
44
#include <linux/sunrpc/rpc_rdma.h>
45
45
#include <linux/spinlock.h>
46
+ #include <linux/highmem.h>
46
47
#include <asm/unaligned.h>
47
48
#include <rdma/ib_verbs.h>
48
49
#include <rdma/rdma_cm.h>
@@ -435,6 +436,32 @@ static int rdma_read_chunks(struct svcxprt_rdma *xprt,
435
436
return ret ;
436
437
}
437
438
439
+ /*
440
+ * To avoid a separate RDMA READ just for a handful of zero bytes,
441
+ * RFC 5666 section 3.7 allows the client to omit the XDR zero pad
442
+ * in chunk lists.
443
+ */
444
+ static void
445
+ rdma_fix_xdr_pad (struct xdr_buf * buf )
446
+ {
447
+ unsigned int page_len = buf -> page_len ;
448
+ unsigned int size = (XDR_QUADLEN (page_len ) << 2 ) - page_len ;
449
+ unsigned int offset , pg_no ;
450
+ char * p ;
451
+
452
+ if (size == 0 )
453
+ return ;
454
+
455
+ pg_no = page_len >> PAGE_SHIFT ;
456
+ offset = page_len & ~PAGE_MASK ;
457
+ p = page_address (buf -> pages [pg_no ]);
458
+ memset (p + offset , 0 , size );
459
+
460
+ buf -> page_len += size ;
461
+ buf -> buflen += size ;
462
+ buf -> len += size ;
463
+ }
464
+
438
465
static int rdma_read_complete (struct svc_rqst * rqstp ,
439
466
struct svc_rdma_op_ctxt * head )
440
467
{
@@ -449,6 +476,7 @@ static int rdma_read_complete(struct svc_rqst *rqstp,
449
476
rqstp -> rq_pages [page_no ] = head -> pages [page_no ];
450
477
}
451
478
/* Point rq_arg.pages past header */
479
+ rdma_fix_xdr_pad (& head -> arg );
452
480
rqstp -> rq_arg .pages = & rqstp -> rq_pages [head -> hdr_count ];
453
481
rqstp -> rq_arg .page_len = head -> arg .page_len ;
454
482
rqstp -> rq_arg .page_base = head -> arg .page_base ;
0 commit comments