We need access to the struct iomap_ops in iomap_write_end to call the (optional) page_write_end hook, so instead of passing the operators to iomap_write_end differently depending on the code path, add an ops field to struct iomap. Signed-off-by: Andreas Gruenbacher <agruenba@xxxxxxxxxx> --- fs/dax.c | 8 ++++-- fs/gfs2/bmap.c | 4 ++- fs/gfs2/file.c | 4 ++- fs/iomap.c | 58 ++++++++++++++----------------------------- include/linux/iomap.h | 2 ++ 5 files changed, 32 insertions(+), 44 deletions(-) diff --git a/fs/dax.c b/fs/dax.c index aaec72ded1b6..806bd53129aa 100644 --- a/fs/dax.c +++ b/fs/dax.c @@ -1140,7 +1140,9 @@ static int dax_iomap_pte_fault(struct vm_fault *vmf, pfn_t *pfnp, struct inode *inode = mapping->host; unsigned long vaddr = vmf->address; loff_t pos = (loff_t)vmf->pgoff << PAGE_SHIFT; - struct iomap iomap = { 0 }; + struct iomap iomap = { + .ops = ops + }; unsigned flags = IOMAP_FAULT; int error, major = 0; bool write = vmf->flags & FAULT_FLAG_WRITE; @@ -1359,7 +1361,9 @@ static int dax_iomap_pmd_fault(struct vm_fault *vmf, pfn_t *pfnp, unsigned int iomap_flags = (write ? IOMAP_WRITE : 0) | IOMAP_FAULT; struct inode *inode = mapping->host; int result = VM_FAULT_FALLBACK; - struct iomap iomap = { 0 }; + struct iomap iomap = { + .ops = ops + }; pgoff_t max_pgoff, pgoff; void *entry; loff_t pos; diff --git a/fs/gfs2/bmap.c b/fs/gfs2/bmap.c index 703390824200..e4eeab7b6d52 100644 --- a/fs/gfs2/bmap.c +++ b/fs/gfs2/bmap.c @@ -1192,7 +1192,9 @@ int gfs2_block_map(struct inode *inode, sector_t lblock, loff_t pos = (loff_t)lblock << inode->i_blkbits; loff_t length = bh_map->b_size; struct metapath mp = { .mp_aheight = 1, }; - struct iomap iomap = { }; + struct iomap iomap = { + /* no need to initialize .ops here */ + }; int ret; clear_buffer_mapped(bh_map); diff --git a/fs/gfs2/file.c b/fs/gfs2/file.c index 8de92708f18b..02ccb2d49900 100644 --- a/fs/gfs2/file.c +++ b/fs/gfs2/file.c @@ -883,7 +883,9 @@ static int fallocate_chunk(struct inode *inode, loff_t offset, loff_t len, struct gfs2_inode *ip = GFS2_I(inode); loff_t end = offset + len; struct buffer_head *dibh; - struct iomap iomap = { }; + struct iomap iomap = { + /* no need to initialize .ops here */ + }; int error; error = gfs2_meta_inode_buffer(ip, &dibh); diff --git a/fs/iomap.c b/fs/iomap.c index 34ba1be1d600..571214a6ffaa 100644 --- a/fs/iomap.c +++ b/fs/iomap.c @@ -45,7 +45,9 @@ loff_t iomap_apply(struct inode *inode, loff_t pos, loff_t length, unsigned flags, const struct iomap_ops *ops, void *data, iomap_actor_t actor) { - struct iomap iomap = { 0 }; + struct iomap iomap = { + .ops = ops + }; loff_t written = 0, ret; /* @@ -180,8 +182,7 @@ 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, - const struct iomap_ops *ops) + unsigned copied, struct page *page, struct iomap *iomap) { int ret; @@ -191,8 +192,8 @@ iomap_write_end(struct inode *inode, loff_t pos, unsigned len, return copied; } - if (ops->page_write_end) - ops->page_write_end(inode, pos, copied, page); + if (iomap->ops->page_write_end) + iomap->ops->page_write_end(inode, pos, copied, page); ret = generic_write_end(NULL, inode->i_mapping, pos, len, copied, page, NULL); @@ -201,17 +202,11 @@ 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 iomap_write_args *args = data; - struct iov_iter *i = args->iter; + struct iov_iter *i = data; long status = 0; ssize_t written = 0; unsigned int flags = AOP_FLAG_NOFS; @@ -257,7 +252,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, args->ops); + iomap); if (unlikely(status < 0)) break; copied = status; @@ -294,14 +289,10 @@ 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, &args, iomap_write_actor); + IOMAP_WRITE, ops, iter, iomap_write_actor); if (ret <= 0) break; pos += ret; @@ -332,7 +323,6 @@ 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; @@ -356,8 +346,7 @@ 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, - ops); + status = iomap_write_end(inode, pos, bytes, bytes, page, iomap); if (unlikely(status <= 0)) { if (WARN_ON_ONCE(status == 0)) return -EIO; @@ -384,7 +373,7 @@ iomap_file_dirty(struct inode *inode, loff_t pos, loff_t len, while (len) { ret = iomap_apply(inode, pos, len, IOMAP_WRITE, ops, - (void *)ops, iomap_dirty_actor); + NULL, iomap_dirty_actor); if (ret <= 0) return ret; pos += ret; @@ -396,8 +385,7 @@ 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, const struct iomap_ops *ops, - struct iomap *iomap) + unsigned bytes, struct iomap *iomap) { struct page *page; int status; @@ -410,8 +398,7 @@ 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, - ops); + return iomap_write_end(inode, pos, bytes, bytes, page, iomap); } static int iomap_dax_zero(loff_t pos, unsigned offset, unsigned bytes, @@ -424,16 +411,11 @@ 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) { - struct iomap_zero_range_args *args = data; + bool *did_zero = data; loff_t written = 0; int status; @@ -451,15 +433,15 @@ iomap_zero_range_actor(struct inode *inode, loff_t pos, loff_t count, status = iomap_dax_zero(pos, offset, bytes, iomap); else status = iomap_zero(inode, pos, offset, bytes, - args->ops, iomap); + iomap); if (status < 0) return status; pos += bytes; count -= bytes; written += bytes; - if (args->did_zero) - *args->did_zero = true; + if (did_zero) + *did_zero = true; } while (count > 0); return written; @@ -469,15 +451,11 @@ 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, &args, iomap_zero_range_actor); + ops, did_zero, iomap_zero_range_actor); if (ret <= 0) return ret; diff --git a/include/linux/iomap.h b/include/linux/iomap.h index 88ea8b970a95..98426cdfcc2e 100644 --- a/include/linux/iomap.h +++ b/include/linux/iomap.h @@ -6,6 +6,7 @@ struct fiemap_extent_info; struct inode; +struct iomap_ops; struct iov_iter; struct kiocb; struct page; @@ -43,6 +44,7 @@ struct vm_fault; #define IOMAP_NULL_ADDR -1ULL /* addr is not valid */ struct iomap { + const struct iomap_ops *ops; u64 addr; /* disk offset of mapping, bytes */ loff_t offset; /* file offset of mapping, bytes */ u64 length; /* length of mapping, bytes */ -- 2.17.0