Commit 13dd4e04 authored by Shiyang Ruan's avatar Shiyang Ruan Committed by Andrew Morton

fsdax: unshare: zero destination if srcmap is HOLE or UNWRITTEN

unshare copies data from source to destination.  But if the source is
HOLE or UNWRITTEN extents, we should zero the destination, otherwise
the HOLE or UNWRITTEN part will be user-visible old data of the new
allocated extent.

Found by running generic/649 while mounting with -o dax=always on pmem.

Link: https://lkml.kernel.org/r/1679483469-2-1-git-send-email-ruansy.fnst@fujitsu.com
Fixes: d984648e ("fsdax,xfs: port unshare to fsdax")
Signed-off-by: default avatarShiyang Ruan <ruansy.fnst@fujitsu.com>
Cc: Dan Williams <dan.j.williams@intel.com>
Cc: Darrick J. Wong <djwong@kernel.org>
Cc: Jan Kara <jack@suse.cz>
Cc: Matthew Wilcox (Oracle) <willy@infradead.org>
Cc: Alistair Popple <apopple@nvidia.com>
Cc: Jason Gunthorpe <jgg@nvidia.com>
Cc: John Hubbard <jhubbard@nvidia.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
parent f478b998
...@@ -1258,15 +1258,20 @@ static s64 dax_unshare_iter(struct iomap_iter *iter) ...@@ -1258,15 +1258,20 @@ static s64 dax_unshare_iter(struct iomap_iter *iter)
/* don't bother with blocks that are not shared to start with */ /* don't bother with blocks that are not shared to start with */
if (!(iomap->flags & IOMAP_F_SHARED)) if (!(iomap->flags & IOMAP_F_SHARED))
return length; 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(); id = dax_read_lock();
ret = dax_iomap_direct_access(iomap, pos, length, &daddr, NULL); ret = dax_iomap_direct_access(iomap, pos, length, &daddr, NULL);
if (ret < 0) if (ret < 0)
goto out_unlock; goto out_unlock;
/* zero the distance if srcmap is HOLE or UNWRITTEN */
if (srcmap->flags & IOMAP_F_SHARED || srcmap->type == IOMAP_UNWRITTEN) {
memset(daddr, 0, length);
dax_flush(iomap->dax_dev, daddr, length);
ret = length;
goto out_unlock;
}
ret = dax_iomap_direct_access(srcmap, pos, length, &saddr, NULL); ret = dax_iomap_direct_access(srcmap, pos, length, &saddr, NULL);
if (ret < 0) if (ret < 0)
goto out_unlock; goto out_unlock;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment