aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs
diff options
context:
space:
mode:
authorJosef Bacik <josef@redhat.com>2011-08-19 10:29:59 -0400
committerJosef Bacik <josef@redhat.com>2011-10-19 15:12:37 -0400
commit07127184efb629f1336c0592bfdacec258cab731 (patch)
treec527bfd0444cd9a589278873dd78ef185f66d2fc /fs/btrfs
parent1b9c332b6c92e992b1971a08412c6f460a54b514 (diff)
Btrfs: reduce the amount of space needed for truncates
With btrfs_truncate_inode_items we always return if we have to go to another leaf, which makes us do our reservation again. This means we will only ever modify one leaf at a time, so we only need 1 items worth of slack space. Also, since we are deleting we will not be creating nodes as we go down, if anything we'll be free'ing them as we merge them together, so make a different calculation for truncate which will only have the worst case useage of COW'ing the entire path down to the leaf. Thanks, Signed-off-by: Josef Bacik <josef@redhat.com>
Diffstat (limited to 'fs/btrfs')
-rw-r--r--fs/btrfs/ctree.h11
-rw-r--r--fs/btrfs/inode.c8
2 files changed, 15 insertions, 4 deletions
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index 22a9347a390..2e18b068841 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -2125,6 +2125,17 @@ static inline u64 btrfs_calc_trans_metadata_size(struct btrfs_root *root,
2125 3 * num_items; 2125 3 * num_items;
2126} 2126}
2127 2127
2128/*
2129 * Doing a truncate won't result in new nodes or leaves, just what we need for
2130 * COW.
2131 */
2132static inline u64 btrfs_calc_trunc_metadata_size(struct btrfs_root *root,
2133 unsigned num_items)
2134{
2135 return (root->leafsize + root->nodesize * (BTRFS_MAX_LEVEL - 1)) *
2136 num_items;
2137}
2138
2128void btrfs_put_block_group(struct btrfs_block_group_cache *cache); 2139void btrfs_put_block_group(struct btrfs_block_group_cache *cache);
2129int btrfs_run_delayed_refs(struct btrfs_trans_handle *trans, 2140int btrfs_run_delayed_refs(struct btrfs_trans_handle *trans,
2130 struct btrfs_root *root, unsigned long count); 2141 struct btrfs_root *root, unsigned long count);
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 4d057c084de..8316b570db5 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -3528,7 +3528,7 @@ void btrfs_evict_inode(struct inode *inode)
3528 struct btrfs_trans_handle *trans; 3528 struct btrfs_trans_handle *trans;
3529 struct btrfs_root *root = BTRFS_I(inode)->root; 3529 struct btrfs_root *root = BTRFS_I(inode)->root;
3530 struct btrfs_block_rsv *rsv; 3530 struct btrfs_block_rsv *rsv;
3531 u64 min_size = btrfs_calc_trans_metadata_size(root, 2); 3531 u64 min_size = btrfs_calc_trunc_metadata_size(root, 1);
3532 unsigned long nr; 3532 unsigned long nr;
3533 int ret; 3533 int ret;
3534 3534
@@ -6482,7 +6482,7 @@ static int btrfs_truncate(struct inode *inode)
6482 struct btrfs_trans_handle *trans; 6482 struct btrfs_trans_handle *trans;
6483 unsigned long nr; 6483 unsigned long nr;
6484 u64 mask = root->sectorsize - 1; 6484 u64 mask = root->sectorsize - 1;
6485 u64 min_size = btrfs_calc_trans_metadata_size(root, 2); 6485 u64 min_size = btrfs_calc_trunc_metadata_size(root, 1);
6486 6486
6487 ret = btrfs_truncate_page(inode->i_mapping, inode->i_size); 6487 ret = btrfs_truncate_page(inode->i_mapping, inode->i_size);
6488 if (ret) 6488 if (ret)
@@ -6532,12 +6532,12 @@ static int btrfs_truncate(struct inode *inode)
6532 return -ENOMEM; 6532 return -ENOMEM;
6533 6533
6534 /* 6534 /*
6535 * 2 for the truncate slack space 6535 * 1 for the truncate slack space
6536 * 1 for the orphan item we're going to add 6536 * 1 for the orphan item we're going to add
6537 * 1 for the orphan item deletion 6537 * 1 for the orphan item deletion
6538 * 1 for updating the inode. 6538 * 1 for updating the inode.
6539 */ 6539 */
6540 trans = btrfs_start_transaction(root, 5); 6540 trans = btrfs_start_transaction(root, 4);
6541 if (IS_ERR(trans)) { 6541 if (IS_ERR(trans)) {
6542 err = PTR_ERR(trans); 6542 err = PTR_ERR(trans);
6543 goto out; 6543 goto out;