diff mbox series

[08/17] writeback: Factor should_writeback_folio() out of write_cache_pages()

Message ID 20231218153553.807799-9-hch@lst.de (mailing list archive)
State New, archived
Headers show
Series [01/17] writeback: fix done_index when hitting the wbc->nr_to_write | expand

Commit Message

Christoph Hellwig Dec. 18, 2023, 3:35 p.m. UTC
From: "Matthew Wilcox (Oracle)" <willy@infradead.org>

Reduce write_cache_pages() by about 30 lines; much of it is commentary,
but it all bundles nicely into an obvious function.

Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 mm/page-writeback.c | 59 ++++++++++++++++++++++++---------------------
 1 file changed, 32 insertions(+), 27 deletions(-)

Comments

Jan Kara Dec. 21, 2023, 11:22 a.m. UTC | #1
On Mon 18-12-23 16:35:44, Christoph Hellwig wrote:
> From: "Matthew Wilcox (Oracle)" <willy@infradead.org>
> 
> Reduce write_cache_pages() by about 30 lines; much of it is commentary,
> but it all bundles nicely into an obvious function.
> 
> Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
> Signed-off-by: Christoph Hellwig <hch@lst.de>

One nit below, otherwise feel free to add:

Reviewed-by: Jan Kara <jack@suse.cz>

> +static bool should_writeback_folio(struct address_space *mapping,
> +		struct writeback_control *wbc, struct folio *folio)
> +{

I'd call this function folio_prepare_writeback() or something like that to
make it clearer that this function is not only about the decision whether
we want to write folio or not but we also clear the dirty bit &
writeprotect the folio in page tables.

								Honza
Christoph Hellwig Dec. 21, 2023, 12:23 p.m. UTC | #2
On Thu, Dec 21, 2023 at 12:22:06PM +0100, Jan Kara wrote:
> > +static bool should_writeback_folio(struct address_space *mapping,
> > +		struct writeback_control *wbc, struct folio *folio)
> > +{
> 
> I'd call this function folio_prepare_writeback() or something like that to
> make it clearer that this function is not only about the decision whether
> we want to write folio or not but we also clear the dirty bit &
> writeprotect the folio in page tables.

Fine with me.  I'll wait for willy to chime in if he has a strong
preference.
diff mbox series

Patch

diff --git a/mm/page-writeback.c b/mm/page-writeback.c
index 798e5264dc0353..2a004c0b9bdfbf 100644
--- a/mm/page-writeback.c
+++ b/mm/page-writeback.c
@@ -2406,6 +2406,36 @@  static void writeback_get_batch(struct address_space *mapping,
 			wbc_to_tag(wbc), &wbc->fbatch);
 }
 
+static bool should_writeback_folio(struct address_space *mapping,
+		struct writeback_control *wbc, struct folio *folio)
+{
+	/*
+	 * Folio truncated or invalidated. We can freely skip it then,
+	 * even for data integrity operations: the folio has disappeared
+	 * concurrently, so there could be no real expectation of this
+	 * data integrity operation even if there is now a new, dirty
+	 * folio at the same pagecache index.
+	 */
+	if (unlikely(folio->mapping != mapping))
+		return false;
+
+	/* Did somebody write it for us? */
+	if (!folio_test_dirty(folio))
+		return false;
+
+	if (folio_test_writeback(folio)) {
+		if (wbc->sync_mode == WB_SYNC_NONE)
+			return false;
+		folio_wait_writeback(folio);
+	}
+
+	BUG_ON(folio_test_writeback(folio));
+	if (!folio_clear_dirty_for_io(folio))
+		return false;
+
+	return true;
+}
+
 /**
  * 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
@@ -2470,38 +2500,13 @@  int write_cache_pages(struct address_space *mapping,
 			unsigned long nr;
 
 			folio_lock(folio);
-
-			/*
-			 * Page truncated or invalidated. We can freely skip it
-			 * then, even for data integrity operations: the page
-			 * has disappeared concurrently, so there could be no
-			 * real expectation of this data integrity operation
-			 * even if there is now a new, dirty page at the same
-			 * pagecache address.
-			 */
-			if (unlikely(folio->mapping != mapping)) {
-continue_unlock:
+			if (!should_writeback_folio(mapping, wbc, folio)) {
 				folio_unlock(folio);
 				continue;
 			}
 
-			if (!folio_test_dirty(folio)) {
-				/* someone wrote it for us */
-				goto continue_unlock;
-			}
-
-			if (folio_test_writeback(folio)) {
-				if (wbc->sync_mode != WB_SYNC_NONE)
-					folio_wait_writeback(folio);
-				else
-					goto continue_unlock;
-			}
-
-			BUG_ON(folio_test_writeback(folio));
-			if (!folio_clear_dirty_for_io(folio))
-				goto 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;