History

jbd2: Factor out common parts of stopping and restarting a handle

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.

Jan Kara committed 7 years ago

Commit ec8b6f61 parent 5559b2d1 file · +46 −52Browse files

Unified · Split

fs/jbd2/transaction.c+46−52
@@ -512,12 +512,17 @@ handle_t *jbd2_journal_start(journal_t *journal, int nblocks) · 511 unmodified lines
512}512}
513EXPORT_SYMBOL(jbd2_journal_start);513EXPORT_SYMBOL(jbd2_journal_start);
514 514
515void jbd2_journal_free_reserved(handle_t *handle)515static void __jbd2_journal_unreserve_handle(handle_t *handle)
516{516{
517 journal_t *journal = handle->h_journal;517 journal_t *journal = handle->h_journal;
518 518
519 WARN_ON(!handle->h_reserved);519 WARN_ON(!handle->h_reserved);
520 sub_reserved_credits(journal, handle->h_buffer_credits);520 sub_reserved_credits(journal, handle->h_buffer_credits);
521}
522
523void jbd2_journal_free_reserved(handle_t *handle)
524{
525 __jbd2_journal_unreserve_handle(handle);
521 jbd2_free_handle(handle);526 jbd2_free_handle(handle);
522}527}
523EXPORT_SYMBOL(jbd2_journal_free_reserved);528EXPORT_SYMBOL(jbd2_journal_free_reserved);
@@ -655,6 +660,28 @@ error_out: · 131 unmodified lines
655 return result;660 return result;
656}661}
657 662
663static 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 * int jbd2_journal_restart() - restart a handle .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 transaction_t *transaction = handle->h_transaction;704 transaction_t *transaction = handle->h_transaction;
678 journal_t *journal;705 journal_t *journal;
679 tid_t tid;706 tid_t tid;
680 int need_to_start, ret;707 int need_to_start;
681 708
682 /* If we've had an abort of any type, don't even think about709 /* If we've had an abort of any type, don't even think about
683 * actually doing the restart! */710 * actually doing the restart! */
684 if (is_handle_aborted(handle))711 if (is_handle_aborted(handle))
685 return 0;712 return 0;
686 journal = transaction->t_journal;713 journal = transaction->t_journal;
714 tid = transaction->t_tid;
687 715
688 /*716 /*
689 * First unlink the handle from its current transaction, and start the717 * First unlink the handle from its current transaction, and start the
690 * commit on that.718 * commit on that.
691 */719 */
692 J_ASSERT(atomic_read(&transaction->t_updates) > 0);720 jbd_debug(2, "restarting handle %p\n", handle);
693 J_ASSERT(journal_current_handle() == handle);721 stop_this_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);
707 handle->h_transaction = NULL;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 need_to_start = !tid_geq(journal->j_commit_request, tid);729 need_to_start = !tid_geq(journal->j_commit_request, tid);
712 read_unlock(&journal->j_state_lock);730 read_unlock(&journal->j_state_lock);
713 if (need_to_start)731 if (need_to_start)
714 jbd2_log_start_commit(journal, tid);732 jbd2_log_start_commit(journal, tid);
715
716 rwsem_release(&journal->j_trans_commit_map, 1, _THIS_IP_);
717 handle->h_buffer_credits = nblocks;733 handle->h_buffer_credits = nblocks;
718 /*734 return start_this_handle(journal, handle, gfp_mask);
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;
726}735}
727EXPORT_SYMBOL(jbd2__journal_restart);736EXPORT_SYMBOL(jbd2__journal_restart);
728 737
@@ -1718,16 +1727,12 @@ int jbd2_journal_stop(handle_t *handle) · 989 unmodified lines
1718 * Handle is already detached from the transaction so there is1727 * Handle is already detached from the transaction so there is
1719 * nothing to do other than free the handle.1728 * nothing to do other than free the handle.
1720 */1729 */
1721 if (handle->h_rsv_handle)1730 memalloc_nofs_restore(handle->saved_alloc_context);
1722 jbd2_free_handle(handle->h_rsv_handle);
1723 goto free_and_exit;1731 goto free_and_exit;
1724 }1732 }
1725 journal = transaction->t_journal;1733 journal = transaction->t_journal;
1726 tid = transaction->t_tid;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 if (is_handle_aborted(handle))1736 if (is_handle_aborted(handle))
1732 err = -EIO;1737 err = -EIO;
1733 1738
@@ -1797,9 +1802,6 @@ int jbd2_journal_stop(handle_t *handle) · 63 unmodified lines
1797 1802
1798 if (handle->h_sync)1803 if (handle->h_sync)
1799 transaction->t_synchronous_commit = 1;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 * If the handle is marked SYNC, we need to set another commit1807 * 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 transaction1831 * Once stop_this_handle() drops t_updates, the transaction could start
1830 * could start committing on us and eventually disappear. So1832 * committing on us and eventually disappear. So we must not
1831 * once we do this, we must not dereference transaction1833 * dereference transaction pointer again after calling
1832 * pointer again.1834 * stop_this_handle().
1833 */1835 */
1834 if (atomic_dec_and_test(&transaction->t_updates))1836 stop_this_handle(handle);
1835 wake_up(&journal->j_wait_updates);
1836
1837 rwsem_release(&journal->j_trans_commit_map, 1, _THIS_IP_);
1838 1837
1839 if (wait_for_commit)1838 if (wait_for_commit)
1840 err = jbd2_log_wait_commit(journal, tid);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);
1844free_and_exit:1841free_and_exit:
1845 /*1842 if (handle->h_rsv_handle)
1846 * Scope of the GFP_NOFS context is over here and so we can restore the1843 jbd2_free_handle(handle->h_rsv_handle);
1847 * original alloc context.
1848 */
1849 memalloc_nofs_restore(handle->saved_alloc_context);
1850 jbd2_free_handle(handle);1844 jbd2_free_handle(handle);
1851 return err;1845 return err;
1852}1846}

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t