aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs
diff options
context:
space:
mode:
authorTrond Myklebust <trond.myklebust@primarydata.com>2014-05-29 11:45:57 -0400
committerTrond Myklebust <trond.myklebust@primarydata.com>2014-05-29 12:12:27 -0400
commitf868089b09b51bd17ee41dedb96f98a1d0952fec (patch)
treebb7b2c8503616cea06eba345d7b47cc479695d24 /fs/nfs
parentc1109558ae0f07a3434357cd26203bfc7adfea75 (diff)
NFS: Fix a potential busy wait in nfs_page_group_lock
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>
Diffstat (limited to 'fs/nfs')
-rw-r--r--fs/nfs/pagelist.c19
1 files changed, 9 insertions, 10 deletions
diff --git a/fs/nfs/pagelist.c b/fs/nfs/pagelist.c
index 0b8446f1008d..a8759825ac76 100644
--- a/fs/nfs/pagelist.c
+++ b/fs/nfs/pagelist.c
@@ -138,6 +138,12 @@ nfs_iocounter_wait(struct nfs_io_counter *c)
138 return __nfs_iocounter_wait(c); 138 return __nfs_iocounter_wait(c);
139} 139}
140 140
141static int nfs_wait_bit_uninterruptible(void *word)
142{
143 io_schedule();
144 return 0;
145}
146
141/* 147/*
142 * nfs_page_group_lock - lock the head of the page group 148 * nfs_page_group_lock - lock the head of the page group
143 * @req - request in group that is to be locked 149 * @req - request in group that is to be locked
@@ -148,13 +154,12 @@ void
148nfs_page_group_lock(struct nfs_page *req) 154nfs_page_group_lock(struct nfs_page *req)
149{ 155{
150 struct nfs_page *head = req->wb_head; 156 struct nfs_page *head = req->wb_head;
151 int err = -EAGAIN;
152 157
153 WARN_ON_ONCE(head != head->wb_head); 158 WARN_ON_ONCE(head != head->wb_head);
154 159
155 while (err) 160 wait_on_bit_lock(&head->wb_flags, PG_HEADLOCK,
156 err = wait_on_bit_lock(&head->wb_flags, PG_HEADLOCK, 161 nfs_wait_bit_uninterruptible,
157 nfs_wait_bit_killable, TASK_KILLABLE); 162 TASK_UNINTERRUPTIBLE);
158} 163}
159 164
160/* 165/*
@@ -410,12 +415,6 @@ void nfs_release_request(struct nfs_page *req)
410 kref_put(&req->wb_kref, nfs_page_group_destroy); 415 kref_put(&req->wb_kref, nfs_page_group_destroy);
411} 416}
412 417
413static int nfs_wait_bit_uninterruptible(void *word)
414{
415 io_schedule();
416 return 0;
417}
418
419/** 418/**
420 * nfs_wait_on_request - Wait for a request to complete. 419 * nfs_wait_on_request - Wait for a request to complete.
421 * @req: request to wait upon. 420 * @req: request to wait upon.