diff options
author | Christoph Hellwig <hch@lst.de> | 2014-09-10 11:23:35 -0400 |
---|---|---|
committer | Trond Myklebust <trond.myklebust@primarydata.com> | 2014-09-10 15:47:03 -0400 |
commit | 71d5b76302e21390b4ab747875de6bd5cfbca979 (patch) | |
tree | 00f81f6bead7fb6acf3b08465c4c501c6a15bc3d /fs/nfs | |
parent | 8067253c8cc531b6f367b9f5942bdc6168385701 (diff) |
pnfs/blocklayout: implement the return_range method
This allows removing extents from the extent tree especially on truncate
operations, and thus fixing reads from truncated and re-extended that
previously returned stale data.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Diffstat (limited to 'fs/nfs')
-rw-r--r-- | fs/nfs/blocklayout/blocklayout.c | 30 |
1 files changed, 30 insertions, 0 deletions
diff --git a/fs/nfs/blocklayout/blocklayout.c b/fs/nfs/blocklayout/blocklayout.c index 8502e620f644..d3c3c5c972c3 100644 --- a/fs/nfs/blocklayout/blocklayout.c +++ b/fs/nfs/blocklayout/blocklayout.c | |||
@@ -470,6 +470,35 @@ static struct pnfs_layout_segment *bl_alloc_lseg(struct pnfs_layout_hdr *lo, | |||
470 | } | 470 | } |
471 | 471 | ||
472 | static void | 472 | static void |
473 | bl_return_range(struct pnfs_layout_hdr *lo, | ||
474 | struct pnfs_layout_range *range) | ||
475 | { | ||
476 | struct pnfs_block_layout *bl = BLK_LO2EXT(lo); | ||
477 | sector_t offset = range->offset >> SECTOR_SHIFT, end; | ||
478 | int err; | ||
479 | |||
480 | if (range->offset % 8) { | ||
481 | dprintk("%s: offset %lld not block size aligned\n", | ||
482 | __func__, range->offset); | ||
483 | return; | ||
484 | } | ||
485 | |||
486 | if (range->length != NFS4_MAX_UINT64) { | ||
487 | if (range->length % 8) { | ||
488 | dprintk("%s: length %lld not block size aligned\n", | ||
489 | __func__, range->length); | ||
490 | return; | ||
491 | } | ||
492 | |||
493 | end = offset + (range->length >> SECTOR_SHIFT); | ||
494 | } else { | ||
495 | end = round_down(NFS4_MAX_UINT64, PAGE_SIZE); | ||
496 | } | ||
497 | |||
498 | err = ext_tree_remove(bl, range->iomode & IOMODE_RW, offset, end); | ||
499 | } | ||
500 | |||
501 | static void | ||
473 | bl_encode_layoutcommit(struct pnfs_layout_hdr *lo, struct xdr_stream *xdr, | 502 | bl_encode_layoutcommit(struct pnfs_layout_hdr *lo, struct xdr_stream *xdr, |
474 | const struct nfs4_layoutcommit_args *arg) | 503 | const struct nfs4_layoutcommit_args *arg) |
475 | { | 504 | { |
@@ -777,6 +806,7 @@ static struct pnfs_layoutdriver_type blocklayout_type = { | |||
777 | .free_layout_hdr = bl_free_layout_hdr, | 806 | .free_layout_hdr = bl_free_layout_hdr, |
778 | .alloc_lseg = bl_alloc_lseg, | 807 | .alloc_lseg = bl_alloc_lseg, |
779 | .free_lseg = bl_free_lseg, | 808 | .free_lseg = bl_free_lseg, |
809 | .return_range = bl_return_range, | ||
780 | .encode_layoutcommit = bl_encode_layoutcommit, | 810 | .encode_layoutcommit = bl_encode_layoutcommit, |
781 | .cleanup_layoutcommit = bl_cleanup_layoutcommit, | 811 | .cleanup_layoutcommit = bl_cleanup_layoutcommit, |
782 | .set_layoutdriver = bl_set_layoutdriver, | 812 | .set_layoutdriver = bl_set_layoutdriver, |