aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-11-16 16:14:56 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2013-11-16 16:14:56 -0500
commit673fdfe3f0630b03f3854d0361b1232f2e5ef7fb (patch)
tree5f1c1374f786c9a9d47bde36387dea8757725238
parent73d75ba99e3bdd627275afd3fe48cc933723084b (diff)
parent8c2fabc6542d9d0f8b16bd1045c2eda59bdcde13 (diff)
Merge tag 'nfs-for-3.13-2' of git://git.linux-nfs.org/projects/trondmy/linux-nfs
Pull NFS client bugfixes: - Stable fix for data corruption when retransmitting O_DIRECT writes - Stable fix for a deep recursion/stack overflow bug in rpc_release_client - Stable fix for infinite looping when mounting a NFSv4.x volume - Fix a typo in the nfs mount option parser - Allow pNFS layouts to be compiled into the kernel when NFSv4.1 is * tag 'nfs-for-3.13-2' of git://git.linux-nfs.org/projects/trondmy/linux-nfs: nfs: fix pnfs Kconfig defaults NFS: correctly report misuse of "migration" mount option. nfs: don't retry detect_trunking with RPC_AUTH_UNIX more than once SUNRPC: Avoid deep recursion in rpc_release_client SUNRPC: Fix a data corruption issue when retransmitting RPC calls
-rw-r--r--fs/nfs/Kconfig6
-rw-r--r--fs/nfs/nfs4state.c7
-rw-r--r--fs/nfs/super.c2
-rw-r--r--net/sunrpc/clnt.c29
-rw-r--r--net/sunrpc/xprtsock.c28
5 files changed, 48 insertions, 24 deletions
diff --git a/fs/nfs/Kconfig b/fs/nfs/Kconfig
index 38c1768b4142..3dece03f2fc8 100644
--- a/fs/nfs/Kconfig
+++ b/fs/nfs/Kconfig
@@ -116,17 +116,17 @@ config NFS_V4_2
116config PNFS_FILE_LAYOUT 116config PNFS_FILE_LAYOUT
117 tristate 117 tristate
118 depends on NFS_V4_1 118 depends on NFS_V4_1
119 default m 119 default NFS_V4
120 120
121config PNFS_BLOCK 121config PNFS_BLOCK
122 tristate 122 tristate
123 depends on NFS_V4_1 && BLK_DEV_DM 123 depends on NFS_V4_1 && BLK_DEV_DM
124 default m 124 default NFS_V4
125 125
126config PNFS_OBJLAYOUT 126config PNFS_OBJLAYOUT
127 tristate 127 tristate
128 depends on NFS_V4_1 && SCSI_OSD_ULD 128 depends on NFS_V4_1 && SCSI_OSD_ULD
129 default m 129 default NFS_V4
130 130
131config NFS_V4_1_IMPLEMENTATION_ID_DOMAIN 131config NFS_V4_1_IMPLEMENTATION_ID_DOMAIN
132 string "NFSv4.1 Implementation ID Domain" 132 string "NFSv4.1 Implementation ID Domain"
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c
index 74a7e12e10df..059c01b67a71 100644
--- a/fs/nfs/nfs4state.c
+++ b/fs/nfs/nfs4state.c
@@ -2093,10 +2093,15 @@ again:
2093 nfs4_root_machine_cred(clp); 2093 nfs4_root_machine_cred(clp);
2094 goto again; 2094 goto again;
2095 } 2095 }
2096 if (i > 2) 2096 if (clnt->cl_auth->au_flavor == RPC_AUTH_UNIX)
2097 break; 2097 break;
2098 case -NFS4ERR_CLID_INUSE: 2098 case -NFS4ERR_CLID_INUSE:
2099 case -NFS4ERR_WRONGSEC: 2099 case -NFS4ERR_WRONGSEC:
2100 /* No point in retrying if we already used RPC_AUTH_UNIX */
2101 if (clnt->cl_auth->au_flavor == RPC_AUTH_UNIX) {
2102 status = -EPERM;
2103 break;
2104 }
2100 clnt = rpc_clone_client_set_auth(clnt, RPC_AUTH_UNIX); 2105 clnt = rpc_clone_client_set_auth(clnt, RPC_AUTH_UNIX);
2101 if (IS_ERR(clnt)) { 2106 if (IS_ERR(clnt)) {
2102 status = PTR_ERR(clnt); 2107 status = PTR_ERR(clnt);
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index 317d6fc2160e..910ed906eb82 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -1614,7 +1614,7 @@ static int nfs_parse_mount_options(char *raw,
1614 goto out_minorversion_mismatch; 1614 goto out_minorversion_mismatch;
1615 1615
1616 if (mnt->options & NFS_OPTION_MIGRATION && 1616 if (mnt->options & NFS_OPTION_MIGRATION &&
1617 mnt->version != 4 && mnt->minorversion != 0) 1617 (mnt->version != 4 || mnt->minorversion != 0))
1618 goto out_migration_misuse; 1618 goto out_migration_misuse;
1619 1619
1620 /* 1620 /*
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
index dab09dac8fc7..f09b7db2c492 100644
--- a/net/sunrpc/clnt.c
+++ b/net/sunrpc/clnt.c
@@ -750,14 +750,16 @@ EXPORT_SYMBOL_GPL(rpc_shutdown_client);
750/* 750/*
751 * Free an RPC client 751 * Free an RPC client
752 */ 752 */
753static void 753static struct rpc_clnt *
754rpc_free_client(struct rpc_clnt *clnt) 754rpc_free_client(struct rpc_clnt *clnt)
755{ 755{
756 struct rpc_clnt *parent = NULL;
757
756 dprintk_rcu("RPC: destroying %s client for %s\n", 758 dprintk_rcu("RPC: destroying %s client for %s\n",
757 clnt->cl_program->name, 759 clnt->cl_program->name,
758 rcu_dereference(clnt->cl_xprt)->servername); 760 rcu_dereference(clnt->cl_xprt)->servername);
759 if (clnt->cl_parent != clnt) 761 if (clnt->cl_parent != clnt)
760 rpc_release_client(clnt->cl_parent); 762 parent = clnt->cl_parent;
761 rpc_clnt_remove_pipedir(clnt); 763 rpc_clnt_remove_pipedir(clnt);
762 rpc_unregister_client(clnt); 764 rpc_unregister_client(clnt);
763 rpc_free_iostats(clnt->cl_metrics); 765 rpc_free_iostats(clnt->cl_metrics);
@@ -766,18 +768,17 @@ rpc_free_client(struct rpc_clnt *clnt)
766 rpciod_down(); 768 rpciod_down();
767 rpc_free_clid(clnt); 769 rpc_free_clid(clnt);
768 kfree(clnt); 770 kfree(clnt);
771 return parent;
769} 772}
770 773
771/* 774/*
772 * Free an RPC client 775 * Free an RPC client
773 */ 776 */
774static void 777static struct rpc_clnt *
775rpc_free_auth(struct rpc_clnt *clnt) 778rpc_free_auth(struct rpc_clnt *clnt)
776{ 779{
777 if (clnt->cl_auth == NULL) { 780 if (clnt->cl_auth == NULL)
778 rpc_free_client(clnt); 781 return rpc_free_client(clnt);
779 return;
780 }
781 782
782 /* 783 /*
783 * Note: RPCSEC_GSS may need to send NULL RPC calls in order to 784 * Note: RPCSEC_GSS may need to send NULL RPC calls in order to
@@ -788,7 +789,8 @@ rpc_free_auth(struct rpc_clnt *clnt)
788 rpcauth_release(clnt->cl_auth); 789 rpcauth_release(clnt->cl_auth);
789 clnt->cl_auth = NULL; 790 clnt->cl_auth = NULL;
790 if (atomic_dec_and_test(&clnt->cl_count)) 791 if (atomic_dec_and_test(&clnt->cl_count))
791 rpc_free_client(clnt); 792 return rpc_free_client(clnt);
793 return NULL;
792} 794}
793 795
794/* 796/*
@@ -799,10 +801,13 @@ rpc_release_client(struct rpc_clnt *clnt)
799{ 801{
800 dprintk("RPC: rpc_release_client(%p)\n", clnt); 802 dprintk("RPC: rpc_release_client(%p)\n", clnt);
801 803
802 if (list_empty(&clnt->cl_tasks)) 804 do {
803 wake_up(&destroy_wait); 805 if (list_empty(&clnt->cl_tasks))
804 if (atomic_dec_and_test(&clnt->cl_count)) 806 wake_up(&destroy_wait);
805 rpc_free_auth(clnt); 807 if (!atomic_dec_and_test(&clnt->cl_count))
808 break;
809 clnt = rpc_free_auth(clnt);
810 } while (clnt != NULL);
806} 811}
807EXPORT_SYMBOL_GPL(rpc_release_client); 812EXPORT_SYMBOL_GPL(rpc_release_client);
808 813
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
index 17c88928b7db..dd9d295813cf 100644
--- a/net/sunrpc/xprtsock.c
+++ b/net/sunrpc/xprtsock.c
@@ -393,8 +393,10 @@ static int xs_send_kvec(struct socket *sock, struct sockaddr *addr, int addrlen,
393 return kernel_sendmsg(sock, &msg, NULL, 0, 0); 393 return kernel_sendmsg(sock, &msg, NULL, 0, 0);
394} 394}
395 395
396static int xs_send_pagedata(struct socket *sock, struct xdr_buf *xdr, unsigned int base, int more) 396static int xs_send_pagedata(struct socket *sock, struct xdr_buf *xdr, unsigned int base, int more, bool zerocopy)
397{ 397{
398 ssize_t (*do_sendpage)(struct socket *sock, struct page *page,
399 int offset, size_t size, int flags);
398 struct page **ppage; 400 struct page **ppage;
399 unsigned int remainder; 401 unsigned int remainder;
400 int err, sent = 0; 402 int err, sent = 0;
@@ -403,6 +405,9 @@ static int xs_send_pagedata(struct socket *sock, struct xdr_buf *xdr, unsigned i
403 base += xdr->page_base; 405 base += xdr->page_base;
404 ppage = xdr->pages + (base >> PAGE_SHIFT); 406 ppage = xdr->pages + (base >> PAGE_SHIFT);
405 base &= ~PAGE_MASK; 407 base &= ~PAGE_MASK;
408 do_sendpage = sock->ops->sendpage;
409 if (!zerocopy)
410 do_sendpage = sock_no_sendpage;
406 for(;;) { 411 for(;;) {
407 unsigned int len = min_t(unsigned int, PAGE_SIZE - base, remainder); 412 unsigned int len = min_t(unsigned int, PAGE_SIZE - base, remainder);
408 int flags = XS_SENDMSG_FLAGS; 413 int flags = XS_SENDMSG_FLAGS;
@@ -410,7 +415,7 @@ static int xs_send_pagedata(struct socket *sock, struct xdr_buf *xdr, unsigned i
410 remainder -= len; 415 remainder -= len;
411 if (remainder != 0 || more) 416 if (remainder != 0 || more)
412 flags |= MSG_MORE; 417 flags |= MSG_MORE;
413 err = sock->ops->sendpage(sock, *ppage, base, len, flags); 418 err = do_sendpage(sock, *ppage, base, len, flags);
414 if (remainder == 0 || err != len) 419 if (remainder == 0 || err != len)
415 break; 420 break;
416 sent += err; 421 sent += err;
@@ -431,9 +436,10 @@ static int xs_send_pagedata(struct socket *sock, struct xdr_buf *xdr, unsigned i
431 * @addrlen: UDP only -- length of destination address 436 * @addrlen: UDP only -- length of destination address
432 * @xdr: buffer containing this request 437 * @xdr: buffer containing this request
433 * @base: starting position in the buffer 438 * @base: starting position in the buffer
439 * @zerocopy: true if it is safe to use sendpage()
434 * 440 *
435 */ 441 */
436static int xs_sendpages(struct socket *sock, struct sockaddr *addr, int addrlen, struct xdr_buf *xdr, unsigned int base) 442static int xs_sendpages(struct socket *sock, struct sockaddr *addr, int addrlen, struct xdr_buf *xdr, unsigned int base, bool zerocopy)
437{ 443{
438 unsigned int remainder = xdr->len - base; 444 unsigned int remainder = xdr->len - base;
439 int err, sent = 0; 445 int err, sent = 0;
@@ -461,7 +467,7 @@ static int xs_sendpages(struct socket *sock, struct sockaddr *addr, int addrlen,
461 if (base < xdr->page_len) { 467 if (base < xdr->page_len) {
462 unsigned int len = xdr->page_len - base; 468 unsigned int len = xdr->page_len - base;
463 remainder -= len; 469 remainder -= len;
464 err = xs_send_pagedata(sock, xdr, base, remainder != 0); 470 err = xs_send_pagedata(sock, xdr, base, remainder != 0, zerocopy);
465 if (remainder == 0 || err != len) 471 if (remainder == 0 || err != len)
466 goto out; 472 goto out;
467 sent += err; 473 sent += err;
@@ -564,7 +570,7 @@ static int xs_local_send_request(struct rpc_task *task)
564 req->rq_svec->iov_base, req->rq_svec->iov_len); 570 req->rq_svec->iov_base, req->rq_svec->iov_len);
565 571
566 status = xs_sendpages(transport->sock, NULL, 0, 572 status = xs_sendpages(transport->sock, NULL, 0,
567 xdr, req->rq_bytes_sent); 573 xdr, req->rq_bytes_sent, true);
568 dprintk("RPC: %s(%u) = %d\n", 574 dprintk("RPC: %s(%u) = %d\n",
569 __func__, xdr->len - req->rq_bytes_sent, status); 575 __func__, xdr->len - req->rq_bytes_sent, status);
570 if (likely(status >= 0)) { 576 if (likely(status >= 0)) {
@@ -620,7 +626,7 @@ static int xs_udp_send_request(struct rpc_task *task)
620 status = xs_sendpages(transport->sock, 626 status = xs_sendpages(transport->sock,
621 xs_addr(xprt), 627 xs_addr(xprt),
622 xprt->addrlen, xdr, 628 xprt->addrlen, xdr,
623 req->rq_bytes_sent); 629 req->rq_bytes_sent, true);
624 630
625 dprintk("RPC: xs_udp_send_request(%u) = %d\n", 631 dprintk("RPC: xs_udp_send_request(%u) = %d\n",
626 xdr->len - req->rq_bytes_sent, status); 632 xdr->len - req->rq_bytes_sent, status);
@@ -693,6 +699,7 @@ static int xs_tcp_send_request(struct rpc_task *task)
693 struct rpc_xprt *xprt = req->rq_xprt; 699 struct rpc_xprt *xprt = req->rq_xprt;
694 struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt); 700 struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt);
695 struct xdr_buf *xdr = &req->rq_snd_buf; 701 struct xdr_buf *xdr = &req->rq_snd_buf;
702 bool zerocopy = true;
696 int status; 703 int status;
697 704
698 xs_encode_stream_record_marker(&req->rq_snd_buf); 705 xs_encode_stream_record_marker(&req->rq_snd_buf);
@@ -700,13 +707,20 @@ static int xs_tcp_send_request(struct rpc_task *task)
700 xs_pktdump("packet data:", 707 xs_pktdump("packet data:",
701 req->rq_svec->iov_base, 708 req->rq_svec->iov_base,
702 req->rq_svec->iov_len); 709 req->rq_svec->iov_len);
710 /* Don't use zero copy if this is a resend. If the RPC call
711 * completes while the socket holds a reference to the pages,
712 * then we may end up resending corrupted data.
713 */
714 if (task->tk_flags & RPC_TASK_SENT)
715 zerocopy = false;
703 716
704 /* Continue transmitting the packet/record. We must be careful 717 /* Continue transmitting the packet/record. We must be careful
705 * to cope with writespace callbacks arriving _after_ we have 718 * to cope with writespace callbacks arriving _after_ we have
706 * called sendmsg(). */ 719 * called sendmsg(). */
707 while (1) { 720 while (1) {
708 status = xs_sendpages(transport->sock, 721 status = xs_sendpages(transport->sock,
709 NULL, 0, xdr, req->rq_bytes_sent); 722 NULL, 0, xdr, req->rq_bytes_sent,
723 zerocopy);
710 724
711 dprintk("RPC: xs_tcp_send_request(%u) = %d\n", 725 dprintk("RPC: xs_tcp_send_request(%u) = %d\n",
712 xdr->len - req->rq_bytes_sent, status); 726 xdr->len - req->rq_bytes_sent, status);