aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/md/dm-log-writes.c88
1 files changed, 87 insertions, 1 deletions
diff --git a/drivers/md/dm-log-writes.c b/drivers/md/dm-log-writes.c
index 34b9b4146021..189badbeddaf 100644
--- a/drivers/md/dm-log-writes.c
+++ b/drivers/md/dm-log-writes.c
@@ -10,9 +10,11 @@
10#include <linux/init.h> 10#include <linux/init.h>
11#include <linux/blkdev.h> 11#include <linux/blkdev.h>
12#include <linux/bio.h> 12#include <linux/bio.h>
13#include <linux/dax.h>
13#include <linux/slab.h> 14#include <linux/slab.h>
14#include <linux/kthread.h> 15#include <linux/kthread.h>
15#include <linux/freezer.h> 16#include <linux/freezer.h>
17#include <linux/uio.h>
16 18
17#define DM_MSG_PREFIX "log-writes" 19#define DM_MSG_PREFIX "log-writes"
18 20
@@ -608,6 +610,51 @@ static int log_mark(struct log_writes_c *lc, char *data)
608 return 0; 610 return 0;
609} 611}
610 612
613static int log_dax(struct log_writes_c *lc, sector_t sector, size_t bytes,
614 struct iov_iter *i)
615{
616 struct pending_block *block;
617
618 if (!bytes)
619 return 0;
620
621 block = kzalloc(sizeof(struct pending_block), GFP_KERNEL);
622 if (!block) {
623 DMERR("Error allocating dax pending block");
624 return -ENOMEM;
625 }
626
627 block->data = kzalloc(bytes, GFP_KERNEL);
628 if (!block->data) {
629 DMERR("Error allocating dax data space");
630 kfree(block);
631 return -ENOMEM;
632 }
633
634 /* write data provided via the iterator */
635 if (!copy_from_iter(block->data, bytes, i)) {
636 DMERR("Error copying dax data");
637 kfree(block->data);
638 kfree(block);
639 return -EIO;
640 }
641
642 /* rewind the iterator so that the block driver can use it */
643 iov_iter_revert(i, bytes);
644
645 block->datalen = bytes;
646 block->sector = bio_to_dev_sectors(lc, sector);
647 block->nr_sectors = ALIGN(bytes, lc->sectorsize) >> lc->sectorshift;
648
649 atomic_inc(&lc->pending_blocks);
650 spin_lock_irq(&lc->blocks_lock);
651 list_add_tail(&block->list, &lc->unflushed_blocks);
652 spin_unlock_irq(&lc->blocks_lock);
653 wake_up_process(lc->log_kthread);
654
655 return 0;
656}
657
611static void log_writes_dtr(struct dm_target *ti) 658static void log_writes_dtr(struct dm_target *ti)
612{ 659{
613 struct log_writes_c *lc = ti->private; 660 struct log_writes_c *lc = ti->private;
@@ -873,9 +920,46 @@ static void log_writes_io_hints(struct dm_target *ti, struct queue_limits *limit
873 limits->io_min = limits->physical_block_size; 920 limits->io_min = limits->physical_block_size;
874} 921}
875 922
923static long log_writes_dax_direct_access(struct dm_target *ti, pgoff_t pgoff,
924 long nr_pages, void **kaddr, pfn_t *pfn)
925{
926 struct log_writes_c *lc = ti->private;
927 sector_t sector = pgoff * PAGE_SECTORS;
928 int ret;
929
930 ret = bdev_dax_pgoff(lc->dev->bdev, sector, nr_pages * PAGE_SIZE, &pgoff);
931 if (ret)
932 return ret;
933 return dax_direct_access(lc->dev->dax_dev, pgoff, nr_pages, kaddr, pfn);
934}
935
936static size_t log_writes_dax_copy_from_iter(struct dm_target *ti,
937 pgoff_t pgoff, void *addr, size_t bytes,
938 struct iov_iter *i)
939{
940 struct log_writes_c *lc = ti->private;
941 sector_t sector = pgoff * PAGE_SECTORS;
942 int err;
943
944 if (bdev_dax_pgoff(lc->dev->bdev, sector, ALIGN(bytes, PAGE_SIZE), &pgoff))
945 return 0;
946
947 /* Don't bother doing anything if logging has been disabled */
948 if (!lc->logging_enabled)
949 goto dax_copy;
950
951 err = log_dax(lc, sector, bytes, i);
952 if (err) {
953 DMWARN("Error %d logging DAX write", err);
954 return 0;
955 }
956dax_copy:
957 return dax_copy_from_iter(lc->dev->dax_dev, pgoff, addr, bytes, i);
958}
959
876static struct target_type log_writes_target = { 960static struct target_type log_writes_target = {
877 .name = "log-writes", 961 .name = "log-writes",
878 .version = {1, 0, 0}, 962 .version = {1, 1, 0},
879 .module = THIS_MODULE, 963 .module = THIS_MODULE,
880 .ctr = log_writes_ctr, 964 .ctr = log_writes_ctr,
881 .dtr = log_writes_dtr, 965 .dtr = log_writes_dtr,
@@ -886,6 +970,8 @@ static struct target_type log_writes_target = {
886 .message = log_writes_message, 970 .message = log_writes_message,
887 .iterate_devices = log_writes_iterate_devices, 971 .iterate_devices = log_writes_iterate_devices,
888 .io_hints = log_writes_io_hints, 972 .io_hints = log_writes_io_hints,
973 .direct_access = log_writes_dax_direct_access,
974 .dax_copy_from_iter = log_writes_dax_copy_from_iter,
889}; 975};
890 976
891static int __init dm_log_writes_init(void) 977static int __init dm_log_writes_init(void)