aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJosef Bacik <jbacik@fusionio.com>2012-06-26 16:13:18 -0400
committerChris Mason <chris.mason@fusionio.com>2012-07-23 16:27:55 -0400
commit0e721106923be82f651dd0ee504742a8a3eb089f (patch)
tree03503ad628e903b381cd0a1874eaeb796359634c
parentb9959295151625c17723103afd79077e80b24ddd (diff)
Btrfs: change how we indicate we're adding csums
There is weird logic I had to put in place to make sure that when we were adding csums that we'd used the delalloc block rsv instead of the global block rsv. Part of this meant that we had to free up our transaction reservation before we ran the delayed refs since csum deletion happens during the delayed ref work. The problem with this is that when we release a reservation we will add it to the global reserve if it is not full in order to keep us going along longer before we have to force a transaction commit. By releasing our reservation before we run delayed refs we don't get the opportunity to drain down the global reserve for the work we did, so we won't refill it as often. This isn't a problem per-se, it just results in us possibly committing transactions more and more often, and in rare cases could cause those WARN_ON()'s to pop in use_block_rsv because we ran out of space in our block rsv. This also helps us by holding onto space while the delayed refs run so we don't end up with as many people trying to do things at the same time, which again will help us not force commits or hit the use_block_rsv warnings. Thanks, Signed-off-by: Josef Bacik <jbacik@fusionio.com>
-rw-r--r--fs/btrfs/extent-tree.c8
-rw-r--r--fs/btrfs/file-item.c2
-rw-r--r--fs/btrfs/transaction.c22
-rw-r--r--fs/btrfs/transaction.h1
4 files changed, 18 insertions, 15 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index 3cde907a25a5..ec0328bb86db 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -3961,7 +3961,10 @@ static struct btrfs_block_rsv *get_block_rsv(
3961{ 3961{
3962 struct btrfs_block_rsv *block_rsv = NULL; 3962 struct btrfs_block_rsv *block_rsv = NULL;
3963 3963
3964 if (root->ref_cows || root == root->fs_info->csum_root) 3964 if (root->ref_cows)
3965 block_rsv = trans->block_rsv;
3966
3967 if (root == root->fs_info->csum_root && trans->adding_csums)
3965 block_rsv = trans->block_rsv; 3968 block_rsv = trans->block_rsv;
3966 3969
3967 if (!block_rsv) 3970 if (!block_rsv)
@@ -4313,6 +4316,9 @@ static void release_global_block_rsv(struct btrfs_fs_info *fs_info)
4313void btrfs_trans_release_metadata(struct btrfs_trans_handle *trans, 4316void btrfs_trans_release_metadata(struct btrfs_trans_handle *trans,
4314 struct btrfs_root *root) 4317 struct btrfs_root *root)
4315{ 4318{
4319 if (!trans->block_rsv)
4320 return;
4321
4316 if (!trans->bytes_reserved) 4322 if (!trans->bytes_reserved)
4317 return; 4323 return;
4318 4324
diff --git a/fs/btrfs/file-item.c b/fs/btrfs/file-item.c
index 5d158d320233..863c34d111b5 100644
--- a/fs/btrfs/file-item.c
+++ b/fs/btrfs/file-item.c
@@ -690,6 +690,7 @@ int btrfs_csum_file_blocks(struct btrfs_trans_handle *trans,
690 return -ENOMEM; 690 return -ENOMEM;
691 691
692 sector_sum = sums->sums; 692 sector_sum = sums->sums;
693 trans->adding_csums = 1;
693again: 694again:
694 next_offset = (u64)-1; 695 next_offset = (u64)-1;
695 found_next = 0; 696 found_next = 0;
@@ -853,6 +854,7 @@ next_sector:
853 goto again; 854 goto again;
854 } 855 }
855out: 856out:
857 trans->adding_csums = 0;
856 btrfs_free_path(path); 858 btrfs_free_path(path);
857 return ret; 859 return ret;
858 860
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c
index cb2dfe293947..328b95f67660 100644
--- a/fs/btrfs/transaction.c
+++ b/fs/btrfs/transaction.c
@@ -351,6 +351,7 @@ again:
351 h->bytes_reserved = 0; 351 h->bytes_reserved = 0;
352 h->delayed_ref_updates = 0; 352 h->delayed_ref_updates = 0;
353 h->use_count = 1; 353 h->use_count = 1;
354 h->adding_csums = 0;
354 h->block_rsv = NULL; 355 h->block_rsv = NULL;
355 h->orig_rsv = NULL; 356 h->orig_rsv = NULL;
356 h->aborted = 0; 357 h->aborted = 0;
@@ -473,7 +474,6 @@ int btrfs_should_end_transaction(struct btrfs_trans_handle *trans,
473 struct btrfs_root *root) 474 struct btrfs_root *root)
474{ 475{
475 struct btrfs_transaction *cur_trans = trans->transaction; 476 struct btrfs_transaction *cur_trans = trans->transaction;
476 struct btrfs_block_rsv *rsv = trans->block_rsv;
477 int updates; 477 int updates;
478 int err; 478 int err;
479 479
@@ -481,12 +481,6 @@ int btrfs_should_end_transaction(struct btrfs_trans_handle *trans,
481 if (cur_trans->blocked || cur_trans->delayed_refs.flushing) 481 if (cur_trans->blocked || cur_trans->delayed_refs.flushing)
482 return 1; 482 return 1;
483 483
484 /*
485 * We need to do this in case we're deleting csums so the global block
486 * rsv get's used instead of the csum block rsv.
487 */
488 trans->block_rsv = NULL;
489
490 updates = trans->delayed_ref_updates; 484 updates = trans->delayed_ref_updates;
491 trans->delayed_ref_updates = 0; 485 trans->delayed_ref_updates = 0;
492 if (updates) { 486 if (updates) {
@@ -495,8 +489,6 @@ int btrfs_should_end_transaction(struct btrfs_trans_handle *trans,
495 return err; 489 return err;
496 } 490 }
497 491
498 trans->block_rsv = rsv;
499
500 return should_end_transaction(trans, root); 492 return should_end_transaction(trans, root);
501} 493}
502 494
@@ -513,8 +505,6 @@ static int __btrfs_end_transaction(struct btrfs_trans_handle *trans,
513 return 0; 505 return 0;
514 } 506 }
515 507
516 btrfs_trans_release_metadata(trans, root);
517 trans->block_rsv = NULL;
518 while (count < 2) { 508 while (count < 2) {
519 unsigned long cur = trans->delayed_ref_updates; 509 unsigned long cur = trans->delayed_ref_updates;
520 trans->delayed_ref_updates = 0; 510 trans->delayed_ref_updates = 0;
@@ -527,6 +517,8 @@ static int __btrfs_end_transaction(struct btrfs_trans_handle *trans,
527 } 517 }
528 count++; 518 count++;
529 } 519 }
520 btrfs_trans_release_metadata(trans, root);
521 trans->block_rsv = NULL;
530 522
531 if (lock && !atomic_read(&root->fs_info->open_ioctl_trans) && 523 if (lock && !atomic_read(&root->fs_info->open_ioctl_trans) &&
532 should_end_transaction(trans, root)) { 524 should_end_transaction(trans, root)) {
@@ -1269,9 +1261,6 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
1269 1261
1270 btrfs_run_ordered_operations(root, 0); 1262 btrfs_run_ordered_operations(root, 0);
1271 1263
1272 btrfs_trans_release_metadata(trans, root);
1273 trans->block_rsv = NULL;
1274
1275 if (cur_trans->aborted) 1264 if (cur_trans->aborted)
1276 goto cleanup_transaction; 1265 goto cleanup_transaction;
1277 1266
@@ -1282,6 +1271,9 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
1282 if (ret) 1271 if (ret)
1283 goto cleanup_transaction; 1272 goto cleanup_transaction;
1284 1273
1274 btrfs_trans_release_metadata(trans, root);
1275 trans->block_rsv = NULL;
1276
1285 cur_trans = trans->transaction; 1277 cur_trans = trans->transaction;
1286 1278
1287 /* 1279 /*
@@ -1533,6 +1525,8 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
1533 return ret; 1525 return ret;
1534 1526
1535cleanup_transaction: 1527cleanup_transaction:
1528 btrfs_trans_release_metadata(trans, root);
1529 trans->block_rsv = NULL;
1536 btrfs_printk(root->fs_info, "Skipping commit of aborted transaction.\n"); 1530 btrfs_printk(root->fs_info, "Skipping commit of aborted transaction.\n");
1537// WARN_ON(1); 1531// WARN_ON(1);
1538 if (current->journal_info == trans) 1532 if (current->journal_info == trans)
diff --git a/fs/btrfs/transaction.h b/fs/btrfs/transaction.h
index fe27379e368b..d314a74b4968 100644
--- a/fs/btrfs/transaction.h
+++ b/fs/btrfs/transaction.h
@@ -57,6 +57,7 @@ struct btrfs_trans_handle {
57 struct btrfs_block_rsv *block_rsv; 57 struct btrfs_block_rsv *block_rsv;
58 struct btrfs_block_rsv *orig_rsv; 58 struct btrfs_block_rsv *orig_rsv;
59 int aborted; 59 int aborted;
60 int adding_csums;
60}; 61};
61 62
62struct btrfs_pending_snapshot { 63struct btrfs_pending_snapshot {