aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/btrfs/ctree.h3
-rw-r--r--fs/btrfs/extent-tree.c20
-rw-r--r--fs/btrfs/transaction.c36
3 files changed, 17 insertions, 42 deletions
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index 60e13ef23a5e..28e170bcdcb5 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -2223,9 +2223,6 @@ void btrfs_set_inode_space_info(struct btrfs_root *root, struct inode *ionde);
2223void btrfs_clear_space_info_full(struct btrfs_fs_info *info); 2223void btrfs_clear_space_info_full(struct btrfs_fs_info *info);
2224int btrfs_check_data_free_space(struct inode *inode, u64 bytes); 2224int btrfs_check_data_free_space(struct inode *inode, u64 bytes);
2225void btrfs_free_reserved_data_space(struct inode *inode, u64 bytes); 2225void btrfs_free_reserved_data_space(struct inode *inode, u64 bytes);
2226int btrfs_trans_reserve_metadata(struct btrfs_trans_handle *trans,
2227 struct btrfs_root *root,
2228 int num_items);
2229void btrfs_trans_release_metadata(struct btrfs_trans_handle *trans, 2226void btrfs_trans_release_metadata(struct btrfs_trans_handle *trans,
2230 struct btrfs_root *root); 2227 struct btrfs_root *root);
2231int btrfs_orphan_reserve_metadata(struct btrfs_trans_handle *trans, 2228int btrfs_orphan_reserve_metadata(struct btrfs_trans_handle *trans,
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index 71cd456fdb60..0ed5fe03a06a 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -3874,26 +3874,6 @@ int btrfs_truncate_reserve_metadata(struct btrfs_trans_handle *trans,
3874 return 0; 3874 return 0;
3875} 3875}
3876 3876
3877int btrfs_trans_reserve_metadata(struct btrfs_trans_handle *trans,
3878 struct btrfs_root *root,
3879 int num_items)
3880{
3881 u64 num_bytes;
3882 int ret;
3883
3884 if (num_items == 0 || root->fs_info->chunk_root == root)
3885 return 0;
3886
3887 num_bytes = btrfs_calc_trans_metadata_size(root, num_items);
3888 ret = btrfs_block_rsv_add(trans, root, &root->fs_info->trans_block_rsv,
3889 num_bytes);
3890 if (!ret) {
3891 trans->bytes_reserved += num_bytes;
3892 trans->block_rsv = &root->fs_info->trans_block_rsv;
3893 }
3894 return ret;
3895}
3896
3897void btrfs_trans_release_metadata(struct btrfs_trans_handle *trans, 3877void btrfs_trans_release_metadata(struct btrfs_trans_handle *trans,
3898 struct btrfs_root *root) 3878 struct btrfs_root *root)
3899{ 3879{
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c
index 51dcec86757f..654755b18951 100644
--- a/fs/btrfs/transaction.c
+++ b/fs/btrfs/transaction.c
@@ -260,7 +260,7 @@ static struct btrfs_trans_handle *start_transaction(struct btrfs_root *root,
260{ 260{
261 struct btrfs_trans_handle *h; 261 struct btrfs_trans_handle *h;
262 struct btrfs_transaction *cur_trans; 262 struct btrfs_transaction *cur_trans;
263 int retries = 0; 263 u64 num_bytes = 0;
264 int ret; 264 int ret;
265 265
266 if (root->fs_info->fs_state & BTRFS_SUPER_FLAG_ERROR) 266 if (root->fs_info->fs_state & BTRFS_SUPER_FLAG_ERROR)
@@ -274,6 +274,19 @@ static struct btrfs_trans_handle *start_transaction(struct btrfs_root *root,
274 h->block_rsv = NULL; 274 h->block_rsv = NULL;
275 goto got_it; 275 goto got_it;
276 } 276 }
277
278 /*
279 * Do the reservation before we join the transaction so we can do all
280 * the appropriate flushing if need be.
281 */
282 if (num_items > 0 && root != root->fs_info->chunk_root) {
283 num_bytes = btrfs_calc_trans_metadata_size(root, num_items);
284 ret = btrfs_block_rsv_add(NULL, root,
285 &root->fs_info->trans_block_rsv,
286 num_bytes);
287 if (ret)
288 return ERR_PTR(ret);
289 }
277again: 290again:
278 h = kmem_cache_alloc(btrfs_trans_handle_cachep, GFP_NOFS); 291 h = kmem_cache_alloc(btrfs_trans_handle_cachep, GFP_NOFS);
279 if (!h) 292 if (!h)
@@ -310,24 +323,9 @@ again:
310 goto again; 323 goto again;
311 } 324 }
312 325
313 if (num_items > 0) { 326 if (num_bytes) {
314 ret = btrfs_trans_reserve_metadata(h, root, num_items); 327 h->block_rsv = &root->fs_info->trans_block_rsv;
315 if (ret == -EAGAIN && !retries) { 328 h->bytes_reserved = num_bytes;
316 retries++;
317 btrfs_commit_transaction(h, root);
318 goto again;
319 } else if (ret == -EAGAIN) {
320 /*
321 * We have already retried and got EAGAIN, so really we
322 * don't have space, so set ret to -ENOSPC.
323 */
324 ret = -ENOSPC;
325 }
326
327 if (ret < 0) {
328 btrfs_end_transaction(h, root);
329 return ERR_PTR(ret);
330 }
331 } 329 }
332 330
333got_it: 331got_it: