The patch titled Subject: fsdax,xfs: port unshare to fsdax has been added to the -mm mm-unstable branch. Its filename is fsdaxxfs-port-unshare-to-fsdax.patch This patch will shortly appear at https://git.kernel.org/pub/scm/linux/kernel/git/akpm/25-new.git/tree/patches/fsdaxxfs-port-unshare-to-fsdax.patch This patch will later appear in the mm-unstable branch at git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm Before you just go and hit "reply", please: a) Consider who else should be cc'ed b) Prefer to cc a suitable mailing list as well c) Ideally: find the original patch on the mailing list and do a reply-to-all to that, adding suitable additional cc's *** Remember to use Documentation/process/submit-checklist.rst when testing your code *** The -mm tree is included into linux-next via the mm-everything branch at git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm and is updated there every 2-3 working days ------------------------------------------------------ From: Shiyang Ruan <ruansy.fnst@xxxxxxxxxxx> Subject: fsdax,xfs: port unshare to fsdax Date: Thu, 1 Dec 2022 15:32:33 +0000 Implement unshare in fsdax mode: copy data from srcmap to iomap. Link: https://lkml.kernel.org/r/1669908753-169-1-git-send-email-ruansy.fnst@xxxxxxxxxxx Signed-off-by: Shiyang Ruan <ruansy.fnst@xxxxxxxxxxx> Reviewed-by: Darrick J. Wong <djwong@xxxxxxxxxx> Cc: Alistair Popple <apopple@xxxxxxxxxx> Cc: Dan Williams <dan.j.williams@xxxxxxxxx> Cc: Dave Chinner <david@xxxxxxxxxxxxx> Cc: Jason Gunthorpe <jgg@xxxxxxxxxx> Cc: John Hubbard <jhubbard@xxxxxxxxxx> Signed-off-by: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx> --- fs/dax.c | 52 +++++++++++++++++++++++++++++++++++++++++ fs/xfs/xfs_reflink.c | 8 ++++-- include/linux/dax.h | 2 + 3 files changed, 60 insertions(+), 2 deletions(-) --- a/fs/dax.c~fsdaxxfs-port-unshare-to-fsdax +++ a/fs/dax.c @@ -1244,6 +1244,58 @@ static vm_fault_t dax_pmd_load_hole(stru } #endif /* CONFIG_FS_DAX_PMD */ +static s64 dax_unshare_iter(struct iomap_iter *iter) +{ + struct iomap *iomap = &iter->iomap; + const struct iomap *srcmap = iomap_iter_srcmap(iter); + loff_t pos = iter->pos; + loff_t length = iomap_length(iter); + int id = 0; + s64 ret = 0; + void *daddr = NULL, *saddr = NULL; + + /* don't bother with blocks that are not shared to start with */ + if (!(iomap->flags & IOMAP_F_SHARED)) + return length; + /* don't bother with holes or unwritten extents */ + if (srcmap->type == IOMAP_HOLE || srcmap->type == IOMAP_UNWRITTEN) + return length; + + id = dax_read_lock(); + ret = dax_iomap_direct_access(iomap, pos, length, &daddr, NULL); + if (ret < 0) + goto out_unlock; + + ret = dax_iomap_direct_access(srcmap, pos, length, &saddr, NULL); + if (ret < 0) + goto out_unlock; + + ret = copy_mc_to_kernel(daddr, saddr, length); + if (ret) + ret = -EIO; + +out_unlock: + dax_read_unlock(id); + return ret; +} + +int dax_file_unshare(struct inode *inode, loff_t pos, loff_t len, + const struct iomap_ops *ops) +{ + struct iomap_iter iter = { + .inode = inode, + .pos = pos, + .len = len, + .flags = IOMAP_WRITE | IOMAP_UNSHARE | IOMAP_DAX, + }; + int ret; + + while ((ret = iomap_iter(&iter, ops)) > 0) + iter.processed = dax_unshare_iter(&iter); + return ret; +} +EXPORT_SYMBOL_GPL(dax_file_unshare); + static int dax_memzero(struct iomap_iter *iter, loff_t pos, size_t size) { const struct iomap *iomap = &iter->iomap; --- a/fs/xfs/xfs_reflink.c~fsdaxxfs-port-unshare-to-fsdax +++ a/fs/xfs/xfs_reflink.c @@ -1693,8 +1693,12 @@ xfs_reflink_unshare( inode_dio_wait(inode); - error = iomap_file_unshare(inode, offset, len, - &xfs_buffered_write_iomap_ops); + if (IS_DAX(inode)) + error = dax_file_unshare(inode, offset, len, + &xfs_dax_write_iomap_ops); + else + error = iomap_file_unshare(inode, offset, len, + &xfs_buffered_write_iomap_ops); if (error) goto out; --- a/include/linux/dax.h~fsdaxxfs-port-unshare-to-fsdax +++ a/include/linux/dax.h @@ -205,6 +205,8 @@ static inline void dax_unlock_mapping_en } #endif +int dax_file_unshare(struct inode *inode, loff_t pos, loff_t len, + const struct iomap_ops *ops); int dax_zero_range(struct inode *inode, loff_t pos, loff_t len, bool *did_zero, const struct iomap_ops *ops); int dax_truncate_page(struct inode *inode, loff_t pos, bool *did_zero, _ Patches currently in -mm which might be from ruansy.fnst@xxxxxxxxxxx are fsdax-introduce-page-share-for-fsdax-in-reflink-mode.patch fsdax-invalidate-pages-when-cow.patch fsdax-zero-the-edges-if-source-is-hole-or-unwritten.patch fsdaxxfs-set-the-shared-flag-when-file-extent-is-shared.patch fsdax-dedupe-iter-two-files-at-the-same-time.patch xfs-use-dax-ops-for-zero-and-truncate-in-fsdax-mode.patch fsdaxxfs-port-unshare-to-fsdax.patch xfs-remove-restrictions-for-fsdax-and-reflink.patch