+++ /dev/null
-From a4129775c6479663ad5f5cbbdc61517bfe03530c Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Tue, 5 Nov 2019 17:44:22 +0100
-Subject: jbd2: Drop pointless wakeup from jbd2_journal_stop()
-
-From: Jan Kara <jack@suse.cz>
-
-[ Upstream commit 5559b2d81b51de75cb7864bb1fbb82982f7e8fff ]
-
-When we drop last handle from a transaction and journal->j_barrier_count
-> 0, jbd2_journal_stop() wakes up journal->j_wait_transaction_locked
-wait queue. This looks pointless - wait for outstanding handles always
-happens on journal->j_wait_updates waitqueue.
-journal->j_wait_transaction_locked is used to wait for transaction state
-changes and by start_this_handle() for waiting until
-journal->j_barrier_count drops to 0. The first case is clearly
-irrelevant here since only jbd2 thread changes transaction state. The
-second case looks related but jbd2_journal_unlock_updates() is
-responsible for the wakeup in this case. So just drop the wakeup.
-
-Reviewed-by: Theodore Ts'o <tytso@mit.edu>
-Signed-off-by: Jan Kara <jack@suse.cz>
-Link: https://lore.kernel.org/r/20191105164437.32602-16-jack@suse.cz
-Signed-off-by: Theodore Ts'o <tytso@mit.edu>
-Stable-dep-of: f6b1a1cf1c3e ("ext4: fix use-after-free in ext4_ext_shift_extents")
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- fs/jbd2/transaction.c | 5 +----
- 1 file changed, 1 insertion(+), 4 deletions(-)
-
-diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c
-index ce66dbbf0f90..6d78648392f0 100644
---- a/fs/jbd2/transaction.c
-+++ b/fs/jbd2/transaction.c
-@@ -1850,11 +1850,8 @@ int jbd2_journal_stop(handle_t *handle)
- * once we do this, we must not dereference transaction
- * pointer again.
- */
-- if (atomic_dec_and_test(&transaction->t_updates)) {
-+ if (atomic_dec_and_test(&transaction->t_updates))
- wake_up(&journal->j_wait_updates);
-- if (journal->j_barrier_count)
-- wake_up(&journal->j_wait_transaction_locked);
-- }
-
- rwsem_release(&journal->j_trans_commit_map, 1, _THIS_IP_);
-
---
-2.35.1
-
+++ /dev/null
-From 598c77a12e153e9e93ccd16bd289141f0eea4a9e Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Tue, 5 Nov 2019 17:44:23 +0100
-Subject: jbd2: Factor out common parts of stopping and restarting a handle
-
-From: Jan Kara <jack@suse.cz>
-
-[ Upstream commit ec8b6f600e49dc87a8564807fec4193bf93ee2b5 ]
-
-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.
-
-Signed-off-by: Jan Kara <jack@suse.cz>
-Link: https://lore.kernel.org/r/20191105164437.32602-17-jack@suse.cz
-Signed-off-by: Theodore Ts'o <tytso@mit.edu>
-Stable-dep-of: f6b1a1cf1c3e ("ext4: fix use-after-free in ext4_ext_shift_extents")
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- fs/jbd2/transaction.c | 98 ++++++++++++++++++++-----------------------
- 1 file changed, 46 insertions(+), 52 deletions(-)
-
-diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c
-index 6d78648392f0..ee9a778c8fbe 100644
---- a/fs/jbd2/transaction.c
-+++ b/fs/jbd2/transaction.c
-@@ -514,12 +514,17 @@ handle_t *jbd2_journal_start(journal_t *journal, int nblocks)
- }
- EXPORT_SYMBOL(jbd2_journal_start);
-
--void jbd2_journal_free_reserved(handle_t *handle)
-+static void __jbd2_journal_unreserve_handle(handle_t *handle)
- {
- journal_t *journal = handle->h_journal;
-
- WARN_ON(!handle->h_reserved);
- sub_reserved_credits(journal, handle->h_buffer_credits);
-+}
-+
-+void jbd2_journal_free_reserved(handle_t *handle)
-+{
-+ __jbd2_journal_unreserve_handle(handle);
- jbd2_free_handle(handle);
- }
- EXPORT_SYMBOL(jbd2_journal_free_reserved);
-@@ -657,6 +662,28 @@ int jbd2_journal_extend(handle_t *handle, int nblocks)
- return result;
- }
-
-+static void stop_this_handle(handle_t *handle)
-+{
-+ transaction_t *transaction = handle->h_transaction;
-+ journal_t *journal = transaction->t_journal;
-+
-+ J_ASSERT(journal_current_handle() == handle);
-+ J_ASSERT(atomic_read(&transaction->t_updates) > 0);
-+ current->journal_info = NULL;
-+ atomic_sub(handle->h_buffer_credits,
-+ &transaction->t_outstanding_credits);
-+ if (handle->h_rsv_handle)
-+ __jbd2_journal_unreserve_handle(handle->h_rsv_handle);
-+ if (atomic_dec_and_test(&transaction->t_updates))
-+ wake_up(&journal->j_wait_updates);
-+
-+ rwsem_release(&journal->j_trans_commit_map, 1, _THIS_IP_);
-+ /*
-+ * Scope of the GFP_NOFS context is over here and so we can restore the
-+ * original alloc context.
-+ */
-+ memalloc_nofs_restore(handle->saved_alloc_context);
-+}
-
- /**
- * int jbd2_journal_restart() - restart a handle .
-@@ -679,52 +706,34 @@ int jbd2__journal_restart(handle_t *handle, int nblocks, gfp_t gfp_mask)
- transaction_t *transaction = handle->h_transaction;
- journal_t *journal;
- tid_t tid;
-- int need_to_start, ret;
-+ int need_to_start;
-
- /* If we've had an abort of any type, don't even think about
- * actually doing the restart! */
- if (is_handle_aborted(handle))
- return 0;
- journal = transaction->t_journal;
-+ tid = transaction->t_tid;
-
- /*
- * First unlink the handle from its current transaction, and start the
- * commit on that.
- */
-- J_ASSERT(atomic_read(&transaction->t_updates) > 0);
-- J_ASSERT(journal_current_handle() == handle);
--
-- read_lock(&journal->j_state_lock);
-- spin_lock(&transaction->t_handle_lock);
-- atomic_sub(handle->h_buffer_credits,
-- &transaction->t_outstanding_credits);
-- if (handle->h_rsv_handle) {
-- sub_reserved_credits(journal,
-- handle->h_rsv_handle->h_buffer_credits);
-- }
-- if (atomic_dec_and_test(&transaction->t_updates))
-- wake_up(&journal->j_wait_updates);
-- tid = transaction->t_tid;
-- spin_unlock(&transaction->t_handle_lock);
-+ jbd_debug(2, "restarting handle %p\n", handle);
-+ stop_this_handle(handle);
- handle->h_transaction = NULL;
-- current->journal_info = NULL;
-
-- jbd_debug(2, "restarting handle %p\n", handle);
-+ /*
-+ * TODO: If we use READ_ONCE / WRITE_ONCE for j_commit_request we can
-+ * get rid of pointless j_state_lock traffic like this.
-+ */
-+ read_lock(&journal->j_state_lock);
- need_to_start = !tid_geq(journal->j_commit_request, tid);
- read_unlock(&journal->j_state_lock);
- if (need_to_start)
- jbd2_log_start_commit(journal, tid);
--
-- rwsem_release(&journal->j_trans_commit_map, 1, _THIS_IP_);
- handle->h_buffer_credits = nblocks;
-- /*
-- * Restore the original nofs context because the journal restart
-- * is basically the same thing as journal stop and start.
-- * start_this_handle will start a new nofs context.
-- */
-- memalloc_nofs_restore(handle->saved_alloc_context);
-- ret = start_this_handle(journal, handle, gfp_mask);
-- return ret;
-+ return start_this_handle(journal, handle, gfp_mask);
- }
- EXPORT_SYMBOL(jbd2__journal_restart);
-
-@@ -1734,16 +1743,12 @@ int jbd2_journal_stop(handle_t *handle)
- * Handle is already detached from the transaction so there is
- * nothing to do other than free the handle.
- */
-- if (handle->h_rsv_handle)
-- jbd2_free_handle(handle->h_rsv_handle);
-+ memalloc_nofs_restore(handle->saved_alloc_context);
- goto free_and_exit;
- }
- journal = transaction->t_journal;
- tid = transaction->t_tid;
-
-- J_ASSERT(journal_current_handle() == handle);
-- J_ASSERT(atomic_read(&transaction->t_updates) > 0);
--
- if (is_handle_aborted(handle))
- err = -EIO;
-
-@@ -1813,9 +1818,6 @@ int jbd2_journal_stop(handle_t *handle)
-
- if (handle->h_sync)
- transaction->t_synchronous_commit = 1;
-- current->journal_info = NULL;
-- atomic_sub(handle->h_buffer_credits,
-- &transaction->t_outstanding_credits);
-
- /*
- * If the handle is marked SYNC, we need to set another commit
-@@ -1845,27 +1847,19 @@ int jbd2_journal_stop(handle_t *handle)
- }
-
- /*
-- * Once we drop t_updates, if it goes to zero the transaction
-- * could start committing on us and eventually disappear. So
-- * once we do this, we must not dereference transaction
-- * pointer again.
-+ * Once stop_this_handle() drops t_updates, the transaction could start
-+ * committing on us and eventually disappear. So we must not
-+ * dereference transaction pointer again after calling
-+ * stop_this_handle().
- */
-- if (atomic_dec_and_test(&transaction->t_updates))
-- wake_up(&journal->j_wait_updates);
--
-- rwsem_release(&journal->j_trans_commit_map, 1, _THIS_IP_);
-+ stop_this_handle(handle);
-
- if (wait_for_commit)
- err = jbd2_log_wait_commit(journal, tid);
-
-- if (handle->h_rsv_handle)
-- jbd2_journal_free_reserved(handle->h_rsv_handle);
- free_and_exit:
-- /*
-- * Scope of the GFP_NOFS context is over here and so we can restore the
-- * original alloc context.
-- */
-- memalloc_nofs_restore(handle->saved_alloc_context);
-+ if (handle->h_rsv_handle)
-+ jbd2_free_handle(handle->h_rsv_handle);
- jbd2_free_handle(handle);
- return err;
- }
---
-2.35.1
-
+++ /dev/null
-From 526e6da0a66d8df0bb8243398f73b1ebf9279a78 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Tue, 5 Nov 2019 17:44:20 +0100
-Subject: jbd2: Reorganize jbd2_journal_stop()
-
-From: Jan Kara <jack@suse.cz>
-
-[ Upstream commit dfaf5ffda227be3e867fee7c0f6a66749392fbd0 ]
-
-Move code in jbd2_journal_stop() around a bit. It removes some
-unnecessary code duplication and will make factoring out parts common
-with jbd2__journal_restart() easier.
-
-Reviewed-by: Theodore Ts'o <tytso@mit.edu>
-Signed-off-by: Jan Kara <jack@suse.cz>
-Link: https://lore.kernel.org/r/20191105164437.32602-14-jack@suse.cz
-Signed-off-by: Theodore Ts'o <tytso@mit.edu>
-Stable-dep-of: f6b1a1cf1c3e ("ext4: fix use-after-free in ext4_ext_shift_extents")
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- fs/jbd2/transaction.c | 40 ++++++++++++++++------------------------
- 1 file changed, 16 insertions(+), 24 deletions(-)
-
-diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c
-index 09f4d00fece2..ce66dbbf0f90 100644
---- a/fs/jbd2/transaction.c
-+++ b/fs/jbd2/transaction.c
-@@ -1722,41 +1722,34 @@ int jbd2_journal_stop(handle_t *handle)
- tid_t tid;
- pid_t pid;
-
-+ if (--handle->h_ref > 0) {
-+ jbd_debug(4, "h_ref %d -> %d\n", handle->h_ref + 1,
-+ handle->h_ref);
-+ if (is_handle_aborted(handle))
-+ return -EIO;
-+ return 0;
-+ }
- if (!transaction) {
- /*
-- * Handle is already detached from the transaction so
-- * there is nothing to do other than decrease a refcount,
-- * or free the handle if refcount drops to zero
-+ * Handle is already detached from the transaction so there is
-+ * nothing to do other than free the handle.
- */
-- if (--handle->h_ref > 0) {
-- jbd_debug(4, "h_ref %d -> %d\n", handle->h_ref + 1,
-- handle->h_ref);
-- return err;
-- } else {
-- if (handle->h_rsv_handle)
-- jbd2_free_handle(handle->h_rsv_handle);
-- goto free_and_exit;
-- }
-+ if (handle->h_rsv_handle)
-+ jbd2_free_handle(handle->h_rsv_handle);
-+ goto free_and_exit;
- }
- journal = transaction->t_journal;
-+ tid = transaction->t_tid;
-
- J_ASSERT(journal_current_handle() == handle);
-+ J_ASSERT(atomic_read(&transaction->t_updates) > 0);
-
- if (is_handle_aborted(handle))
- err = -EIO;
-- else
-- J_ASSERT(atomic_read(&transaction->t_updates) > 0);
--
-- if (--handle->h_ref > 0) {
-- jbd_debug(4, "h_ref %d -> %d\n", handle->h_ref + 1,
-- handle->h_ref);
-- return err;
-- }
-
- jbd_debug(4, "Handle %p going down\n", handle);
- trace_jbd2_handle_stats(journal->j_fs_dev->bd_dev,
-- transaction->t_tid,
-- handle->h_type, handle->h_line_no,
-+ tid, handle->h_type, handle->h_line_no,
- jiffies - handle->h_start_jiffies,
- handle->h_sync, handle->h_requested_credits,
- (handle->h_requested_credits -
-@@ -1841,7 +1834,7 @@ int jbd2_journal_stop(handle_t *handle)
- jbd_debug(2, "transaction too old, requesting commit for "
- "handle %p\n", handle);
- /* This is non-blocking */
-- jbd2_log_start_commit(journal, transaction->t_tid);
-+ jbd2_log_start_commit(journal, tid);
-
- /*
- * Special case: JBD2_SYNC synchronous updates require us
-@@ -1857,7 +1850,6 @@ int jbd2_journal_stop(handle_t *handle)
- * once we do this, we must not dereference transaction
- * pointer again.
- */
-- tid = transaction->t_tid;
- if (atomic_dec_and_test(&transaction->t_updates)) {
- wake_up(&journal->j_wait_updates);
- if (journal->j_barrier_count)
---
-2.35.1
-