diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/btrfs/ctree.h | 3 | ||||
-rw-r--r-- | fs/btrfs/delayed-inode.c | 36 | ||||
-rw-r--r-- | fs/btrfs/extent-tree.c | 18 |
3 files changed, 49 insertions, 8 deletions
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index 3002e5d4da0b..6bb34fc1ff22 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h | |||
@@ -2353,6 +2353,9 @@ void btrfs_free_block_rsv(struct btrfs_root *root, | |||
2353 | int btrfs_block_rsv_add(struct btrfs_root *root, | 2353 | int btrfs_block_rsv_add(struct btrfs_root *root, |
2354 | struct btrfs_block_rsv *block_rsv, | 2354 | struct btrfs_block_rsv *block_rsv, |
2355 | u64 num_bytes); | 2355 | u64 num_bytes); |
2356 | int btrfs_block_rsv_add_noflush(struct btrfs_root *root, | ||
2357 | struct btrfs_block_rsv *block_rsv, | ||
2358 | u64 num_bytes); | ||
2356 | int btrfs_block_rsv_check(struct btrfs_root *root, | 2359 | int btrfs_block_rsv_check(struct btrfs_root *root, |
2357 | struct btrfs_block_rsv *block_rsv, int min_factor); | 2360 | struct btrfs_block_rsv *block_rsv, int min_factor); |
2358 | int btrfs_block_rsv_refill(struct btrfs_root *root, | 2361 | int btrfs_block_rsv_refill(struct btrfs_root *root, |
diff --git a/fs/btrfs/delayed-inode.c b/fs/btrfs/delayed-inode.c index fc4026af7290..bbe8496d5339 100644 --- a/fs/btrfs/delayed-inode.c +++ b/fs/btrfs/delayed-inode.c | |||
@@ -624,13 +624,36 @@ static int btrfs_delayed_inode_reserve_metadata( | |||
624 | u64 num_bytes; | 624 | u64 num_bytes; |
625 | int ret; | 625 | int ret; |
626 | 626 | ||
627 | if (!trans->bytes_reserved) | ||
628 | return 0; | ||
629 | |||
630 | src_rsv = trans->block_rsv; | 627 | src_rsv = trans->block_rsv; |
631 | dst_rsv = &root->fs_info->delayed_block_rsv; | 628 | dst_rsv = &root->fs_info->delayed_block_rsv; |
632 | 629 | ||
633 | num_bytes = btrfs_calc_trans_metadata_size(root, 1); | 630 | num_bytes = btrfs_calc_trans_metadata_size(root, 1); |
631 | |||
632 | /* | ||
633 | * btrfs_dirty_inode will update the inode under btrfs_join_transaction | ||
634 | * which doesn't reserve space for speed. This is a problem since we | ||
635 | * still need to reserve space for this update, so try to reserve the | ||
636 | * space. | ||
637 | * | ||
638 | * Now if src_rsv == delalloc_block_rsv we'll let it just steal since | ||
639 | * we're accounted for. | ||
640 | */ | ||
641 | if (!trans->bytes_reserved && | ||
642 | src_rsv != &root->fs_info->delalloc_block_rsv) { | ||
643 | ret = btrfs_block_rsv_add_noflush(root, dst_rsv, num_bytes); | ||
644 | /* | ||
645 | * Since we're under a transaction reserve_metadata_bytes could | ||
646 | * try to commit the transaction which will make it return | ||
647 | * EAGAIN to make us stop the transaction we have, so return | ||
648 | * ENOSPC instead so that btrfs_dirty_inode knows what to do. | ||
649 | */ | ||
650 | if (ret == -EAGAIN) | ||
651 | ret = -ENOSPC; | ||
652 | if (!ret) | ||
653 | node->bytes_reserved = num_bytes; | ||
654 | return ret; | ||
655 | } | ||
656 | |||
634 | ret = btrfs_block_rsv_migrate(src_rsv, dst_rsv, num_bytes); | 657 | ret = btrfs_block_rsv_migrate(src_rsv, dst_rsv, num_bytes); |
635 | if (!ret) | 658 | if (!ret) |
636 | node->bytes_reserved = num_bytes; | 659 | node->bytes_reserved = num_bytes; |
@@ -1686,11 +1709,8 @@ int btrfs_delayed_update_inode(struct btrfs_trans_handle *trans, | |||
1686 | } | 1709 | } |
1687 | 1710 | ||
1688 | ret = btrfs_delayed_inode_reserve_metadata(trans, root, delayed_node); | 1711 | ret = btrfs_delayed_inode_reserve_metadata(trans, root, delayed_node); |
1689 | /* | 1712 | if (ret) |
1690 | * we must reserve enough space when we start a new transaction, | 1713 | goto release_node; |
1691 | * so reserving metadata failure is impossible | ||
1692 | */ | ||
1693 | BUG_ON(ret); | ||
1694 | 1714 | ||
1695 | fill_stack_inode_item(trans, &delayed_node->inode_item, inode); | 1715 | fill_stack_inode_item(trans, &delayed_node->inode_item, inode); |
1696 | delayed_node->inode_dirty = 1; | 1716 | delayed_node->inode_dirty = 1; |
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 5b84205e7685..23e936c3de76 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
@@ -3814,6 +3814,24 @@ int btrfs_block_rsv_add(struct btrfs_root *root, | |||
3814 | return ret; | 3814 | return ret; |
3815 | } | 3815 | } |
3816 | 3816 | ||
3817 | int btrfs_block_rsv_add_noflush(struct btrfs_root *root, | ||
3818 | struct btrfs_block_rsv *block_rsv, | ||
3819 | u64 num_bytes) | ||
3820 | { | ||
3821 | int ret; | ||
3822 | |||
3823 | if (num_bytes == 0) | ||
3824 | return 0; | ||
3825 | |||
3826 | ret = reserve_metadata_bytes(root, block_rsv, num_bytes, 0); | ||
3827 | if (!ret) { | ||
3828 | block_rsv_add_bytes(block_rsv, num_bytes, 1); | ||
3829 | return 0; | ||
3830 | } | ||
3831 | |||
3832 | return ret; | ||
3833 | } | ||
3834 | |||
3817 | int btrfs_block_rsv_check(struct btrfs_root *root, | 3835 | int btrfs_block_rsv_check(struct btrfs_root *root, |
3818 | struct btrfs_block_rsv *block_rsv, int min_factor) | 3836 | struct btrfs_block_rsv *block_rsv, int min_factor) |
3819 | { | 3837 | { |