Skip to content

Commit 5d22c5a

Browse files
committed
Merge tag 'nfsd-4.7' of git://linux-nfs.org/~bfields/linux
Pull nfsd updates from Bruce Fields: "A very quiet cycle for nfsd, mainly just an RDMA update from Chuck Lever" * tag 'nfsd-4.7' of git://linux-nfs.org/~bfields/linux: sunrpc: fix stripping of padded MIC tokens svcrpc: autoload rdma module svcrdma: Generalize svc_rdma_xdr_decode_req() svcrdma: Eliminate code duplication in svc_rdma_recvfrom() svcrdma: Drain QP before freeing svcrdma_xprt svcrdma: Post Receives only for forward channel requests svcrdma: Remove superfluous line from rdma_read_chunks() svcrdma: svc_rdma_put_context() is invoked twice in Send error path svcrdma: Do not add XDR padding to xdr_buf page vector svcrdma: Support IPv6 with NFS/RDMA nfsd: handle seqid wraparound in nfsd4_preprocess_layout_stateid Remove unnecessary allocation
2 parents 0e01df1 + c0cb8bf commit 5d22c5a

File tree

11 files changed

+90
-72
lines changed

11 files changed

+90
-72
lines changed

fs/nfsd/nfs3xdr.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -379,7 +379,7 @@ nfs3svc_decode_writeargs(struct svc_rqst *rqstp, __be32 *p,
379379
*/
380380
hdr = (void*)p - rqstp->rq_arg.head[0].iov_base;
381381
dlen = rqstp->rq_arg.head[0].iov_len + rqstp->rq_arg.page_len
382-
- hdr;
382+
+ rqstp->rq_arg.tail[0].iov_len - hdr;
383383
/*
384384
* Round the length of the data which was specified up to
385385
* the next multiple of XDR units and then compare that

fs/nfsd/nfs4layouts.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,7 @@ nfsd4_preprocess_layout_stateid(struct svc_rqst *rqstp,
289289

290290
status = nfserr_bad_stateid;
291291
mutex_lock(&ls->ls_mutex);
292-
if (stateid->si_generation > stid->sc_stateid.si_generation)
292+
if (nfsd4_stateid_generation_after(stateid, &stid->sc_stateid))
293293
goto out_unlock_stid;
294294
if (layout_type != ls->ls_layout_type)
295295
goto out_unlock_stid;

fs/nfsd/nfs4state.c

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4651,12 +4651,6 @@ grace_disallows_io(struct net *net, struct inode *inode)
46514651
return opens_in_grace(net) && mandatory_lock(inode);
46524652
}
46534653

4654-
/* Returns true iff a is later than b: */
4655-
static bool stateid_generation_after(stateid_t *a, stateid_t *b)
4656-
{
4657-
return (s32)(a->si_generation - b->si_generation) > 0;
4658-
}
4659-
46604654
static __be32 check_stateid_generation(stateid_t *in, stateid_t *ref, bool has_session)
46614655
{
46624656
/*
@@ -4670,7 +4664,7 @@ static __be32 check_stateid_generation(stateid_t *in, stateid_t *ref, bool has_s
46704664
return nfs_ok;
46714665

46724666
/* If the client sends us a stateid from the future, it's buggy: */
4673-
if (stateid_generation_after(in, ref))
4667+
if (nfsd4_stateid_generation_after(in, ref))
46744668
return nfserr_bad_stateid;
46754669
/*
46764670
* However, we could see a stateid from the past, even from a

fs/nfsd/state.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -573,6 +573,11 @@ enum nfsd4_cb_op {
573573
NFSPROC4_CLNT_CB_SEQUENCE,
574574
};
575575

576+
/* Returns true iff a is later than b: */
577+
static inline bool nfsd4_stateid_generation_after(stateid_t *a, stateid_t *b)
578+
{
579+
return (s32)(a->si_generation - b->si_generation) > 0;
580+
}
576581

577582
struct nfsd4_compound_state;
578583
struct nfsd_net;

include/linux/sunrpc/svc_rdma.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ extern int svc_rdma_handle_bc_reply(struct rpc_xprt *xprt,
199199
struct xdr_buf *rcvbuf);
200200

201201
/* svc_rdma_marshal.c */
202-
extern int svc_rdma_xdr_decode_req(struct rpcrdma_msg *, struct svc_rqst *);
202+
extern int svc_rdma_xdr_decode_req(struct xdr_buf *);
203203
extern int svc_rdma_xdr_encode_error(struct svcxprt_rdma *,
204204
struct rpcrdma_msg *,
205205
enum rpcrdma_errcode, __be32 *);

net/sunrpc/auth_gss/svcauth_gss.c

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -569,10 +569,9 @@ gss_svc_searchbyctx(struct cache_detail *cd, struct xdr_netobj *handle)
569569
struct rsc *found;
570570

571571
memset(&rsci, 0, sizeof(rsci));
572-
if (dup_to_netobj(&rsci.handle, handle->data, handle->len))
573-
return NULL;
572+
rsci.handle.data = handle->data;
573+
rsci.handle.len = handle->len;
574574
found = rsc_lookup(cd, &rsci);
575-
rsc_free(&rsci);
576575
if (!found)
577576
return NULL;
578577
if (cache_check(cd, &found->h, NULL))
@@ -857,8 +856,8 @@ unwrap_integ_data(struct svc_rqst *rqstp, struct xdr_buf *buf, u32 seq, struct g
857856
goto out;
858857
if (svc_getnl(&buf->head[0]) != seq)
859858
goto out;
860-
/* trim off the mic at the end before returning */
861-
xdr_buf_trim(buf, mic.len + 4);
859+
/* trim off the mic and padding at the end before returning */
860+
xdr_buf_trim(buf, round_up_to_quad(mic.len) + 4);
862861
stat = 0;
863862
out:
864863
kfree(mic.data);

net/sunrpc/svc_xprt.c

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -244,13 +244,12 @@ void svc_add_new_perm_xprt(struct svc_serv *serv, struct svc_xprt *new)
244244
svc_xprt_received(new);
245245
}
246246

247-
int svc_create_xprt(struct svc_serv *serv, const char *xprt_name,
247+
int _svc_create_xprt(struct svc_serv *serv, const char *xprt_name,
248248
struct net *net, const int family,
249249
const unsigned short port, int flags)
250250
{
251251
struct svc_xprt_class *xcl;
252252

253-
dprintk("svc: creating transport %s[%d]\n", xprt_name, port);
254253
spin_lock(&svc_xprt_class_lock);
255254
list_for_each_entry(xcl, &svc_xprt_class_list, xcl_list) {
256255
struct svc_xprt *newxprt;
@@ -274,12 +273,28 @@ int svc_create_xprt(struct svc_serv *serv, const char *xprt_name,
274273
}
275274
err:
276275
spin_unlock(&svc_xprt_class_lock);
277-
dprintk("svc: transport %s not found\n", xprt_name);
278-
279276
/* This errno is exposed to user space. Provide a reasonable
280277
* perror msg for a bad transport. */
281278
return -EPROTONOSUPPORT;
282279
}
280+
281+
int svc_create_xprt(struct svc_serv *serv, const char *xprt_name,
282+
struct net *net, const int family,
283+
const unsigned short port, int flags)
284+
{
285+
int err;
286+
287+
dprintk("svc: creating transport %s[%d]\n", xprt_name, port);
288+
err = _svc_create_xprt(serv, xprt_name, net, family, port, flags);
289+
if (err == -EPROTONOSUPPORT) {
290+
request_module("svc%s", xprt_name);
291+
err = _svc_create_xprt(serv, xprt_name, net, family, port, flags);
292+
}
293+
if (err)
294+
dprintk("svc: transport %s not found, err %d\n",
295+
xprt_name, err);
296+
return err;
297+
}
283298
EXPORT_SYMBOL_GPL(svc_create_xprt);
284299

285300
/*

net/sunrpc/xprtrdma/svc_rdma_marshal.c

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -145,19 +145,32 @@ static __be32 *decode_reply_array(__be32 *va, __be32 *vaend)
145145
return (__be32 *)&ary->wc_array[nchunks];
146146
}
147147

148-
int svc_rdma_xdr_decode_req(struct rpcrdma_msg *rmsgp, struct svc_rqst *rqstp)
148+
/**
149+
* svc_rdma_xdr_decode_req - Parse incoming RPC-over-RDMA header
150+
* @rq_arg: Receive buffer
151+
*
152+
* On entry, xdr->head[0].iov_base points to first byte in the
153+
* RPC-over-RDMA header.
154+
*
155+
* On successful exit, head[0] points to first byte past the
156+
* RPC-over-RDMA header. For RDMA_MSG, this is the RPC message.
157+
* The length of the RPC-over-RDMA header is returned.
158+
*/
159+
int svc_rdma_xdr_decode_req(struct xdr_buf *rq_arg)
149160
{
161+
struct rpcrdma_msg *rmsgp;
150162
__be32 *va, *vaend;
151163
unsigned int len;
152164
u32 hdr_len;
153165

154166
/* Verify that there's enough bytes for header + something */
155-
if (rqstp->rq_arg.len <= RPCRDMA_HDRLEN_ERR) {
167+
if (rq_arg->len <= RPCRDMA_HDRLEN_ERR) {
156168
dprintk("svcrdma: header too short = %d\n",
157-
rqstp->rq_arg.len);
169+
rq_arg->len);
158170
return -EINVAL;
159171
}
160172

173+
rmsgp = (struct rpcrdma_msg *)rq_arg->head[0].iov_base;
161174
if (rmsgp->rm_vers != rpcrdma_version) {
162175
dprintk("%s: bad version %u\n", __func__,
163176
be32_to_cpu(rmsgp->rm_vers));
@@ -189,10 +202,10 @@ int svc_rdma_xdr_decode_req(struct rpcrdma_msg *rmsgp, struct svc_rqst *rqstp)
189202
be32_to_cpu(rmsgp->rm_body.rm_padded.rm_thresh);
190203

191204
va = &rmsgp->rm_body.rm_padded.rm_pempty[4];
192-
rqstp->rq_arg.head[0].iov_base = va;
205+
rq_arg->head[0].iov_base = va;
193206
len = (u32)((unsigned long)va - (unsigned long)rmsgp);
194-
rqstp->rq_arg.head[0].iov_len -= len;
195-
if (len > rqstp->rq_arg.len)
207+
rq_arg->head[0].iov_len -= len;
208+
if (len > rq_arg->len)
196209
return -EINVAL;
197210
return len;
198211
default:
@@ -205,7 +218,7 @@ int svc_rdma_xdr_decode_req(struct rpcrdma_msg *rmsgp, struct svc_rqst *rqstp)
205218
* chunk list and a reply chunk list.
206219
*/
207220
va = &rmsgp->rm_body.rm_chunks[0];
208-
vaend = (__be32 *)((unsigned long)rmsgp + rqstp->rq_arg.len);
221+
vaend = (__be32 *)((unsigned long)rmsgp + rq_arg->len);
209222
va = decode_read_list(va, vaend);
210223
if (!va) {
211224
dprintk("svcrdma: failed to decode read list\n");
@@ -222,10 +235,9 @@ int svc_rdma_xdr_decode_req(struct rpcrdma_msg *rmsgp, struct svc_rqst *rqstp)
222235
return -EINVAL;
223236
}
224237

225-
rqstp->rq_arg.head[0].iov_base = va;
238+
rq_arg->head[0].iov_base = va;
226239
hdr_len = (unsigned long)va - (unsigned long)rmsgp;
227-
rqstp->rq_arg.head[0].iov_len -= hdr_len;
228-
240+
rq_arg->head[0].iov_len -= hdr_len;
229241
return hdr_len;
230242
}
231243

net/sunrpc/xprtrdma/svc_rdma_recvfrom.c

Lines changed: 8 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -447,10 +447,8 @@ static int rdma_read_chunks(struct svcxprt_rdma *xprt,
447447
head->arg.len = rqstp->rq_arg.len;
448448
head->arg.buflen = rqstp->rq_arg.buflen;
449449

450-
ch = (struct rpcrdma_read_chunk *)&rmsgp->rm_body.rm_chunks[0];
451-
position = be32_to_cpu(ch->rc_position);
452-
453450
/* RDMA_NOMSG: RDMA READ data should land just after RDMA RECV data */
451+
position = be32_to_cpu(ch->rc_position);
454452
if (position == 0) {
455453
head->arg.pages = &head->pages[0];
456454
page_offset = head->byte_len;
@@ -488,7 +486,7 @@ static int rdma_read_chunks(struct svcxprt_rdma *xprt,
488486
if (page_offset & 3) {
489487
u32 pad = 4 - (page_offset & 3);
490488

491-
head->arg.page_len += pad;
489+
head->arg.tail[0].iov_len += pad;
492490
head->arg.len += pad;
493491
head->arg.buflen += pad;
494492
page_offset += pad;
@@ -510,11 +508,10 @@ static int rdma_read_chunks(struct svcxprt_rdma *xprt,
510508
return ret;
511509
}
512510

513-
static int rdma_read_complete(struct svc_rqst *rqstp,
514-
struct svc_rdma_op_ctxt *head)
511+
static void rdma_read_complete(struct svc_rqst *rqstp,
512+
struct svc_rdma_op_ctxt *head)
515513
{
516514
int page_no;
517-
int ret;
518515

519516
/* Copy RPC pages */
520517
for (page_no = 0; page_no < head->count; page_no++) {
@@ -550,23 +547,6 @@ static int rdma_read_complete(struct svc_rqst *rqstp,
550547
rqstp->rq_arg.tail[0] = head->arg.tail[0];
551548
rqstp->rq_arg.len = head->arg.len;
552549
rqstp->rq_arg.buflen = head->arg.buflen;
553-
554-
/* Free the context */
555-
svc_rdma_put_context(head, 0);
556-
557-
/* XXX: What should this be? */
558-
rqstp->rq_prot = IPPROTO_MAX;
559-
svc_xprt_copy_addrs(rqstp, rqstp->rq_xprt);
560-
561-
ret = rqstp->rq_arg.head[0].iov_len
562-
+ rqstp->rq_arg.page_len
563-
+ rqstp->rq_arg.tail[0].iov_len;
564-
dprintk("svcrdma: deferred read ret=%d, rq_arg.len=%u, "
565-
"rq_arg.head[0].iov_base=%p, rq_arg.head[0].iov_len=%zu\n",
566-
ret, rqstp->rq_arg.len, rqstp->rq_arg.head[0].iov_base,
567-
rqstp->rq_arg.head[0].iov_len);
568-
569-
return ret;
570550
}
571551

572552
/* By convention, backchannel calls arrive via rdma_msg type
@@ -624,7 +604,8 @@ int svc_rdma_recvfrom(struct svc_rqst *rqstp)
624604
dto_q);
625605
list_del_init(&ctxt->dto_q);
626606
spin_unlock_bh(&rdma_xprt->sc_rq_dto_lock);
627-
return rdma_read_complete(rqstp, ctxt);
607+
rdma_read_complete(rqstp, ctxt);
608+
goto complete;
628609
} else if (!list_empty(&rdma_xprt->sc_rq_dto_q)) {
629610
ctxt = list_entry(rdma_xprt->sc_rq_dto_q.next,
630611
struct svc_rdma_op_ctxt,
@@ -655,7 +636,7 @@ int svc_rdma_recvfrom(struct svc_rqst *rqstp)
655636

656637
/* Decode the RDMA header. */
657638
rmsgp = (struct rpcrdma_msg *)rqstp->rq_arg.head[0].iov_base;
658-
ret = svc_rdma_xdr_decode_req(rmsgp, rqstp);
639+
ret = svc_rdma_xdr_decode_req(&rqstp->rq_arg);
659640
if (ret < 0)
660641
goto out_err;
661642
if (ret == 0)
@@ -682,6 +663,7 @@ int svc_rdma_recvfrom(struct svc_rqst *rqstp)
682663
return 0;
683664
}
684665

666+
complete:
685667
ret = rqstp->rq_arg.head[0].iov_len
686668
+ rqstp->rq_arg.page_len
687669
+ rqstp->rq_arg.tail[0].iov_len;

net/sunrpc/xprtrdma/svc_rdma_sendto.c

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -463,25 +463,21 @@ static int send_reply(struct svcxprt_rdma *rdma,
463463
struct svc_rqst *rqstp,
464464
struct page *page,
465465
struct rpcrdma_msg *rdma_resp,
466-
struct svc_rdma_op_ctxt *ctxt,
467466
struct svc_rdma_req_map *vec,
468467
int byte_count)
469468
{
469+
struct svc_rdma_op_ctxt *ctxt;
470470
struct ib_send_wr send_wr;
471471
u32 xdr_off;
472472
int sge_no;
473473
int sge_bytes;
474474
int page_no;
475475
int pages;
476-
int ret;
477-
478-
ret = svc_rdma_repost_recv(rdma, GFP_KERNEL);
479-
if (ret) {
480-
svc_rdma_put_context(ctxt, 0);
481-
return -ENOTCONN;
482-
}
476+
int ret = -EIO;
483477

484478
/* Prepare the context */
479+
ctxt = svc_rdma_get_context(rdma);
480+
ctxt->direction = DMA_TO_DEVICE;
485481
ctxt->pages[0] = page;
486482
ctxt->count = 1;
487483

@@ -565,8 +561,7 @@ static int send_reply(struct svcxprt_rdma *rdma,
565561
err:
566562
svc_rdma_unmap_dma(ctxt);
567563
svc_rdma_put_context(ctxt, 1);
568-
pr_err("svcrdma: failed to send reply, rc=%d\n", ret);
569-
return -EIO;
564+
return ret;
570565
}
571566

572567
void svc_rdma_prep_reply_hdr(struct svc_rqst *rqstp)
@@ -585,7 +580,6 @@ int svc_rdma_sendto(struct svc_rqst *rqstp)
585580
int ret;
586581
int inline_bytes;
587582
struct page *res_page;
588-
struct svc_rdma_op_ctxt *ctxt;
589583
struct svc_rdma_req_map *vec;
590584

591585
dprintk("svcrdma: sending response for rqstp=%p\n", rqstp);
@@ -598,8 +592,6 @@ int svc_rdma_sendto(struct svc_rqst *rqstp)
598592
rp_ary = svc_rdma_get_reply_array(rdma_argp, wr_ary);
599593

600594
/* Build an req vec for the XDR */
601-
ctxt = svc_rdma_get_context(rdma);
602-
ctxt->direction = DMA_TO_DEVICE;
603595
vec = svc_rdma_get_req_map(rdma);
604596
ret = svc_rdma_map_xdr(rdma, &rqstp->rq_res, vec, wr_ary != NULL);
605597
if (ret)
@@ -635,7 +627,12 @@ int svc_rdma_sendto(struct svc_rqst *rqstp)
635627
inline_bytes -= ret;
636628
}
637629

638-
ret = send_reply(rdma, rqstp, res_page, rdma_resp, ctxt, vec,
630+
/* Post a fresh Receive buffer _before_ sending the reply */
631+
ret = svc_rdma_post_recv(rdma, GFP_KERNEL);
632+
if (ret)
633+
goto err1;
634+
635+
ret = send_reply(rdma, rqstp, res_page, rdma_resp, vec,
639636
inline_bytes);
640637
if (ret < 0)
641638
goto err1;
@@ -648,7 +645,8 @@ int svc_rdma_sendto(struct svc_rqst *rqstp)
648645
put_page(res_page);
649646
err0:
650647
svc_rdma_put_req_map(rdma, vec);
651-
svc_rdma_put_context(ctxt, 0);
648+
pr_err("svcrdma: Could not send reply, err=%d. Closing transport.\n",
649+
ret);
652650
set_bit(XPT_CLOSE, &rdma->sc_xprt.xpt_flags);
653651
return -ENOTCONN;
654652
}

0 commit comments

Comments
 (0)