diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-09-12 17:13:45 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-09-12 17:13:45 -0400 |
commit | 2c937eb4ddca946bb74936cf63aba0f94aa0efb3 (patch) | |
tree | f1038c15e15871e77365b96ea3e7497a352629f2 | |
parent | da499f8f5385c181e29978fdaab15a58de185302 (diff) | |
parent | b519d408ea32040b1c7e10b155a3ee9a36660947 (diff) |
Merge tag 'nfs-for-4.8-4' of git://git.linux-nfs.org/projects/trondmy/linux-nfs
Pull NFS client bugfixes from Trond Myklebust:
"Highlights include:
Stable patches:
- We must serialise LAYOUTGET and LAYOUTRETURN to ensure correct
state accounting
- Fix the CREATE_SESSION slot number
Bugfixes:
- sunrpc: fix a UDP memory accounting regression
- NFS: Fix an error reporting regression in nfs_file_write()
- pNFS: Fix further layout stateid issues
- RPC/rdma: Revert 3d4cf35bd4fa ("xprtrdma: Reply buffer
exhaustion...")
- RPC/rdma: Fix receive buffer accounting"
* tag 'nfs-for-4.8-4' of git://git.linux-nfs.org/projects/trondmy/linux-nfs:
NFSv4.1: Fix the CREATE_SESSION slot number accounting
xprtrdma: Fix receive buffer accounting
xprtrdma: Revert 3d4cf35bd4fa ("xprtrdma: Reply buffer exhaustion...")
pNFS: Don't forget the layout stateid if there are outstanding LAYOUTGETs
pNFS: Clear out all layout segments if the server unsets lrp->res.lrs_present
pNFS: Fix pnfs_set_layout_stateid() to clear NFS_LAYOUT_INVALID_STID
pNFS: Ensure LAYOUTGET and LAYOUTRETURN are properly serialised
NFS: Fix error reporting in nfs_file_write()
sunrpc: fix UDP memory accounting
-rw-r--r-- | fs/nfs/file.c | 5 | ||||
-rw-r--r-- | fs/nfs/nfs4proc.c | 21 | ||||
-rw-r--r-- | fs/nfs/pnfs.c | 42 | ||||
-rw-r--r-- | net/sunrpc/xprtrdma/verbs.c | 45 | ||||
-rw-r--r-- | net/sunrpc/xprtrdma/xprt_rdma.h | 1 | ||||
-rw-r--r-- | net/sunrpc/xprtsock.c | 2 |
6 files changed, 78 insertions, 38 deletions
diff --git a/fs/nfs/file.c b/fs/nfs/file.c index 7d620970f2e1..ca699ddc11c1 100644 --- a/fs/nfs/file.c +++ b/fs/nfs/file.c | |||
@@ -657,7 +657,10 @@ ssize_t nfs_file_write(struct kiocb *iocb, struct iov_iter *from) | |||
657 | if (result <= 0) | 657 | if (result <= 0) |
658 | goto out; | 658 | goto out; |
659 | 659 | ||
660 | written = generic_write_sync(iocb, result); | 660 | result = generic_write_sync(iocb, result); |
661 | if (result < 0) | ||
662 | goto out; | ||
663 | written = result; | ||
661 | iocb->ki_pos += written; | 664 | iocb->ki_pos += written; |
662 | 665 | ||
663 | /* Return error values */ | 666 | /* Return error values */ |
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index f5aecaabcb7c..a9dec32ba9ba 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c | |||
@@ -7570,12 +7570,20 @@ static int _nfs4_proc_create_session(struct nfs_client *clp, | |||
7570 | status = rpc_call_sync(session->clp->cl_rpcclient, &msg, RPC_TASK_TIMEOUT); | 7570 | status = rpc_call_sync(session->clp->cl_rpcclient, &msg, RPC_TASK_TIMEOUT); |
7571 | trace_nfs4_create_session(clp, status); | 7571 | trace_nfs4_create_session(clp, status); |
7572 | 7572 | ||
7573 | switch (status) { | ||
7574 | case -NFS4ERR_STALE_CLIENTID: | ||
7575 | case -NFS4ERR_DELAY: | ||
7576 | case -ETIMEDOUT: | ||
7577 | case -EACCES: | ||
7578 | case -EAGAIN: | ||
7579 | goto out; | ||
7580 | }; | ||
7581 | |||
7582 | clp->cl_seqid++; | ||
7573 | if (!status) { | 7583 | if (!status) { |
7574 | /* Verify the session's negotiated channel_attrs values */ | 7584 | /* Verify the session's negotiated channel_attrs values */ |
7575 | status = nfs4_verify_channel_attrs(&args, &res); | 7585 | status = nfs4_verify_channel_attrs(&args, &res); |
7576 | /* Increment the clientid slot sequence id */ | 7586 | /* Increment the clientid slot sequence id */ |
7577 | if (clp->cl_seqid == res.seqid) | ||
7578 | clp->cl_seqid++; | ||
7579 | if (status) | 7587 | if (status) |
7580 | goto out; | 7588 | goto out; |
7581 | nfs4_update_session(session, &res); | 7589 | nfs4_update_session(session, &res); |
@@ -8190,10 +8198,13 @@ static void nfs4_layoutreturn_release(void *calldata) | |||
8190 | 8198 | ||
8191 | dprintk("--> %s\n", __func__); | 8199 | dprintk("--> %s\n", __func__); |
8192 | spin_lock(&lo->plh_inode->i_lock); | 8200 | spin_lock(&lo->plh_inode->i_lock); |
8193 | pnfs_mark_matching_lsegs_invalid(lo, &freeme, &lrp->args.range, | 8201 | if (lrp->res.lrs_present) { |
8194 | be32_to_cpu(lrp->args.stateid.seqid)); | 8202 | pnfs_mark_matching_lsegs_invalid(lo, &freeme, |
8195 | if (lrp->res.lrs_present && pnfs_layout_is_valid(lo)) | 8203 | &lrp->args.range, |
8204 | be32_to_cpu(lrp->args.stateid.seqid)); | ||
8196 | pnfs_set_layout_stateid(lo, &lrp->res.stateid, true); | 8205 | pnfs_set_layout_stateid(lo, &lrp->res.stateid, true); |
8206 | } else | ||
8207 | pnfs_mark_layout_stateid_invalid(lo, &freeme); | ||
8197 | pnfs_clear_layoutreturn_waitbit(lo); | 8208 | pnfs_clear_layoutreturn_waitbit(lo); |
8198 | spin_unlock(&lo->plh_inode->i_lock); | 8209 | spin_unlock(&lo->plh_inode->i_lock); |
8199 | nfs4_sequence_free_slot(&lrp->res.seq_res); | 8210 | nfs4_sequence_free_slot(&lrp->res.seq_res); |
diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c index 6daf034645c8..2c93a85eda51 100644 --- a/fs/nfs/pnfs.c +++ b/fs/nfs/pnfs.c | |||
@@ -365,7 +365,8 @@ pnfs_layout_remove_lseg(struct pnfs_layout_hdr *lo, | |||
365 | /* Matched by pnfs_get_layout_hdr in pnfs_layout_insert_lseg */ | 365 | /* Matched by pnfs_get_layout_hdr in pnfs_layout_insert_lseg */ |
366 | atomic_dec(&lo->plh_refcount); | 366 | atomic_dec(&lo->plh_refcount); |
367 | if (list_empty(&lo->plh_segs)) { | 367 | if (list_empty(&lo->plh_segs)) { |
368 | set_bit(NFS_LAYOUT_INVALID_STID, &lo->plh_flags); | 368 | if (atomic_read(&lo->plh_outstanding) == 0) |
369 | set_bit(NFS_LAYOUT_INVALID_STID, &lo->plh_flags); | ||
369 | clear_bit(NFS_LAYOUT_BULK_RECALL, &lo->plh_flags); | 370 | clear_bit(NFS_LAYOUT_BULK_RECALL, &lo->plh_flags); |
370 | } | 371 | } |
371 | rpc_wake_up(&NFS_SERVER(inode)->roc_rpcwaitq); | 372 | rpc_wake_up(&NFS_SERVER(inode)->roc_rpcwaitq); |
@@ -768,17 +769,32 @@ pnfs_destroy_all_layouts(struct nfs_client *clp) | |||
768 | pnfs_destroy_layouts_byclid(clp, false); | 769 | pnfs_destroy_layouts_byclid(clp, false); |
769 | } | 770 | } |
770 | 771 | ||
772 | static void | ||
773 | pnfs_clear_layoutreturn_info(struct pnfs_layout_hdr *lo) | ||
774 | { | ||
775 | lo->plh_return_iomode = 0; | ||
776 | lo->plh_return_seq = 0; | ||
777 | clear_bit(NFS_LAYOUT_RETURN_REQUESTED, &lo->plh_flags); | ||
778 | } | ||
779 | |||
771 | /* update lo->plh_stateid with new if is more recent */ | 780 | /* update lo->plh_stateid with new if is more recent */ |
772 | void | 781 | void |
773 | pnfs_set_layout_stateid(struct pnfs_layout_hdr *lo, const nfs4_stateid *new, | 782 | pnfs_set_layout_stateid(struct pnfs_layout_hdr *lo, const nfs4_stateid *new, |
774 | bool update_barrier) | 783 | bool update_barrier) |
775 | { | 784 | { |
776 | u32 oldseq, newseq, new_barrier = 0; | 785 | u32 oldseq, newseq, new_barrier = 0; |
777 | bool invalid = !pnfs_layout_is_valid(lo); | ||
778 | 786 | ||
779 | oldseq = be32_to_cpu(lo->plh_stateid.seqid); | 787 | oldseq = be32_to_cpu(lo->plh_stateid.seqid); |
780 | newseq = be32_to_cpu(new->seqid); | 788 | newseq = be32_to_cpu(new->seqid); |
781 | if (invalid || pnfs_seqid_is_newer(newseq, oldseq)) { | 789 | |
790 | if (!pnfs_layout_is_valid(lo)) { | ||
791 | nfs4_stateid_copy(&lo->plh_stateid, new); | ||
792 | lo->plh_barrier = newseq; | ||
793 | pnfs_clear_layoutreturn_info(lo); | ||
794 | clear_bit(NFS_LAYOUT_INVALID_STID, &lo->plh_flags); | ||
795 | return; | ||
796 | } | ||
797 | if (pnfs_seqid_is_newer(newseq, oldseq)) { | ||
782 | nfs4_stateid_copy(&lo->plh_stateid, new); | 798 | nfs4_stateid_copy(&lo->plh_stateid, new); |
783 | /* | 799 | /* |
784 | * Because of wraparound, we want to keep the barrier | 800 | * Because of wraparound, we want to keep the barrier |
@@ -790,7 +806,7 @@ pnfs_set_layout_stateid(struct pnfs_layout_hdr *lo, const nfs4_stateid *new, | |||
790 | new_barrier = be32_to_cpu(new->seqid); | 806 | new_barrier = be32_to_cpu(new->seqid); |
791 | else if (new_barrier == 0) | 807 | else if (new_barrier == 0) |
792 | return; | 808 | return; |
793 | if (invalid || pnfs_seqid_is_newer(new_barrier, lo->plh_barrier)) | 809 | if (pnfs_seqid_is_newer(new_barrier, lo->plh_barrier)) |
794 | lo->plh_barrier = new_barrier; | 810 | lo->plh_barrier = new_barrier; |
795 | } | 811 | } |
796 | 812 | ||
@@ -886,19 +902,14 @@ void pnfs_clear_layoutreturn_waitbit(struct pnfs_layout_hdr *lo) | |||
886 | rpc_wake_up(&NFS_SERVER(lo->plh_inode)->roc_rpcwaitq); | 902 | rpc_wake_up(&NFS_SERVER(lo->plh_inode)->roc_rpcwaitq); |
887 | } | 903 | } |
888 | 904 | ||
889 | static void | ||
890 | pnfs_clear_layoutreturn_info(struct pnfs_layout_hdr *lo) | ||
891 | { | ||
892 | lo->plh_return_iomode = 0; | ||
893 | lo->plh_return_seq = 0; | ||
894 | clear_bit(NFS_LAYOUT_RETURN_REQUESTED, &lo->plh_flags); | ||
895 | } | ||
896 | |||
897 | static bool | 905 | static bool |
898 | pnfs_prepare_layoutreturn(struct pnfs_layout_hdr *lo, | 906 | pnfs_prepare_layoutreturn(struct pnfs_layout_hdr *lo, |
899 | nfs4_stateid *stateid, | 907 | nfs4_stateid *stateid, |
900 | enum pnfs_iomode *iomode) | 908 | enum pnfs_iomode *iomode) |
901 | { | 909 | { |
910 | /* Serialise LAYOUTGET/LAYOUTRETURN */ | ||
911 | if (atomic_read(&lo->plh_outstanding) != 0) | ||
912 | return false; | ||
902 | if (test_and_set_bit(NFS_LAYOUT_RETURN, &lo->plh_flags)) | 913 | if (test_and_set_bit(NFS_LAYOUT_RETURN, &lo->plh_flags)) |
903 | return false; | 914 | return false; |
904 | pnfs_get_layout_hdr(lo); | 915 | pnfs_get_layout_hdr(lo); |
@@ -1798,16 +1809,11 @@ pnfs_layout_process(struct nfs4_layoutget *lgp) | |||
1798 | */ | 1809 | */ |
1799 | pnfs_mark_layout_stateid_invalid(lo, &free_me); | 1810 | pnfs_mark_layout_stateid_invalid(lo, &free_me); |
1800 | 1811 | ||
1801 | nfs4_stateid_copy(&lo->plh_stateid, &res->stateid); | 1812 | pnfs_set_layout_stateid(lo, &res->stateid, true); |
1802 | lo->plh_barrier = be32_to_cpu(res->stateid.seqid); | ||
1803 | } | 1813 | } |
1804 | 1814 | ||
1805 | pnfs_get_lseg(lseg); | 1815 | pnfs_get_lseg(lseg); |
1806 | pnfs_layout_insert_lseg(lo, lseg, &free_me); | 1816 | pnfs_layout_insert_lseg(lo, lseg, &free_me); |
1807 | if (!pnfs_layout_is_valid(lo)) { | ||
1808 | pnfs_clear_layoutreturn_info(lo); | ||
1809 | clear_bit(NFS_LAYOUT_INVALID_STID, &lo->plh_flags); | ||
1810 | } | ||
1811 | 1817 | ||
1812 | 1818 | ||
1813 | if (res->return_on_close) | 1819 | if (res->return_on_close) |
diff --git a/net/sunrpc/xprtrdma/verbs.c b/net/sunrpc/xprtrdma/verbs.c index 536d0be3f61b..799cce6cbe45 100644 --- a/net/sunrpc/xprtrdma/verbs.c +++ b/net/sunrpc/xprtrdma/verbs.c | |||
@@ -51,6 +51,7 @@ | |||
51 | #include <linux/slab.h> | 51 | #include <linux/slab.h> |
52 | #include <linux/prefetch.h> | 52 | #include <linux/prefetch.h> |
53 | #include <linux/sunrpc/addr.h> | 53 | #include <linux/sunrpc/addr.h> |
54 | #include <linux/sunrpc/svc_rdma.h> | ||
54 | #include <asm/bitops.h> | 55 | #include <asm/bitops.h> |
55 | #include <linux/module.h> /* try_module_get()/module_put() */ | 56 | #include <linux/module.h> /* try_module_get()/module_put() */ |
56 | 57 | ||
@@ -923,7 +924,7 @@ rpcrdma_buffer_create(struct rpcrdma_xprt *r_xprt) | |||
923 | } | 924 | } |
924 | 925 | ||
925 | INIT_LIST_HEAD(&buf->rb_recv_bufs); | 926 | INIT_LIST_HEAD(&buf->rb_recv_bufs); |
926 | for (i = 0; i < buf->rb_max_requests; i++) { | 927 | for (i = 0; i < buf->rb_max_requests + RPCRDMA_MAX_BC_REQUESTS; i++) { |
927 | struct rpcrdma_rep *rep; | 928 | struct rpcrdma_rep *rep; |
928 | 929 | ||
929 | rep = rpcrdma_create_rep(r_xprt); | 930 | rep = rpcrdma_create_rep(r_xprt); |
@@ -1018,6 +1019,7 @@ rpcrdma_buffer_destroy(struct rpcrdma_buffer *buf) | |||
1018 | rep = rpcrdma_buffer_get_rep_locked(buf); | 1019 | rep = rpcrdma_buffer_get_rep_locked(buf); |
1019 | rpcrdma_destroy_rep(ia, rep); | 1020 | rpcrdma_destroy_rep(ia, rep); |
1020 | } | 1021 | } |
1022 | buf->rb_send_count = 0; | ||
1021 | 1023 | ||
1022 | spin_lock(&buf->rb_reqslock); | 1024 | spin_lock(&buf->rb_reqslock); |
1023 | while (!list_empty(&buf->rb_allreqs)) { | 1025 | while (!list_empty(&buf->rb_allreqs)) { |
@@ -1032,6 +1034,7 @@ rpcrdma_buffer_destroy(struct rpcrdma_buffer *buf) | |||
1032 | spin_lock(&buf->rb_reqslock); | 1034 | spin_lock(&buf->rb_reqslock); |
1033 | } | 1035 | } |
1034 | spin_unlock(&buf->rb_reqslock); | 1036 | spin_unlock(&buf->rb_reqslock); |
1037 | buf->rb_recv_count = 0; | ||
1035 | 1038 | ||
1036 | rpcrdma_destroy_mrs(buf); | 1039 | rpcrdma_destroy_mrs(buf); |
1037 | } | 1040 | } |
@@ -1074,8 +1077,27 @@ rpcrdma_put_mw(struct rpcrdma_xprt *r_xprt, struct rpcrdma_mw *mw) | |||
1074 | spin_unlock(&buf->rb_mwlock); | 1077 | spin_unlock(&buf->rb_mwlock); |
1075 | } | 1078 | } |
1076 | 1079 | ||
1080 | static struct rpcrdma_rep * | ||
1081 | rpcrdma_buffer_get_rep(struct rpcrdma_buffer *buffers) | ||
1082 | { | ||
1083 | /* If an RPC previously completed without a reply (say, a | ||
1084 | * credential problem or a soft timeout occurs) then hold off | ||
1085 | * on supplying more Receive buffers until the number of new | ||
1086 | * pending RPCs catches up to the number of posted Receives. | ||
1087 | */ | ||
1088 | if (unlikely(buffers->rb_send_count < buffers->rb_recv_count)) | ||
1089 | return NULL; | ||
1090 | |||
1091 | if (unlikely(list_empty(&buffers->rb_recv_bufs))) | ||
1092 | return NULL; | ||
1093 | buffers->rb_recv_count++; | ||
1094 | return rpcrdma_buffer_get_rep_locked(buffers); | ||
1095 | } | ||
1096 | |||
1077 | /* | 1097 | /* |
1078 | * Get a set of request/reply buffers. | 1098 | * Get a set of request/reply buffers. |
1099 | * | ||
1100 | * Reply buffer (if available) is attached to send buffer upon return. | ||
1079 | */ | 1101 | */ |
1080 | struct rpcrdma_req * | 1102 | struct rpcrdma_req * |
1081 | rpcrdma_buffer_get(struct rpcrdma_buffer *buffers) | 1103 | rpcrdma_buffer_get(struct rpcrdma_buffer *buffers) |
@@ -1085,21 +1107,15 @@ rpcrdma_buffer_get(struct rpcrdma_buffer *buffers) | |||
1085 | spin_lock(&buffers->rb_lock); | 1107 | spin_lock(&buffers->rb_lock); |
1086 | if (list_empty(&buffers->rb_send_bufs)) | 1108 | if (list_empty(&buffers->rb_send_bufs)) |
1087 | goto out_reqbuf; | 1109 | goto out_reqbuf; |
1110 | buffers->rb_send_count++; | ||
1088 | req = rpcrdma_buffer_get_req_locked(buffers); | 1111 | req = rpcrdma_buffer_get_req_locked(buffers); |
1089 | if (list_empty(&buffers->rb_recv_bufs)) | 1112 | req->rl_reply = rpcrdma_buffer_get_rep(buffers); |
1090 | goto out_repbuf; | ||
1091 | req->rl_reply = rpcrdma_buffer_get_rep_locked(buffers); | ||
1092 | spin_unlock(&buffers->rb_lock); | 1113 | spin_unlock(&buffers->rb_lock); |
1093 | return req; | 1114 | return req; |
1094 | 1115 | ||
1095 | out_reqbuf: | 1116 | out_reqbuf: |
1096 | spin_unlock(&buffers->rb_lock); | 1117 | spin_unlock(&buffers->rb_lock); |
1097 | pr_warn("rpcrdma: out of request buffers (%p)\n", buffers); | 1118 | pr_warn("RPC: %s: out of request buffers\n", __func__); |
1098 | return NULL; | ||
1099 | out_repbuf: | ||
1100 | list_add(&req->rl_free, &buffers->rb_send_bufs); | ||
1101 | spin_unlock(&buffers->rb_lock); | ||
1102 | pr_warn("rpcrdma: out of reply buffers (%p)\n", buffers); | ||
1103 | return NULL; | 1119 | return NULL; |
1104 | } | 1120 | } |
1105 | 1121 | ||
@@ -1117,9 +1133,12 @@ rpcrdma_buffer_put(struct rpcrdma_req *req) | |||
1117 | req->rl_reply = NULL; | 1133 | req->rl_reply = NULL; |
1118 | 1134 | ||
1119 | spin_lock(&buffers->rb_lock); | 1135 | spin_lock(&buffers->rb_lock); |
1136 | buffers->rb_send_count--; | ||
1120 | list_add_tail(&req->rl_free, &buffers->rb_send_bufs); | 1137 | list_add_tail(&req->rl_free, &buffers->rb_send_bufs); |
1121 | if (rep) | 1138 | if (rep) { |
1139 | buffers->rb_recv_count--; | ||
1122 | list_add_tail(&rep->rr_list, &buffers->rb_recv_bufs); | 1140 | list_add_tail(&rep->rr_list, &buffers->rb_recv_bufs); |
1141 | } | ||
1123 | spin_unlock(&buffers->rb_lock); | 1142 | spin_unlock(&buffers->rb_lock); |
1124 | } | 1143 | } |
1125 | 1144 | ||
@@ -1133,8 +1152,7 @@ rpcrdma_recv_buffer_get(struct rpcrdma_req *req) | |||
1133 | struct rpcrdma_buffer *buffers = req->rl_buffer; | 1152 | struct rpcrdma_buffer *buffers = req->rl_buffer; |
1134 | 1153 | ||
1135 | spin_lock(&buffers->rb_lock); | 1154 | spin_lock(&buffers->rb_lock); |
1136 | if (!list_empty(&buffers->rb_recv_bufs)) | 1155 | req->rl_reply = rpcrdma_buffer_get_rep(buffers); |
1137 | req->rl_reply = rpcrdma_buffer_get_rep_locked(buffers); | ||
1138 | spin_unlock(&buffers->rb_lock); | 1156 | spin_unlock(&buffers->rb_lock); |
1139 | } | 1157 | } |
1140 | 1158 | ||
@@ -1148,6 +1166,7 @@ rpcrdma_recv_buffer_put(struct rpcrdma_rep *rep) | |||
1148 | struct rpcrdma_buffer *buffers = &rep->rr_rxprt->rx_buf; | 1166 | struct rpcrdma_buffer *buffers = &rep->rr_rxprt->rx_buf; |
1149 | 1167 | ||
1150 | spin_lock(&buffers->rb_lock); | 1168 | spin_lock(&buffers->rb_lock); |
1169 | buffers->rb_recv_count--; | ||
1151 | list_add_tail(&rep->rr_list, &buffers->rb_recv_bufs); | 1170 | list_add_tail(&rep->rr_list, &buffers->rb_recv_bufs); |
1152 | spin_unlock(&buffers->rb_lock); | 1171 | spin_unlock(&buffers->rb_lock); |
1153 | } | 1172 | } |
diff --git a/net/sunrpc/xprtrdma/xprt_rdma.h b/net/sunrpc/xprtrdma/xprt_rdma.h index 670fad57153a..a71b0f5897d8 100644 --- a/net/sunrpc/xprtrdma/xprt_rdma.h +++ b/net/sunrpc/xprtrdma/xprt_rdma.h | |||
@@ -321,6 +321,7 @@ struct rpcrdma_buffer { | |||
321 | char *rb_pool; | 321 | char *rb_pool; |
322 | 322 | ||
323 | spinlock_t rb_lock; /* protect buf lists */ | 323 | spinlock_t rb_lock; /* protect buf lists */ |
324 | int rb_send_count, rb_recv_count; | ||
324 | struct list_head rb_send_bufs; | 325 | struct list_head rb_send_bufs; |
325 | struct list_head rb_recv_bufs; | 326 | struct list_head rb_recv_bufs; |
326 | u32 rb_max_requests; | 327 | u32 rb_max_requests; |
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c index 8ede3bc52481..bf168838a029 100644 --- a/net/sunrpc/xprtsock.c +++ b/net/sunrpc/xprtsock.c | |||
@@ -1074,7 +1074,7 @@ static void xs_udp_data_receive(struct sock_xprt *transport) | |||
1074 | skb = skb_recv_datagram(sk, 0, 1, &err); | 1074 | skb = skb_recv_datagram(sk, 0, 1, &err); |
1075 | if (skb != NULL) { | 1075 | if (skb != NULL) { |
1076 | xs_udp_data_read_skb(&transport->xprt, sk, skb); | 1076 | xs_udp_data_read_skb(&transport->xprt, sk, skb); |
1077 | skb_free_datagram(sk, skb); | 1077 | skb_free_datagram_locked(sk, skb); |
1078 | continue; | 1078 | continue; |
1079 | } | 1079 | } |
1080 | if (!test_and_clear_bit(XPRT_SOCK_DATA_READY, &transport->sock_state)) | 1080 | if (!test_and_clear_bit(XPRT_SOCK_DATA_READY, &transport->sock_state)) |