]> www.infradead.org Git - users/willy/pagecache.git/commitdiff
writeback: Factor writeback_get_batch() out of write_cache_pages()
authorMatthew Wilcox (Oracle) <willy@infradead.org>
Thu, 22 Jun 2023 21:01:59 +0000 (17:01 -0400)
committerMatthew Wilcox (Oracle) <willy@infradead.org>
Wed, 28 Jun 2023 19:06:39 +0000 (15:06 -0400)
This simple helper will be the basis of the writeback iterator.
To make this work, we need to remember the current index
and end positions in writeback_control.

Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
include/linux/writeback.h
mm/page-writeback.c

index 5b7d11f540132e4c42cf9ca3c403195a5b0bc793..7dd050b40e4b40dc2d11a7eb59dc2ca4320b6c85 100644 (file)
@@ -54,6 +54,8 @@ struct writeback_control {
        loff_t range_end;
 
        struct folio_batch fbatch;
+       pgoff_t index;
+       pgoff_t end;            /* Inclusive */
        pgoff_t done_index;
        int err;
 
index b5421510b593cce517bc08d7a9731432e1c363ec..1a6a919fed2b10f210b0e304ebe8d668242818e9 100644 (file)
@@ -2378,6 +2378,22 @@ static int writeback_finish(struct address_space *mapping,
        return wbc->err;
 }
 
+static void writeback_get_batch(struct address_space *mapping,
+               struct writeback_control *wbc)
+{
+       xa_mark_t tag;
+
+       if (wbc->sync_mode == WB_SYNC_ALL || wbc->tagged_writepages)
+               tag = PAGECACHE_TAG_TOWRITE;
+       else
+               tag = PAGECACHE_TAG_DIRTY;
+
+       folio_batch_release(&wbc->fbatch);
+       cond_resched();
+       filemap_get_folios_tag(mapping, &wbc->index, wbc->end, tag,
+                       &wbc->fbatch);
+}
+
 /**
  * write_cache_pages - walk the list of dirty pages of the given address space and write all of them.
  * @mapping: address space structure to write
@@ -2414,41 +2430,32 @@ int write_cache_pages(struct address_space *mapping,
                      void *data)
 {
        int error;
-       int nr_folios;
-       pgoff_t index;
-       pgoff_t end;            /* Inclusive */
-       xa_mark_t tag;
 
        if (wbc->range_cyclic) {
-               index = mapping->writeback_index; /* prev offset */
-               end = -1;
+               wbc->index = mapping->writeback_index; /* prev offset */
+               wbc->end = -1;
        } else {
-               index = wbc->range_start >> PAGE_SHIFT;
-               end = wbc->range_end >> PAGE_SHIFT;
+               wbc->index = wbc->range_start >> PAGE_SHIFT;
+               wbc->end = wbc->range_end >> PAGE_SHIFT;
                if (wbc->range_start == 0 && wbc->range_end == LLONG_MAX)
                        wbc->range_whole = 1;
        }
-       if (wbc->sync_mode == WB_SYNC_ALL || wbc->tagged_writepages) {
-               tag_pages_for_writeback(mapping, index, end);
-               tag = PAGECACHE_TAG_TOWRITE;
-       } else {
-               tag = PAGECACHE_TAG_DIRTY;
-       }
+       if (wbc->sync_mode == WB_SYNC_ALL || wbc->tagged_writepages)
+               tag_pages_for_writeback(mapping, wbc->index, wbc->end);
 
-       wbc->done_index = index;
+       wbc->done_index = wbc->index;
        folio_batch_init(&wbc->fbatch);
        wbc->err = 0;
 
-       while (index <= end) {
+       while (wbc->index <= wbc->end) {
                int i;
 
-               nr_folios = filemap_get_folios_tag(mapping, &index, end,
-                               tag, &wbc->fbatch);
+               writeback_get_batch(mapping, wbc);
 
-               if (nr_folios == 0)
+               if (wbc->fbatch.nr == 0)
                        break;
 
-               for (i = 0; i < nr_folios; i++) {
+               for (i = 0; i < wbc->fbatch.nr; i++) {
                        struct folio *folio = wbc->fbatch.folios[i];
                        unsigned long nr;
 
@@ -2526,8 +2533,6 @@ continue_unlock:
                            wbc->sync_mode == WB_SYNC_NONE)
                                return writeback_finish(mapping, wbc, true);
                }
-               folio_batch_release(&wbc->fbatch);
-               cond_resched();
        }
 
        return writeback_finish(mapping, wbc, false);