diff options
Diffstat (limited to 'fs/nfs/direct.c')
-rw-r--r-- | fs/nfs/direct.c | 17 |
1 files changed, 13 insertions, 4 deletions
diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c index fc07ce4885da..3f87a72bd137 100644 --- a/fs/nfs/direct.c +++ b/fs/nfs/direct.c | |||
@@ -218,14 +218,17 @@ static struct nfs_direct_req *nfs_direct_read_alloc(size_t nbytes, unsigned int | |||
218 | * until the RPCs complete. This could be long *after* we are woken up in | 218 | * until the RPCs complete. This could be long *after* we are woken up in |
219 | * nfs_direct_read_wait (for instance, if someone hits ^C on a slow server). | 219 | * nfs_direct_read_wait (for instance, if someone hits ^C on a slow server). |
220 | */ | 220 | */ |
221 | static void nfs_direct_read_result(struct nfs_read_data *data, int status) | 221 | static void nfs_direct_read_result(struct rpc_task *task, void *calldata) |
222 | { | 222 | { |
223 | struct nfs_read_data *data = calldata; | ||
223 | struct nfs_direct_req *dreq = (struct nfs_direct_req *) data->req; | 224 | struct nfs_direct_req *dreq = (struct nfs_direct_req *) data->req; |
224 | 225 | ||
225 | if (likely(status >= 0)) | 226 | if (nfs_readpage_result(task, data) != 0) |
227 | return; | ||
228 | if (likely(task->tk_status >= 0)) | ||
226 | atomic_add(data->res.count, &dreq->count); | 229 | atomic_add(data->res.count, &dreq->count); |
227 | else | 230 | else |
228 | atomic_set(&dreq->error, status); | 231 | atomic_set(&dreq->error, task->tk_status); |
229 | 232 | ||
230 | if (unlikely(atomic_dec_and_test(&dreq->complete))) { | 233 | if (unlikely(atomic_dec_and_test(&dreq->complete))) { |
231 | nfs_free_user_pages(dreq->pages, dreq->npages, 1); | 234 | nfs_free_user_pages(dreq->pages, dreq->npages, 1); |
@@ -234,6 +237,11 @@ static void nfs_direct_read_result(struct nfs_read_data *data, int status) | |||
234 | } | 237 | } |
235 | } | 238 | } |
236 | 239 | ||
240 | static const struct rpc_call_ops nfs_read_direct_ops = { | ||
241 | .rpc_call_done = nfs_direct_read_result, | ||
242 | .rpc_release = nfs_readdata_release, | ||
243 | }; | ||
244 | |||
237 | /** | 245 | /** |
238 | * nfs_direct_read_schedule - dispatch NFS READ operations for a direct read | 246 | * nfs_direct_read_schedule - dispatch NFS READ operations for a direct read |
239 | * @dreq: address of nfs_direct_req struct for this request | 247 | * @dreq: address of nfs_direct_req struct for this request |
@@ -280,10 +288,11 @@ static void nfs_direct_read_schedule(struct nfs_direct_req *dreq, | |||
280 | data->res.eof = 0; | 288 | data->res.eof = 0; |
281 | data->res.count = bytes; | 289 | data->res.count = bytes; |
282 | 290 | ||
291 | rpc_init_task(&data->task, NFS_CLIENT(inode), RPC_TASK_ASYNC, | ||
292 | &nfs_read_direct_ops, data); | ||
283 | NFS_PROTO(inode)->read_setup(data); | 293 | NFS_PROTO(inode)->read_setup(data); |
284 | 294 | ||
285 | data->task.tk_cookie = (unsigned long) inode; | 295 | data->task.tk_cookie = (unsigned long) inode; |
286 | data->complete = nfs_direct_read_result; | ||
287 | 296 | ||
288 | lock_kernel(); | 297 | lock_kernel(); |
289 | rpc_execute(&data->task); | 298 | rpc_execute(&data->task); |