aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/btrfs/ctree.h3
-rw-r--r--fs/btrfs/delayed-inode.c36
-rw-r--r--fs/btrfs/extent-tree.c18
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,
2353int btrfs_block_rsv_add(struct btrfs_root *root, 2353int 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);
2356int btrfs_block_rsv_add_noflush(struct btrfs_root *root,
2357 struct btrfs_block_rsv *block_rsv,
2358 u64 num_bytes);
2356int btrfs_block_rsv_check(struct btrfs_root *root, 2359int 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);
2358int btrfs_block_rsv_refill(struct btrfs_root *root, 2361int 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
3817int 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
3817int btrfs_block_rsv_check(struct btrfs_root *root, 3835int 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{