netfs: Fix the loop that unmarks folios after writing to the cache
authorDavid Howells <dhowells@redhat.com>
Fri, 5 Jan 2024 22:03:58 +0000 (22:03 +0000)
committerDavid Howells <dhowells@redhat.com>
Fri, 5 Jan 2024 23:13:48 +0000 (23:13 +0000)
In the loop in netfs_rreq_unmark_after_write() that removes the PG_fscache
from folios after they've been written to the cache, as soon as we remove
the mark from a multipage folio, it can get split - and then we might see a
fragment of folio again.

Guard against this by advancing the 'unlocked' tracker to the index of the
last page in the folio to avoid a double removal of the PG_fscache mark.

Reported-by: Marc Dionne <marc.dionne@auristor.com>
Signed-off-by: David Howells <dhowells@redhat.com>
cc: Matthew Wilcox <willy@infradead.org>
cc: linux-afs@lists.infradead.org
cc: linux-cachefs@redhat.com
cc: linux-fsdevel@vger.kernel.org
cc: linux-mm@kvack.org

fs/netfs/buffered_write.c
fs/netfs/io.c

index 6cd8f7422e9ab88bebdcf54f5ef0f5edb92c6ab5..0b2b7a60dabc040dc8b1623f9d47275dbf0e8b5d 100644 (file)
@@ -698,6 +698,7 @@ static void netfs_pages_written_back(struct netfs_io_request *wreq)
        end_wb:
                if (folio_test_fscache(folio))
                        folio_end_fscache(folio);
+               xas_advance(&xas, folio_next_index(folio) - 1);
                folio_end_writeback(folio);
        }
 
index 5b5af96cd4b95bc445132613a6c6249b6000c223..4309edf338627eee2963e1520ab6485a483e1c5d 100644 (file)
@@ -126,7 +126,7 @@ static void netfs_rreq_unmark_after_write(struct netfs_io_request *rreq,
                         */
                        if (have_unlocked && folio_index(folio) <= unlocked)
                                continue;
-                       unlocked = folio_index(folio);
+                       unlocked = folio_next_index(folio) - 1;
                        trace_netfs_folio(folio, netfs_folio_trace_end_copy);
                        folio_end_fscache(folio);
                        have_unlocked = true;