Merge tag 'libnvdimm-for-4.18' of git://git.kernel.org/pub/scm/linux/kernel/git/nvdim...
[linux-2.6-block.git] / drivers / md / dm.c
index 20a8d63754bfe2f3b2d0789f955409720697fbb8..e65429a29c06e2554e8a0e23ba5a0b2a3b18a8c8 100644 (file)
@@ -1089,6 +1089,30 @@ static size_t dm_dax_copy_from_iter(struct dax_device *dax_dev, pgoff_t pgoff,
        return ret;
 }
 
+static size_t dm_dax_copy_to_iter(struct dax_device *dax_dev, pgoff_t pgoff,
+               void *addr, size_t bytes, struct iov_iter *i)
+{
+       struct mapped_device *md = dax_get_private(dax_dev);
+       sector_t sector = pgoff * PAGE_SECTORS;
+       struct dm_target *ti;
+       long ret = 0;
+       int srcu_idx;
+
+       ti = dm_dax_get_live_target(md, sector, &srcu_idx);
+
+       if (!ti)
+               goto out;
+       if (!ti->type->dax_copy_to_iter) {
+               ret = copy_to_iter(addr, bytes, i);
+               goto out;
+       }
+       ret = ti->type->dax_copy_to_iter(ti, pgoff, addr, bytes, i);
+ out:
+       dm_put_live_table(md, srcu_idx);
+
+       return ret;
+}
+
 /*
  * A target may call dm_accept_partial_bio only from the map routine.  It is
  * allowed for all bio types except REQ_PREFLUSH and REQ_OP_ZONE_RESET.
@@ -3137,6 +3161,7 @@ static const struct block_device_operations dm_blk_dops = {
 static const struct dax_operations dm_dax_ops = {
        .direct_access = dm_dax_direct_access,
        .copy_from_iter = dm_dax_copy_from_iter,
+       .copy_to_iter = dm_dax_copy_to_iter,
 };
 
 /*