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) |
