diff options
Diffstat (limited to 'fs/btrfs/transaction.c')
-rw-r--r-- | fs/btrfs/transaction.c | 88 |
1 files changed, 59 insertions, 29 deletions
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c index cac4a3f76323..57c16b46afbd 100644 --- a/fs/btrfs/transaction.c +++ b/fs/btrfs/transaction.c | |||
@@ -57,7 +57,7 @@ static unsigned int btrfs_blocked_trans_types[TRANS_STATE_MAX] = { | |||
57 | __TRANS_JOIN_NOLOCK), | 57 | __TRANS_JOIN_NOLOCK), |
58 | }; | 58 | }; |
59 | 59 | ||
60 | static void put_transaction(struct btrfs_transaction *transaction) | 60 | void btrfs_put_transaction(struct btrfs_transaction *transaction) |
61 | { | 61 | { |
62 | WARN_ON(atomic_read(&transaction->use_count) == 0); | 62 | WARN_ON(atomic_read(&transaction->use_count) == 0); |
63 | if (atomic_dec_and_test(&transaction->use_count)) { | 63 | if (atomic_dec_and_test(&transaction->use_count)) { |
@@ -332,7 +332,7 @@ static void wait_current_trans(struct btrfs_root *root) | |||
332 | wait_event(root->fs_info->transaction_wait, | 332 | wait_event(root->fs_info->transaction_wait, |
333 | cur_trans->state >= TRANS_STATE_UNBLOCKED || | 333 | cur_trans->state >= TRANS_STATE_UNBLOCKED || |
334 | cur_trans->aborted); | 334 | cur_trans->aborted); |
335 | put_transaction(cur_trans); | 335 | btrfs_put_transaction(cur_trans); |
336 | } else { | 336 | } else { |
337 | spin_unlock(&root->fs_info->trans_lock); | 337 | spin_unlock(&root->fs_info->trans_lock); |
338 | } | 338 | } |
@@ -353,6 +353,17 @@ static int may_wait_transaction(struct btrfs_root *root, int type) | |||
353 | return 0; | 353 | return 0; |
354 | } | 354 | } |
355 | 355 | ||
356 | static inline bool need_reserve_reloc_root(struct btrfs_root *root) | ||
357 | { | ||
358 | if (!root->fs_info->reloc_ctl || | ||
359 | !root->ref_cows || | ||
360 | root->root_key.objectid == BTRFS_TREE_RELOC_OBJECTID || | ||
361 | root->reloc_root) | ||
362 | return false; | ||
363 | |||
364 | return true; | ||
365 | } | ||
366 | |||
356 | static struct btrfs_trans_handle * | 367 | static struct btrfs_trans_handle * |
357 | start_transaction(struct btrfs_root *root, u64 num_items, unsigned int type, | 368 | start_transaction(struct btrfs_root *root, u64 num_items, unsigned int type, |
358 | enum btrfs_reserve_flush_enum flush) | 369 | enum btrfs_reserve_flush_enum flush) |
@@ -360,8 +371,9 @@ start_transaction(struct btrfs_root *root, u64 num_items, unsigned int type, | |||
360 | struct btrfs_trans_handle *h; | 371 | struct btrfs_trans_handle *h; |
361 | struct btrfs_transaction *cur_trans; | 372 | struct btrfs_transaction *cur_trans; |
362 | u64 num_bytes = 0; | 373 | u64 num_bytes = 0; |
363 | int ret; | ||
364 | u64 qgroup_reserved = 0; | 374 | u64 qgroup_reserved = 0; |
375 | bool reloc_reserved = false; | ||
376 | int ret; | ||
365 | 377 | ||
366 | if (test_bit(BTRFS_FS_STATE_ERROR, &root->fs_info->fs_state)) | 378 | if (test_bit(BTRFS_FS_STATE_ERROR, &root->fs_info->fs_state)) |
367 | return ERR_PTR(-EROFS); | 379 | return ERR_PTR(-EROFS); |
@@ -390,6 +402,14 @@ start_transaction(struct btrfs_root *root, u64 num_items, unsigned int type, | |||
390 | } | 402 | } |
391 | 403 | ||
392 | num_bytes = btrfs_calc_trans_metadata_size(root, num_items); | 404 | num_bytes = btrfs_calc_trans_metadata_size(root, num_items); |
405 | /* | ||
406 | * Do the reservation for the relocation root creation | ||
407 | */ | ||
408 | if (unlikely(need_reserve_reloc_root(root))) { | ||
409 | num_bytes += root->nodesize; | ||
410 | reloc_reserved = true; | ||
411 | } | ||
412 | |||
393 | ret = btrfs_block_rsv_add(root, | 413 | ret = btrfs_block_rsv_add(root, |
394 | &root->fs_info->trans_block_rsv, | 414 | &root->fs_info->trans_block_rsv, |
395 | num_bytes, flush); | 415 | num_bytes, flush); |
@@ -451,6 +471,7 @@ again: | |||
451 | h->delayed_ref_elem.seq = 0; | 471 | h->delayed_ref_elem.seq = 0; |
452 | h->type = type; | 472 | h->type = type; |
453 | h->allocating_chunk = false; | 473 | h->allocating_chunk = false; |
474 | h->reloc_reserved = false; | ||
454 | INIT_LIST_HEAD(&h->qgroup_ref_list); | 475 | INIT_LIST_HEAD(&h->qgroup_ref_list); |
455 | INIT_LIST_HEAD(&h->new_bgs); | 476 | INIT_LIST_HEAD(&h->new_bgs); |
456 | 477 | ||
@@ -466,6 +487,7 @@ again: | |||
466 | h->transid, num_bytes, 1); | 487 | h->transid, num_bytes, 1); |
467 | h->block_rsv = &root->fs_info->trans_block_rsv; | 488 | h->block_rsv = &root->fs_info->trans_block_rsv; |
468 | h->bytes_reserved = num_bytes; | 489 | h->bytes_reserved = num_bytes; |
490 | h->reloc_reserved = reloc_reserved; | ||
469 | } | 491 | } |
470 | h->qgroup_reserved = qgroup_reserved; | 492 | h->qgroup_reserved = qgroup_reserved; |
471 | 493 | ||
@@ -610,7 +632,7 @@ int btrfs_wait_for_commit(struct btrfs_root *root, u64 transid) | |||
610 | } | 632 | } |
611 | 633 | ||
612 | wait_for_commit(root, cur_trans); | 634 | wait_for_commit(root, cur_trans); |
613 | put_transaction(cur_trans); | 635 | btrfs_put_transaction(cur_trans); |
614 | out: | 636 | out: |
615 | return ret; | 637 | return ret; |
616 | } | 638 | } |
@@ -735,7 +757,7 @@ static int __btrfs_end_transaction(struct btrfs_trans_handle *trans, | |||
735 | smp_mb(); | 757 | smp_mb(); |
736 | if (waitqueue_active(&cur_trans->writer_wait)) | 758 | if (waitqueue_active(&cur_trans->writer_wait)) |
737 | wake_up(&cur_trans->writer_wait); | 759 | wake_up(&cur_trans->writer_wait); |
738 | put_transaction(cur_trans); | 760 | btrfs_put_transaction(cur_trans); |
739 | 761 | ||
740 | if (current->journal_info == trans) | 762 | if (current->journal_info == trans) |
741 | current->journal_info = NULL; | 763 | current->journal_info = NULL; |
@@ -744,8 +766,10 @@ static int __btrfs_end_transaction(struct btrfs_trans_handle *trans, | |||
744 | btrfs_run_delayed_iputs(root); | 766 | btrfs_run_delayed_iputs(root); |
745 | 767 | ||
746 | if (trans->aborted || | 768 | if (trans->aborted || |
747 | test_bit(BTRFS_FS_STATE_ERROR, &root->fs_info->fs_state)) | 769 | test_bit(BTRFS_FS_STATE_ERROR, &root->fs_info->fs_state)) { |
770 | wake_up_process(info->transaction_kthread); | ||
748 | err = -EIO; | 771 | err = -EIO; |
772 | } | ||
749 | assert_qgroups_uptodate(trans); | 773 | assert_qgroups_uptodate(trans); |
750 | 774 | ||
751 | kmem_cache_free(btrfs_trans_handle_cachep, trans); | 775 | kmem_cache_free(btrfs_trans_handle_cachep, trans); |
@@ -948,16 +972,19 @@ static noinline int commit_cowonly_roots(struct btrfs_trans_handle *trans, | |||
948 | return ret; | 972 | return ret; |
949 | 973 | ||
950 | ret = btrfs_run_dev_stats(trans, root->fs_info); | 974 | ret = btrfs_run_dev_stats(trans, root->fs_info); |
951 | WARN_ON(ret); | 975 | if (ret) |
976 | return ret; | ||
952 | ret = btrfs_run_dev_replace(trans, root->fs_info); | 977 | ret = btrfs_run_dev_replace(trans, root->fs_info); |
953 | WARN_ON(ret); | 978 | if (ret) |
954 | 979 | return ret; | |
955 | ret = btrfs_run_qgroups(trans, root->fs_info); | 980 | ret = btrfs_run_qgroups(trans, root->fs_info); |
956 | BUG_ON(ret); | 981 | if (ret) |
982 | return ret; | ||
957 | 983 | ||
958 | /* run_qgroups might have added some more refs */ | 984 | /* run_qgroups might have added some more refs */ |
959 | ret = btrfs_run_delayed_refs(trans, root, (unsigned long)-1); | 985 | ret = btrfs_run_delayed_refs(trans, root, (unsigned long)-1); |
960 | BUG_ON(ret); | 986 | if (ret) |
987 | return ret; | ||
961 | 988 | ||
962 | while (!list_empty(&fs_info->dirty_cowonly_roots)) { | 989 | while (!list_empty(&fs_info->dirty_cowonly_roots)) { |
963 | next = fs_info->dirty_cowonly_roots.next; | 990 | next = fs_info->dirty_cowonly_roots.next; |
@@ -1510,7 +1537,7 @@ int btrfs_commit_transaction_async(struct btrfs_trans_handle *trans, | |||
1510 | if (current->journal_info == trans) | 1537 | if (current->journal_info == trans) |
1511 | current->journal_info = NULL; | 1538 | current->journal_info = NULL; |
1512 | 1539 | ||
1513 | put_transaction(cur_trans); | 1540 | btrfs_put_transaction(cur_trans); |
1514 | return 0; | 1541 | return 0; |
1515 | } | 1542 | } |
1516 | 1543 | ||
@@ -1552,8 +1579,10 @@ static void cleanup_transaction(struct btrfs_trans_handle *trans, | |||
1552 | root->fs_info->running_transaction = NULL; | 1579 | root->fs_info->running_transaction = NULL; |
1553 | spin_unlock(&root->fs_info->trans_lock); | 1580 | spin_unlock(&root->fs_info->trans_lock); |
1554 | 1581 | ||
1555 | put_transaction(cur_trans); | 1582 | if (trans->type & __TRANS_FREEZABLE) |
1556 | put_transaction(cur_trans); | 1583 | sb_end_intwrite(root->fs_info->sb); |
1584 | btrfs_put_transaction(cur_trans); | ||
1585 | btrfs_put_transaction(cur_trans); | ||
1557 | 1586 | ||
1558 | trace_btrfs_transaction_commit(root); | 1587 | trace_btrfs_transaction_commit(root); |
1559 | 1588 | ||
@@ -1571,15 +1600,19 @@ static int btrfs_flush_all_pending_stuffs(struct btrfs_trans_handle *trans, | |||
1571 | int ret; | 1600 | int ret; |
1572 | 1601 | ||
1573 | ret = btrfs_run_delayed_items(trans, root); | 1602 | ret = btrfs_run_delayed_items(trans, root); |
1574 | if (ret) | ||
1575 | return ret; | ||
1576 | |||
1577 | /* | 1603 | /* |
1578 | * running the delayed items may have added new refs. account | 1604 | * running the delayed items may have added new refs. account |
1579 | * them now so that they hinder processing of more delayed refs | 1605 | * them now so that they hinder processing of more delayed refs |
1580 | * as little as possible. | 1606 | * as little as possible. |
1581 | */ | 1607 | */ |
1582 | btrfs_delayed_refs_qgroup_accounting(trans, root->fs_info); | 1608 | if (ret) { |
1609 | btrfs_delayed_refs_qgroup_accounting(trans, root->fs_info); | ||
1610 | return ret; | ||
1611 | } | ||
1612 | |||
1613 | ret = btrfs_delayed_refs_qgroup_accounting(trans, root->fs_info); | ||
1614 | if (ret) | ||
1615 | return ret; | ||
1583 | 1616 | ||
1584 | /* | 1617 | /* |
1585 | * rename don't use btrfs_join_transaction, so, once we | 1618 | * rename don't use btrfs_join_transaction, so, once we |
@@ -1596,14 +1629,14 @@ static int btrfs_flush_all_pending_stuffs(struct btrfs_trans_handle *trans, | |||
1596 | static inline int btrfs_start_delalloc_flush(struct btrfs_fs_info *fs_info) | 1629 | static inline int btrfs_start_delalloc_flush(struct btrfs_fs_info *fs_info) |
1597 | { | 1630 | { |
1598 | if (btrfs_test_opt(fs_info->tree_root, FLUSHONCOMMIT)) | 1631 | if (btrfs_test_opt(fs_info->tree_root, FLUSHONCOMMIT)) |
1599 | return btrfs_start_all_delalloc_inodes(fs_info, 1); | 1632 | return btrfs_start_delalloc_roots(fs_info, 1); |
1600 | return 0; | 1633 | return 0; |
1601 | } | 1634 | } |
1602 | 1635 | ||
1603 | static inline void btrfs_wait_delalloc_flush(struct btrfs_fs_info *fs_info) | 1636 | static inline void btrfs_wait_delalloc_flush(struct btrfs_fs_info *fs_info) |
1604 | { | 1637 | { |
1605 | if (btrfs_test_opt(fs_info->tree_root, FLUSHONCOMMIT)) | 1638 | if (btrfs_test_opt(fs_info->tree_root, FLUSHONCOMMIT)) |
1606 | btrfs_wait_all_ordered_extents(fs_info, 1); | 1639 | btrfs_wait_ordered_roots(fs_info, -1); |
1607 | } | 1640 | } |
1608 | 1641 | ||
1609 | int btrfs_commit_transaction(struct btrfs_trans_handle *trans, | 1642 | int btrfs_commit_transaction(struct btrfs_trans_handle *trans, |
@@ -1669,7 +1702,7 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, | |||
1669 | 1702 | ||
1670 | wait_for_commit(root, cur_trans); | 1703 | wait_for_commit(root, cur_trans); |
1671 | 1704 | ||
1672 | put_transaction(cur_trans); | 1705 | btrfs_put_transaction(cur_trans); |
1673 | 1706 | ||
1674 | return ret; | 1707 | return ret; |
1675 | } | 1708 | } |
@@ -1686,7 +1719,7 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, | |||
1686 | 1719 | ||
1687 | wait_for_commit(root, prev_trans); | 1720 | wait_for_commit(root, prev_trans); |
1688 | 1721 | ||
1689 | put_transaction(prev_trans); | 1722 | btrfs_put_transaction(prev_trans); |
1690 | } else { | 1723 | } else { |
1691 | spin_unlock(&root->fs_info->trans_lock); | 1724 | spin_unlock(&root->fs_info->trans_lock); |
1692 | } | 1725 | } |
@@ -1838,11 +1871,8 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, | |||
1838 | assert_qgroups_uptodate(trans); | 1871 | assert_qgroups_uptodate(trans); |
1839 | update_super_roots(root); | 1872 | update_super_roots(root); |
1840 | 1873 | ||
1841 | if (!root->fs_info->log_root_recovering) { | 1874 | btrfs_set_super_log_root(root->fs_info->super_copy, 0); |
1842 | btrfs_set_super_log_root(root->fs_info->super_copy, 0); | 1875 | btrfs_set_super_log_root_level(root->fs_info->super_copy, 0); |
1843 | btrfs_set_super_log_root_level(root->fs_info->super_copy, 0); | ||
1844 | } | ||
1845 | |||
1846 | memcpy(root->fs_info->super_for_commit, root->fs_info->super_copy, | 1876 | memcpy(root->fs_info->super_for_commit, root->fs_info->super_copy, |
1847 | sizeof(*root->fs_info->super_copy)); | 1877 | sizeof(*root->fs_info->super_copy)); |
1848 | 1878 | ||
@@ -1888,8 +1918,8 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, | |||
1888 | list_del_init(&cur_trans->list); | 1918 | list_del_init(&cur_trans->list); |
1889 | spin_unlock(&root->fs_info->trans_lock); | 1919 | spin_unlock(&root->fs_info->trans_lock); |
1890 | 1920 | ||
1891 | put_transaction(cur_trans); | 1921 | btrfs_put_transaction(cur_trans); |
1892 | put_transaction(cur_trans); | 1922 | btrfs_put_transaction(cur_trans); |
1893 | 1923 | ||
1894 | if (trans->type & __TRANS_FREEZABLE) | 1924 | if (trans->type & __TRANS_FREEZABLE) |
1895 | sb_end_intwrite(root->fs_info->sb); | 1925 | sb_end_intwrite(root->fs_info->sb); |