summaryrefslogtreecommitdiffstats
path: root/fs/nfs/blocklayout/blocklayout.h
diff options
context:
space:
mode:
authorBenjamin Coddington <bcodding@redhat.com>2016-08-22 14:11:16 -0400
committerTrond Myklebust <trond.myklebust@primarydata.com>2016-08-23 11:41:38 -0400
commit41963c10c47a35185e68cb9049f7a3493c94d2d7 (patch)
treea561ace1f94987e1a66cf15d2f218b386bdd8487 /fs/nfs/blocklayout/blocklayout.h
parentb88fa69eaa8649f11828158c7b65c4bcd886ebd5 (diff)
downloadlinux-41963c10c47a35185e68cb9049f7a3493c94d2d7.tar.gz
linux-41963c10c47a35185e68cb9049f7a3493c94d2d7.tar.bz2
linux-41963c10c47a35185e68cb9049f7a3493c94d2d7.zip
pnfs/blocklayout: update last_write_offset atomically with extents
Block/SCSI layout write completion may add committable extents to the extent tree before updating the layout's last-written byte under the inode lock. If a sync happens before this value is updated, then prepare_layoutcommit may find and encode these extents which would produce a LAYOUTCOMMIT request whose encoded extents are larger than the request's loca_length. Fix this by using a last-written byte value that is updated atomically with the extent tree so that commitable extents always match. Signed-off-by: Benjamin Coddington <bcodding@redhat.com> Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Diffstat (limited to 'fs/nfs/blocklayout/blocklayout.h')
-rw-r--r--fs/nfs/blocklayout/blocklayout.h3
1 files changed, 2 insertions, 1 deletions
diff --git a/fs/nfs/blocklayout/blocklayout.h b/fs/nfs/blocklayout/blocklayout.h
index 18e6fd0b9506..efc007f00742 100644
--- a/fs/nfs/blocklayout/blocklayout.h
+++ b/fs/nfs/blocklayout/blocklayout.h
@@ -141,6 +141,7 @@ struct pnfs_block_layout {
struct rb_root bl_ext_ro;
spinlock_t bl_ext_lock; /* Protects list manipulation */
bool bl_scsi_layout;
+ u64 bl_lwb;
};
static inline struct pnfs_block_layout *
@@ -182,7 +183,7 @@ int ext_tree_insert(struct pnfs_block_layout *bl,
int ext_tree_remove(struct pnfs_block_layout *bl, bool rw, sector_t start,
sector_t end);
int ext_tree_mark_written(struct pnfs_block_layout *bl, sector_t start,
- sector_t len);
+ sector_t len, u64 lwb);
bool ext_tree_lookup(struct pnfs_block_layout *bl, sector_t isect,
struct pnfs_block_extent *ret, bool rw);
int ext_tree_prepare_commit(struct nfs4_layoutcommit_args *arg);