forked from luck/tmp_suning_uos_patched
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>
This commit is contained in:
parent
e3b8a48585
commit
8e138e0d92
|
@ -3502,13 +3502,6 @@ static int cache_save_setup(struct btrfs_block_group_cache *block_group,
|
||||||
goto again;
|
goto again;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We've already setup this transaction, go ahead and exit */
|
|
||||||
if (block_group->cache_generation == trans->transid &&
|
|
||||||
i_size_read(inode)) {
|
|
||||||
dcs = BTRFS_DC_SETUP;
|
|
||||||
goto out_put;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We want to set the generation to 0, that way if anything goes wrong
|
* We want to set the generation to 0, that way if anything goes wrong
|
||||||
* from here on out we know not to trust this cache when we load up next
|
* from here on out we know not to trust this cache when we load up next
|
||||||
|
@ -3532,6 +3525,13 @@ static int cache_save_setup(struct btrfs_block_group_cache *block_group,
|
||||||
}
|
}
|
||||||
WARN_ON(ret);
|
WARN_ON(ret);
|
||||||
|
|
||||||
|
/* We've already setup this transaction, go ahead and exit */
|
||||||
|
if (block_group->cache_generation == trans->transid &&
|
||||||
|
i_size_read(inode)) {
|
||||||
|
dcs = BTRFS_DC_SETUP;
|
||||||
|
goto out_put;
|
||||||
|
}
|
||||||
|
|
||||||
if (i_size_read(inode) > 0) {
|
if (i_size_read(inode) > 0) {
|
||||||
ret = btrfs_check_trunc_cache_free_space(fs_info,
|
ret = btrfs_check_trunc_cache_free_space(fs_info,
|
||||||
&fs_info->global_block_rsv);
|
&fs_info->global_block_rsv);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user