Skip to content

Commit b914c5b

Browse files
committed
Merge branch 'for-3.18' of git://linux-nfs.org/~bfields/linux
Pull nfsd bugfixes from Bruce Fields: "These fix one mishandling of the case when security labels are configured out, and two races in the 4.1 backchannel code" * 'for-3.18' of git://linux-nfs.org/~bfields/linux: nfsd: Fix slot wake up race in the nfsv4.1 callback code SUNRPC: Fix locking around callback channel reply receive nfsd: correctly define v4.2 support attributes
2 parents 277f850 + c6c15e1 commit b914c5b

File tree

3 files changed

+28
-16
lines changed

3 files changed

+28
-16
lines changed

fs/nfsd/nfs4callback.c

+6-2
Original file line numberDiff line numberDiff line change
@@ -774,8 +774,12 @@ static bool nfsd41_cb_get_slot(struct nfs4_client *clp, struct rpc_task *task)
774774
{
775775
if (test_and_set_bit(0, &clp->cl_cb_slot_busy) != 0) {
776776
rpc_sleep_on(&clp->cl_cb_waitq, task, NULL);
777-
dprintk("%s slot is busy\n", __func__);
778-
return false;
777+
/* Race breaker */
778+
if (test_and_set_bit(0, &clp->cl_cb_slot_busy) != 0) {
779+
dprintk("%s slot is busy\n", __func__);
780+
return false;
781+
}
782+
rpc_wake_up_queued_task(&clp->cl_cb_waitq, task);
779783
}
780784
return true;
781785
}

fs/nfsd/nfsd.h

+6-3
Original file line numberDiff line numberDiff line change
@@ -335,12 +335,15 @@ void nfsd_lockd_shutdown(void);
335335
(NFSD4_SUPPORTED_ATTRS_WORD2 | FATTR4_WORD2_SUPPATTR_EXCLCREAT)
336336

337337
#ifdef CONFIG_NFSD_V4_SECURITY_LABEL
338-
#define NFSD4_2_SUPPORTED_ATTRS_WORD2 \
339-
(NFSD4_1_SUPPORTED_ATTRS_WORD2 | FATTR4_WORD2_SECURITY_LABEL)
338+
#define NFSD4_2_SECURITY_ATTRS FATTR4_WORD2_SECURITY_LABEL
340339
#else
341-
#define NFSD4_2_SUPPORTED_ATTRS_WORD2 0
340+
#define NFSD4_2_SECURITY_ATTRS 0
342341
#endif
343342

343+
#define NFSD4_2_SUPPORTED_ATTRS_WORD2 \
344+
(NFSD4_1_SUPPORTED_ATTRS_WORD2 | \
345+
NFSD4_2_SECURITY_ATTRS)
346+
344347
static inline u32 nfsd_suppattrs0(u32 minorversion)
345348
{
346349
return minorversion ? NFSD4_1_SUPPORTED_ATTRS_WORD0

net/sunrpc/svcsock.c

+16-11
Original file line numberDiff line numberDiff line change
@@ -1019,17 +1019,12 @@ static int receive_cb_reply(struct svc_sock *svsk, struct svc_rqst *rqstp)
10191019
xid = *p++;
10201020
calldir = *p;
10211021

1022-
if (bc_xprt)
1023-
req = xprt_lookup_rqst(bc_xprt, xid);
1024-
1025-
if (!req) {
1026-
printk(KERN_NOTICE
1027-
"%s: Got unrecognized reply: "
1028-
"calldir 0x%x xpt_bc_xprt %p xid %08x\n",
1029-
__func__, ntohl(calldir),
1030-
bc_xprt, ntohl(xid));
1022+
if (!bc_xprt)
10311023
return -EAGAIN;
1032-
}
1024+
spin_lock_bh(&bc_xprt->transport_lock);
1025+
req = xprt_lookup_rqst(bc_xprt, xid);
1026+
if (!req)
1027+
goto unlock_notfound;
10331028

10341029
memcpy(&req->rq_private_buf, &req->rq_rcv_buf, sizeof(struct xdr_buf));
10351030
/*
@@ -1040,11 +1035,21 @@ static int receive_cb_reply(struct svc_sock *svsk, struct svc_rqst *rqstp)
10401035
dst = &req->rq_private_buf.head[0];
10411036
src = &rqstp->rq_arg.head[0];
10421037
if (dst->iov_len < src->iov_len)
1043-
return -EAGAIN; /* whatever; just giving up. */
1038+
goto unlock_eagain; /* whatever; just giving up. */
10441039
memcpy(dst->iov_base, src->iov_base, src->iov_len);
10451040
xprt_complete_rqst(req->rq_task, rqstp->rq_arg.len);
10461041
rqstp->rq_arg.len = 0;
1042+
spin_unlock_bh(&bc_xprt->transport_lock);
10471043
return 0;
1044+
unlock_notfound:
1045+
printk(KERN_NOTICE
1046+
"%s: Got unrecognized reply: "
1047+
"calldir 0x%x xpt_bc_xprt %p xid %08x\n",
1048+
__func__, ntohl(calldir),
1049+
bc_xprt, ntohl(xid));
1050+
unlock_eagain:
1051+
spin_unlock_bh(&bc_xprt->transport_lock);
1052+
return -EAGAIN;
10481053
}
10491054

10501055
static int copy_pages_to_kvecs(struct kvec *vec, struct page **pages, int len)

0 commit comments

Comments
 (0)