aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/transaction.c
diff options
context:
space:
mode:
authorJosef Bacik <josef@redhat.com>2010-10-15 16:52:49 -0400
committerJosef Bacik <josef@redhat.com>2010-10-22 15:55:01 -0400
commit8bb8ab2e93f9c3c9453e13be0f37d344a32a3a6d (patch)
tree619600c7458a3af18555f189d53efc4c092b9280 /fs/btrfs/transaction.c
parent14ed0ca6e8236f2d264c4a8faec9e3a2b3d04377 (diff)
Btrfs: rework how we reserve metadata bytes
With multi-threaded writes we were getting ENOSPC early because somebody would come in, start flushing delalloc because they couldn't make their reservation, and in the meantime other threads would come in and use the space that was getting freed up, so when the original thread went to check to see if they had space they didn't and they'd return ENOSPC. So instead if we have some free space but not enough for our reservation, take the reservation and then start doing the flushing. The only time we don't take reservations is when we've already overcommitted our space, that way we don't have people who come late to the party way overcommitting ourselves. This also moves all of the retrying and flushing code into reserve_metdata_bytes so it's all uniform. This keeps my fs_mark test from returning -ENOSPC as soon as it starts and actually lets me fill up the disk. Thanks, Signed-off-by: Josef Bacik <josef@redhat.com>
Diffstat (limited to 'fs/btrfs/transaction.c')
-rw-r--r--fs/btrfs/transaction.c7
1 files changed, 2 insertions, 5 deletions
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c
index 66e4c66cc63b..abbec80aaa44 100644
--- a/fs/btrfs/transaction.c
+++ b/fs/btrfs/transaction.c
@@ -179,7 +179,6 @@ static struct btrfs_trans_handle *start_transaction(struct btrfs_root *root,
179{ 179{
180 struct btrfs_trans_handle *h; 180 struct btrfs_trans_handle *h;
181 struct btrfs_transaction *cur_trans; 181 struct btrfs_transaction *cur_trans;
182 int retries = 0;
183 int ret; 182 int ret;
184again: 183again:
185 h = kmem_cache_alloc(btrfs_trans_handle_cachep, GFP_NOFS); 184 h = kmem_cache_alloc(btrfs_trans_handle_cachep, GFP_NOFS);
@@ -212,8 +211,7 @@ again:
212 } 211 }
213 212
214 if (num_items > 0) { 213 if (num_items > 0) {
215 ret = btrfs_trans_reserve_metadata(h, root, num_items, 214 ret = btrfs_trans_reserve_metadata(h, root, num_items);
216 &retries);
217 if (ret == -EAGAIN) { 215 if (ret == -EAGAIN) {
218 btrfs_commit_transaction(h, root); 216 btrfs_commit_transaction(h, root);
219 goto again; 217 goto again;
@@ -836,7 +834,6 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans,
836 struct extent_buffer *tmp; 834 struct extent_buffer *tmp;
837 struct extent_buffer *old; 835 struct extent_buffer *old;
838 int ret; 836 int ret;
839 int retries = 0;
840 u64 to_reserve = 0; 837 u64 to_reserve = 0;
841 u64 index = 0; 838 u64 index = 0;
842 u64 objectid; 839 u64 objectid;
@@ -858,7 +855,7 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans,
858 855
859 if (to_reserve > 0) { 856 if (to_reserve > 0) {
860 ret = btrfs_block_rsv_add(trans, root, &pending->block_rsv, 857 ret = btrfs_block_rsv_add(trans, root, &pending->block_rsv,
861 to_reserve, &retries); 858 to_reserve);
862 if (ret) { 859 if (ret) {
863 pending->error = ret; 860 pending->error = ret;
864 goto fail; 861 goto fail;