aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorScott Mayhew <smayhew@redhat.com>2018-11-06 13:35:08 -0500
committerJ. Bruce Fields <bfields@redhat.com>2018-11-28 18:36:03 -0500
commitb493fd31c0b89d9453917e977002de58bebc3802 (patch)
treed73173fc371f3f0f62e492137c3c496c5c19f0cf
parent62a063b8e7d1db684db3f207261a466fa3194e72 (diff)
nfsd: fix a warning in __cld_pipe_upcall()
__cld_pipe_upcall() emits a "do not call blocking ops when !TASK_RUNNING" warning due to the dput() call in rpc_queue_upcall(). Fix it by using a completion instead of hand coding the wait. Signed-off-by: Scott Mayhew <smayhew@redhat.com> Signed-off-by: J. Bruce Fields <bfields@redhat.com>
-rw-r--r--fs/nfsd/nfs4recover.c17
1 files changed, 6 insertions, 11 deletions
diff --git a/fs/nfsd/nfs4recover.c b/fs/nfsd/nfs4recover.c
index 9c247fa1e959..5188f9f70c78 100644
--- a/fs/nfsd/nfs4recover.c
+++ b/fs/nfsd/nfs4recover.c
@@ -662,7 +662,7 @@ struct cld_net {
662struct cld_upcall { 662struct cld_upcall {
663 struct list_head cu_list; 663 struct list_head cu_list;
664 struct cld_net *cu_net; 664 struct cld_net *cu_net;
665 struct task_struct *cu_task; 665 struct completion cu_done;
666 struct cld_msg cu_msg; 666 struct cld_msg cu_msg;
667}; 667};
668 668
@@ -671,23 +671,18 @@ __cld_pipe_upcall(struct rpc_pipe *pipe, struct cld_msg *cmsg)
671{ 671{
672 int ret; 672 int ret;
673 struct rpc_pipe_msg msg; 673 struct rpc_pipe_msg msg;
674 struct cld_upcall *cup = container_of(cmsg, struct cld_upcall, cu_msg);
674 675
675 memset(&msg, 0, sizeof(msg)); 676 memset(&msg, 0, sizeof(msg));
676 msg.data = cmsg; 677 msg.data = cmsg;
677 msg.len = sizeof(*cmsg); 678 msg.len = sizeof(*cmsg);
678 679
679 /*
680 * Set task state before we queue the upcall. That prevents
681 * wake_up_process in the downcall from racing with schedule.
682 */
683 set_current_state(TASK_UNINTERRUPTIBLE);
684 ret = rpc_queue_upcall(pipe, &msg); 680 ret = rpc_queue_upcall(pipe, &msg);
685 if (ret < 0) { 681 if (ret < 0) {
686 set_current_state(TASK_RUNNING);
687 goto out; 682 goto out;
688 } 683 }
689 684
690 schedule(); 685 wait_for_completion(&cup->cu_done);
691 686
692 if (msg.errno < 0) 687 if (msg.errno < 0)
693 ret = msg.errno; 688 ret = msg.errno;
@@ -754,7 +749,7 @@ cld_pipe_downcall(struct file *filp, const char __user *src, size_t mlen)
754 if (copy_from_user(&cup->cu_msg, src, mlen) != 0) 749 if (copy_from_user(&cup->cu_msg, src, mlen) != 0)
755 return -EFAULT; 750 return -EFAULT;
756 751
757 wake_up_process(cup->cu_task); 752 complete(&cup->cu_done);
758 return mlen; 753 return mlen;
759} 754}
760 755
@@ -769,7 +764,7 @@ cld_pipe_destroy_msg(struct rpc_pipe_msg *msg)
769 if (msg->errno >= 0) 764 if (msg->errno >= 0)
770 return; 765 return;
771 766
772 wake_up_process(cup->cu_task); 767 complete(&cup->cu_done);
773} 768}
774 769
775static const struct rpc_pipe_ops cld_upcall_ops = { 770static const struct rpc_pipe_ops cld_upcall_ops = {
@@ -900,7 +895,7 @@ restart_search:
900 goto restart_search; 895 goto restart_search;
901 } 896 }
902 } 897 }
903 new->cu_task = current; 898 init_completion(&new->cu_done);
904 new->cu_msg.cm_vers = CLD_UPCALL_VERSION; 899 new->cu_msg.cm_vers = CLD_UPCALL_VERSION;
905 put_unaligned(cn->cn_xid++, &new->cu_msg.cm_xid); 900 put_unaligned(cn->cn_xid++, &new->cu_msg.cm_xid);
906 new->cu_net = cn; 901 new->cu_net = cn;