Commit 8dbfc76d authored by Shiyang Ruan's avatar Shiyang Ruan Committed by akpm

fsdax: add dax_iomap_cow_copy() for dax zero

Punch hole on a reflinked file needs dax_iomap_cow_copy() too.  Otherwise,
data in not aligned area will be not correct.  So, add the CoW operation
for not aligned case in dax_memzero().

Link: https://lkml.kernel.org/r/20220603053738.1218681-12-ruansy.fnst@fujitsu.comSigned-off-by: default avatarShiyang Ruan <ruansy.fnst@fujitsu.com>
Reviewed-by: default avatarRitesh Harjani <riteshh@linux.ibm.com>
Reviewed-by: default avatarDarrick J. Wong <djwong@kernel.org>
Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Cc: Dan Williams <dan.j.wiliams@intel.com>
Cc: Dan Williams <dan.j.williams@intel.com>
Cc: Dave Chinner <david@fromorbit.com>
Cc: Goldwyn Rodrigues <rgoldwyn@suse.com>
Cc: Goldwyn Rodrigues <rgoldwyn@suse.de>
Cc: Jane Chu <jane.chu@oracle.com>
Cc: Matthew Wilcox <willy@infradead.org>
Cc: Miaohe Lin <linmiaohe@huawei.com>
Cc: Naoya Horiguchi <naoya.horiguchi@nec.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
parent e5d6df73
...@@ -1221,17 +1221,28 @@ static vm_fault_t dax_pmd_load_hole(struct xa_state *xas, struct vm_fault *vmf, ...@@ -1221,17 +1221,28 @@ static vm_fault_t dax_pmd_load_hole(struct xa_state *xas, struct vm_fault *vmf,
} }
#endif /* CONFIG_FS_DAX_PMD */ #endif /* CONFIG_FS_DAX_PMD */
static int dax_memzero(struct dax_device *dax_dev, pgoff_t pgoff, static int dax_memzero(struct iomap_iter *iter, loff_t pos, size_t size)
unsigned int offset, size_t size)
{ {
const struct iomap *iomap = &iter->iomap;
const struct iomap *srcmap = iomap_iter_srcmap(iter);
unsigned offset = offset_in_page(pos);
pgoff_t pgoff = dax_iomap_pgoff(iomap, pos);
void *kaddr; void *kaddr;
long ret; long ret;
ret = dax_direct_access(dax_dev, pgoff, 1, DAX_ACCESS, &kaddr, NULL); ret = dax_direct_access(iomap->dax_dev, pgoff, 1, DAX_ACCESS, &kaddr,
if (ret > 0) { NULL);
if (ret < 0)
return ret;
memset(kaddr + offset, 0, size); memset(kaddr + offset, 0, size);
dax_flush(dax_dev, kaddr + offset, size); if (srcmap->addr != iomap->addr) {
} ret = dax_iomap_cow_copy(pos, size, PAGE_SIZE, srcmap,
kaddr);
if (ret < 0)
return ret;
dax_flush(iomap->dax_dev, kaddr, PAGE_SIZE);
} else
dax_flush(iomap->dax_dev, kaddr + offset, size);
return ret; return ret;
} }
...@@ -1258,7 +1269,7 @@ static s64 dax_zero_iter(struct iomap_iter *iter, bool *did_zero) ...@@ -1258,7 +1269,7 @@ static s64 dax_zero_iter(struct iomap_iter *iter, bool *did_zero)
if (IS_ALIGNED(pos, PAGE_SIZE) && size == PAGE_SIZE) if (IS_ALIGNED(pos, PAGE_SIZE) && size == PAGE_SIZE)
rc = dax_zero_page_range(iomap->dax_dev, pgoff, 1); rc = dax_zero_page_range(iomap->dax_dev, pgoff, 1);
else else
rc = dax_memzero(iomap->dax_dev, pgoff, offset, size); rc = dax_memzero(iter, pos, size);
dax_read_unlock(id); dax_read_unlock(id);
if (rc < 0) if (rc < 0)
......
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