aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/inode.c
diff options
context:
space:
mode:
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) {