Btrfs: fix fsync data loss after a ranged fsync
authorFilipe Manana <fdmanana@suse.com>
Sat, 6 Sep 2014 21:34:39 +0000 (22:34 +0100)
committerChris Mason <clm@fb.com>
Mon, 8 Sep 2014 20:56:43 +0000 (13:56 -0700)
commit49dae1bc1c665817e434d01eefaa11967f618243
tree4c306620e23a5c0446ce1826919ed5e62f8f0a5c
parentc47ca32d3aadb234f73389a34c97574085bc9eda
Btrfs: fix fsync data loss after a ranged fsync

While we're doing a full fsync (when the inode has the flag
BTRFS_INODE_NEEDS_FULL_SYNC set) that is ranged too (covers only a
portion of the file), we might have ordered operations that are started
before or while we're logging the inode and that fall outside the fsync
range.

Therefore when a full ranged fsync finishes don't remove every extent
map from the list of modified extent maps - as for some of them, that
fall outside our fsync range, their respective ordered operation hasn't
finished yet, meaning the corresponding file extent item wasn't inserted
into the fs/subvol tree yet and therefore we didn't log it, and we must
let the next fast fsync (one that checks only the modified list) see this
extent map and log a matching file extent item to the log btree and wait
for its ordered operation to finish (if it's still ongoing).

A test case for xfstests follows.

Signed-off-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: Chris Mason <clm@fb.com>
fs/btrfs/file.c
fs/btrfs/tree-log.c
fs/btrfs/tree-log.h