diff options
-rw-r--r-- | fs/btrfs/ctree.h | 3 | ||||
-rw-r--r-- | fs/btrfs/extent-tree.c | 20 | ||||
-rw-r--r-- | fs/btrfs/transaction.c | 36 |
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); | |||
2223 | void btrfs_clear_space_info_full(struct btrfs_fs_info *info); | 2223 | void btrfs_clear_space_info_full(struct btrfs_fs_info *info); |
2224 | int btrfs_check_data_free_space(struct inode *inode, u64 bytes); | 2224 | int btrfs_check_data_free_space(struct inode *inode, u64 bytes); |
2225 | void btrfs_free_reserved_data_space(struct inode *inode, u64 bytes); | 2225 | void btrfs_free_reserved_data_space(struct inode *inode, u64 bytes); |
2226 | int btrfs_trans_reserve_metadata(struct btrfs_trans_handle *trans, | ||
2227 | struct btrfs_root *root, | ||
2228 | int num_items); | ||
2229 | void btrfs_trans_release_metadata(struct btrfs_trans_handle *trans, | 2226 | void btrfs_trans_release_metadata(struct btrfs_trans_handle *trans, |
2230 | struct btrfs_root *root); | 2227 | struct btrfs_root *root); |
2231 | int btrfs_orphan_reserve_metadata(struct btrfs_trans_handle *trans, | 2228 | int 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 | ||
3877 | int 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 | |||
3897 | void btrfs_trans_release_metadata(struct btrfs_trans_handle *trans, | 3877 | void 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 | } | ||
277 | again: | 290 | again: |
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 | ||
333 | got_it: | 331 | got_it: |