Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs
Pull btrfs fixes from Chris Mason: "Outside of misc fixes, Filipe has a few fsync corners and we're pulling in one more of Josef's fixes from production use here" * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs: Btrfs:__add_inode_ref: out of bounds memory read when looking for extended ref. Btrfs: fix data loss in the fast fsync path Btrfs: remove extra run_delayed_refs in update_cowonly_root Btrfs: incremental send, don't rename a directory too soon btrfs: fix lost return value due to variable shadowing Btrfs: do not ignore errors from btrfs_lookup_xattr in do_setxattr Btrfs: fix off-by-one logic error in btrfs_realloc_node Btrfs: add missing inode update when punching hole Btrfs: abort the transaction if we fail to update the free space cache inode Btrfs: fix fsync race leading to ordered extent memory leaks
This commit is contained in:
@@ -3208,6 +3208,8 @@ static int cache_save_setup(struct btrfs_block_group_cache *block_group,
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (trans->aborted)
|
||||
return 0;
|
||||
again:
|
||||
inode = lookup_free_space_inode(root, block_group, path);
|
||||
if (IS_ERR(inode) && PTR_ERR(inode) != -ENOENT) {
|
||||
@@ -3243,6 +3245,20 @@ again:
|
||||
*/
|
||||
BTRFS_I(inode)->generation = 0;
|
||||
ret = btrfs_update_inode(trans, root, inode);
|
||||
if (ret) {
|
||||
/*
|
||||
* So theoretically we could recover from this, simply set the
|
||||
* super cache generation to 0 so we know to invalidate the
|
||||
* cache, but then we'd have to keep track of the block groups
|
||||
* that fail this way so we know we _have_ to reset this cache
|
||||
* before the next commit or risk reading stale cache. So to
|
||||
* limit our exposure to horrible edge cases lets just abort the
|
||||
* transaction, this only happens in really bad situations
|
||||
* anyway.
|
||||
*/
|
||||
btrfs_abort_transaction(trans, root, ret);
|
||||
goto out_put;
|
||||
}
|
||||
WARN_ON(ret);
|
||||
|
||||
if (i_size_read(inode) > 0) {
|
||||
|
Reference in New Issue
Block a user