[Cluster-devel] [PATCH v8 06/10] iomap: Add page_write_end iomap hook
Andreas Grünbacher
andreas.gruenbacher at gmail.com
Tue Jun 5 07:56:29 UTC 2018
2018-06-04 21:31 GMT+02:00 Andreas Gruenbacher <agruenba at redhat.com>:
> Add a page_write_end hook called when done writing to a page, for
> filesystems that implement data journaling: in that case, pages are
> written to the journal before being written back to their proper on-disk
> locations.
> The new hook is bypassed for IOMAP_INLINE mappings.
Oops, no longer true of course.
> Signed-off-by: Andreas Gruenbacher <agruenba at redhat.com>
> ---
> fs/iomap.c | 58 ++++++++++++++++++++++++++++++++-----------
> include/linux/iomap.h | 8 ++++++
> 2 files changed, 52 insertions(+), 14 deletions(-)
>
> diff --git a/fs/iomap.c b/fs/iomap.c
> index 48cd67227811..3b34c957d2fd 100644
> --- a/fs/iomap.c
> +++ b/fs/iomap.c
> @@ -181,16 +181,22 @@ iomap_write_begin(struct inode *inode, loff_t pos, unsigned len, unsigned flags,
>
> static int
> iomap_write_end(struct inode *inode, loff_t pos, unsigned len,
> - unsigned copied, struct page *page, struct iomap *iomap)
> + unsigned copied, struct page *page, struct iomap *iomap,
> + const struct iomap_ops *ops)
> {
> + typeof(ops->page_write_end) page_write_end = ops->page_write_end;
> int ret;
>
> if (iomap->type == IOMAP_INLINE) {
> iomap_write_inline_data(inode, page, iomap, pos, copied);
> __generic_write_end(inode, pos, copied, page);
> + if (page_write_end)
> + page_write_end(inode, pos, copied, page, iomap);
> return copied;
> }
>
> + if (page_write_end)
> + page_write_end(inode, pos, copied, page, iomap);
> ret = generic_write_end(NULL, inode->i_mapping, pos, len,
> copied, page, NULL);
> if (ret < len)
> @@ -198,11 +204,17 @@ iomap_write_end(struct inode *inode, loff_t pos, unsigned len,
> return ret;
> }
>
> +struct iomap_write_args {
> + const struct iomap_ops *ops;
> + struct iov_iter *iter;
> +};
> +
> 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_args *args = data;
> + struct iov_iter *i = args->iter;
> long status = 0;
> ssize_t written = 0;
> unsigned int flags = AOP_FLAG_NOFS;
> @@ -248,7 +260,7 @@ iomap_write_actor(struct inode *inode, loff_t pos, loff_t length, void *data,
> flush_dcache_page(page);
>
> status = iomap_write_end(inode, pos, bytes, copied, page,
> - iomap);
> + iomap, args->ops);
> if (unlikely(status < 0))
> break;
> copied = status;
> @@ -285,10 +297,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_args args = {
> + .ops = ops,
> + .iter = iter,
> + };
>
> while (iov_iter_count(iter)) {
> ret = iomap_apply(inode, pos, iov_iter_count(iter),
> - IOMAP_WRITE, ops, iter, iomap_write_actor);
> + IOMAP_WRITE, ops, &args, iomap_write_actor);
> if (ret <= 0)
> break;
> pos += ret;
> @@ -319,6 +335,7 @@ static loff_t
> iomap_dirty_actor(struct inode *inode, loff_t pos, loff_t length, void *data,
> struct iomap *iomap)
> {
> + const struct iomap_ops *ops = data;
> long status = 0;
> ssize_t written = 0;
>
> @@ -342,7 +359,8 @@ iomap_dirty_actor(struct inode *inode, loff_t pos, loff_t length, void *data,
>
> WARN_ON_ONCE(!PageUptodate(page));
>
> - status = iomap_write_end(inode, pos, bytes, bytes, page, iomap);
> + status = iomap_write_end(inode, pos, bytes, bytes, page, iomap,
> + ops);
> if (unlikely(status <= 0)) {
> if (WARN_ON_ONCE(status == 0))
> return -EIO;
> @@ -368,8 +386,8 @@ iomap_file_dirty(struct inode *inode, loff_t pos, loff_t len,
> loff_t ret;
>
> while (len) {
> - ret = iomap_apply(inode, pos, len, IOMAP_WRITE, ops, NULL,
> - iomap_dirty_actor);
> + ret = iomap_apply(inode, pos, len, IOMAP_WRITE, ops,
> + (void *)ops, iomap_dirty_actor);
> if (ret <= 0)
> return ret;
> pos += ret;
> @@ -381,7 +399,8 @@ iomap_file_dirty(struct inode *inode, loff_t pos, loff_t len,
> EXPORT_SYMBOL_GPL(iomap_file_dirty);
>
> static int iomap_zero(struct inode *inode, loff_t pos, unsigned offset,
> - unsigned bytes, struct iomap *iomap)
> + unsigned bytes, const struct iomap_ops *ops,
> + struct iomap *iomap)
> {
> struct page *page;
> int status;
> @@ -394,7 +413,8 @@ static int iomap_zero(struct inode *inode, loff_t pos, unsigned offset,
> zero_user(page, offset, bytes);
> mark_page_accessed(page);
>
> - return iomap_write_end(inode, pos, bytes, bytes, page, iomap);
> + return iomap_write_end(inode, pos, bytes, bytes, page, iomap,
> + ops);
> }
>
> static int iomap_dax_zero(loff_t pos, unsigned offset, unsigned bytes,
> @@ -407,11 +427,16 @@ static int iomap_dax_zero(loff_t pos, unsigned offset, unsigned bytes,
> offset, bytes);
> }
>
> +struct iomap_zero_range_args {
> + const struct iomap_ops *ops;
> + bool *did_zero;
> +};
> +
> static loff_t
> iomap_zero_range_actor(struct inode *inode, loff_t pos, loff_t count,
> void *data, struct iomap *iomap)
> {
> - bool *did_zero = data;
> + struct iomap_zero_range_args *args = data;
> loff_t written = 0;
> int status;
>
> @@ -428,15 +453,16 @@ iomap_zero_range_actor(struct inode *inode, loff_t pos, loff_t count,
> if (IS_DAX(inode))
> status = iomap_dax_zero(pos, offset, bytes, iomap);
> else
> - status = iomap_zero(inode, pos, offset, bytes, iomap);
> + status = iomap_zero(inode, pos, offset, bytes,
> + args->ops, iomap);
> if (status < 0)
> return status;
>
> pos += bytes;
> count -= bytes;
> written += bytes;
> - if (did_zero)
> - *did_zero = true;
> + if (args->did_zero)
> + *args->did_zero = true;
> } while (count > 0);
>
> return written;
> @@ -446,11 +472,15 @@ int
> iomap_zero_range(struct inode *inode, loff_t pos, loff_t len, bool *did_zero,
> const struct iomap_ops *ops)
> {
> + struct iomap_zero_range_args args = {
> + .ops = ops,
> + .did_zero = did_zero,
> + };
> loff_t ret;
>
> while (len > 0) {
> ret = iomap_apply(inode, pos, len, IOMAP_ZERO,
> - ops, did_zero, iomap_zero_range_actor);
> + ops, &args, iomap_zero_range_actor);
> if (ret <= 0)
> return ret;
>
> diff --git a/include/linux/iomap.h b/include/linux/iomap.h
> index c61113c71a60..ac7f1b2c1cbe 100644
> --- a/include/linux/iomap.h
> +++ b/include/linux/iomap.h
> @@ -8,6 +8,7 @@ struct fiemap_extent_info;
> struct inode;
> struct iov_iter;
> struct kiocb;
> +struct page;
> struct vm_area_struct;
> struct vm_fault;
>
> @@ -71,6 +72,13 @@ struct iomap_ops {
> int (*iomap_begin)(struct inode *inode, loff_t pos, loff_t length,
> unsigned flags, struct iomap *iomap);
>
> + /*
> + * Called when done writing to a page (optional; skipped for
> + * IOMAP_INLINE mappings).
The comment needs updating too, of course.
> + */
> + void (*page_write_end)(struct inode *inode, loff_t pos, unsigned copied,
> + struct page *page, struct iomap *iomap);
> +
> /*
> * Commit and/or unreserve space previous allocated using iomap_begin.
> * Written indicates the length of the successful write operation which
> --
> 2.17.0
>
With those two changes, is this commit okay as well?
Thanks,
Andreas
More information about the Cluster-devel
mailing list