On Mon, Jun 26, 2023 at 06:35:18PM +0100, Matthew Wilcox (Oracle) wrote: > Pull the post-processing of the writepage_t callback into a > separate function. That means changing writeback_finish() to > return NULL, and writeback_get_next() to call writeback_finish() > when we naturally run out of folios. > > Signed-off-by: Matthew Wilcox (Oracle) <willy@xxxxxxxxxxxxx> > --- > mm/page-writeback.c | 84 ++++++++++++++++++++++++--------------------- > 1 file changed, 44 insertions(+), 40 deletions(-) > > diff --git a/mm/page-writeback.c b/mm/page-writeback.c > index 659df2b5c7c0..ef61d7006c5e 100644 > --- a/mm/page-writeback.c > +++ b/mm/page-writeback.c > @@ -2360,7 +2360,7 @@ void tag_pages_for_writeback(struct address_space *mapping, > } > EXPORT_SYMBOL(tag_pages_for_writeback); > > -static int writeback_finish(struct address_space *mapping, > +static struct folio *writeback_finish(struct address_space *mapping, > struct writeback_control *wbc, bool done) > { > folio_batch_release(&wbc->fbatch); > @@ -2375,7 +2375,7 @@ static int writeback_finish(struct address_space *mapping, > if (wbc->range_cyclic || (wbc->range_whole && wbc->nr_to_write > 0)) > mapping->writeback_index = wbc->done_index; > > - return wbc->err; > + return NULL; Having a return value that is always NULL feels a bit weird vs just doing that return in the caller. > +static struct folio *writeback_iter_next(struct address_space *mapping, > + struct writeback_control *wbc, struct folio *folio, int error) > +{ > + if (unlikely(error)) { > + /* > + * Handle errors according to the type of writeback. > + * There's no need to continue for background writeback. > + * Just push done_index past this folio so media > + * errors won't choke writeout for the entire file. > + * For integrity writeback, we must process the entire > + * dirty set regardless of errors because the fs may > + * still have state to clear for each folio. In that > + * case we continue processing and return the first error. > + */ > + if (error == AOP_WRITEPAGE_ACTIVATE) { > + folio_unlock(folio); > + error = 0; Note there really shouldn't be any need for this in outside of the legacy >writepage case. But it might make sense to delay the removal until after ->writepage is gone to avoid bugs in conversions. > + } else if (wbc->sync_mode != WB_SYNC_ALL) { > + wbc->err = error; > + wbc->done_index = folio->index + > + folio_nr_pages(folio); Btw, I wonder if a folio_next_index helper for this might be useful as it's a pattern we have in a few places.