iomap: convert iomap_unshare_iter to use large folios
authorDarrick J. Wong <djwong@kernel.org>
Mon, 18 Sep 2023 22:57:40 +0000 (15:57 -0700)
committerDarrick J. Wong <djwong@kernel.org>
Tue, 19 Sep 2023 16:05:35 +0000 (09:05 -0700)
Convert iomap_unshare_iter to create large folios if possible, since the
write and zeroing paths already do that.  I think this got missed in the
conversion of the write paths that landed in 6.6-rc1.

Cc: ritesh.list@gmail.com, willy@infradead.org
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Ritesh Harjani (IBM) <ritesh.list@gmail.com>
fs/iomap/buffered-io.c

index 0350830..644479c 100644 (file)
@@ -1263,7 +1263,6 @@ static loff_t iomap_unshare_iter(struct iomap_iter *iter)
        const struct iomap *srcmap = iomap_iter_srcmap(iter);
        loff_t pos = iter->pos;
        loff_t length = iomap_length(iter);
-       long status = 0;
        loff_t written = 0;
 
        /* don't bother with blocks that are not shared to start with */
@@ -1274,28 +1273,33 @@ static loff_t iomap_unshare_iter(struct iomap_iter *iter)
                return length;
 
        do {
-               unsigned long offset = offset_in_page(pos);
-               unsigned long bytes = min_t(loff_t, PAGE_SIZE - offset, length);
                struct folio *folio;
+               int status;
+               size_t offset;
+               size_t bytes = min_t(u64, SIZE_MAX, length);
 
                status = iomap_write_begin(iter, pos, bytes, &folio);
                if (unlikely(status))
                        return status;
-               if (iter->iomap.flags & IOMAP_F_STALE)
+               if (iomap->flags & IOMAP_F_STALE)
                        break;
 
-               status = iomap_write_end(iter, pos, bytes, bytes, folio);
-               if (WARN_ON_ONCE(status == 0))
+               offset = offset_in_folio(folio, pos);
+               if (bytes > folio_size(folio) - offset)
+                       bytes = folio_size(folio) - offset;
+
+               bytes = iomap_write_end(iter, pos, bytes, bytes, folio);
+               if (WARN_ON_ONCE(bytes == 0))
                        return -EIO;
 
                cond_resched();
 
-               pos += status;
-               written += status;
-               length -= status;
+               pos += bytes;
+               written += bytes;
+               length -= bytes;
 
                balance_dirty_pages_ratelimited(iter->inode->i_mapping);
-       } while (length);
+       } while (length > 0);
 
        return written;
 }