summaryrefslogtreecommitdiffstats
path: root/fs/btrfs
diff options
context:
space:
mode:
authorJosef Bacik <jbacik@fb.com>2017-11-17 14:50:46 -0500
committerDavid Sterba <dsterba@suse.com>2017-11-20 14:43:39 -0500
commit8e138e0d92c6c9d3d481674fb14e3439b495be37 (patch)
tree996f716135f903d962d3d5ce419c70d64115d8b7 /fs/btrfs
parente3b8a4858566a6cc25422fbfdfdd760b13b79280 (diff)
btrfs: clear space cache inode generation always
We discovered a box that had double allocations, and suspected the space cache may be to blame. While auditing the write out path I noticed that if we've already setup the space cache we will just carry on. This means that any error we hit after cache_save_setup before we go to actually write the cache out we won't reset the inode generation, so whatever was already written will be considered correct, except it'll be stale. Fix this by _always_ resetting the generation on the block group inode, this way we only ever have valid or invalid cache. With this patch I was no longer able to reproduce cache corruption with dm-log-writes and my bpf error injection tool. Cc: stable@vger.kernel.org Signed-off-by: Josef Bacik <jbacik@fb.com> Signed-off-by: David Sterba <dsterba@suse.com>
Diffstat (limited to 'fs/btrfs')
-rw-r--r--fs/btrfs/extent-tree.c14
1 files changed, 7 insertions, 7 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index 673ac4e01dd0..784d41e95ed9 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -3502,13 +3502,6 @@ again:
3502 goto again; 3502 goto again;
3503 } 3503 }
3504 3504
3505 /* We've already setup this transaction, go ahead and exit */
3506 if (block_group->cache_generation == trans->transid &&
3507 i_size_read(inode)) {
3508 dcs = BTRFS_DC_SETUP;
3509 goto out_put;
3510 }
3511
3512 /* 3505 /*
3513 * We want to set the generation to 0, that way if anything goes wrong 3506 * We want to set the generation to 0, that way if anything goes wrong
3514 * from here on out we know not to trust this cache when we load up next 3507 * from here on out we know not to trust this cache when we load up next
@@ -3532,6 +3525,13 @@ again:
3532 } 3525 }
3533 WARN_ON(ret); 3526 WARN_ON(ret);
3534 3527
3528 /* We've already setup this transaction, go ahead and exit */
3529 if (block_group->cache_generation == trans->transid &&
3530 i_size_read(inode)) {
3531 dcs = BTRFS_DC_SETUP;
3532 goto out_put;
3533 }
3534
3535 if (i_size_read(inode) > 0) { 3535 if (i_size_read(inode) > 0) {
3536 ret = btrfs_check_trunc_cache_free_space(fs_info, 3536 ret = btrfs_check_trunc_cache_free_space(fs_info,
3537 &fs_info->global_block_rsv); 3537 &fs_info->global_block_rsv);