Add a callback to iomap_file_buffered_write that's called whenever writing to a page has completed. This is needed for implementing data journaling: in the data journaling case, pages are written into the journal before being written back to their proper on-disk locations. (So far, the only user of iomap_file_buffered_write is xfs, which doesn't do data journaling.) Signed-off-by: Andreas Gruenbacher <agruenba@xxxxxxxxxx> --- fs/iomap.c | 21 +++++++++++++++++++-- include/linux/iomap.h | 9 +++++++++ 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/fs/iomap.c b/fs/iomap.c index 47d29ccffaef..98903be66c35 100644 --- a/fs/iomap.c +++ b/fs/iomap.c @@ -149,11 +149,21 @@ iomap_write_end(struct inode *inode, loff_t pos, unsigned len, return ret; } +struct iomap_write_data { + struct iov_iter *iter; + const struct iomap_ops *ops; +}; + static loff_t iomap_write_actor(struct inode *inode, loff_t pos, loff_t length, void *data, struct iomap *iomap) { - struct iov_iter *i = data; + struct iomap_write_data *d = data; + struct iov_iter *i = d->iter; + void (*iomap_written)(struct inode *inode, struct page *page, + unsigned int offset, unsigned int length, + unsigned int written) = + d->ops->iomap_written; long status = 0; ssize_t written = 0; unsigned int flags = AOP_FLAG_NOFS; @@ -198,6 +208,9 @@ iomap_write_actor(struct inode *inode, loff_t pos, loff_t length, void *data, flush_dcache_page(page); + if (iomap_written) + iomap_written(inode, page, offset, bytes, copied); + status = iomap_write_end(inode, pos, bytes, copied, page); if (unlikely(status < 0)) break; @@ -235,10 +248,14 @@ iomap_file_buffered_write(struct kiocb *iocb, struct iov_iter *iter, { struct inode *inode = iocb->ki_filp->f_mapping->host; loff_t pos = iocb->ki_pos, ret = 0, written = 0; + struct iomap_write_data data = { + .iter = iter, + .ops = ops, + }; while (iov_iter_count(iter)) { ret = iomap_apply(inode, pos, iov_iter_count(iter), - IOMAP_WRITE, ops, iter, iomap_write_actor); + IOMAP_WRITE, ops, &data, iomap_write_actor); if (ret <= 0) break; pos += ret; diff --git a/include/linux/iomap.h b/include/linux/iomap.h index 19a07de28212..042b8c8df44b 100644 --- a/include/linux/iomap.h +++ b/include/linux/iomap.h @@ -61,6 +61,8 @@ struct iomap { #define IOMAP_DIRECT (1 << 4) /* direct I/O */ #define IOMAP_NOWAIT (1 << 5) /* Don't wait for writeback */ +struct page; + struct iomap_ops { /* * Return the existing mapping at pos, or reserve space starting at @@ -70,6 +72,13 @@ struct iomap_ops { int (*iomap_begin)(struct inode *inode, loff_t pos, loff_t length, unsigned flags, struct iomap *iomap); + /* + * Called after writing to a page has completed. + */ + void (*iomap_written)(struct inode *inode, struct page *page, + unsigned int offset, unsigned int length, + unsigned int written); + /* * Commit and/or unreserve space previous allocated using iomap_begin. * Written indicates the length of the successful write operation which -- 2.14.3