Hi Christoph, On Tue, Apr 04, 2023 at 08:37:02AM -0700, Christoph Hellwig wrote: > > if (iomap_block_needs_zeroing(iter, pos)) { > > folio_zero_range(folio, poff, plen); > > + if (iomap->flags & IOMAP_F_READ_VERITY) { > > Wju do we need the new flag vs just testing that folio_ops and > folio_ops->verify_folio is non-NULL? Yes, it can be just test, haven't noticed that it's used only here, initially I used it in several places. > > > - ctx->bio = bio_alloc(iomap->bdev, bio_max_segs(nr_vecs), > > - REQ_OP_READ, gfp); > > + ctx->bio = bio_alloc_bioset(iomap->bdev, bio_max_segs(nr_vecs), > > + REQ_OP_READ, GFP_NOFS, &iomap_read_ioend_bioset); > > All other callers don't really need the larger bioset, so I'd avoid > the unconditional allocation here, but more on that later. Ok, make sense. > > > + ioend = container_of(ctx->bio, struct iomap_read_ioend, > > + read_inline_bio); > > + ioend->io_inode = iter->inode; > > + if (ctx->ops && ctx->ops->prepare_ioend) > > + ctx->ops->prepare_ioend(ioend); > > + > > So what we're doing in writeback and direct I/O, is to: > > a) have a submit_bio hook > b) allow the file system to then hook the bi_end_io caller > c) (only in direct O/O for now) allow the file system to provide > a bio_set to allocate from I see. > > I wonder if that also makes sense and keep all the deferral in the > file system. We'll need that for the btrfs iomap conversion anyway, > and it seems more flexible. The ioend processing would then move into > XFS. > Not sure what you mean here. > > @@ -156,6 +160,11 @@ struct iomap_folio_ops { > > * locked by the iomap code. > > */ > > bool (*iomap_valid)(struct inode *inode, const struct iomap *iomap); > > + > > + /* > > + * Verify folio when successfully read > > + */ > > + bool (*verify_folio)(struct folio *folio, loff_t pos, unsigned int len); > > Why isn't this in iomap_readpage_ops? > Yes, it can be. But it appears to me to be more relevant to _folio_ops, any particular reason to move it there? Don't mind moving it to iomap_readpage_ops. -- - Andrey