NFS: Fix a potential busy wait in nfs_page_group_lock
authorTrond Myklebust <trond.myklebust@primarydata.com>
Thu, 29 May 2014 15:45:57 +0000 (11:45 -0400)
committerTrond Myklebust <trond.myklebust@primarydata.com>
Thu, 29 May 2014 16:12:27 +0000 (12:12 -0400)
We cannot allow nfs_page_group_lock to use TASK_KILLABLE here, since
the loop would cause a busy wait if somebody kills the task.

Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
fs/nfs/pagelist.c

index 0b8446f1008dbbb65864501869c9e0c4634e2e18..a8759825ac764343afdc172d0fb6800a2d43fd46 100644 (file)
@@ -138,6 +138,12 @@ nfs_iocounter_wait(struct nfs_io_counter *c)
        return __nfs_iocounter_wait(c);
 }
 
+static int nfs_wait_bit_uninterruptible(void *word)
+{
+       io_schedule();
+       return 0;
+}
+
 /*
  * nfs_page_group_lock - lock the head of the page group
  * @req - request in group that is to be locked
@@ -148,13 +154,12 @@ void
 nfs_page_group_lock(struct nfs_page *req)
 {
        struct nfs_page *head = req->wb_head;
-       int err = -EAGAIN;
 
        WARN_ON_ONCE(head != head->wb_head);
 
-       while (err)
-               err = wait_on_bit_lock(&head->wb_flags, PG_HEADLOCK,
-                       nfs_wait_bit_killable, TASK_KILLABLE);
+       wait_on_bit_lock(&head->wb_flags, PG_HEADLOCK,
+                       nfs_wait_bit_uninterruptible,
+                       TASK_UNINTERRUPTIBLE);
 }
 
 /*
@@ -410,12 +415,6 @@ void nfs_release_request(struct nfs_page *req)
        kref_put(&req->wb_kref, nfs_page_group_destroy);
 }
 
-static int nfs_wait_bit_uninterruptible(void *word)
-{
-       io_schedule();
-       return 0;
-}
-
 /**
  * nfs_wait_on_request - Wait for a request to complete.
  * @req: request to wait upon.