diff options
author | Josef Bacik <jwhiter@redhat.com> | 2007-08-10 16:22:09 -0400 |
---|---|---|
committer | David Woodhouse <dwmw2@hera.kernel.org> | 2007-08-10 16:22:09 -0400 |
commit | 15ee9bc7ed171248d1405df5854da5fa91bfdc39 (patch) | |
tree | 5f29f51e1c14a6b35b2019a2ada5bb80fb97e2bd /fs/btrfs/transaction.c | |
parent | f2183bde1a918d338337955c8e8ba29bd8f5e7b1 (diff) |
Btrfs: delay commits during fsync to allow more writers
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/transaction.c')
-rw-r--r-- | fs/btrfs/transaction.c | 44 |
1 files changed, 32 insertions, 12 deletions
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c index c9d52dc83e48..18abea802794 100644 --- a/fs/btrfs/transaction.c +++ b/fs/btrfs/transaction.c | |||
@@ -55,7 +55,8 @@ static int join_transaction(struct btrfs_root *root) | |||
55 | BUG_ON(!cur_trans); | 55 | BUG_ON(!cur_trans); |
56 | root->fs_info->generation++; | 56 | root->fs_info->generation++; |
57 | root->fs_info->running_transaction = cur_trans; | 57 | root->fs_info->running_transaction = cur_trans; |
58 | cur_trans->num_writers = 0; | 58 | cur_trans->num_writers = 1; |
59 | cur_trans->num_joined = 0; | ||
59 | cur_trans->transid = root->fs_info->generation; | 60 | cur_trans->transid = root->fs_info->generation; |
60 | init_waitqueue_head(&cur_trans->writer_wait); | 61 | init_waitqueue_head(&cur_trans->writer_wait); |
61 | init_waitqueue_head(&cur_trans->commit_wait); | 62 | init_waitqueue_head(&cur_trans->commit_wait); |
@@ -65,8 +66,11 @@ static int join_transaction(struct btrfs_root *root) | |||
65 | cur_trans->start_time = get_seconds(); | 66 | cur_trans->start_time = get_seconds(); |
66 | list_add_tail(&cur_trans->list, &root->fs_info->trans_list); | 67 | list_add_tail(&cur_trans->list, &root->fs_info->trans_list); |
67 | init_bit_radix(&cur_trans->dirty_pages); | 68 | init_bit_radix(&cur_trans->dirty_pages); |
69 | } else { | ||
70 | cur_trans->num_writers++; | ||
71 | cur_trans->num_joined++; | ||
68 | } | 72 | } |
69 | cur_trans->num_writers++; | 73 | |
70 | return 0; | 74 | return 0; |
71 | } | 75 | } |
72 | 76 | ||
@@ -428,12 +432,14 @@ static int drop_dirty_roots(struct btrfs_root *tree_root, | |||
428 | int btrfs_commit_transaction(struct btrfs_trans_handle *trans, | 432 | int btrfs_commit_transaction(struct btrfs_trans_handle *trans, |
429 | struct btrfs_root *root) | 433 | struct btrfs_root *root) |
430 | { | 434 | { |
431 | int ret = 0; | 435 | unsigned long joined = 0; |
436 | unsigned long timeout = 1; | ||
432 | struct btrfs_transaction *cur_trans; | 437 | struct btrfs_transaction *cur_trans; |
433 | struct btrfs_transaction *prev_trans = NULL; | 438 | struct btrfs_transaction *prev_trans = NULL; |
434 | struct list_head dirty_fs_roots; | 439 | struct list_head dirty_fs_roots; |
435 | struct radix_tree_root pinned_copy; | 440 | struct radix_tree_root pinned_copy; |
436 | DEFINE_WAIT(wait); | 441 | DEFINE_WAIT(wait); |
442 | int ret; | ||
437 | 443 | ||
438 | init_bit_radix(&pinned_copy); | 444 | init_bit_radix(&pinned_copy); |
439 | INIT_LIST_HEAD(&dirty_fs_roots); | 445 | INIT_LIST_HEAD(&dirty_fs_roots); |
@@ -448,7 +454,11 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, | |||
448 | mutex_unlock(&root->fs_info->fs_mutex); | 454 | mutex_unlock(&root->fs_info->fs_mutex); |
449 | ret = wait_for_commit(root, cur_trans); | 455 | ret = wait_for_commit(root, cur_trans); |
450 | BUG_ON(ret); | 456 | BUG_ON(ret); |
457 | |||
458 | mutex_lock(&root->fs_info->trans_mutex); | ||
451 | put_transaction(cur_trans); | 459 | put_transaction(cur_trans); |
460 | mutex_unlock(&root->fs_info->trans_mutex); | ||
461 | |||
452 | mutex_lock(&root->fs_info->fs_mutex); | 462 | mutex_lock(&root->fs_info->fs_mutex); |
453 | return 0; | 463 | return 0; |
454 | } | 464 | } |
@@ -463,26 +473,35 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, | |||
463 | mutex_unlock(&root->fs_info->trans_mutex); | 473 | mutex_unlock(&root->fs_info->trans_mutex); |
464 | 474 | ||
465 | wait_for_commit(root, prev_trans); | 475 | wait_for_commit(root, prev_trans); |
466 | put_transaction(prev_trans); | ||
467 | 476 | ||
468 | mutex_lock(&root->fs_info->fs_mutex); | 477 | mutex_lock(&root->fs_info->fs_mutex); |
469 | mutex_lock(&root->fs_info->trans_mutex); | 478 | mutex_lock(&root->fs_info->trans_mutex); |
479 | put_transaction(prev_trans); | ||
470 | } | 480 | } |
471 | } | 481 | } |
472 | while (trans->transaction->num_writers > 1) { | 482 | |
483 | do { | ||
484 | joined = cur_trans->num_joined; | ||
473 | WARN_ON(cur_trans != trans->transaction); | 485 | WARN_ON(cur_trans != trans->transaction); |
474 | prepare_to_wait(&trans->transaction->writer_wait, &wait, | 486 | prepare_to_wait(&cur_trans->writer_wait, &wait, |
475 | TASK_UNINTERRUPTIBLE); | 487 | TASK_UNINTERRUPTIBLE); |
476 | if (trans->transaction->num_writers <= 1) | 488 | |
477 | break; | 489 | if (cur_trans->num_writers > 1) |
490 | timeout = MAX_SCHEDULE_TIMEOUT; | ||
491 | else | ||
492 | timeout = 1; | ||
493 | |||
478 | mutex_unlock(&root->fs_info->fs_mutex); | 494 | mutex_unlock(&root->fs_info->fs_mutex); |
479 | mutex_unlock(&root->fs_info->trans_mutex); | 495 | mutex_unlock(&root->fs_info->trans_mutex); |
480 | schedule(); | 496 | |
497 | schedule_timeout(timeout); | ||
498 | |||
481 | mutex_lock(&root->fs_info->fs_mutex); | 499 | mutex_lock(&root->fs_info->fs_mutex); |
482 | mutex_lock(&root->fs_info->trans_mutex); | 500 | mutex_lock(&root->fs_info->trans_mutex); |
483 | finish_wait(&trans->transaction->writer_wait, &wait); | 501 | finish_wait(&cur_trans->writer_wait, &wait); |
484 | } | 502 | } while (cur_trans->num_writers > 1 || |
485 | finish_wait(&trans->transaction->writer_wait, &wait); | 503 | (cur_trans->num_joined != joined)); |
504 | |||
486 | WARN_ON(cur_trans != trans->transaction); | 505 | WARN_ON(cur_trans != trans->transaction); |
487 | ret = add_dirty_roots(trans, &root->fs_info->fs_roots_radix, | 506 | ret = add_dirty_roots(trans, &root->fs_info->fs_roots_radix, |
488 | &dirty_fs_roots); | 507 | &dirty_fs_roots); |
@@ -511,6 +530,7 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, | |||
511 | btrfs_finish_extent_commit(trans, root, &pinned_copy); | 530 | btrfs_finish_extent_commit(trans, root, &pinned_copy); |
512 | mutex_lock(&root->fs_info->trans_mutex); | 531 | mutex_lock(&root->fs_info->trans_mutex); |
513 | cur_trans->commit_done = 1; | 532 | cur_trans->commit_done = 1; |
533 | root->fs_info->last_trans_committed = cur_trans->transid; | ||
514 | wake_up(&cur_trans->commit_wait); | 534 | wake_up(&cur_trans->commit_wait); |
515 | put_transaction(cur_trans); | 535 | put_transaction(cur_trans); |
516 | put_transaction(cur_trans); | 536 | put_transaction(cur_trans); |