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.c32
1 files changed, 13 insertions, 19 deletions
diff --git a/fs/nfs/pagelist.c b/fs/nfs/pagelist.c
index 345bb9b4765b..7f079209d70a 100644
--- a/fs/nfs/pagelist.c
+++ b/fs/nfs/pagelist.c
@@ -58,7 +58,6 @@ nfs_create_request(struct nfs_open_context *ctx, struct inode *inode,
58 struct page *page, 58 struct page *page,
59 unsigned int offset, unsigned int count) 59 unsigned int offset, unsigned int count)
60{ 60{
61 struct nfs_server *server = NFS_SERVER(inode);
62 struct nfs_page *req; 61 struct nfs_page *req;
63 62
64 for (;;) { 63 for (;;) {
@@ -67,7 +66,7 @@ nfs_create_request(struct nfs_open_context *ctx, struct inode *inode,
67 if (req != NULL) 66 if (req != NULL)
68 break; 67 break;
69 68
70 if (signalled() && (server->flags & NFS_MOUNT_INTR)) 69 if (fatal_signal_pending(current))
71 return ERR_PTR(-ERESTARTSYS); 70 return ERR_PTR(-ERESTARTSYS);
72 yield(); 71 yield();
73 } 72 }
@@ -111,13 +110,14 @@ void nfs_unlock_request(struct nfs_page *req)
111 * nfs_set_page_tag_locked - Tag a request as locked 110 * nfs_set_page_tag_locked - Tag a request as locked
112 * @req: 111 * @req:
113 */ 112 */
114static int nfs_set_page_tag_locked(struct nfs_page *req) 113int nfs_set_page_tag_locked(struct nfs_page *req)
115{ 114{
116 struct nfs_inode *nfsi = NFS_I(req->wb_context->path.dentry->d_inode); 115 struct nfs_inode *nfsi = NFS_I(req->wb_context->path.dentry->d_inode);
117 116
118 if (!nfs_lock_request(req)) 117 if (!nfs_lock_request_dontget(req))
119 return 0; 118 return 0;
120 radix_tree_tag_set(&nfsi->nfs_page_tree, req->wb_index, NFS_PAGE_TAG_LOCKED); 119 if (req->wb_page != NULL)
120 radix_tree_tag_set(&nfsi->nfs_page_tree, req->wb_index, NFS_PAGE_TAG_LOCKED);
121 return 1; 121 return 1;
122} 122}
123 123
@@ -132,9 +132,10 @@ void nfs_clear_page_tag_locked(struct nfs_page *req)
132 if (req->wb_page != NULL) { 132 if (req->wb_page != NULL) {
133 spin_lock(&inode->i_lock); 133 spin_lock(&inode->i_lock);
134 radix_tree_tag_clear(&nfsi->nfs_page_tree, req->wb_index, NFS_PAGE_TAG_LOCKED); 134 radix_tree_tag_clear(&nfsi->nfs_page_tree, req->wb_index, NFS_PAGE_TAG_LOCKED);
135 nfs_unlock_request(req);
135 spin_unlock(&inode->i_lock); 136 spin_unlock(&inode->i_lock);
136 } 137 } else
137 nfs_unlock_request(req); 138 nfs_unlock_request(req);
138} 139}
139 140
140/** 141/**
@@ -175,11 +176,11 @@ void nfs_release_request(struct nfs_page *req)
175 kref_put(&req->wb_kref, nfs_free_request); 176 kref_put(&req->wb_kref, nfs_free_request);
176} 177}
177 178
178static int nfs_wait_bit_interruptible(void *word) 179static int nfs_wait_bit_killable(void *word)
179{ 180{
180 int ret = 0; 181 int ret = 0;
181 182
182 if (signal_pending(current)) 183 if (fatal_signal_pending(current))
183 ret = -ERESTARTSYS; 184 ret = -ERESTARTSYS;
184 else 185 else
185 schedule(); 186 schedule();
@@ -190,26 +191,18 @@ static int nfs_wait_bit_interruptible(void *word)
190 * nfs_wait_on_request - Wait for a request to complete. 191 * nfs_wait_on_request - Wait for a request to complete.
191 * @req: request to wait upon. 192 * @req: request to wait upon.
192 * 193 *
193 * Interruptible by signals only if mounted with intr flag. 194 * Interruptible by fatal signals only.
194 * The user is responsible for holding a count on the request. 195 * The user is responsible for holding a count on the request.
195 */ 196 */
196int 197int
197nfs_wait_on_request(struct nfs_page *req) 198nfs_wait_on_request(struct nfs_page *req)
198{ 199{
199 struct rpc_clnt *clnt = NFS_CLIENT(req->wb_context->path.dentry->d_inode);
200 sigset_t oldmask;
201 int ret = 0; 200 int ret = 0;
202 201
203 if (!test_bit(PG_BUSY, &req->wb_flags)) 202 if (!test_bit(PG_BUSY, &req->wb_flags))
204 goto out; 203 goto out;
205 /*
206 * Note: the call to rpc_clnt_sigmask() suffices to ensure that we
207 * are not interrupted if intr flag is not set
208 */
209 rpc_clnt_sigmask(clnt, &oldmask);
210 ret = out_of_line_wait_on_bit(&req->wb_flags, PG_BUSY, 204 ret = out_of_line_wait_on_bit(&req->wb_flags, PG_BUSY,
211 nfs_wait_bit_interruptible, TASK_INTERRUPTIBLE); 205 nfs_wait_bit_killable, TASK_KILLABLE);
212 rpc_clnt_sigunmask(clnt, &oldmask);
213out: 206out:
214 return ret; 207 return ret;
215} 208}
@@ -421,6 +414,7 @@ int nfs_scan_list(struct nfs_inode *nfsi,
421 goto out; 414 goto out;
422 idx_start = req->wb_index + 1; 415 idx_start = req->wb_index + 1;
423 if (nfs_set_page_tag_locked(req)) { 416 if (nfs_set_page_tag_locked(req)) {
417 kref_get(&req->wb_kref);
424 nfs_list_remove_request(req); 418 nfs_list_remove_request(req);
425 radix_tree_tag_clear(&nfsi->nfs_page_tree, 419 radix_tree_tag_clear(&nfsi->nfs_page_tree,
426 req->wb_index, tag); 420 req->wb_index, tag);