aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/pagelist.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfs/pagelist.c')
-rw-r--r--fs/nfs/pagelist.c35
1 files changed, 28 insertions, 7 deletions
diff --git a/fs/nfs/pagelist.c b/fs/nfs/pagelist.c
index 4f1ba723848d..80777f99a58a 100644
--- a/fs/nfs/pagelist.c
+++ b/fs/nfs/pagelist.c
@@ -107,7 +107,7 @@ void nfs_unlock_request(struct nfs_page *req)
107 smp_mb__before_clear_bit(); 107 smp_mb__before_clear_bit();
108 clear_bit(PG_BUSY, &req->wb_flags); 108 clear_bit(PG_BUSY, &req->wb_flags);
109 smp_mb__after_clear_bit(); 109 smp_mb__after_clear_bit();
110 wake_up_all(&req->wb_context->waitq); 110 wake_up_bit(&req->wb_flags, PG_BUSY);
111 nfs_release_request(req); 111 nfs_release_request(req);
112} 112}
113 113
@@ -180,6 +180,17 @@ nfs_list_add_request(struct nfs_page *req, struct list_head *head)
180 req->wb_list_head = head; 180 req->wb_list_head = head;
181} 181}
182 182
183static int nfs_wait_bit_interruptible(void *word)
184{
185 int ret = 0;
186
187 if (signal_pending(current))
188 ret = -ERESTARTSYS;
189 else
190 schedule();
191 return ret;
192}
193
183/** 194/**
184 * nfs_wait_on_request - Wait for a request to complete. 195 * nfs_wait_on_request - Wait for a request to complete.
185 * @req: request to wait upon. 196 * @req: request to wait upon.
@@ -190,12 +201,22 @@ nfs_list_add_request(struct nfs_page *req, struct list_head *head)
190int 201int
191nfs_wait_on_request(struct nfs_page *req) 202nfs_wait_on_request(struct nfs_page *req)
192{ 203{
193 struct inode *inode = req->wb_context->dentry->d_inode; 204 struct rpc_clnt *clnt = NFS_CLIENT(req->wb_context->dentry->d_inode);
194 struct rpc_clnt *clnt = NFS_CLIENT(inode); 205 sigset_t oldmask;
195 206 int ret = 0;
196 if (!NFS_WBACK_BUSY(req)) 207
197 return 0; 208 if (!test_bit(PG_BUSY, &req->wb_flags))
198 return nfs_wait_event(clnt, req->wb_context->waitq, !NFS_WBACK_BUSY(req)); 209 goto out;
210 /*
211 * Note: the call to rpc_clnt_sigmask() suffices to ensure that we
212 * are not interrupted if intr flag is not set
213 */
214 rpc_clnt_sigmask(clnt, &oldmask);
215 ret = out_of_line_wait_on_bit(&req->wb_flags, PG_BUSY,
216 nfs_wait_bit_interruptible, TASK_INTERRUPTIBLE);
217 rpc_clnt_sigunmask(clnt, &oldmask);
218out:
219 return ret;
199} 220}
200 221
201/** 222/**