[PATCH v2 11/16] iomap: replace ->submit_ioend() with generic ->writeback_complete() for writeback

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



As part of the larger effort to have iomap buffered io code support
generic io, replace submit_ioend() with writeback_complete() and move the
bio ioend code into a helper function, iomap_bio_writeback_complete(),
that callers using bios can directly invoke.

No functional changes.

Signed-off-by: Joanne Koong <joannelkoong@xxxxxxxxx>
---
 .../filesystems/iomap/operations.rst          | 18 ++++----
 fs/iomap/buffered-io-bio.c                    | 42 ++++++++++++++++++-
 fs/iomap/buffered-io.c                        | 38 +++--------------
 fs/iomap/internal.h                           |  4 +-
 fs/xfs/xfs_aops.c                             | 14 ++++++-
 include/linux/iomap.h                         | 26 ++++++++----
 6 files changed, 88 insertions(+), 54 deletions(-)

diff --git a/Documentation/filesystems/iomap/operations.rst b/Documentation/filesystems/iomap/operations.rst
index 5d018d504145..47213c810622 100644
--- a/Documentation/filesystems/iomap/operations.rst
+++ b/Documentation/filesystems/iomap/operations.rst
@@ -291,7 +291,7 @@ The ``ops`` structure must be specified and is as follows:
 
  struct iomap_writeback_ops {
      int (*writeback_folio)(struct iomap_writeback_folio_range *ctx);
-     int (*submit_ioend)(struct iomap_writepage_ctx *wpc, int status);
+     int (*writeback_complete)(struct iomap_writepage_ctx *wpc, int status);
      void (*discard_folio)(struct folio *folio, loff_t pos);
  };
 
@@ -319,13 +319,15 @@ The fields are as follows:
 
     This function must be supplied by the filesystem.
 
-  - ``submit_ioend``: Allows the file systems to hook into writeback bio
-    submission.
-    This might include pre-write space accounting updates, or installing
-    a custom ``->bi_end_io`` function for internal purposes, such as
-    deferring the ioend completion to a workqueue to run metadata update
-    transactions from process context before submitting the bio.
-    This function is optional.
+  - ``writeback_complete``: Allows the file systems to execute any logic that
+    needs to happen after ``->writeback_folio`` has been called for all dirty
+    folios. This might include hooking into writeback bio submission for
+    pre-write space accounting updates, or installing a custom ``->bi_end_io``
+    function for internal purposes, such as deferring the ioend completion to
+    a workqueue to run metadata update transactions from process context
+    before submitting the bio.
+    This function is optional. If this function is not provided, iomap will
+    default to ``iomap_bio_writeback_complete``.
 
   - ``discard_folio``: iomap calls this function after ``->writeback_folio``
     fails to schedule I/O for any part of a dirty folio.
diff --git a/fs/iomap/buffered-io-bio.c b/fs/iomap/buffered-io-bio.c
index e052fc8b46c1..e9f26a938c8d 100644
--- a/fs/iomap/buffered-io-bio.c
+++ b/fs/iomap/buffered-io-bio.c
@@ -151,7 +151,7 @@ static void iomap_writepage_end_bio(struct bio *bio)
 	iomap_finish_ioend_buffered(ioend);
 }
 
