mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-18 17:54:13 +08:00
Btrfs: cleanup reserved space when freeing tree log on error
On error we will wait and free the tree log at unmount without a transaction. This means that the actual freeing of the blocks doesn't happen which means we complain about space leaks on unmount. So to fix this just skip the transaction specific cleanup part of the tree log free'ing if we don't have a transaction and that way we can free up our reserved space and our counters stay happy. Thanks, Signed-off-by: Josef Bacik <jbacik@fusionio.com> Signed-off-by: Chris Mason <chris.mason@fusionio.com>
This commit is contained in:
parent
eb58bb371a
commit
681ae50917
@ -2151,11 +2151,13 @@ static noinline int walk_down_log_tree(struct btrfs_trans_handle *trans,
|
||||
return ret;
|
||||
}
|
||||
|
||||
btrfs_tree_lock(next);
|
||||
btrfs_set_lock_blocking(next);
|
||||
clean_tree_block(trans, root, next);
|
||||
btrfs_wait_tree_block_writeback(next);
|
||||
btrfs_tree_unlock(next);
|
||||
if (trans) {
|
||||
btrfs_tree_lock(next);
|
||||
btrfs_set_lock_blocking(next);
|
||||
clean_tree_block(trans, root, next);
|
||||
btrfs_wait_tree_block_writeback(next);
|
||||
btrfs_tree_unlock(next);
|
||||
}
|
||||
|
||||
WARN_ON(root_owner !=
|
||||
BTRFS_TREE_LOG_OBJECTID);
|
||||
@ -2227,11 +2229,13 @@ static noinline int walk_up_log_tree(struct btrfs_trans_handle *trans,
|
||||
|
||||
next = path->nodes[*level];
|
||||
|
||||
btrfs_tree_lock(next);
|
||||
btrfs_set_lock_blocking(next);
|
||||
clean_tree_block(trans, root, next);
|
||||
btrfs_wait_tree_block_writeback(next);
|
||||
btrfs_tree_unlock(next);
|
||||
if (trans) {
|
||||
btrfs_tree_lock(next);
|
||||
btrfs_set_lock_blocking(next);
|
||||
clean_tree_block(trans, root, next);
|
||||
btrfs_wait_tree_block_writeback(next);
|
||||
btrfs_tree_unlock(next);
|
||||
}
|
||||
|
||||
WARN_ON(root_owner != BTRFS_TREE_LOG_OBJECTID);
|
||||
ret = btrfs_free_and_pin_reserved_extent(root,
|
||||
@ -2301,11 +2305,13 @@ static int walk_log_tree(struct btrfs_trans_handle *trans,
|
||||
|
||||
next = path->nodes[orig_level];
|
||||
|
||||
btrfs_tree_lock(next);
|
||||
btrfs_set_lock_blocking(next);
|
||||
clean_tree_block(trans, log, next);
|
||||
btrfs_wait_tree_block_writeback(next);
|
||||
btrfs_tree_unlock(next);
|
||||
if (trans) {
|
||||
btrfs_tree_lock(next);
|
||||
btrfs_set_lock_blocking(next);
|
||||
clean_tree_block(trans, log, next);
|
||||
btrfs_wait_tree_block_writeback(next);
|
||||
btrfs_tree_unlock(next);
|
||||
}
|
||||
|
||||
WARN_ON(log->root_key.objectid !=
|
||||
BTRFS_TREE_LOG_OBJECTID);
|
||||
@ -2608,13 +2614,10 @@ static void free_log_tree(struct btrfs_trans_handle *trans,
|
||||
.process_func = process_one_buffer
|
||||
};
|
||||
|
||||
if (trans) {
|
||||
ret = walk_log_tree(trans, log, &wc);
|
||||
|
||||
/* I don't think this can happen but just in case */
|
||||
if (ret)
|
||||
btrfs_abort_transaction(trans, log, ret);
|
||||
}
|
||||
ret = walk_log_tree(trans, log, &wc);
|
||||
/* I don't think this can happen but just in case */
|
||||
if (ret)
|
||||
btrfs_abort_transaction(trans, log, ret);
|
||||
|
||||
while (1) {
|
||||
ret = find_first_extent_bit(&log->dirty_log_pages,
|
||||
|
Loading…
Reference in New Issue
Block a user