jbd2: move the clearing of b_modified flag to the journal_unmap_buffer()
authorzhangyi (F) <yi.zhang@huawei.com>
Tue, 18 Feb 2020 10:58:22 +0000 (18:58 +0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 28 Feb 2020 14:42:14 +0000 (15:42 +0100)
[ Upstream commit 6a66a7ded12baa6ebbb2e3e82f8cb91382814839 ]

There is no need to delay the clearing of b_modified flag to the
transaction committing time when unmapping the journalled buffer, so
just move it to the journal_unmap_buffer().

Link: https://lore.kernel.org/r/20200213063821.30455-2-yi.zhang@huawei.com
Reviewed-by: Jan Kara <jack@suse.cz>
Signed-off-by: zhangyi (F) <yi.zhang@huawei.com>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Cc: stable@kernel.org
Signed-off-by: Sasha Levin <sashal@kernel.org>
fs/jbd2/commit.c
fs/jbd2/transaction.c

index d002b2b..2ee0013 100644 (file)
@@ -969,34 +969,21 @@ restart_loop:
                 * it. */
 
                /*
-               * A buffer which has been freed while still being journaled by
-               * a previous transaction.
-               */
-               if (buffer_freed(bh)) {
-                       /*
-                        * If the running transaction is the one containing
-                        * "add to orphan" operation (b_next_transaction !=
-                        * NULL), we have to wait for that transaction to
-                        * commit before we can really get rid of the buffer.
-                        * So just clear b_modified to not confuse transaction
-                        * credit accounting and refile the buffer to
-                        * BJ_Forget of the running transaction. If the just
-                        * committed transaction contains "add to orphan"
-                        * operation, we can completely invalidate the buffer
-                        * now. We are rather through in that since the
-                        * buffer may be still accessible when blocksize <
-                        * pagesize and it is attached to the last partial
-                        * page.
-                        */
-                       jh->b_modified = 0;
-                       if (!jh->b_next_transaction) {
-                               clear_buffer_freed(bh);
-                               clear_buffer_jbddirty(bh);
-                               clear_buffer_mapped(bh);
-                               clear_buffer_new(bh);
-                               clear_buffer_req(bh);
-                               bh->b_bdev = NULL;
-                       }
+                * A buffer which has been freed while still being journaled
+                * by a previous transaction, refile the buffer to BJ_Forget of
+                * the running transaction. If the just committed transaction
+                * contains "add to orphan" operation, we can completely
+                * invalidate the buffer now. We are rather through in that
+                * since the buffer may be still accessible when blocksize <
+                * pagesize and it is attached to the last partial page.
+                */
+               if (buffer_freed(bh) && !jh->b_next_transaction) {
+                       clear_buffer_freed(bh);
+                       clear_buffer_jbddirty(bh);
+                       clear_buffer_mapped(bh);
+                       clear_buffer_new(bh);
+                       clear_buffer_req(bh);
+                       bh->b_bdev = NULL;
                }
 
                if (buffer_jbddirty(bh)) {
index 799f96c..04dd065 100644 (file)
@@ -2213,14 +2213,16 @@ static int journal_unmap_buffer(journal_t *journal, struct buffer_head *bh,
                        return -EBUSY;
                }
                /*
-                * OK, buffer won't be reachable after truncate. We just set
-                * j_next_transaction to the running transaction (if there is
-                * one) and mark buffer as freed so that commit code knows it
-                * should clear dirty bits when it is done with the buffer.
+                * OK, buffer won't be reachable after truncate. We just clear
+                * b_modified to not confuse transaction credit accounting, and
+                * set j_next_transaction to the running transaction (if there
+                * is one) and mark buffer as freed so that commit code knows
+                * it should clear dirty bits when it is done with the buffer.
                 */
                set_buffer_freed(bh);
                if (journal->j_running_transaction && buffer_jbddirty(bh))
                        jh->b_next_transaction = journal->j_running_transaction;
+               jh->b_modified = 0;
                jbd2_journal_put_journal_head(jh);
                spin_unlock(&journal->j_list_lock);
                jbd_unlock_bh_state(bh);