Message ID | 20210915104501.4146910-6-ruansy.fnst@fujitsu.com (mailing list archive) |
---|---|
State | Superseded |
Headers | show |
Series | fsdax,xfs: Add reflink&dedupe support for fsdax | expand |
On Wed, Sep 15, 2021 at 06:44:58PM +0800, Shiyang Ruan wrote: > + rc = dax_direct_access(iomap->dax_dev, pgoff, 1, &kaddr, NULL); > + if (rc < 0) > + goto out; > + memset(kaddr + offset, 0, size); > + if (srcmap->addr != IOMAP_HOLE && srcmap->addr != iomap->addr) { Should we also check that ->dax_dev for iomap and srcmap are different first to deal with case of file system with multiple devices? Otherwise looks good: Reviewed-by: Christoph Hellwig <hch@lst.de>
On 2021/9/16 14:16, Christoph Hellwig wrote: > On Wed, Sep 15, 2021 at 06:44:58PM +0800, Shiyang Ruan wrote: >> + rc = dax_direct_access(iomap->dax_dev, pgoff, 1, &kaddr, NULL); >> + if (rc < 0) >> + goto out; >> + memset(kaddr + offset, 0, size); >> + if (srcmap->addr != IOMAP_HOLE && srcmap->addr != iomap->addr) { > > Should we also check that ->dax_dev for iomap and srcmap are different > first to deal with case of file system with multiple devices? I have not thought of this case. Isn't it possible to CoW between different devices? -- Thanks, Ruan > > Otherwise looks good: > > Reviewed-by: Christoph Hellwig <hch@lst.de> >
On Thu, Sep 16, 2021 at 04:49:19PM +0800, Shiyang Ruan wrote: > > > On 2021/9/16 14:16, Christoph Hellwig wrote: > > On Wed, Sep 15, 2021 at 06:44:58PM +0800, Shiyang Ruan wrote: > > > + rc = dax_direct_access(iomap->dax_dev, pgoff, 1, &kaddr, NULL); > > > + if (rc < 0) > > > + goto out; > > > + memset(kaddr + offset, 0, size); > > > + if (srcmap->addr != IOMAP_HOLE && srcmap->addr != iomap->addr) { > > > > Should we also check that ->dax_dev for iomap and srcmap are different > > first to deal with case of file system with multiple devices? > > I have not thought of this case. Isn't it possible to CoW between different > devices? There's nothing in the iomap API that prevents a filesystem from doing that, though there are no filesystems today that do such a thing. That said, if btrfs ever joins the fold (and adds DAX support) then they could totally COW to a different device. --D > > > -- > Thanks, > Ruan > > > > > Otherwise looks good: > > > > Reviewed-by: Christoph Hellwig <hch@lst.de> > > > >
diff --git a/fs/dax.c b/fs/dax.c index 4f346e25e488..ca4308c85988 100644 --- a/fs/dax.c +++ b/fs/dax.c @@ -1212,6 +1212,7 @@ static vm_fault_t dax_pmd_load_hole(struct xa_state *xas, struct vm_fault *vmf, s64 dax_iomap_zero(struct iomap_iter *iter, loff_t pos, u64 length) { const struct iomap *iomap = &iter->iomap; + const struct iomap *srcmap = &iter->srcmap; sector_t sector = iomap_sector(iomap, pos & PAGE_MASK); pgoff_t pgoff; long rc, id; @@ -1230,21 +1231,27 @@ s64 dax_iomap_zero(struct iomap_iter *iter, loff_t pos, u64 length) id = dax_read_lock(); - if (page_aligned) + if (page_aligned) { rc = dax_zero_page_range(iomap->dax_dev, pgoff, 1); - else - rc = dax_direct_access(iomap->dax_dev, pgoff, 1, &kaddr, NULL); - if (rc < 0) { - dax_read_unlock(id); - return rc; + goto out; } - if (!page_aligned) { - memset(kaddr + offset, 0, size); + rc = dax_direct_access(iomap->dax_dev, pgoff, 1, &kaddr, NULL); + if (rc < 0) + goto out; + memset(kaddr + offset, 0, size); + if (srcmap->addr != IOMAP_HOLE && srcmap->addr != iomap->addr) { + rc = dax_iomap_cow_copy(pos, size, PAGE_SIZE, srcmap, + kaddr); + if (rc < 0) + goto out; + dax_flush(iomap->dax_dev, kaddr, PAGE_SIZE); + } else dax_flush(iomap->dax_dev, kaddr + offset, size); - } + +out: dax_read_unlock(id); - return size; + return rc < 0 ? rc : size; } static loff_t dax_iomap_iter(const struct iomap_iter *iomi,