]> git.ipfire.org Git - thirdparty/kernel/linux.git/blobdiff - mm/page-writeback.c
writeback: only update ->writeback_index for range_cyclic writeback
[thirdparty/kernel/linux.git] / mm / page-writeback.c
index 3f255534986a2fda07e2d35187bb385f64749c5c..f02014007b57ccdbb397f254ba1d15b0c73d0519 100644 (file)
@@ -2403,7 +2403,6 @@ int write_cache_pages(struct address_space *mapping,
        pgoff_t index;
        pgoff_t end;            /* Inclusive */
        pgoff_t done_index;
-       int range_whole = 0;
        xa_mark_t tag;
 
        folio_batch_init(&fbatch);
@@ -2413,8 +2412,6 @@ int write_cache_pages(struct address_space *mapping,
        } else {
                index = wbc->range_start >> PAGE_SHIFT;
                end = wbc->range_end >> PAGE_SHIFT;
-               if (wbc->range_start == 0 && wbc->range_end == LLONG_MAX)
-                       range_whole = 1;
        }
        if (wbc->sync_mode == WB_SYNC_ALL || wbc->tagged_writepages) {
                tag_pages_for_writeback(mapping, index, end);
@@ -2473,6 +2470,7 @@ continue_unlock:
                        trace_wbc_writepage(wbc, inode_to_bdi(mapping->host));
                        error = writepage(folio, wbc, data);
                        nr = folio_nr_pages(folio);
+                       wbc->nr_to_write -= nr;
                        if (unlikely(error)) {
                                /*
                                 * Handle errors according to the type of
@@ -2505,7 +2503,7 @@ continue_unlock:
                         * keep going until we have written all the pages
                         * we tagged for writeback prior to entering this loop.
                         */
-                       wbc->nr_to_write -= nr;
+                       done_index = folio->index + nr;
                        if (wbc->nr_to_write <= 0 &&
                            wbc->sync_mode == WB_SYNC_NONE) {
                                done = 1;
@@ -2517,14 +2515,21 @@ continue_unlock:
        }
 
        /*
-        * If we hit the last page and there is more work to be done: wrap
-        * back the index back to the start of the file for the next
-        * time we are called.
+        * For range cyclic writeback we need to remember where we stopped so
+        * that we can continue there next time we are called.  If  we hit the
+        * last page and there is more work to be done, wrap back to the start
+        * of the file.
+        *
+        * For non-cyclic writeback we always start looking up at the beginning
+        * of the file if we are called again, which can only happen due to
+        * -ENOMEM from the file system.
         */
-       if (wbc->range_cyclic && !done)
-               done_index = 0;
-       if (wbc->range_cyclic || (range_whole && wbc->nr_to_write > 0))
-               mapping->writeback_index = done_index;
+       if (wbc->range_cyclic) {
+               if (done)
+                       mapping->writeback_index = done_index;
+               else
+                       mapping->writeback_index = 0;
+       }
 
        return ret;
 }
@@ -2535,7 +2540,9 @@ static int writepage_cb(struct folio *folio, struct writeback_control *wbc,
 {
        struct address_space *mapping = data;
        int ret = mapping->a_ops->writepage(&folio->page, wbc);
-       mapping_set_error(mapping, ret);
+
+       if (ret < 0)
+               mapping_set_error(mapping, ret);
        return ret;
 }