diff options
author | Fred Isaman <iisaman@netapp.com> | 2012-04-20 14:47:44 -0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2012-04-27 14:10:37 -0400 |
commit | cd841605f7a721878d8a2d1362484723d8abf569 (patch) | |
tree | b5c37db575cd545a183577249909e042fe38d646 /fs/nfs/objlayout | |
parent | b5542849764aa56fd3f05c0041195b637b9d2ac2 (diff) |
NFS: create common nfs_pgio_header for both read and write
In order to avoid duplicating all the data in nfs_read_data whenever we
split it up into multiple RPC calls (either due to a short read result
or due to rsize < PAGE_SIZE), we split out the bits that are the same
per RPC call into a separate "header" structure.
The goal this patch moves towards is to have a single header
refcounted by several rpc_data structures. Thus, want to always refer
from rpc_data to the header, and not the other way. This patch comes
close to that ideal, but the directio code currently needs some
special casing, isolated in the nfs_direct_[read_write]hdr_release()
functions. This will be dealt with in a future patch.
Signed-off-by: Fred Isaman <iisaman@netapp.com>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs/objlayout')
-rw-r--r-- | fs/nfs/objlayout/objio_osd.c | 16 | ||||
-rw-r--r-- | fs/nfs/objlayout/objlayout.c | 19 |
2 files changed, 20 insertions, 15 deletions
diff --git a/fs/nfs/objlayout/objio_osd.c b/fs/nfs/objlayout/objio_osd.c index 4bff4a3dab46..fbf4874ec252 100644 --- a/fs/nfs/objlayout/objio_osd.c +++ b/fs/nfs/objlayout/objio_osd.c | |||
@@ -440,11 +440,12 @@ static void _read_done(struct ore_io_state *ios, void *private) | |||
440 | 440 | ||
441 | int objio_read_pagelist(struct nfs_read_data *rdata) | 441 | int objio_read_pagelist(struct nfs_read_data *rdata) |
442 | { | 442 | { |
443 | struct nfs_pgio_header *hdr = rdata->header; | ||
443 | struct objio_state *objios; | 444 | struct objio_state *objios; |
444 | int ret; | 445 | int ret; |
445 | 446 | ||
446 | ret = objio_alloc_io_state(NFS_I(rdata->inode)->layout, true, | 447 | ret = objio_alloc_io_state(NFS_I(hdr->inode)->layout, true, |
447 | rdata->lseg, rdata->args.pages, rdata->args.pgbase, | 448 | hdr->lseg, rdata->args.pages, rdata->args.pgbase, |
448 | rdata->args.offset, rdata->args.count, rdata, | 449 | rdata->args.offset, rdata->args.count, rdata, |
449 | GFP_KERNEL, &objios); | 450 | GFP_KERNEL, &objios); |
450 | if (unlikely(ret)) | 451 | if (unlikely(ret)) |
@@ -483,12 +484,12 @@ static struct page *__r4w_get_page(void *priv, u64 offset, bool *uptodate) | |||
483 | { | 484 | { |
484 | struct objio_state *objios = priv; | 485 | struct objio_state *objios = priv; |
485 | struct nfs_write_data *wdata = objios->oir.rpcdata; | 486 | struct nfs_write_data *wdata = objios->oir.rpcdata; |
487 | struct address_space *mapping = wdata->header->inode->i_mapping; | ||
486 | pgoff_t index = offset / PAGE_SIZE; | 488 | pgoff_t index = offset / PAGE_SIZE; |
487 | struct page *page = find_get_page(wdata->inode->i_mapping, index); | 489 | struct page *page = find_get_page(mapping, index); |
488 | 490 | ||
489 | if (!page) { | 491 | if (!page) { |
490 | page = find_or_create_page(wdata->inode->i_mapping, | 492 | page = find_or_create_page(mapping, index, GFP_NOFS); |
491 | index, GFP_NOFS); | ||
492 | if (unlikely(!page)) { | 493 | if (unlikely(!page)) { |
493 | dprintk("%s: grab_cache_page Failed index=0x%lx\n", | 494 | dprintk("%s: grab_cache_page Failed index=0x%lx\n", |
494 | __func__, index); | 495 | __func__, index); |
@@ -518,11 +519,12 @@ static const struct _ore_r4w_op _r4w_op = { | |||
518 | 519 | ||
519 | int objio_write_pagelist(struct nfs_write_data *wdata, int how) | 520 | int objio_write_pagelist(struct nfs_write_data *wdata, int how) |
520 | { | 521 | { |
522 | struct nfs_pgio_header *hdr = wdata->header; | ||
521 | struct objio_state *objios; | 523 | struct objio_state *objios; |
522 | int ret; | 524 | int ret; |
523 | 525 | ||
524 | ret = objio_alloc_io_state(NFS_I(wdata->inode)->layout, false, | 526 | ret = objio_alloc_io_state(NFS_I(hdr->inode)->layout, false, |
525 | wdata->lseg, wdata->args.pages, wdata->args.pgbase, | 527 | hdr->lseg, wdata->args.pages, wdata->args.pgbase, |
526 | wdata->args.offset, wdata->args.count, wdata, GFP_NOFS, | 528 | wdata->args.offset, wdata->args.count, wdata, GFP_NOFS, |
527 | &objios); | 529 | &objios); |
528 | if (unlikely(ret)) | 530 | if (unlikely(ret)) |
diff --git a/fs/nfs/objlayout/objlayout.c b/fs/nfs/objlayout/objlayout.c index 595c5fc21a19..874613545301 100644 --- a/fs/nfs/objlayout/objlayout.c +++ b/fs/nfs/objlayout/objlayout.c | |||
@@ -258,7 +258,7 @@ objlayout_read_done(struct objlayout_io_res *oir, ssize_t status, bool sync) | |||
258 | if (status >= 0) | 258 | if (status >= 0) |
259 | rdata->res.count = status; | 259 | rdata->res.count = status; |
260 | else | 260 | else |
261 | rdata->pnfs_error = status; | 261 | rdata->header->pnfs_error = status; |
262 | objlayout_iodone(oir); | 262 | objlayout_iodone(oir); |
263 | /* must not use oir after this point */ | 263 | /* must not use oir after this point */ |
264 | 264 | ||
@@ -279,12 +279,14 @@ objlayout_read_done(struct objlayout_io_res *oir, ssize_t status, bool sync) | |||
279 | enum pnfs_try_status | 279 | enum pnfs_try_status |
280 | objlayout_read_pagelist(struct nfs_read_data *rdata) | 280 | objlayout_read_pagelist(struct nfs_read_data *rdata) |
281 | { | 281 | { |
282 | struct nfs_pgio_header *hdr = rdata->header; | ||
283 | struct inode *inode = hdr->inode; | ||
282 | loff_t offset = rdata->args.offset; | 284 | loff_t offset = rdata->args.offset; |
283 | size_t count = rdata->args.count; | 285 | size_t count = rdata->args.count; |
284 | int err; | 286 | int err; |
285 | loff_t eof; | 287 | loff_t eof; |
286 | 288 | ||
287 | eof = i_size_read(rdata->inode); | 289 | eof = i_size_read(inode); |
288 | if (unlikely(offset + count > eof)) { | 290 | if (unlikely(offset + count > eof)) { |
289 | if (offset >= eof) { | 291 | if (offset >= eof) { |
290 | err = 0; | 292 | err = 0; |
@@ -297,17 +299,17 @@ objlayout_read_pagelist(struct nfs_read_data *rdata) | |||
297 | } | 299 | } |
298 | 300 | ||
299 | rdata->res.eof = (offset + count) >= eof; | 301 | rdata->res.eof = (offset + count) >= eof; |
300 | _fix_verify_io_params(rdata->lseg, &rdata->args.pages, | 302 | _fix_verify_io_params(hdr->lseg, &rdata->args.pages, |
301 | &rdata->args.pgbase, | 303 | &rdata->args.pgbase, |
302 | rdata->args.offset, rdata->args.count); | 304 | rdata->args.offset, rdata->args.count); |
303 | 305 | ||
304 | dprintk("%s: inode(%lx) offset 0x%llx count 0x%Zx eof=%d\n", | 306 | dprintk("%s: inode(%lx) offset 0x%llx count 0x%Zx eof=%d\n", |
305 | __func__, rdata->inode->i_ino, offset, count, rdata->res.eof); | 307 | __func__, inode->i_ino, offset, count, rdata->res.eof); |
306 | 308 | ||
307 | err = objio_read_pagelist(rdata); | 309 | err = objio_read_pagelist(rdata); |
308 | out: | 310 | out: |
309 | if (unlikely(err)) { | 311 | if (unlikely(err)) { |
310 | rdata->pnfs_error = err; | 312 | hdr->pnfs_error = err; |
311 | dprintk("%s: Returned Error %d\n", __func__, err); | 313 | dprintk("%s: Returned Error %d\n", __func__, err); |
312 | return PNFS_NOT_ATTEMPTED; | 314 | return PNFS_NOT_ATTEMPTED; |
313 | } | 315 | } |
@@ -340,7 +342,7 @@ objlayout_write_done(struct objlayout_io_res *oir, ssize_t status, bool sync) | |||
340 | wdata->res.count = status; | 342 | wdata->res.count = status; |
341 | wdata->verf.committed = oir->committed; | 343 | wdata->verf.committed = oir->committed; |
342 | } else { | 344 | } else { |
343 | wdata->pnfs_error = status; | 345 | wdata->header->pnfs_error = status; |
344 | } | 346 | } |
345 | objlayout_iodone(oir); | 347 | objlayout_iodone(oir); |
346 | /* must not use oir after this point */ | 348 | /* must not use oir after this point */ |
@@ -363,15 +365,16 @@ enum pnfs_try_status | |||
363 | objlayout_write_pagelist(struct nfs_write_data *wdata, | 365 | objlayout_write_pagelist(struct nfs_write_data *wdata, |
364 | int how) | 366 | int how) |
365 | { | 367 | { |
368 | struct nfs_pgio_header *hdr = wdata->header; | ||
366 | int err; | 369 | int err; |
367 | 370 | ||
368 | _fix_verify_io_params(wdata->lseg, &wdata->args.pages, | 371 | _fix_verify_io_params(hdr->lseg, &wdata->args.pages, |
369 | &wdata->args.pgbase, | 372 | &wdata->args.pgbase, |
370 | wdata->args.offset, wdata->args.count); | 373 | wdata->args.offset, wdata->args.count); |
371 | 374 | ||
372 | err = objio_write_pagelist(wdata, how); | 375 | err = objio_write_pagelist(wdata, how); |
373 | if (unlikely(err)) { | 376 | if (unlikely(err)) { |
374 | wdata->pnfs_error = err; | 377 | hdr->pnfs_error = err; |
375 | dprintk("%s: Returned Error %d\n", __func__, err); | 378 | dprintk("%s: Returned Error %d\n", __func__, err); |
376 | return PNFS_NOT_ATTEMPTED; | 379 | return PNFS_NOT_ATTEMPTED; |
377 | } | 380 | } |