Commit 807d1fe3 authored by Matthew Wilcox (Oracle)'s avatar Matthew Wilcox (Oracle) Committed by Andrew Morton
Browse files

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: default avatarMatthew Wilcox (Oracle) <willy@infradead.org>
Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
Reviewed-by: default avatarBrian Foster <bfoster@redhat.com>
Reviewed-by: default avatarJan Kara <jack@suse.cz>
Acked-by: default avatarDave Chinner <dchinner@redhat.com>
Cc: Christian Brauner <brauner@kernel.org>
Cc: David Howells <dhowells@redhat.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
parent 751e0d55
Loading
Loading
Loading
Loading
+36 −39
Original line number Diff line number Diff line
@@ -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,16 +2468,15 @@ int write_cache_pages(struct address_space *mapping,

	folio_batch_init(&wbc->fbatch);

	while (wbc->index <= end) {
		int i;

	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)) {
@@ -2495,17 +2495,15 @@ int write_cache_pages(struct address_space *mapping,
		}

		/*
			 * 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 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.
		 * 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)
@@ -2515,7 +2513,6 @@ int write_cache_pages(struct address_space *mapping,
				goto done;
		}
	}
	}

	/*
	 * For range cyclic writeback we need to remember where we stopped so