summaryrefslogtreecommitdiffstats
path: root/drivers/md/dm.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/md/dm.c')
-rw-r--r--drivers/md/dm.c67
1 files changed, 53 insertions, 14 deletions
diff --git a/drivers/md/dm.c b/drivers/md/dm.c
index 268edf402bbb..6ef9500226c0 100644
--- a/drivers/md/dm.c
+++ b/drivers/md/dm.c
@@ -16,6 +16,7 @@
16#include <linux/blkpg.h> 16#include <linux/blkpg.h>
17#include <linux/bio.h> 17#include <linux/bio.h>
18#include <linux/mempool.h> 18#include <linux/mempool.h>
19#include <linux/dax.h>
19#include <linux/slab.h> 20#include <linux/slab.h>
20#include <linux/idr.h> 21#include <linux/idr.h>
21#include <linux/hdreg.h> 22#include <linux/hdreg.h>
@@ -629,6 +630,7 @@ static int open_table_device(struct table_device *td, dev_t dev,
629 } 630 }
630 631
631 td->dm_dev.bdev = bdev; 632 td->dm_dev.bdev = bdev;
633 td->dm_dev.dax_dev = dax_get_by_host(bdev->bd_disk->disk_name);
632 return 0; 634 return 0;
633} 635}
634 636
@@ -642,7 +644,9 @@ static void close_table_device(struct table_device *td, struct mapped_device *md
642 644
643 bd_unlink_disk_holder(td->dm_dev.bdev, dm_disk(md)); 645 bd_unlink_disk_holder(td->dm_dev.bdev, dm_disk(md));
644 blkdev_put(td->dm_dev.bdev, td->dm_dev.mode | FMODE_EXCL); 646 blkdev_put(td->dm_dev.bdev, td->dm_dev.mode | FMODE_EXCL);
647 put_dax(td->dm_dev.dax_dev);
645 td->dm_dev.bdev = NULL; 648 td->dm_dev.bdev = NULL;
649 td->dm_dev.dax_dev = NULL;
646} 650}
647 651
648static struct table_device *find_table_device(struct list_head *l, dev_t dev, 652static struct table_device *find_table_device(struct list_head *l, dev_t dev,
@@ -920,31 +924,49 @@ int dm_set_target_max_io_len(struct dm_target *ti, sector_t len)
920} 924}
921EXPORT_SYMBOL_GPL(dm_set_target_max_io_len); 925EXPORT_SYMBOL_GPL(dm_set_target_max_io_len);
922 926
923static long dm_blk_direct_access(struct block_device *bdev, sector_t sector, 927static struct dm_target *dm_dax_get_live_target(struct mapped_device *md,
924 void **kaddr, pfn_t *pfn, long size) 928 sector_t sector, int *srcu_idx)
925{ 929{
926 struct mapped_device *md = bdev->bd_disk->private_data;
927 struct dm_table *map; 930 struct dm_table *map;
928 struct dm_target *ti; 931 struct dm_target *ti;
929 int srcu_idx;
930 long len, ret = -EIO;
931 932
932 map = dm_get_live_table(md, &srcu_idx); 933 map = dm_get_live_table(md, srcu_idx);
933 if (!map) 934 if (!map)
934 goto out; 935 return NULL;
935 936
936 ti = dm_table_find_target(map, sector); 937 ti = dm_table_find_target(map, sector);
937 if (!dm_target_is_valid(ti)) 938 if (!dm_target_is_valid(ti))
938 goto out; 939 return NULL;
940
941 return ti;
942}
943
944static long dm_dax_direct_access(struct dax_device *dax_dev, pgoff_t pgoff,
945 long nr_pages, void **kaddr, pfn_t *pfn)
946{
947 struct mapped_device *md = dax_get_private(dax_dev);
948 sector_t sector = pgoff * PAGE_SECTORS;
949 struct dm_target *ti;
950 long len, ret = -EIO;
951 int srcu_idx;
939 952
940 len = max_io_len(sector, ti) << SECTOR_SHIFT; 953 ti = dm_dax_get_live_target(md, sector, &srcu_idx);
941 size = min(len, size);
942 954
955 if (!ti)
956 goto out;
957 if (!ti->type->direct_access)
958 goto out;
959 len = max_io_len(sector, ti) / PAGE_SECTORS;
960 if (len < 1)
961 goto out;
962 nr_pages = min(len, nr_pages);
943 if (ti->type->direct_access) 963 if (ti->type->direct_access)
944 ret = ti->type->direct_access(ti, sector, kaddr, pfn, size); 964 ret = ti->type->direct_access(ti, pgoff, nr_pages, kaddr, pfn);
945out: 965
966 out:
946 dm_put_live_table(md, srcu_idx); 967 dm_put_live_table(md, srcu_idx);
947 return min(ret, size); 968
969 return ret;
948} 970}
949 971
950/* 972/*
@@ -1471,6 +1493,7 @@ static int next_free_minor(int *minor)
1471} 1493}
1472 1494
1473static const struct block_device_operations dm_blk_dops; 1495static const struct block_device_operations dm_blk_dops;
1496static const struct dax_operations dm_dax_ops;
1474 1497
1475static void dm_wq_work(struct work_struct *work); 1498static void dm_wq_work(struct work_struct *work);
1476 1499
@@ -1517,6 +1540,12 @@ static void cleanup_mapped_device(struct mapped_device *md)
1517 if (md->bs) 1540 if (md->bs)
1518 bioset_free(md->bs); 1541 bioset_free(md->bs);
1519 1542
1543 if (md->dax_dev) {
1544 kill_dax(md->dax_dev);
1545 put_dax(md->dax_dev);
1546 md->dax_dev = NULL;
1547 }
1548
1520 if (md->disk) { 1549 if (md->disk) {
1521 spin_lock(&_minor_lock); 1550 spin_lock(&_minor_lock);
1522 md->disk->private_data = NULL; 1551 md->disk->private_data = NULL;
@@ -1544,6 +1573,7 @@ static void cleanup_mapped_device(struct mapped_device *md)
1544static struct mapped_device *alloc_dev(int minor) 1573static struct mapped_device *alloc_dev(int minor)
1545{ 1574{
1546 int r, numa_node_id = dm_get_numa_node(); 1575 int r, numa_node_id = dm_get_numa_node();
1576 struct dax_device *dax_dev;
1547 struct mapped_device *md; 1577 struct mapped_device *md;
1548 void *old_md; 1578 void *old_md;
1549 1579
@@ -1608,6 +1638,12 @@ static struct mapped_device *alloc_dev(int minor)
1608 md->disk->queue = md->queue; 1638 md->disk->queue = md->queue;
1609 md->disk->private_data = md; 1639 md->disk->private_data = md;
1610 sprintf(md->disk->disk_name, "dm-%d", minor); 1640 sprintf(md->disk->disk_name, "dm-%d", minor);
1641
1642 dax_dev = alloc_dax(md, md->disk->disk_name, &dm_dax_ops);
1643 if (!dax_dev)
1644 goto bad;
1645 md->dax_dev = dax_dev;
1646
1611 add_disk(md->disk); 1647 add_disk(md->disk);
1612 format_dev_t(md->name, MKDEV(_major, minor)); 1648 format_dev_t(md->name, MKDEV(_major, minor));
1613 1649
@@ -2816,12 +2852,15 @@ static const struct block_device_operations dm_blk_dops = {
2816 .open = dm_blk_open, 2852 .open = dm_blk_open,
2817 .release = dm_blk_close, 2853 .release = dm_blk_close,
2818 .ioctl = dm_blk_ioctl, 2854 .ioctl = dm_blk_ioctl,
2819 .direct_access = dm_blk_direct_access,
2820 .getgeo = dm_blk_getgeo, 2855 .getgeo = dm_blk_getgeo,
2821 .pr_ops = &dm_pr_ops, 2856 .pr_ops = &dm_pr_ops,
2822 .owner = THIS_MODULE 2857 .owner = THIS_MODULE
2823}; 2858};
2824 2859
2860static const struct dax_operations dm_dax_ops = {
2861 .direct_access = dm_dax_direct_access,
2862};
2863
2825/* 2864/*
2826 * module hooks 2865 * module hooks
2827 */ 2866 */