aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-09-12 17:13:45 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2016-09-12 17:13:45 -0400
commit2c937eb4ddca946bb74936cf63aba0f94aa0efb3 (patch)
treef1038c15e15871e77365b96ea3e7497a352629f2
parentda499f8f5385c181e29978fdaab15a58de185302 (diff)
parentb519d408ea32040b1c7e10b155a3ee9a36660947 (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.c5
-rw-r--r--fs/nfs/nfs4proc.c21
-rw-r--r--fs/nfs/pnfs.c42
-rw-r--r--net/sunrpc/xprtrdma/verbs.c45
-rw-r--r--net/sunrpc/xprtrdma/xprt_rdma.h1
-rw-r--r--net/sunrpc/xprtsock.c2
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
772static void
773pnfs_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 */
772void 781void
773pnfs_set_layout_stateid(struct pnfs_layout_hdr *lo, const nfs4_stateid *new, 782pnfs_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
889static void
890pnfs_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
897static bool 905static bool
898pnfs_prepare_layoutreturn(struct pnfs_layout_hdr *lo, 906pnfs_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
1080static struct rpcrdma_rep *
1081rpcrdma_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 */
1080struct rpcrdma_req * 1102struct rpcrdma_req *
1081rpcrdma_buffer_get(struct rpcrdma_buffer *buffers) 1103rpcrdma_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
1095out_reqbuf: 1116out_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;
1099out_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))