jbd2__journal_restart() has quite some code that is common with jbd2_journal_stop(). Factor this functionality into stop_this_handle() helper and use it from both functions. Note that this also drops t_handle_lock protection from jbd2__journal_restart() as jbd2_journal_stop() does the same thing without it.
Unified · Split
| @@ -512,12 +512,17 @@ handle_t *jbd2_journal_start(journal_t *journal, int nblocks) · 511 unmodified lines | ||
| 512 | 512 | } |
| 513 | 513 | EXPORT_SYMBOL(jbd2_journal_start); |
| 514 | 514 | |
| 515 | −void jbd2_journal_free_reserved(handle_t *handle) | |
| 515 | +static void __jbd2_journal_unreserve_handle(handle_t *handle) | |
| 516 | 516 | { |
| 517 | 517 | journal_t *journal = handle->h_journal; |
| 518 | 518 | |
| 519 | 519 | WARN_ON(!handle->h_reserved); |
| 520 | 520 | sub_reserved_credits(journal, handle->h_buffer_credits); |
| 521 | +} | |
| 522 | + | |
| 523 | +void jbd2_journal_free_reserved(handle_t *handle) | |
| 524 | +{ | |
| 525 | + __jbd2_journal_unreserve_handle(handle); | |
| 521 | 526 | jbd2_free_handle(handle); |
| 522 | 527 | } |
| 523 | 528 | EXPORT_SYMBOL(jbd2_journal_free_reserved); |
| @@ -655,6 +660,28 @@ error_out: · 131 unmodified lines | ||
| 655 | 660 | return result; |
| 656 | 661 | } |
| 657 | 662 | |
| 663 | +static void stop_this_handle(handle_t *handle) | |
| 664 | +{ | |
| 665 | + transaction_t *transaction = handle->h_transaction; | |
| 666 | + journal_t *journal = transaction->t_journal; | |
| 667 | + | |
| 668 | + J_ASSERT(journal_current_handle() == handle); | |
| 669 | + J_ASSERT(atomic_read(&transaction->t_updates) > 0); | |
| 670 | + current->journal_info = NULL; | |
| 671 | + atomic_sub(handle->h_buffer_credits, | |
| 672 | + &transaction->t_outstanding_credits); | |
| 673 | + if (handle->h_rsv_handle) | |
| 674 | + __jbd2_journal_unreserve_handle(handle->h_rsv_handle); | |
| 675 | + if (atomic_dec_and_test(&transaction->t_updates)) | |
| 676 | + wake_up(&journal->j_wait_updates); | |
| 677 | + | |
| 678 | + rwsem_release(&journal->j_trans_commit_map, 1, _THIS_IP_); | |
| 679 | + /* | |
| 680 | + * Scope of the GFP_NOFS context is over here and so we can restore the | |
| 681 | + * original alloc context. | |
| 682 | + */ | |
| 683 | + memalloc_nofs_restore(handle->saved_alloc_context); | |
| 684 | +} | |
| 658 | 685 | |
| 659 | 686 | /** |
| 660 | 687 | * int jbd2_journal_restart() - restart a handle . |
| @@ -677,52 +704,34 @@ int jbd2__journal_restart(handle_t *handle, int nblocks, gfp_t gfp_mask) · 16 unmodified lines | ||
| 677 | 704 | transaction_t *transaction = handle->h_transaction; |
| 678 | 705 | journal_t *journal; |
| 679 | 706 | tid_t tid; |
| 680 | − int need_to_start, ret; | |
| 707 | + int need_to_start; | |
| 681 | 708 | |
| 682 | 709 | /* If we've had an abort of any type, don't even think about |
| 683 | 710 | * actually doing the restart! */ |
| 684 | 711 | if (is_handle_aborted(handle)) |
| 685 | 712 | return 0; |
| 686 | 713 | journal = transaction->t_journal; |
| 714 | + tid = transaction->t_tid; | |
| 687 | 715 | |
| 688 | 716 | /* |
| 689 | 717 | * First unlink the handle from its current transaction, and start the |
| 690 | 718 | * commit on that. |
| 691 | 719 | */ |
| 692 | − J_ASSERT(atomic_read(&transaction->t_updates) > 0); | |
| 693 | − J_ASSERT(journal_current_handle() == handle); | |
| 694 | − | |
| 695 | − read_lock(&journal->j_state_lock); | |
| 696 | − spin_lock(&transaction->t_handle_lock); | |
| 697 | − atomic_sub(handle->h_buffer_credits, | |
| 698 | − &transaction->t_outstanding_credits); | |
| 699 | − if (handle->h_rsv_handle) { | |
| 700 | − sub_reserved_credits(journal, | |
| 701 | − handle->h_rsv_handle->h_buffer_credits); | |
| 702 | − } | |
| 703 | − if (atomic_dec_and_test(&transaction->t_updates)) | |
| 704 | − wake_up(&journal->j_wait_updates); | |
| 705 | − tid = transaction->t_tid; | |
| 706 | − spin_unlock(&transaction->t_handle_lock); | |
| 720 | + jbd_debug(2, "restarting handle %p\n", handle); | |
| 721 | + stop_this_handle(handle); | |
| 707 | 722 | handle->h_transaction = NULL; |
| 708 | − current->journal_info = NULL; | |
| 709 | 723 | |
| 710 | − jbd_debug(2, "restarting handle %p\n", handle); | |
| 724 | + /* | |
| 725 | + * TODO: If we use READ_ONCE / WRITE_ONCE for j_commit_request we can | |
| 726 | + * get rid of pointless j_state_lock traffic like this. | |
| 727 | + */ | |
| 728 | + read_lock(&journal->j_state_lock); | |
| 711 | 729 | need_to_start = !tid_geq(journal->j_commit_request, tid); |
| 712 | 730 | read_unlock(&journal->j_state_lock); |
| 713 | 731 | if (need_to_start) |
| 714 | 732 | jbd2_log_start_commit(journal, tid); |
| 715 | − | |
| 716 | − rwsem_release(&journal->j_trans_commit_map, 1, _THIS_IP_); | |
| 717 | 733 | handle->h_buffer_credits = nblocks; |
| 718 | − /* | |
| 719 | − * Restore the original nofs context because the journal restart | |
| 720 | − * is basically the same thing as journal stop and start. | |
| 721 | − * start_this_handle will start a new nofs context. | |
| 722 | − */ | |
| 723 | − memalloc_nofs_restore(handle->saved_alloc_context); | |
| 724 | − ret = start_this_handle(journal, handle, gfp_mask); | |
| 725 | − return ret; | |
| 734 | + return start_this_handle(journal, handle, gfp_mask); | |
| 726 | 735 | } |
| 727 | 736 | EXPORT_SYMBOL(jbd2__journal_restart); |
| 728 | 737 | |
| @@ -1718,16 +1727,12 @@ int jbd2_journal_stop(handle_t *handle) · 989 unmodified lines | ||
| 1718 | 1727 | * Handle is already detached from the transaction so there is |
| 1719 | 1728 | * nothing to do other than free the handle. |
| 1720 | 1729 | */ |
| 1721 | − if (handle->h_rsv_handle) | |
| 1722 | − jbd2_free_handle(handle->h_rsv_handle); | |
| 1730 | + memalloc_nofs_restore(handle->saved_alloc_context); | |
| 1723 | 1731 | goto free_and_exit; |
| 1724 | 1732 | } |
| 1725 | 1733 | journal = transaction->t_journal; |
| 1726 | 1734 | tid = transaction->t_tid; |
| 1727 | 1735 | |
| 1728 | − J_ASSERT(journal_current_handle() == handle); | |
| 1729 | − J_ASSERT(atomic_read(&transaction->t_updates) > 0); | |
| 1730 | − | |
| 1731 | 1736 | if (is_handle_aborted(handle)) |
| 1732 | 1737 | err = -EIO; |
| 1733 | 1738 | |
| @@ -1797,9 +1802,6 @@ int jbd2_journal_stop(handle_t *handle) · 63 unmodified lines | ||
| 1797 | 1802 | |
| 1798 | 1803 | if (handle->h_sync) |
| 1799 | 1804 | transaction->t_synchronous_commit = 1; |
| 1800 | − current->journal_info = NULL; | |
| 1801 | − atomic_sub(handle->h_buffer_credits, | |
| 1802 | − &transaction->t_outstanding_credits); | |
| 1803 | 1805 | |
| 1804 | 1806 | /* |
| 1805 | 1807 | * If the handle is marked SYNC, we need to set another commit |
| @@ -1826,27 +1828,19 @@ int jbd2_journal_stop(handle_t *handle) · 20 unmodified lines | ||
| 1826 | 1828 | } |
| 1827 | 1829 | |
| 1828 | 1830 | /* |
| 1829 | − * Once we drop t_updates, if it goes to zero the transaction | |
| 1830 | − * could start committing on us and eventually disappear. So | |
| 1831 | − * once we do this, we must not dereference transaction | |
| 1832 | − * pointer again. | |
| 1831 | + * Once stop_this_handle() drops t_updates, the transaction could start | |
| 1832 | + * committing on us and eventually disappear. So we must not | |
| 1833 | + * dereference transaction pointer again after calling | |
| 1834 | + * stop_this_handle(). | |
| 1833 | 1835 | */ |
| 1834 | − if (atomic_dec_and_test(&transaction->t_updates)) | |
| 1835 | − wake_up(&journal->j_wait_updates); | |
| 1836 | − | |
| 1837 | − rwsem_release(&journal->j_trans_commit_map, 1, _THIS_IP_); | |
| 1836 | + stop_this_handle(handle); | |
| 1838 | 1837 | |
| 1839 | 1838 | if (wait_for_commit) |
| 1840 | 1839 | err = jbd2_log_wait_commit(journal, tid); |
| 1841 | 1840 | |
| 1842 | − if (handle->h_rsv_handle) | |
| 1843 | − jbd2_journal_free_reserved(handle->h_rsv_handle); | |
| 1844 | 1841 | free_and_exit: |
| 1845 | − /* | |
| 1846 | − * Scope of the GFP_NOFS context is over here and so we can restore the | |
| 1847 | − * original alloc context. | |
| 1848 | − */ | |
| 1849 | − memalloc_nofs_restore(handle->saved_alloc_context); | |
| 1842 | + if (handle->h_rsv_handle) | |
| 1843 | + jbd2_free_handle(handle->h_rsv_handle); | |
| 1850 | 1844 | jbd2_free_handle(handle); |
| 1851 | 1845 | return err; |
| 1852 | 1846 | } |