aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/inode.c
diff options
context:
space:
mode:
authorJosef Bacik <jbacik@fusionio.com>2012-08-27 17:48:15 -0400
committerChris Mason <chris.mason@fusionio.com>2012-10-01 15:19:04 -0400
commitca7e70f59078046db28501519308c2061b0e7a6f (patch)
tree9685496d94625bc732e029f2a21f049506bf8618 /fs/btrfs/inode.c
parent06d3d22b456c2f87aeb1eb4517eeabb47e21fcc9 (diff)
Btrfs: do not needlessly restart the transaction for enospc
We will stop and restart a transaction every time we move to a different leaf when truncating a file. This is for enospc reasons, but really we could probably get away with doing this a little better by actually working until we hit an ENOSPC. So add a ->failfast flag to the block_rsv and set it when we do truncates which will fail as soon as the block rsv runs out of space, and then at that point we can stop and restart the transaction and refill the block rsv and carry on. This will make rm'ing of a file with lots of extents a bit faster. Thanks, Signed-off-by: Josef Bacik <jbacik@fusionio.com>
Diffstat (limited to 'fs/btrfs/inode.c')
-rw-r--r--fs/btrfs/inode.c53
1 files changed, 18 insertions, 35 deletions
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 1b99fe8a129d..ca4fa05171ab 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -3448,12 +3448,6 @@ delete:
3448 3448
3449 if (path->slots[0] == 0 || 3449 if (path->slots[0] == 0 ||
3450 path->slots[0] != pending_del_slot) { 3450 path->slots[0] != pending_del_slot) {
3451 if (root->ref_cows &&
3452 BTRFS_I(inode)->location.objectid !=
3453 BTRFS_FREE_INO_OBJECTID) {
3454 err = -EAGAIN;
3455 goto out;
3456 }
3457 if (pending_del_nr) { 3451 if (pending_del_nr) {
3458 ret = btrfs_del_items(trans, root, path, 3452 ret = btrfs_del_items(trans, root, path,
3459 pending_del_slot, 3453 pending_del_slot,
@@ -3826,6 +3820,7 @@ void btrfs_evict_inode(struct inode *inode)
3826 goto no_delete; 3820 goto no_delete;
3827 } 3821 }
3828 rsv->size = min_size; 3822 rsv->size = min_size;
3823 rsv->failfast = 1;
3829 global_rsv = &root->fs_info->global_block_rsv; 3824 global_rsv = &root->fs_info->global_block_rsv;
3830 3825
3831 btrfs_i_size_write(inode, 0); 3826 btrfs_i_size_write(inode, 0);
@@ -3870,7 +3865,7 @@ void btrfs_evict_inode(struct inode *inode)
3870 trans->block_rsv = rsv; 3865 trans->block_rsv = rsv;
3871 3866
3872 ret = btrfs_truncate_inode_items(trans, root, inode, 0, 0); 3867 ret = btrfs_truncate_inode_items(trans, root, inode, 0, 0);
3873 if (ret != -EAGAIN) 3868 if (ret != -ENOSPC)
3874 break; 3869 break;
3875 3870
3876 nr = trans->blocks_used; 3871 nr = trans->blocks_used;
@@ -6852,6 +6847,7 @@ static int btrfs_truncate(struct inode *inode)
6852 if (!rsv) 6847 if (!rsv)
6853 return -ENOMEM; 6848 return -ENOMEM;
6854 rsv->size = min_size; 6849 rsv->size = min_size;
6850 rsv->failfast = 1;
6855 6851
6856 /* 6852 /*
6857 * 1 for the truncate slack space 6853 * 1 for the truncate slack space
@@ -6905,37 +6901,13 @@ static int btrfs_truncate(struct inode *inode)
6905 * safe. 6901 * safe.
6906 */ 6902 */
6907 set_bit(BTRFS_INODE_NEEDS_FULL_SYNC, &BTRFS_I(inode)->runtime_flags); 6903 set_bit(BTRFS_INODE_NEEDS_FULL_SYNC, &BTRFS_I(inode)->runtime_flags);
6904 trans->block_rsv = rsv;
6908 6905
6909 while (1) { 6906 while (1) {
6910 ret = btrfs_block_rsv_refill(root, rsv, min_size);
6911 if (ret) {
6912 /*
6913 * This can only happen with the original transaction we
6914 * started above, every other time we shouldn't have a
6915 * transaction started yet.
6916 */
6917 if (ret == -EAGAIN)
6918 goto end_trans;
6919 err = ret;
6920 break;
6921 }
6922
6923 if (!trans) {
6924 /* Just need the 1 for updating the inode */
6925 trans = btrfs_start_transaction(root, 1);
6926 if (IS_ERR(trans)) {
6927 ret = err = PTR_ERR(trans);
6928 trans = NULL;
6929 break;
6930 }
6931 }
6932
6933 trans->block_rsv = rsv;
6934
6935 ret = btrfs_truncate_inode_items(trans, root, inode, 6907 ret = btrfs_truncate_inode_items(trans, root, inode,
6936 inode->i_size, 6908 inode->i_size,
6937 BTRFS_EXTENT_DATA_KEY); 6909 BTRFS_EXTENT_DATA_KEY);
6938 if (ret != -EAGAIN) { 6910 if (ret != -ENOSPC) {
6939 err = ret; 6911 err = ret;
6940 break; 6912 break;
6941 } 6913 }
@@ -6946,11 +6918,22 @@ static int btrfs_truncate(struct inode *inode)
6946 err = ret; 6918 err = ret;
6947 break; 6919 break;
6948 } 6920 }
6949end_trans: 6921
6950 nr = trans->blocks_used; 6922 nr = trans->blocks_used;
6951 btrfs_end_transaction(trans, root); 6923 btrfs_end_transaction(trans, root);
6952 trans = NULL;
6953 btrfs_btree_balance_dirty(root, nr); 6924 btrfs_btree_balance_dirty(root, nr);
6925
6926 trans = btrfs_start_transaction(root, 2);
6927 if (IS_ERR(trans)) {
6928 ret = err = PTR_ERR(trans);
6929 trans = NULL;
6930 break;
6931 }
6932
6933 ret = btrfs_block_rsv_migrate(&root->fs_info->trans_block_rsv,
6934 rsv, min_size);
6935 BUG_ON(ret); /* shouldn't happen */
6936 trans->block_rsv = rsv;
6954 } 6937 }
6955 6938
6956 if (ret == 0 && inode->i_nlink > 0) { 6939 if (ret == 0 && inode->i_nlink > 0) {