diff options
author | Matthew Wilcox (Oracle) <willy@infradead.org> | 2024-02-15 09:36:44 +0300 |
---|---|---|
committer | Andrew Morton <akpm@linux-foundation.org> | 2024-02-24 04:48:36 +0300 |
commit | 807d1fe36077decf6f4ef8d4b63a084760a5c5fc (patch) | |
tree | aada37024a42396ccefb080eb0d7c6a4efc1e00a | |
parent | 751e0d559c62a87dc828af22c3c58dc078c734e3 (diff) | |
download | linux-807d1fe36077decf6f4ef8d4b63a084760a5c5fc.tar.xz |
writeback: simplify the loops in write_cache_pages()
Collapse the two nested loops into one. This is needed as a step towards
turning this into an iterator.
Note that this drops the "index <= end" check in the previous outer loop
and just relies on filemap_get_folios_tag() to return 0 entries when index
> end. This actually has a subtle implication when end == -1 because then
the returned index will be -1 as well and thus if there is page present on
index -1, we could be looping indefinitely. But as the comment in
filemap_get_folios_tag documents this as already broken anyway we should
not worry about it here either. The fix for that would probably a change
to the filemap_get_folios_tag() calling convention.
[hch@lst.de: update the commit log per Jan]
Link: https://lkml.kernel.org/r/20240215063649.2164017-10-hch@lst.de
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Brian Foster <bfoster@redhat.com>
Reviewed-by: Jan Kara <jack@suse.cz>
Acked-by: Dave Chinner <dchinner@redhat.com>
Cc: Christian Brauner <brauner@kernel.org>
Cc: David Howells <dhowells@redhat.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
-rw-r--r-- | mm/page-writeback.c | 75 |
1 files changed, 36 insertions, 39 deletions
diff --git a/mm/page-writeback.c b/mm/page-writeback.c index 5b8dbbef7137..358ce3ade9ad 100644 --- a/mm/page-writeback.c +++ b/mm/page-writeback.c @@ -2454,6 +2454,7 @@ int write_cache_pages(struct address_space *mapping, int error; struct folio *folio; pgoff_t end; /* Inclusive */ + int i = 0; if (wbc->range_cyclic) { wbc->index = mapping->writeback_index; /* prev offset */ @@ -2467,53 +2468,49 @@ int write_cache_pages(struct address_space *mapping, folio_batch_init(&wbc->fbatch); - while (wbc->index <= end) { - int i; - - writeback_get_batch(mapping, wbc); - + for (;;) { + if (i == wbc->fbatch.nr) { + writeback_get_batch(mapping, wbc); + i = 0; + } if (wbc->fbatch.nr == 0) break; - for (i = 0; i < wbc->fbatch.nr; i++) { - folio = wbc->fbatch.folios[i]; + folio = wbc->fbatch.folios[i++]; - folio_lock(folio); - if (!folio_prepare_writeback(mapping, wbc, folio)) { - folio_unlock(folio); - continue; - } + folio_lock(folio); + if (!folio_prepare_writeback(mapping, wbc, folio)) { + folio_unlock(folio); + continue; + } - trace_wbc_writepage(wbc, inode_to_bdi(mapping->host)); + trace_wbc_writepage(wbc, inode_to_bdi(mapping->host)); - error = writepage(folio, wbc, data); - wbc->nr_to_write -= folio_nr_pages(folio); + error = writepage(folio, wbc, data); + wbc->nr_to_write -= folio_nr_pages(folio); - if (error == AOP_WRITEPAGE_ACTIVATE) { - folio_unlock(folio); - error = 0; - } + if (error == AOP_WRITEPAGE_ACTIVATE) { + folio_unlock(folio); + error = 0; + } - /* - * For integrity writeback we have to keep going until - * we have written all the folios we tagged for - * writeback above, even if we run past wbc->nr_to_write - * or encounter errors. - * We stash away the first error we encounter in - * wbc->saved_err so that it can be retrieved when we're - * done. This is because the file system may still have - * state to clear for each folio. - * - * For background writeback we exit as soon as we run - * past wbc->nr_to_write or encounter the first error. - */ - if (wbc->sync_mode == WB_SYNC_ALL) { - if (error && !ret) - ret = error; - } else { - if (error || wbc->nr_to_write <= 0) - goto done; - } + /* + * For integrity writeback we have to keep going until we have + * written all the folios we tagged for writeback above, even if + * we run past wbc->nr_to_write or encounter errors. + * We stash away the first error we encounter in wbc->saved_err + * so that it can be retrieved when we're done. This is because + * the file system may still have state to clear for each folio. + * + * For background writeback we exit as soon as we run past + * wbc->nr_to_write or encounter the first error. + */ + if (wbc->sync_mode == WB_SYNC_ALL) { + if (error && !ret) + ret = error; + } else { + if (error || wbc->nr_to_write <= 0) + goto done; } } |