Skip to content

Commit af4eb6f

Browse files
riteshharjanibrauner
authored andcommitted
iomap: Optimize iomap_read_folio
iomap_readpage_iter() handles "uptodate blocks" and "not uptodate blocks" within a folio separately. This makes iomap_read_folio() to call into ->iomap_begin() to request for extent mapping even though it might already have an extent which is not fully processed. This happens when we either have a large folio or with bs < ps. In these cases we can have sub blocks which can be uptodate (say for e.g. due to previous writes). With iomap_read_folio_iter(), this is handled more efficiently by not calling ->iomap_begin() call until all the sub blocks with the current folio are processed. iomap_read_folio_iter() handles multiple sub blocks within a given folio but it's implementation logic is similar to how iomap_readahead_iter() handles multiple folios within a single mapped extent. Both of them iterate over a given range of folio/mapped extent and call iomap_readpage_iter() for reading. Signed-off-by: Ritesh Harjani (IBM) <[email protected]> Link: https://lore.kernel.org/r/92ae9f3333c9a7e66214568d08f45664261c899c.1715067055.git.ritesh.list@gmail.com Reviewed-by: Darrick J. Wong <[email protected]> Reviewed-by: Christoph Hellwig <[email protected]> Reviewed-by: Jan Kara <[email protected]> cc: Ojaswin Mujoo <[email protected]> Signed-off-by: Christian Brauner <[email protected]>
1 parent 6ba59ff commit af4eb6f

File tree

1 file changed

+19
-1
lines changed

1 file changed

+19
-1
lines changed

fs/iomap/buffered-io.c

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -444,6 +444,24 @@ static loff_t iomap_readpage_iter(const struct iomap_iter *iter,
444444
return pos - orig_pos + plen;
445445
}
446446

447+
static loff_t iomap_read_folio_iter(const struct iomap_iter *iter,
448+
struct iomap_readpage_ctx *ctx)
449+
{
450+
struct folio *folio = ctx->cur_folio;
451+
size_t offset = offset_in_folio(folio, iter->pos);
452+
loff_t length = min_t(loff_t, folio_size(folio) - offset,
453+
iomap_length(iter));
454+
loff_t done, ret;
455+
456+
for (done = 0; done < length; done += ret) {
457+
ret = iomap_readpage_iter(iter, ctx, done);
458+
if (ret <= 0)
459+
return ret;
460+
}
461+
462+
return done;
463+
}
464+
447465
int iomap_read_folio(struct folio *folio, const struct iomap_ops *ops)
448466
{
449467
struct iomap_iter iter = {
@@ -459,7 +477,7 @@ int iomap_read_folio(struct folio *folio, const struct iomap_ops *ops)
459477
trace_iomap_readpage(iter.inode, 1);
460478

461479
while ((ret = iomap_iter(&iter, ops)) > 0)
462-
iter.processed = iomap_readpage_iter(&iter, &ctx, 0);
480+
iter.processed = iomap_read_folio_iter(&iter, &ctx);
463481

464482
if (ret < 0)
465483
folio_set_error(folio);

0 commit comments

Comments
 (0)