Commit d984648e authored by Shiyang Ruan's avatar Shiyang Ruan Committed by Andrew Morton
Browse files

fsdax,xfs: port unshare to fsdax

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@fujitsu.com


Signed-off-by: default avatarShiyang Ruan <ruansy.fnst@fujitsu.com>
Reviewed-by: default avatarDarrick J. Wong <djwong@kernel.org>
Cc: Alistair Popple <apopple@nvidia.com>
Cc: Dan Williams <dan.j.williams@intel.com>
Cc: Dave Chinner <david@fromorbit.com>
Cc: Jason Gunthorpe <jgg@nvidia.com>
Cc: John Hubbard <jhubbard@nvidia.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
parent 64e6edc1
Loading
Loading
Loading
Loading
+52 −0
Original line number Diff line number Diff line
@@ -1245,6 +1245,58 @@ static vm_fault_t dax_pmd_load_hole(struct xa_state *xas, struct vm_fault *vmf,
}
#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;
+6 −2
Original line number Diff line number Diff line
@@ -1693,6 +1693,10 @@ xfs_reflink_unshare(

	inode_dio_wait(inode);

	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)
+2 −0
Original line number Diff line number Diff line
@@ -205,6 +205,8 @@ static inline void dax_unlock_mapping_entry(struct address_space *mapping,
}
#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,