iomap: only call mapping_set_error once for each failed bio
authorChristoph Hellwig <hch@lst.de>
Thu, 7 Dec 2023 07:27:06 +0000 (08:27 +0100)
committerChristian Brauner <brauner@kernel.org>
Thu, 1 Feb 2024 13:20:12 +0000 (14:20 +0100)
Instead of clling mapping_set_error once per folio, only do that once
per bio, and consolidate all the writeback error handling code in
iomap_finish_ioend.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Link: https://lore.kernel.org/r/20231207072710.176093-11-hch@lst.de
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Christian Brauner <brauner@kernel.org>
fs/iomap/buffered-io.c

index 5f6affbe7056ba347ab1dfc37e4bd26089f930f9..71f0aafcc2774d4e8b6fb1a7525d1f3f684a96f2 100644 (file)
@@ -1454,15 +1454,10 @@ out_unlock:
 EXPORT_SYMBOL_GPL(iomap_page_mkwrite);
 
 static void iomap_finish_folio_write(struct inode *inode, struct folio *folio,
-               size_t len, int error)
+               size_t len)
 {
        struct iomap_folio_state *ifs = folio->private;
 
-       if (error) {
-               folio_set_error(folio);
-               mapping_set_error(inode->i_mapping, error);
-       }
-
        WARN_ON_ONCE(i_blocks_per_folio(inode, folio) > 1 && !ifs);
        WARN_ON_ONCE(ifs && atomic_read(&ifs->write_bytes_pending) <= 0);
 
@@ -1483,18 +1478,24 @@ iomap_finish_ioend(struct iomap_ioend *ioend, int error)
        struct folio_iter fi;
        u32 folio_count = 0;
 
+       if (error) {
+               mapping_set_error(inode->i_mapping, error);
+               if (!bio_flagged(bio, BIO_QUIET)) {
+                       pr_err_ratelimited(
+"%s: writeback error on inode %lu, offset %lld, sector %llu",
+                               inode->i_sb->s_id, inode->i_ino,
+                               ioend->io_offset, ioend->io_sector);
+               }
+       }
+
        /* walk all folios in bio, ending page IO on them */
        bio_for_each_folio_all(fi, bio) {
-               iomap_finish_folio_write(inode, fi.folio, fi.length, error);
+               if (error)
+                       folio_set_error(fi.folio);
+               iomap_finish_folio_write(inode, fi.folio, fi.length);
                folio_count++;
        }
 
-       if (unlikely(error && !bio_flagged(bio, BIO_QUIET))) {
-               printk_ratelimited(KERN_ERR
-"%s: writeback error on inode %lu, offset %lld, sector %llu",
-                       inode->i_sb->s_id, inode->i_ino,
-                       ioend->io_offset, ioend->io_sector);
-       }
        bio_put(bio);   /* frees the ioend */
        return folio_count;
 }