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
512512 }
513513 EXPORT_SYMBOL(jbd2_journal_start);
514514
515−void jbd2_journal_free_reserved(handle_t *handle)
515+static void __jbd2_journal_unreserve_handle(handle_t *handle)
516516 {
517517 journal_t *journal = handle->h_journal;
518518
519519 WARN_ON(!handle->h_reserved);
520520 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);
521526 jbd2_free_handle(handle);
522527 }
523528 EXPORT_SYMBOL(jbd2_journal_free_reserved);
@@ -655,6 +660,28 @@ error_out: · 131 unmodified lines
655660 return result;
656661 }
657662
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+}
658685
659686 /**
660687 * 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
677704 transaction_t *transaction = handle->h_transaction;
678705 journal_t *journal;
679706 tid_t tid;
680− int need_to_start, ret;
707+ int need_to_start;
681708
682709 /* If we've had an abort of any type, don't even think about
683710 * actually doing the restart! */
684711 if (is_handle_aborted(handle))
685712 return 0;
686713 journal = transaction->t_journal;
714+ tid = transaction->t_tid;
687715
688716 /*
689717 * First unlink the handle from its current transaction, and start the
690718 * commit on that.
691719 */
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);
707722 handle->h_transaction = NULL;
708− current->journal_info = NULL;
709723
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);
711729 need_to_start = !tid_geq(journal->j_commit_request, tid);
712730 read_unlock(&journal->j_state_lock);
713731 if (need_to_start)
714732 jbd2_log_start_commit(journal, tid);
715−
716− rwsem_release(&journal->j_trans_commit_map, 1, _THIS_IP_);
717733 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);
726735 }
727736 EXPORT_SYMBOL(jbd2__journal_restart);
728737
@@ -1718,16 +1727,12 @@ int jbd2_journal_stop(handle_t *handle) · 989 unmodified lines
17181727 * Handle is already detached from the transaction so there is
17191728 * nothing to do other than free the handle.
17201729 */
1721− if (handle->h_rsv_handle)
1722− jbd2_free_handle(handle->h_rsv_handle);
1730+ memalloc_nofs_restore(handle->saved_alloc_context);
17231731 goto free_and_exit;
17241732 }
17251733 journal = transaction->t_journal;
17261734 tid = transaction->t_tid;
17271735
1728− J_ASSERT(journal_current_handle() == handle);
1729− J_ASSERT(atomic_read(&transaction->t_updates) > 0);
1730−
17311736 if (is_handle_aborted(handle))
17321737 err = -EIO;
17331738
@@ -1797,9 +1802,6 @@ int jbd2_journal_stop(handle_t *handle) · 63 unmodified lines
17971802
17981803 if (handle->h_sync)
17991804 transaction->t_synchronous_commit = 1;
1800− current->journal_info = NULL;
1801− atomic_sub(handle->h_buffer_credits,
1802− &transaction->t_outstanding_credits);
18031805
18041806 /*
18051807 * 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
18261828 }
18271829
18281830 /*
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().
18331835 */
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);
18381837
18391838 if (wait_for_commit)
18401839 err = jbd2_log_wait_commit(journal, tid);
18411840
1842− if (handle->h_rsv_handle)
1843− jbd2_journal_free_reserved(handle->h_rsv_handle);
18441841 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);
18501844 jbd2_free_handle(handle);
18511845 return err;
18521846 }

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