diff options
author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2011-07-12 13:42:02 -0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2011-07-15 09:12:17 -0400 |
commit | 275acaafd45fbc8ecc3beabd6367e60b3049606a (patch) | |
tree | 7da9d9a606c274742d41860cb429c7d25a917f1d /fs/nfs/read.c | |
parent | 3b6091846d5b6113d695c79caec7cc96b62d469b (diff) |
NFS: Clean up: split out the RPC transmission from nfs_pagein_multi/one
...and do the same for nfs_flush_multi/one.
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs/read.c')
-rw-r--r-- | fs/nfs/read.c | 92 |
1 files changed, 50 insertions, 42 deletions
diff --git a/fs/nfs/read.c b/fs/nfs/read.c index 581534a4aed7..0215bac35fc6 100644 --- a/fs/nfs/read.c +++ b/fs/nfs/read.c | |||
@@ -30,8 +30,6 @@ | |||
30 | 30 | ||
31 | #define NFSDBG_FACILITY NFSDBG_PAGECACHE | 31 | #define NFSDBG_FACILITY NFSDBG_PAGECACHE |
32 | 32 | ||
33 | static int nfs_pagein_multi(struct nfs_pageio_descriptor *desc); | ||
34 | static int nfs_pagein_one(struct nfs_pageio_descriptor *desc); | ||
35 | static const struct nfs_pageio_ops nfs_pageio_read_ops; | 33 | static const struct nfs_pageio_ops nfs_pageio_read_ops; |
36 | static const struct rpc_call_ops nfs_read_partial_ops; | 34 | static const struct rpc_call_ops nfs_read_partial_ops; |
37 | static const struct rpc_call_ops nfs_read_full_ops; | 35 | static const struct rpc_call_ops nfs_read_full_ops; |
@@ -253,6 +251,27 @@ static int nfs_do_read(struct nfs_read_data *data, | |||
253 | return nfs_initiate_read(data, NFS_CLIENT(inode), call_ops); | 251 | return nfs_initiate_read(data, NFS_CLIENT(inode), call_ops); |
254 | } | 252 | } |
255 | 253 | ||
254 | static int | ||
255 | nfs_do_multiple_reads(struct list_head *head, | ||
256 | const struct rpc_call_ops *call_ops, | ||
257 | struct pnfs_layout_segment *lseg) | ||
258 | { | ||
259 | struct nfs_read_data *data; | ||
260 | int ret = 0; | ||
261 | |||
262 | while (!list_empty(head)) { | ||
263 | int ret2; | ||
264 | |||
265 | data = list_entry(head->next, struct nfs_read_data, list); | ||
266 | list_del_init(&data->list); | ||
267 | |||
268 | ret2 = nfs_do_read(data, call_ops, lseg); | ||
269 | if (ret == 0) | ||
270 | ret = ret2; | ||
271 | } | ||
272 | return ret; | ||
273 | } | ||
274 | |||
256 | static void | 275 | static void |
257 | nfs_async_read_error(struct list_head *head) | 276 | nfs_async_read_error(struct list_head *head) |
258 | { | 277 | { |
@@ -279,7 +298,7 @@ nfs_async_read_error(struct list_head *head) | |||
279 | * won't see the new data until our attribute cache is updated. This is more | 298 | * won't see the new data until our attribute cache is updated. This is more |
280 | * or less conventional NFS client behavior. | 299 | * or less conventional NFS client behavior. |
281 | */ | 300 | */ |
282 | static int nfs_pagein_multi(struct nfs_pageio_descriptor *desc) | 301 | static int nfs_pagein_multi(struct nfs_pageio_descriptor *desc, struct list_head *res) |
283 | { | 302 | { |
284 | struct nfs_page *req = nfs_list_entry(desc->pg_list.next); | 303 | struct nfs_page *req = nfs_list_entry(desc->pg_list.next); |
285 | struct page *page = req->wb_page; | 304 | struct page *page = req->wb_page; |
@@ -288,11 +307,10 @@ static int nfs_pagein_multi(struct nfs_pageio_descriptor *desc) | |||
288 | unsigned int offset; | 307 | unsigned int offset; |
289 | int requests = 0; | 308 | int requests = 0; |
290 | int ret = 0; | 309 | int ret = 0; |
291 | struct pnfs_layout_segment *lseg = desc->pg_lseg; | ||
292 | LIST_HEAD(list); | ||
293 | 310 | ||
294 | nfs_list_remove_request(req); | 311 | nfs_list_remove_request(req); |
295 | 312 | ||
313 | offset = 0; | ||
296 | nbytes = desc->pg_count; | 314 | nbytes = desc->pg_count; |
297 | do { | 315 | do { |
298 | size_t len = min(nbytes,rsize); | 316 | size_t len = min(nbytes,rsize); |
@@ -300,57 +318,33 @@ static int nfs_pagein_multi(struct nfs_pageio_descriptor *desc) | |||
300 | data = nfs_readdata_alloc(1); | 318 | data = nfs_readdata_alloc(1); |
301 | if (!data) | 319 | if (!data) |
302 | goto out_bad; | 320 | goto out_bad; |
303 | list_add(&data->list, &list); | 321 | data->pagevec[0] = page; |
322 | nfs_read_rpcsetup(req, data, len, offset); | ||
323 | list_add(&data->list, res); | ||
304 | requests++; | 324 | requests++; |
305 | nbytes -= len; | 325 | nbytes -= len; |
326 | offset += len; | ||
306 | } while(nbytes != 0); | 327 | } while(nbytes != 0); |
307 | atomic_set(&req->wb_complete, requests); | 328 | atomic_set(&req->wb_complete, requests); |
308 | |||
309 | ClearPageError(page); | 329 | ClearPageError(page); |
310 | offset = 0; | ||
311 | nbytes = desc->pg_count; | ||
312 | do { | ||
313 | int ret2; | ||
314 | |||
315 | data = list_entry(list.next, struct nfs_read_data, list); | ||
316 | list_del_init(&data->list); | ||
317 | |||
318 | data->pagevec[0] = page; | ||
319 | |||
320 | if (nbytes < rsize) | ||
321 | rsize = nbytes; | ||
322 | nfs_read_rpcsetup(req, data, rsize, offset); | ||
323 | ret2 = nfs_do_read(data, &nfs_read_partial_ops, lseg); | ||
324 | if (ret == 0) | ||
325 | ret = ret2; | ||
326 | offset += rsize; | ||
327 | nbytes -= rsize; | ||
328 | } while (nbytes != 0); | ||
329 | put_lseg(lseg); | ||
330 | desc->pg_lseg = NULL; | ||
331 | |||
332 | return ret; | 330 | return ret; |
333 | |||
334 | out_bad: | 331 | out_bad: |
335 | while (!list_empty(&list)) { | 332 | while (!list_empty(res)) { |
336 | data = list_entry(list.next, struct nfs_read_data, list); | 333 | data = list_entry(res->next, struct nfs_read_data, list); |
337 | list_del(&data->list); | 334 | list_del(&data->list); |
338 | nfs_readdata_free(data); | 335 | nfs_readdata_free(data); |
339 | } | 336 | } |
340 | SetPageError(page); | 337 | SetPageError(page); |
341 | nfs_readpage_release(req); | 338 | nfs_readpage_release(req); |
342 | put_lseg(lseg); | ||
343 | desc->pg_lseg = NULL; | ||
344 | return -ENOMEM; | 339 | return -ENOMEM; |
345 | } | 340 | } |
346 | 341 | ||
347 | static int nfs_pagein_one(struct nfs_pageio_descriptor *desc) | 342 | static int nfs_pagein_one(struct nfs_pageio_descriptor *desc, struct list_head *res) |
348 | { | 343 | { |
349 | struct nfs_page *req; | 344 | struct nfs_page *req; |
350 | struct page **pages; | 345 | struct page **pages; |
351 | struct nfs_read_data *data; | 346 | struct nfs_read_data *data; |
352 | struct list_head *head = &desc->pg_list; | 347 | struct list_head *head = &desc->pg_list; |
353 | struct pnfs_layout_segment *lseg = desc->pg_lseg; | ||
354 | int ret = 0; | 348 | int ret = 0; |
355 | 349 | ||
356 | data = nfs_readdata_alloc(nfs_page_array_len(desc->pg_base, | 350 | data = nfs_readdata_alloc(nfs_page_array_len(desc->pg_base, |
@@ -372,18 +366,32 @@ static int nfs_pagein_one(struct nfs_pageio_descriptor *desc) | |||
372 | req = nfs_list_entry(data->pages.next); | 366 | req = nfs_list_entry(data->pages.next); |
373 | 367 | ||
374 | nfs_read_rpcsetup(req, data, desc->pg_count, 0); | 368 | nfs_read_rpcsetup(req, data, desc->pg_count, 0); |
375 | ret = nfs_do_read(data, &nfs_read_full_ops, lseg); | 369 | list_add(&data->list, res); |
376 | out: | 370 | out: |
377 | put_lseg(lseg); | ||
378 | desc->pg_lseg = NULL; | ||
379 | return ret; | 371 | return ret; |
380 | } | 372 | } |
381 | 373 | ||
382 | int nfs_generic_pg_readpages(struct nfs_pageio_descriptor *desc) | 374 | int nfs_generic_pg_readpages(struct nfs_pageio_descriptor *desc) |
383 | { | 375 | { |
384 | if (desc->pg_bsize < PAGE_CACHE_SIZE) | 376 | LIST_HEAD(head); |
385 | return nfs_pagein_multi(desc); | 377 | int ret; |
386 | return nfs_pagein_one(desc); | 378 | |
379 | if (desc->pg_bsize < PAGE_CACHE_SIZE) { | ||
380 | ret = nfs_pagein_multi(desc, &head); | ||
381 | if (ret == 0) | ||
382 | ret = nfs_do_multiple_reads(&head, | ||
383 | &nfs_read_partial_ops, | ||
384 | desc->pg_lseg); | ||
385 | } else { | ||
386 | ret = nfs_pagein_one(desc, &head); | ||
387 | if (ret == 0) | ||
388 | ret = nfs_do_multiple_reads(&head, | ||
389 | &nfs_read_full_ops, | ||
390 | desc->pg_lseg); | ||
391 | } | ||
392 | put_lseg(desc->pg_lseg); | ||
393 | desc->pg_lseg = NULL; | ||
394 | return ret; | ||
387 | } | 395 | } |
388 | EXPORT_SYMBOL_GPL(nfs_generic_pg_readpages); | 396 | EXPORT_SYMBOL_GPL(nfs_generic_pg_readpages); |
389 | 397 | ||