On Thu, Oct 17, 2019 at 07:56:20PM +0200, Christoph Hellwig wrote: > Take the xfs writeback code and move it to fs/iomap. A new structure > with three methods is added as the abstraction from the generic writeback > code to the file system. These methods are used to map blocks, submit an > ioend, and cancel a page that encountered an error before it was added to > an ioend. > > Signed-off-by: Christoph Hellwig <hch@xxxxxx> <snip> > diff --git a/include/linux/iomap.h b/include/linux/iomap.h > index 24bd227d59f9..71fd12ee5616 100644 > --- a/include/linux/iomap.h > +++ b/include/linux/iomap.h > @@ -4,6 +4,7 @@ > > #include <linux/atomic.h> > #include <linux/bitmap.h> > +#include <linux/blk_types.h> > #include <linux/mm.h> > #include <linux/types.h> > #include <linux/mm_types.h> > @@ -12,6 +13,7 @@ > struct address_space; > struct fiemap_extent_info; > struct inode; > +struct iomap_writepage_ctx; > struct iov_iter; > struct kiocb; > struct page; > @@ -185,6 +187,63 @@ loff_t iomap_seek_data(struct inode *inode, loff_t offset, > sector_t iomap_bmap(struct address_space *mapping, sector_t bno, > const struct iomap_ops *ops); > > +/* > + * Structure for writeback I/O completions. > + */ > +struct iomap_ioend { > + struct list_head io_list; /* next ioend in chain */ > + u16 io_type; > + u16 io_flags; /* IOMAP_F_* */ > + struct inode *io_inode; /* file being written to */ > + size_t io_size; /* size of the extent */ > + loff_t io_offset; /* offset in the file */ > + void *io_private; /* file system private data */ > + struct bio *io_bio; /* bio being built */ > + struct bio io_inline_bio; /* MUST BE LAST! */ > +}; > + > +struct iomap_writeback_ops { > + /* > + * Required, maps the blocks so that writeback can be performed on > + * the range starting at offset. > + */ > + int (*map_blocks)(struct iomap_writepage_ctx *wpc, struct inode *inode, > + loff_t offset); > + > + /* > + * Optional, allows the file systems to perform actions just before > + * submitting the bio and/or override the bio end_io handler for complex > + * operations like copy on write extent manipulation or unwritten extent > + * conversions. > + */ > + int (*submit_ioend)(struct iomap_ioend *ioend, int status); > + Looks ok, but I reserve the right to rename this to ->prepare_ioend() or something. :) Reviewed-by: Darrick J. Wong <darrick.wong@xxxxxxxxxx> --D > + /* > + * Optional, allows the file system to discard state on a page where > + * we failed to submit any I/O. > + */ > + void (*discard_page)(struct page *page); > +}; > + > +struct iomap_writepage_ctx { > + struct iomap iomap; > + struct iomap_ioend *ioend; > + const struct iomap_writeback_ops *ops; > +}; > + > +void iomap_finish_ioends(struct iomap_ioend *ioend, int error); > +void iomap_ioend_try_merge(struct iomap_ioend *ioend, > + struct list_head *more_ioends, > + void (*merge_private)(struct iomap_ioend *ioend, > + struct iomap_ioend *next)); > +void iomap_sort_ioends(struct list_head *ioend_list); > +int iomap_writepage(struct page *page, struct writeback_control *wbc, > + struct iomap_writepage_ctx *wpc, > + const struct iomap_writeback_ops *ops); > +int iomap_writepages(struct address_space *mapping, > + struct writeback_control *wbc, struct iomap_writepage_ctx *wpc, > + const struct iomap_writeback_ops *ops); > + > /* > * Flags for direct I/O ->end_io: > */ > -- > 2.20.1 >