Skip to content
This repository has been archived by the owner on Sep 24, 2020. It is now read-only.

Commit

Permalink
Btrfs: cleanup reserved space when freeing tree log on error
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Josef Bacik authored and Chris Mason committed Nov 12, 2013
1 parent eb58bb3 commit 681ae50
Showing 1 changed file with 25 additions and 22 deletions.
47 changes: 25 additions & 22 deletions fs/btrfs/tree-log.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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,
Expand Down

0 comments on commit 681ae50

Please sign in to comment.