diff options
Diffstat (limited to 'fs/btrfs/extent-tree.c')
-rw-r--r-- | fs/btrfs/extent-tree.c | 31 |
1 files changed, 27 insertions, 4 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 0ec8e228b89f..7effed6f2fa6 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
@@ -3180,8 +3180,6 @@ static int write_one_cache_group(struct btrfs_trans_handle *trans, | |||
3180 | btrfs_mark_buffer_dirty(leaf); | 3180 | btrfs_mark_buffer_dirty(leaf); |
3181 | fail: | 3181 | fail: |
3182 | btrfs_release_path(path); | 3182 | btrfs_release_path(path); |
3183 | if (ret) | ||
3184 | btrfs_abort_transaction(trans, root, ret); | ||
3185 | return ret; | 3183 | return ret; |
3186 | 3184 | ||
3187 | } | 3185 | } |
@@ -3487,8 +3485,30 @@ again: | |||
3487 | ret = 0; | 3485 | ret = 0; |
3488 | } | 3486 | } |
3489 | } | 3487 | } |
3490 | if (!ret) | 3488 | if (!ret) { |
3491 | ret = write_one_cache_group(trans, root, path, cache); | 3489 | ret = write_one_cache_group(trans, root, path, cache); |
3490 | /* | ||
3491 | * Our block group might still be attached to the list | ||
3492 | * of new block groups in the transaction handle of some | ||
3493 | * other task (struct btrfs_trans_handle->new_bgs). This | ||
3494 | * means its block group item isn't yet in the extent | ||
3495 | * tree. If this happens ignore the error, as we will | ||
3496 | * try again later in the critical section of the | ||
3497 | * transaction commit. | ||
3498 | */ | ||
3499 | if (ret == -ENOENT) { | ||
3500 | ret = 0; | ||
3501 | spin_lock(&cur_trans->dirty_bgs_lock); | ||
3502 | if (list_empty(&cache->dirty_list)) { | ||
3503 | list_add_tail(&cache->dirty_list, | ||
3504 | &cur_trans->dirty_bgs); | ||
3505 | btrfs_get_block_group(cache); | ||
3506 | } | ||
3507 | spin_unlock(&cur_trans->dirty_bgs_lock); | ||
3508 | } else if (ret) { | ||
3509 | btrfs_abort_transaction(trans, root, ret); | ||
3510 | } | ||
3511 | } | ||
3492 | 3512 | ||
3493 | /* if its not on the io list, we need to put the block group */ | 3513 | /* if its not on the io list, we need to put the block group */ |
3494 | if (should_put) | 3514 | if (should_put) |
@@ -3597,8 +3617,11 @@ int btrfs_write_dirty_block_groups(struct btrfs_trans_handle *trans, | |||
3597 | ret = 0; | 3617 | ret = 0; |
3598 | } | 3618 | } |
3599 | } | 3619 | } |
3600 | if (!ret) | 3620 | if (!ret) { |
3601 | ret = write_one_cache_group(trans, root, path, cache); | 3621 | ret = write_one_cache_group(trans, root, path, cache); |
3622 | if (ret) | ||
3623 | btrfs_abort_transaction(trans, root, ret); | ||
3624 | } | ||
3602 | 3625 | ||
3603 | /* if its not on the io list, we need to put the block group */ | 3626 | /* if its not on the io list, we need to put the block group */ |
3604 | if (should_put) | 3627 | if (should_put) |