]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blobdiff - fs/jbd2/commit.c
jbd2: move the clearing of b_modified flag to the journal_unmap_buffer()
[mirror_ubuntu-bionic-kernel.git] / fs / jbd2 / commit.c
index 3c1c31321d9bdde030191cae31cadd9856d597fe..89cbf45a1dcda1b26f49bb719f420a9f46353e1d 100644 (file)
@@ -189,14 +189,15 @@ static int journal_wait_on_commit_record(journal_t *journal,
  * use writepages() because with dealyed allocation we may be doing
  * block allocation in writepages().
  */
-static int journal_submit_inode_data_buffers(struct address_space *mapping)
+static int journal_submit_inode_data_buffers(struct address_space *mapping,
+               loff_t dirty_start, loff_t dirty_end)
 {
        int ret;
        struct writeback_control wbc = {
                .sync_mode =  WB_SYNC_ALL,
                .nr_to_write = mapping->nrpages * 2,
-               .range_start = 0,
-               .range_end = i_size_read(mapping->host),
+               .range_start = dirty_start,
+               .range_end = dirty_end,
        };
 
        ret = generic_writepages(mapping, &wbc);
@@ -220,6 +221,9 @@ static int journal_submit_data_buffers(journal_t *journal,
 
        spin_lock(&journal->j_list_lock);
        list_for_each_entry(jinode, &commit_transaction->t_inode_list, i_list) {
+               loff_t dirty_start = jinode->i_dirty_start;
+               loff_t dirty_end = jinode->i_dirty_end;
+
                if (!(jinode->i_flags & JI_WRITE_DATA))
                        continue;
                mapping = jinode->i_vfs_inode->i_mapping;
@@ -232,7 +236,8 @@ static int journal_submit_data_buffers(journal_t *journal,
                 * only allocated blocks here.
                 */
                trace_jbd2_submit_inode_data(jinode->i_vfs_inode);
-               err = journal_submit_inode_data_buffers(mapping);
+               err = journal_submit_inode_data_buffers(mapping, dirty_start,
+                               dirty_end);
                if (!ret)
                        ret = err;
                spin_lock(&journal->j_list_lock);
@@ -259,12 +264,16 @@ static int journal_finish_inode_data_buffers(journal_t *journal,
        /* For locking, see the comment in journal_submit_data_buffers() */
        spin_lock(&journal->j_list_lock);
        list_for_each_entry(jinode, &commit_transaction->t_inode_list, i_list) {
+               loff_t dirty_start = jinode->i_dirty_start;
+               loff_t dirty_end = jinode->i_dirty_end;
+
                if (!(jinode->i_flags & JI_WAIT_DATA))
                        continue;
                jinode->i_flags |= JI_COMMIT_RUNNING;
                spin_unlock(&journal->j_list_lock);
-               err = filemap_fdatawait_keep_errors(
-                               jinode->i_vfs_inode->i_mapping);
+               err = filemap_fdatawait_range_keep_errors(
+                               jinode->i_vfs_inode->i_mapping, dirty_start,
+                               dirty_end);
                if (!ret)
                        ret = err;
                spin_lock(&journal->j_list_lock);
@@ -284,6 +293,8 @@ static int journal_finish_inode_data_buffers(journal_t *journal,
                                &jinode->i_transaction->t_inode_list);
                } else {
                        jinode->i_transaction = NULL;
+                       jinode->i_dirty_start = 0;
+                       jinode->i_dirty_end = 0;
                }
        }
        spin_unlock(&journal->j_list_lock);
@@ -693,9 +704,11 @@ void jbd2_journal_commit_transaction(journal_t *journal)
                            the last tag we set up. */
 
                        tag->t_flags |= cpu_to_be16(JBD2_FLAG_LAST_TAG);
-
-                       jbd2_descriptor_block_csum_set(journal, descriptor);
 start_journal_io:
+                       if (descriptor)
+                               jbd2_descriptor_block_csum_set(journal,
+                                                       descriptor);
+
                        for (i = 0; i < bufs; i++) {
                                struct buffer_head *bh = wbuf[i];
                                /*
@@ -713,7 +726,6 @@ start_journal_io:
                                submit_bh(REQ_OP_WRITE, REQ_SYNC, bh);
                        }
                        cond_resched();
-                       stats.run.rs_blocks_logged += bufs;
 
                        /* Force a new descriptor to be generated next
                            time round the loop. */
@@ -800,6 +812,7 @@ start_journal_io:
                if (unlikely(!buffer_uptodate(bh)))
                        err = -EIO;
                jbd2_unfile_log_bh(bh);
+               stats.run.rs_blocks_logged++;
 
                /*
                 * The list contains temporary buffer heads created by
@@ -845,6 +858,7 @@ start_journal_io:
                BUFFER_TRACE(bh, "ph5: control buffer writeout done: unfile");
                clear_buffer_jwrite(bh);
                jbd2_unfile_log_bh(bh);
+               stats.run.rs_blocks_logged++;
                __brelse(bh);           /* One for getblk */
                /* AKPM: bforget here */
        }
@@ -866,6 +880,7 @@ start_journal_io:
        }
        if (cbh)
                err = journal_wait_on_commit_record(journal, cbh);
+       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);
@@ -958,34 +973,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)) {