|
@@ -354,9 +354,29 @@ static size_t stripe_dax_copy_from_iter(struct dm_target *ti, pgoff_t pgoff,
|
|
|
return dax_copy_from_iter(dax_dev, pgoff, addr, bytes, i);
|
|
|
}
|
|
|
|
|
|
+static size_t stripe_dax_copy_to_iter(struct dm_target *ti, pgoff_t pgoff,
|
|
|
+ void *addr, size_t bytes, struct iov_iter *i)
|
|
|
+{
|
|
|
+ sector_t dev_sector, sector = pgoff * PAGE_SECTORS;
|
|
|
+ struct stripe_c *sc = ti->private;
|
|
|
+ struct dax_device *dax_dev;
|
|
|
+ struct block_device *bdev;
|
|
|
+ uint32_t stripe;
|
|
|
+
|
|
|
+ stripe_map_sector(sc, sector, &stripe, &dev_sector);
|
|
|
+ dev_sector += sc->stripe[stripe].physical_start;
|
|
|
+ dax_dev = sc->stripe[stripe].dev->dax_dev;
|
|
|
+ bdev = sc->stripe[stripe].dev->bdev;
|
|
|
+
|
|
|
+ if (bdev_dax_pgoff(bdev, dev_sector, ALIGN(bytes, PAGE_SIZE), &pgoff))
|
|
|
+ return 0;
|
|
|
+ return dax_copy_to_iter(dax_dev, pgoff, addr, bytes, i);
|
|
|
+}
|
|
|
+
|
|
|
#else
|
|
|
#define stripe_dax_direct_access NULL
|
|
|
#define stripe_dax_copy_from_iter NULL
|
|
|
+#define stripe_dax_copy_to_iter NULL
|
|
|
#endif
|
|
|
|
|
|
/*
|
|
@@ -478,6 +498,7 @@ static struct target_type stripe_target = {
|
|
|
.io_hints = stripe_io_hints,
|
|
|
.direct_access = stripe_dax_direct_access,
|
|
|
.dax_copy_from_iter = stripe_dax_copy_from_iter,
|
|
|
+ .dax_copy_to_iter = stripe_dax_copy_to_iter,
|
|
|
};
|
|
|
|
|
|
int __init dm_stripe_init(void)
|