]> Git Repo - linux.git/blobdiff - fs/jbd2/commit.c
enetc: Migrate to PHYLINK and PCS_LYNX
[linux.git] / fs / jbd2 / commit.c
index 2494095e0340b6c30c450a01c575304b3f4fa4f3..6d2da8ad0e6f51a8f2c1b1abf1455cd4654c92d9 100644 (file)
@@ -775,7 +775,7 @@ start_journal_io:
        if (commit_transaction->t_need_data_flush &&
            (journal->j_fs_dev != journal->j_dev) &&
            (journal->j_flags & JBD2_BARRIER))
-               blkdev_issue_flush(journal->j_fs_dev, GFP_NOFS, NULL);
+               blkdev_issue_flush(journal->j_fs_dev, GFP_NOFS);
 
        /* Done it all: now write the commit record asynchronously. */
        if (jbd2_has_feature_async_commit(journal)) {
@@ -882,7 +882,7 @@ start_journal_io:
        stats.run.rs_blocks_logged++;
        if (jbd2_has_feature_async_commit(journal) &&
            journal->j_flags & JBD2_BARRIER) {
-               blkdev_issue_flush(journal->j_dev, GFP_NOFS, NULL);
+               blkdev_issue_flush(journal->j_dev, GFP_NOFS);
        }
 
        if (err)
@@ -976,29 +976,34 @@ restart_loop:
                 * it. */
 
                /*
-               * A buffer which has been freed while still being journaled by
-               * a previous transaction.
-               */
-               if (buffer_freed(bh)) {
+                * 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) {
+                       struct address_space *mapping;
+
+                       clear_buffer_freed(bh);
+                       clear_buffer_jbddirty(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.
+                        * Block device buffers need to stay mapped all the
+                        * time, so it is enough to clear buffer_jbddirty and
+                        * buffer_freed bits. For the file mapping buffers (i.e.
+                        * journalled data) we need to unmap buffer and clear
+                        * more bits. We also need to be careful about the check
+                        * because the data page mapping can get cleared under
+                        * our hands. Note that if mapping == NULL, we don't
+                        * need to make buffer unmapped because the page is
+                        * already detached from the mapping and buffers cannot
+                        * get reused.
                         */
-                       jh->b_modified = 0;
-                       if (!jh->b_next_transaction) {
-                               clear_buffer_freed(bh);
-                               clear_buffer_jbddirty(bh);
+                       mapping = READ_ONCE(bh->b_page->mapping);
+                       if (mapping && !sb_is_blkdev_sb(mapping->host->i_sb)) {
                                clear_buffer_mapped(bh);
                                clear_buffer_new(bh);
                                clear_buffer_req(bh);
This page took 0.029497 seconds and 4 git commands to generate.