-void iomap_bio_ioend_error(struct iomap_writepage_ctx *wpc, int error)
+static void iomap_ioend_error(struct iomap_writepage_ctx *wpc, int error)
 {
 	wpc->ioend->io_bio.bi_status = errno_to_blk_status(error);
 	bio_endio(&wpc->ioend->io_bio);
@@ -230,7 +230,7 @@ static int iomap_add_to_ioend(struct iomap_writepage_ctx *wpc,
 
 	if (!wpc->ioend || !iomap_can_add_to_ioend(wpc, pos, ioend_flags)) {
 new_ioend:
-		error = iomap_submit_ioend(wpc, 0);
+		error = iomap_writeback_complete(wpc, 0);
 		if (error)
 			return error;
 		wpc->ioend = iomap_alloc_ioend(wpc, wbc, inode, pos,
@@ -337,3 +337,41 @@ int iomap_bio_writeback_folio(struct iomap_writeback_folio_range *ctx,
 	return error;
 }
 EXPORT_SYMBOL_GPL(iomap_bio_writeback_folio);
+
+/*
+ * Submit an ioend.
+ *
+ * If @error is non-zero, it means that we have a situation where some part of
+ * the submission process has failed after we've marked pages for writeback.
+ * We cannot cancel ioend directly in that case, so call the bio end I/O handler
+ * with the error status here to run the normal I/O completion handler to clear
+ * the writeback bit and let the file system proess the errors.
+ */
+int iomap_bio_writeback_complete(struct iomap_writepage_ctx *wpc, int error,
+		iomap_submit_ioend_t submit_ioend)
+{
+	if (!wpc->ioend)
+		return error;
+
+	/*
+	 * Let the file systems prepare the I/O submission and hook in an I/O
+	 * comletion handler.  This also needs to happen in case after a
+	 * failure happened so that the file system end I/O handler gets called
+	 * to clean up.
+	 */
+	if (submit_ioend) {
+		error = submit_ioend(wpc, error);
+	} else {
+		if (WARN_ON_ONCE(wpc->iomap.flags & IOMAP_F_ANON_WRITE))
+			error = -EIO;
+		if (!error)
+			iomap_submit_bio(&wpc->ioend->io_bio);
+	}
+
+	if (error)
+		iomap_ioend_error(wpc, error);
+
+	wpc->ioend = NULL;
+	return error;
+}
+EXPORT_SYMBOL_GPL(iomap_bio_writeback_complete);
diff --git a/fs/iomap/buffered-io.c b/fs/iomap/buffered-io.c
index 2b8d733f65da..bdf917ae56dc 100644
--- a/fs/iomap/buffered-io.c
+++ b/fs/iomap/buffered-io.c
@@ -1450,39 +1450,13 @@ vm_fault_t iomap_page_mkwrite(struct vm_fault *vmf, const struct iomap_ops *ops,
 }
 EXPORT_SYMBOL_GPL(iomap_page_mkwrite);
 
-/*
- * Submit an ioend.
- *
- * If @error is non-zero, it means that we have a situation where some part of
- * the submission process has failed after we've marked pages for writeback.
- * We cannot cancel ioend directly in that case, so call the bio end I/O handler
- * with the error status here to run the normal I/O completion handler to clear
- * the writeback bit and let the file system proess the errors.
- */
-int iomap_submit_ioend(struct iomap_writepage_ctx *wpc, int error)
+int iomap_writeback_complete(struct iomap_writepage_ctx *wpc, int error)
 {
-	if (!wpc->ioend)
-		return error;
-
-	/*
-	 * Let the file systems prepare the I/O submission and hook in an I/O
-	 * comletion handler.  This also needs to happen in case after a
-	 * failure happened so that the file system end I/O handler gets called
-	 * to clean up.
-	 */
-	if (wpc->ops->submit_ioend) {
-		error = wpc->ops->submit_ioend(wpc, error);
-	} else {
-		if (WARN_ON_ONCE(wpc->iomap.flags & IOMAP_F_ANON_WRITE))
-			error = -EIO;
-		if (!error)
-			iomap_submit_bio(&wpc->ioend->io_bio);
-	}
-
-	if (error)
-		iomap_bio_ioend_error(wpc, error);
+	if (wpc->ops->writeback_complete)
+		error = wpc->ops->writeback_complete(wpc, error);
+	else
+		error = iomap_bio_writeback_complete(wpc, error, NULL);
 
-	wpc->ioend = NULL;
 	return error;
 }
 
@@ -1661,6 +1635,6 @@ iomap_writepages(struct address_space *mapping, struct writeback_control *wbc,
 	wpc->ops = ops;
 	while ((folio = writeback_iter(mapping, wbc, folio, &error)))
 		error = iomap_writepage_map(wpc, wbc, folio);
-	return iomap_submit_ioend(wpc, error);
+	return iomap_writeback_complete(wpc, error);
 }
 EXPORT_SYMBOL_GPL(iomap_writepages);
diff --git a/fs/iomap/internal.h b/fs/iomap/internal.h
index 6efb5905bf4f..bfd3f3be845a 100644
--- a/fs/iomap/internal.h
+++ b/fs/iomap/internal.h
@@ -32,7 +32,7 @@ u32 iomap_finish_ioend_buffered(struct iomap_ioend *ioend);
 u32 iomap_finish_ioend_direct(struct iomap_ioend *ioend);
 bool ifs_set_range_uptodate(struct folio *folio, struct iomap_folio_state *ifs,
 		size_t off, size_t len);
-int iomap_submit_ioend(struct iomap_writepage_ctx *wpc, int error);
+int iomap_writeback_complete(struct iomap_writepage_ctx *wpc, int error);
 
 #ifdef CONFIG_BLOCK
 int iomap_bio_read_folio_sync(loff_t block_start, struct folio *folio,
@@ -40,12 +40,10 @@ int iomap_bio_read_folio_sync(loff_t block_start, struct folio *folio,
 void iomap_bio_readpage(const struct iomap *iomap, loff_t pos,
 		struct iomap_readpage_ctx *ctx, size_t poff, size_t plen,
 		loff_t length);
-void iomap_bio_ioend_error(struct iomap_writepage_ctx *wpc, int error);
 void iomap_submit_bio(struct bio *bio);
 #else
 #define iomap_bio_read_folio_sync(...)		(-ENOSYS)
 #define iomap_bio_readpage(...)		((void)0)
-#define iomap_bio_ioend_error(...)		((void)0)
 #define iomap_submit_bio(...)			((void)0)
 #endif /* CONFIG_BLOCK */
 
diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c
index 8878c015bd48..63745ff68250 100644
--- a/fs/xfs/xfs_aops.c
+++ b/fs/xfs/xfs_aops.c
@@ -493,6 +493,11 @@ xfs_submit_ioend(
 	return 0;
 }
 
+static int xfs_writeback_complete(struct iomap_writepage_ctx *wpc, int error)
+{
+	return iomap_bio_writeback_complete(wpc, error, xfs_submit_ioend);
+}
+
 /*
  * If the folio has delalloc blocks on it, the caller is asking us to punch them
  * out. If we don't, we can leave a stale delalloc mapping covered by a clean
@@ -532,7 +537,7 @@ xfs_discard_folio(
 
 static const struct iomap_writeback_ops xfs_writeback_ops = {
 	.writeback_folio	= xfs_writeback_folio,
-	.submit_ioend		= xfs_submit_ioend,
+	.writeback_complete	= xfs_writeback_complete,
 	.discard_folio		= xfs_discard_folio,
 };
 
@@ -630,9 +635,14 @@ xfs_zoned_submit_ioend(
 	return 0;
 }
 
+static int xfs_zoned_writeback_complete(struct iomap_writepage_ctx *wpc, int error)
+{
+	return iomap_bio_writeback_complete(wpc, error, xfs_zoned_submit_ioend);
+}
+
 static const struct iomap_writeback_ops xfs_zoned_writeback_ops = {
 	.writeback_folio	= xfs_zoned_writeback_folio,
-	.submit_ioend		= xfs_zoned_submit_ioend,
+	.writeback_complete	= xfs_zoned_writeback_complete,
 	.discard_folio		= xfs_discard_folio,
 };
 
diff --git a/include/linux/iomap.h b/include/linux/iomap.h
index fe827948035d..f4350e59fe7e 100644
--- a/include/linux/iomap.h
+++ b/include/linux/iomap.h
@@ -437,14 +437,10 @@ struct iomap_writeback_ops {
 	int (*writeback_folio)(struct iomap_writeback_folio_range *ctx);
 
 	/*
-	 * Optional, allows the file systems to hook into bio submission,
-	 * including overriding the bi_end_io handler.
-	 *
-	 * Returns 0 if the bio was successfully submitted, or a negative
-	 * error code if status was non-zero or another error happened and
-	 * the bio could not be submitted.
+	 * Optional, allows the file system to call into this once
+	 * ->writeback_folio() on all dirty ranges have been issued.
 	 */
-	int (*submit_ioend)(struct iomap_writepage_ctx *wpc, int status);
+	int (*writeback_complete)(struct iomap_writepage_ctx *wpc, int status);
 
 	/*
 	 * Optional, allows the file system to discard state on a page where
@@ -563,4 +559,20 @@ typedef int iomap_map_blocks_t(struct iomap_writepage_ctx *wpc,
 int iomap_bio_writeback_folio(struct iomap_writeback_folio_range *ctx,
 		iomap_map_blocks_t map_blocks);
 
+#ifdef CONFIG_BLOCK
+/*
+ * Allows the file systems to hook into bio submission, including overriding
+ * the bi_end_io handler.
+ *
+ * Returns 0 if the bio was successfully submitted, or a negative
+ * error code if status was non-zero or another error happened and
+ * the bio could not be submitted.
+ */
+typedef int iomap_submit_ioend_t(struct iomap_writepage_ctx *wpc, int error);
+int iomap_bio_writeback_complete(struct iomap_writepage_ctx *wpc, int error,
+		iomap_submit_ioend_t submit_ioend);
+#else
+#define iomap_bio_writeback_complete(...)	(-ENOSYS)
+#endif /* CONFIG_BLOCK */
+
 #endif /* LINUX_IOMAP_H */
-- 
2.47.1





[Index of Archives]     [Linux Ext4 Filesystem]     [Union Filesystem]     [Filesystem Testing]     [Ceph Users]     [Ecryptfs]     [NTFS 3]     [AutoFS]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux Cachefs]     [Reiser Filesystem]     [Linux RAID]     [NTFS 3]     [Samba]     [Device Mapper]     [CEPH Development]

  Powered by Linux