aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs
diff options
context:
space:
mode:
Diffstat (limited to 'fs/btrfs')
-rw-r--r--fs/btrfs/delayed-inode.c22
-rw-r--r--fs/btrfs/delayed-inode.h2
-rw-r--r--fs/btrfs/extent-tree.c97
3 files changed, 83 insertions, 38 deletions
diff --git a/fs/btrfs/delayed-inode.c b/fs/btrfs/delayed-inode.c
index 2399f4086915..21d91a8073ee 100644
--- a/fs/btrfs/delayed-inode.c
+++ b/fs/btrfs/delayed-inode.c
@@ -1113,8 +1113,8 @@ static int btrfs_update_delayed_inode(struct btrfs_trans_handle *trans,
1113 * Returns < 0 on error and returns with an aborted transaction with any 1113 * Returns < 0 on error and returns with an aborted transaction with any
1114 * outstanding delayed items cleaned up. 1114 * outstanding delayed items cleaned up.
1115 */ 1115 */
1116int btrfs_run_delayed_items(struct btrfs_trans_handle *trans, 1116static int __btrfs_run_delayed_items(struct btrfs_trans_handle *trans,
1117 struct btrfs_root *root) 1117 struct btrfs_root *root, int nr)
1118{ 1118{
1119 struct btrfs_root *curr_root = root; 1119 struct btrfs_root *curr_root = root;
1120 struct btrfs_delayed_root *delayed_root; 1120 struct btrfs_delayed_root *delayed_root;
@@ -1122,6 +1122,7 @@ int btrfs_run_delayed_items(struct btrfs_trans_handle *trans,
1122 struct btrfs_path *path; 1122 struct btrfs_path *path;
1123 struct btrfs_block_rsv *block_rsv; 1123 struct btrfs_block_rsv *block_rsv;
1124 int ret = 0; 1124 int ret = 0;
1125 bool count = (nr > 0);
1125 1126
1126 if (trans->aborted) 1127 if (trans->aborted)
1127 return -EIO; 1128 return -EIO;
@@ -1137,7 +1138,7 @@ int btrfs_run_delayed_items(struct btrfs_trans_handle *trans,
1137 delayed_root = btrfs_get_delayed_root(root); 1138 delayed_root = btrfs_get_delayed_root(root);
1138 1139
1139 curr_node = btrfs_first_delayed_node(delayed_root); 1140 curr_node = btrfs_first_delayed_node(delayed_root);
1140 while (curr_node) { 1141 while (curr_node && (!count || (count && nr--))) {
1141 curr_root = curr_node->root; 1142 curr_root = curr_node->root;
1142 ret = btrfs_insert_delayed_items(trans, path, curr_root, 1143 ret = btrfs_insert_delayed_items(trans, path, curr_root,
1143 curr_node); 1144 curr_node);
@@ -1149,6 +1150,7 @@ int btrfs_run_delayed_items(struct btrfs_trans_handle *trans,
1149 path, curr_node); 1150 path, curr_node);
1150 if (ret) { 1151 if (ret) {
1151 btrfs_release_delayed_node(curr_node); 1152 btrfs_release_delayed_node(curr_node);
1153 curr_node = NULL;
1152 btrfs_abort_transaction(trans, root, ret); 1154 btrfs_abort_transaction(trans, root, ret);
1153 break; 1155 break;
1154 } 1156 }
@@ -1158,12 +1160,26 @@ int btrfs_run_delayed_items(struct btrfs_trans_handle *trans,
1158 btrfs_release_delayed_node(prev_node); 1160 btrfs_release_delayed_node(prev_node);
1159 } 1161 }
1160 1162
1163 if (curr_node)
1164 btrfs_release_delayed_node(curr_node);
1161 btrfs_free_path(path); 1165 btrfs_free_path(path);
1162 trans->block_rsv = block_rsv; 1166 trans->block_rsv = block_rsv;
1163 1167
1164 return ret; 1168 return ret;
1165} 1169}
1166 1170
1171int btrfs_run_delayed_items(struct btrfs_trans_handle *trans,
1172 struct btrfs_root *root)
1173{
1174 return __btrfs_run_delayed_items(trans, root, -1);
1175}
1176
1177int btrfs_run_delayed_items_nr(struct btrfs_trans_handle *trans,
1178 struct btrfs_root *root, int nr)
1179{
1180 return __btrfs_run_delayed_items(trans, root, nr);
1181}
1182
1167static int __btrfs_commit_inode_delayed_items(struct btrfs_trans_handle *trans, 1183static int __btrfs_commit_inode_delayed_items(struct btrfs_trans_handle *trans,
1168 struct btrfs_delayed_node *node) 1184 struct btrfs_delayed_node *node)
1169{ 1185{
diff --git a/fs/btrfs/delayed-inode.h b/fs/btrfs/delayed-inode.h
index f5aa4023d3e1..4f808e1baeed 100644
--- a/fs/btrfs/delayed-inode.h
+++ b/fs/btrfs/delayed-inode.h
@@ -107,6 +107,8 @@ int btrfs_inode_delayed_dir_index_count(struct inode *inode);
107 107
108int btrfs_run_delayed_items(struct btrfs_trans_handle *trans, 108int btrfs_run_delayed_items(struct btrfs_trans_handle *trans,
109 struct btrfs_root *root); 109 struct btrfs_root *root);
110int btrfs_run_delayed_items_nr(struct btrfs_trans_handle *trans,
111 struct btrfs_root *root, int nr);
110 112
111void btrfs_balance_delayed_items(struct btrfs_root *root); 113void btrfs_balance_delayed_items(struct btrfs_root *root);
112 114
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index 6e1d36702ff7..3cde907a25a5 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -3728,6 +3728,60 @@ commit:
3728 return btrfs_commit_transaction(trans, root); 3728 return btrfs_commit_transaction(trans, root);
3729} 3729}
3730 3730
3731enum flush_state {
3732 FLUSH_DELALLOC = 1,
3733 FLUSH_DELALLOC_WAIT = 2,
3734 FLUSH_DELAYED_ITEMS_NR = 3,
3735 FLUSH_DELAYED_ITEMS = 4,
3736 COMMIT_TRANS = 5,
3737};
3738
3739static int flush_space(struct btrfs_root *root,
3740 struct btrfs_space_info *space_info, u64 num_bytes,
3741 u64 orig_bytes, int state)
3742{
3743 struct btrfs_trans_handle *trans;
3744 int nr;
3745 int ret;
3746
3747 switch (state) {
3748 case FLUSH_DELALLOC:
3749 case FLUSH_DELALLOC_WAIT:
3750 ret = shrink_delalloc(root, num_bytes,
3751 state == FLUSH_DELALLOC_WAIT);
3752 if (ret > 0)
3753 ret = 0;
3754 break;
3755 case FLUSH_DELAYED_ITEMS_NR:
3756 case FLUSH_DELAYED_ITEMS:
3757 if (state == FLUSH_DELAYED_ITEMS_NR) {
3758 u64 bytes = btrfs_calc_trans_metadata_size(root, 1);
3759
3760 nr = (int)div64_u64(num_bytes, bytes);
3761 if (!nr)
3762 nr = 1;
3763 nr *= 2;
3764 } else {
3765 nr = -1;
3766 }
3767 trans = btrfs_join_transaction(root);
3768 if (IS_ERR(trans)) {
3769 ret = PTR_ERR(trans);
3770 break;
3771 }
3772 ret = btrfs_run_delayed_items_nr(trans, root, nr);
3773 btrfs_end_transaction(trans, root);
3774 break;
3775 case COMMIT_TRANS:
3776 ret = may_commit_transaction(root, space_info, orig_bytes, 0);
3777 break;
3778 default:
3779 ret = -ENOSPC;
3780 break;
3781 }
3782
3783 return ret;
3784}
3731/** 3785/**
3732 * reserve_metadata_bytes - try to reserve bytes from the block_rsv's space 3786 * reserve_metadata_bytes - try to reserve bytes from the block_rsv's space
3733 * @root - the root we're allocating for 3787 * @root - the root we're allocating for
@@ -3749,11 +3803,10 @@ static int reserve_metadata_bytes(struct btrfs_root *root,
3749 struct btrfs_space_info *space_info = block_rsv->space_info; 3803 struct btrfs_space_info *space_info = block_rsv->space_info;
3750 u64 used; 3804 u64 used;
3751 u64 num_bytes = orig_bytes; 3805 u64 num_bytes = orig_bytes;
3752 int retries = 0; 3806 int flush_state = FLUSH_DELALLOC;
3753 int ret = 0; 3807 int ret = 0;
3754 bool committed = false;
3755 bool flushing = false; 3808 bool flushing = false;
3756 bool wait_ordered = false; 3809 bool committed = false;
3757 3810
3758again: 3811again:
3759 ret = 0; 3812 ret = 0;
@@ -3812,9 +3865,8 @@ again:
3812 * amount plus the amount of bytes that we need for this 3865 * amount plus the amount of bytes that we need for this
3813 * reservation. 3866 * reservation.
3814 */ 3867 */
3815 wait_ordered = true;
3816 num_bytes = used - space_info->total_bytes + 3868 num_bytes = used - space_info->total_bytes +
3817 (orig_bytes * (retries + 1)); 3869 (orig_bytes * 2);
3818 } 3870 }
3819 3871
3820 if (ret) { 3872 if (ret) {
@@ -3867,8 +3919,6 @@ again:
3867 trace_btrfs_space_reservation(root->fs_info, 3919 trace_btrfs_space_reservation(root->fs_info,
3868 "space_info", space_info->flags, orig_bytes, 1); 3920 "space_info", space_info->flags, orig_bytes, 1);
3869 ret = 0; 3921 ret = 0;
3870 } else {
3871 wait_ordered = true;
3872 } 3922 }
3873 } 3923 }
3874 3924
@@ -3887,36 +3937,13 @@ again:
3887 if (!ret || !flush) 3937 if (!ret || !flush)
3888 goto out; 3938 goto out;
3889 3939
3890 /* 3940 ret = flush_space(root, space_info, num_bytes, orig_bytes,
3891 * We do synchronous shrinking since we don't actually unreserve 3941 flush_state);
3892 * metadata until after the IO is completed. 3942 flush_state++;
3893 */ 3943 if (!ret)
3894 ret = shrink_delalloc(root, num_bytes, wait_ordered);
3895 if (ret < 0)
3896 goto out;
3897
3898 ret = 0;
3899
3900 /*
3901 * So if we were overcommitted it's possible that somebody else flushed
3902 * out enough space and we simply didn't have enough space to reclaim,
3903 * so go back around and try again.
3904 */
3905 if (retries < 2) {
3906 wait_ordered = true;
3907 retries++;
3908 goto again; 3944 goto again;
3909 } 3945 else if (flush_state <= COMMIT_TRANS)
3910
3911 ret = -ENOSPC;
3912 if (committed)
3913 goto out;
3914
3915 ret = may_commit_transaction(root, space_info, orig_bytes, 0);
3916 if (!ret) {
3917 committed = true;
3918 goto again; 3946 goto again;
3919 }
3920 3947
3921out: 3948out:
3922 if (flushing) { 3949 if (flushing) {