summaryrefslogtreecommitdiff
path: root/fs/mpage.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2026-03-31 10:28:08 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2026-03-31 10:28:08 -0700
commitdbf00d8d23b43a7a1d717e704c50651731d01d71 (patch)
treedc867bf11b8d40e598addcea8ee7efb1dcd54fe5 /fs/mpage.c
parentd0c3bcd5b8976159d835a897254048e078f447e6 (diff)
parent102e57d56f81fa5c5ed78f576101d1bf1b3e6fe2 (diff)
Merge tag 'fs_for_v7.0-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs
Pull udf fix from Jan Kara: "Fix for a race in UDF that can lead to memory corruption" * tag 'fs_for_v7.0-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs: udf: Fix race between file type conversion and writeback mpage: Provide variant of mpage_writepages() with own optional folio handler
Diffstat (limited to 'fs/mpage.c')
-rw-r--r--fs/mpage.c30
1 files changed, 24 insertions, 6 deletions
diff --git a/fs/mpage.c b/fs/mpage.c
index 7dae5afc2b9e..b3d9f231a04a 100644
--- a/fs/mpage.c
+++ b/fs/mpage.c
@@ -646,17 +646,24 @@ out:
}
/**
- * mpage_writepages - walk the list of dirty pages of the given address space & writepage() all of them
+ * __mpage_writepages - walk the list of dirty pages of the given address space
+ * & writepage() all of them
* @mapping: address space structure to write
* @wbc: subtract the number of written pages from *@wbc->nr_to_write
* @get_block: the filesystem's block mapper function.
+ * @write_folio: handler to call for each folio before calling
+ * mpage_write_folio()
*
* This is a library function, which implements the writepages()
- * address_space_operation.
+ * address_space_operation. It calls @write_folio handler for each folio. If
+ * the handler returns value > 0, it calls mpage_write_folio() to do the
+ * folio writeback.
*/
int
-mpage_writepages(struct address_space *mapping,
- struct writeback_control *wbc, get_block_t get_block)
+__mpage_writepages(struct address_space *mapping,
+ struct writeback_control *wbc, get_block_t get_block,
+ int (*write_folio)(struct folio *folio,
+ struct writeback_control *wbc))
{
struct mpage_data mpd = {
.get_block = get_block,
@@ -666,11 +673,22 @@ mpage_writepages(struct address_space *mapping,
int error;
blk_start_plug(&plug);
- while ((folio = writeback_iter(mapping, wbc, folio, &error)))
+ while ((folio = writeback_iter(mapping, wbc, folio, &error))) {
+ if (write_folio) {
+ error = write_folio(folio, wbc);
+ /*
+ * == 0 means folio is handled, < 0 means error. In
+ * both cases hand back control to writeback_iter()
+ */
+ if (error <= 0)
+ continue;
+ /* Let mpage_write_folio() handle the folio. */
+ }
error = mpage_write_folio(wbc, folio, &mpd);
+ }
if (mpd.bio)
mpage_bio_submit_write(mpd.bio);
blk_finish_plug(&plug);
return error;
}
-EXPORT_SYMBOL(mpage_writepages);
+EXPORT_SYMBOL(__mpage_writepages);