diff options
| -rw-r--r-- | fs/btrfs/transaction.c | 27 |
1 files changed, 19 insertions, 8 deletions
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c index f15494699f3b..fc03aa60b684 100644 --- a/fs/btrfs/transaction.c +++ b/fs/btrfs/transaction.c | |||
| @@ -333,12 +333,14 @@ start_transaction(struct btrfs_root *root, u64 num_items, int type, | |||
| 333 | &root->fs_info->trans_block_rsv, | 333 | &root->fs_info->trans_block_rsv, |
| 334 | num_bytes, flush); | 334 | num_bytes, flush); |
| 335 | if (ret) | 335 | if (ret) |
| 336 | return ERR_PTR(ret); | 336 | goto reserve_fail; |
| 337 | } | 337 | } |
| 338 | again: | 338 | again: |
| 339 | h = kmem_cache_alloc(btrfs_trans_handle_cachep, GFP_NOFS); | 339 | h = kmem_cache_alloc(btrfs_trans_handle_cachep, GFP_NOFS); |
| 340 | if (!h) | 340 | if (!h) { |
| 341 | return ERR_PTR(-ENOMEM); | 341 | ret = -ENOMEM; |
| 342 | goto alloc_fail; | ||
| 343 | } | ||
| 342 | 344 | ||
| 343 | /* | 345 | /* |
| 344 | * If we are JOIN_NOLOCK we're already committing a transaction and | 346 | * If we are JOIN_NOLOCK we're already committing a transaction and |
| @@ -365,11 +367,7 @@ again: | |||
| 365 | if (ret < 0) { | 367 | if (ret < 0) { |
| 366 | /* We must get the transaction if we are JOIN_NOLOCK. */ | 368 | /* We must get the transaction if we are JOIN_NOLOCK. */ |
| 367 | BUG_ON(type == TRANS_JOIN_NOLOCK); | 369 | BUG_ON(type == TRANS_JOIN_NOLOCK); |
| 368 | 370 | goto join_fail; | |
| 369 | if (type < TRANS_JOIN_NOLOCK) | ||
| 370 | sb_end_intwrite(root->fs_info->sb); | ||
| 371 | kmem_cache_free(btrfs_trans_handle_cachep, h); | ||
| 372 | return ERR_PTR(ret); | ||
| 373 | } | 371 | } |
| 374 | 372 | ||
| 375 | cur_trans = root->fs_info->running_transaction; | 373 | cur_trans = root->fs_info->running_transaction; |
| @@ -410,6 +408,19 @@ got_it: | |||
| 410 | if (!current->journal_info && type != TRANS_USERSPACE) | 408 | if (!current->journal_info && type != TRANS_USERSPACE) |
| 411 | current->journal_info = h; | 409 | current->journal_info = h; |
| 412 | return h; | 410 | return h; |
| 411 | |||
| 412 | join_fail: | ||
| 413 | if (type < TRANS_JOIN_NOLOCK) | ||
| 414 | sb_end_intwrite(root->fs_info->sb); | ||
| 415 | kmem_cache_free(btrfs_trans_handle_cachep, h); | ||
| 416 | alloc_fail: | ||
| 417 | if (num_bytes) | ||
| 418 | btrfs_block_rsv_release(root, &root->fs_info->trans_block_rsv, | ||
| 419 | num_bytes); | ||
| 420 | reserve_fail: | ||
| 421 | if (qgroup_reserved) | ||
| 422 | btrfs_qgroup_free(root, qgroup_reserved); | ||
| 423 | return ERR_PTR(ret); | ||
| 413 | } | 424 | } |
| 414 | 425 | ||
| 415 | struct btrfs_trans_handle *btrfs_start_transaction(struct btrfs_root *root, | 426 | struct btrfs_trans_handle *btrfs_start_transaction(struct btrfs_root *root, |
