aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShiyang Ruan <[email protected]>2023-03-22 11:11:09 +0000
committerAndrew Morton <[email protected]>2023-03-28 15:24:32 -0700
commit13dd4e04625f600e5affb1b3f0b6c35268ab839b (patch)
tree15cb27ec4c1c76c3e3cb832f483d2990a460065e
parentf478b9987cc8236b412d9f2afc958d3e15a7cf85 (diff)
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/[email protected] Fixes: d984648e428b ("fsdax,xfs: port unshare to fsdax") Signed-off-by: Shiyang Ruan <[email protected]> Cc: Dan Williams <[email protected]> Cc: Darrick J. Wong <[email protected]> Cc: Jan Kara <[email protected]> Cc: Matthew Wilcox (Oracle) <[email protected]> Cc: Alistair Popple <[email protected]> Cc: Jason Gunthorpe <[email protected]> Cc: John Hubbard <[email protected]> Cc: <[email protected]> Signed-off-by: Andrew Morton <[email protected]>
-rw-r--r--fs/dax.c11
1 files changed, 8 insertions, 3 deletions
diff --git a/fs/dax.c b/fs/dax.c
index 3e457a16c7d1..e48d68902a8c 100644
--- a/fs/dax.c
+++ b/fs/dax.c
@@ -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 */
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;
+ /* 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);
if (ret < 0)
goto out_unlock;