aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/extent-tree.c
diff options
context:
space:
mode:
authorJosef Bacik <josef@redhat.com>2011-05-03 10:40:22 -0400
committerJosef Bacik <josef@redhat.com>2011-05-23 13:03:08 -0400
commitfcb80c2affd63237cff5b34cba5756be7c976a5a (patch)
tree49c37dce49ebd9a1ada939d1fd2cfa57bba6f500 /fs/btrfs/extent-tree.c
parenta4abeea41adfa3c143c289045f4625dfaeba2212 (diff)
Btrfs: fix how we do space reservation for truncate
The ceph guys keep running into problems where we have space reserved in our orphan block rsv when freeing it up. This is because they tend to do snapshots alot, so their truncates tend to use a bunch of space, so when we go to do things like update the inode we have to steal reservation space in order to make the reservation happen. This happens because truncate can use as much space as it freaking feels like, but we still have to hold space for removing the orphan item and updating the inode, which will definitely always happen. So in order to fix this we need to split all of the reservation stuf up. So with this patch we have 1) The orphan block reserve which only holds the space for deleting our orphan item when everything is over. 2) The truncate block reserve which gets allocated and used specifically for the space that the truncate will use on a per truncate basis. 3) The transaction will always have 1 item's worth of data reserved so we can update the inode normally. Hopefully this will make the ceph problem go away. Thanks, Signed-off-by: Josef Bacik <josef@redhat.com>
Diffstat (limited to 'fs/btrfs/extent-tree.c')
-rw-r--r--fs/btrfs/extent-tree.c46
1 files changed, 36 insertions, 10 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index ca599654ce19..a2ca561c70f0 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -3980,6 +3980,37 @@ static u64 calc_trans_metadata_size(struct btrfs_root *root, int num_items)
3980 3 * num_items; 3980 3 * num_items;
3981} 3981}
3982 3982
3983int btrfs_truncate_reserve_metadata(struct btrfs_trans_handle *trans,
3984 struct btrfs_root *root,
3985 struct btrfs_block_rsv *rsv)
3986{
3987 struct btrfs_block_rsv *trans_rsv = &root->fs_info->trans_block_rsv;
3988 u64 num_bytes;
3989 int ret;
3990
3991 /*
3992 * Truncate should be freeing data, but give us 2 items just in case it
3993 * needs to use some space. We may want to be smarter about this in the
3994 * future.
3995 */
3996 num_bytes = calc_trans_metadata_size(root, 2);
3997
3998 /* We already have enough bytes, just return */
3999 if (rsv->reserved >= num_bytes)
4000 return 0;
4001
4002 num_bytes -= rsv->reserved;
4003
4004 /*
4005 * You should have reserved enough space before hand to do this, so this
4006 * should not fail.
4007 */
4008 ret = block_rsv_migrate_bytes(trans_rsv, rsv, num_bytes);
4009 BUG_ON(ret);
4010
4011 return 0;
4012}
4013
3983int btrfs_trans_reserve_metadata(struct btrfs_trans_handle *trans, 4014int btrfs_trans_reserve_metadata(struct btrfs_trans_handle *trans,
3984 struct btrfs_root *root, 4015 struct btrfs_root *root,
3985 int num_items) 4016 int num_items)
@@ -4020,23 +4051,18 @@ int btrfs_orphan_reserve_metadata(struct btrfs_trans_handle *trans,
4020 struct btrfs_block_rsv *dst_rsv = root->orphan_block_rsv; 4051 struct btrfs_block_rsv *dst_rsv = root->orphan_block_rsv;
4021 4052
4022 /* 4053 /*
4023 * one for deleting orphan item, one for updating inode and 4054 * We need to hold space in order to delete our orphan item once we've
4024 * two for calling btrfs_truncate_inode_items. 4055 * added it, so this takes the reservation so we can release it later
4025 * 4056 * when we are truly done with the orphan item.
4026 * btrfs_truncate_inode_items is a delete operation, it frees
4027 * more space than it uses in most cases. So two units of
4028 * metadata space should be enough for calling it many times.
4029 * If all of the metadata space is used, we can commit
4030 * transaction and use space it freed.
4031 */ 4057 */
4032 u64 num_bytes = calc_trans_metadata_size(root, 4); 4058 u64 num_bytes = calc_trans_metadata_size(root, 1);
4033 return block_rsv_migrate_bytes(src_rsv, dst_rsv, num_bytes); 4059 return block_rsv_migrate_bytes(src_rsv, dst_rsv, num_bytes);
4034} 4060}
4035 4061
4036void btrfs_orphan_release_metadata(struct inode *inode) 4062void btrfs_orphan_release_metadata(struct inode *inode)
4037{ 4063{
4038 struct btrfs_root *root = BTRFS_I(inode)->root; 4064 struct btrfs_root *root = BTRFS_I(inode)->root;
4039 u64 num_bytes = calc_trans_metadata_size(root, 4); 4065 u64 num_bytes = calc_trans_metadata_size(root, 1);
4040 btrfs_block_rsv_release(root, root->orphan_block_rsv, num_bytes); 4066 btrfs_block_rsv_release(root, root->orphan_block_rsv, num_bytes);
4041} 4067}
4042 4068