]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
dm: add support for passing through persistent reservations
authorChristoph Hellwig <hch@lst.de>
Thu, 15 Oct 2015 12:10:51 +0000 (14:10 +0200)
committerMike Snitzer <snitzer@redhat.com>
Sat, 31 Oct 2015 23:05:59 +0000 (19:05 -0400)
This adds support to pass through persistent reservation requests
similar to the existing ioctl handling, and with the same limitations,
e.g. devices may only have a single target attached.

This is mostly intended for multipathing.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Mike Snitzer <snitzer@redhat.com>
drivers/md/dm-mpath.c
drivers/md/dm.c
include/uapi/linux/dm-ioctl.h

index 77066a1999844935abfdb972fecefb6e21e98514..aaa6caa46a9f2dbceaf3d9c1aac92037b3b731b2 100644 (file)
@@ -1682,7 +1682,7 @@ out:
  *---------------------------------------------------------------*/
 static struct target_type multipath_target = {
        .name = "multipath",
-       .version = {1, 9, 0},
+       .version = {1, 10, 0},
        .module = THIS_MODULE,
        .ctr = multipath_ctr,
        .dtr = multipath_dtr,
index 9b3fe5be0cee5013d53bab2b2e5e5dea1cf7cc04..c31ca8bc6af5b24ffed7e9c18ba607d80c396a39 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/ktime.h>
 #include <linux/elevator.h> /* for rq_end_sector() */
 #include <linux/blk-mq.h>
+#include <linux/pr.h>
 
 #include <trace/events/block.h>
 
@@ -3553,11 +3554,133 @@ void dm_free_md_mempools(struct dm_md_mempools *pools)
        kfree(pools);
 }
 
+static int dm_pr_register(struct block_device *bdev, u64 old_key, u64 new_key,
+               u32 flags)
+{
+       struct mapped_device *md = bdev->bd_disk->private_data;
+       const struct pr_ops *ops;
+       struct dm_target *tgt;
+       fmode_t mode;
+       int srcu_idx, r;
+
+       r = dm_get_live_table_for_ioctl(md, &tgt, &bdev, &mode, &srcu_idx);
+       if (r < 0)
+               return r;
+
+       ops = bdev->bd_disk->fops->pr_ops;
+       if (ops && ops->pr_register)
+               r = ops->pr_register(bdev, old_key, new_key, flags);
+       else
+               r = -EOPNOTSUPP;
+
+       dm_put_live_table(md, srcu_idx);
+       return r;
+}
+
+static int dm_pr_reserve(struct block_device *bdev, u64 key, enum pr_type type,
+               u32 flags)
+{
+       struct mapped_device *md = bdev->bd_disk->private_data;
+       const struct pr_ops *ops;
+       struct dm_target *tgt;
+       fmode_t mode;
+       int srcu_idx, r;
+
+       r = dm_get_live_table_for_ioctl(md, &tgt, &bdev, &mode, &srcu_idx);
+       if (r < 0)
+               return r;
+
+       ops = bdev->bd_disk->fops->pr_ops;
+       if (ops && ops->pr_reserve)
+               r = ops->pr_reserve(bdev, key, type, flags);
+       else
+               r = -EOPNOTSUPP;
+
+       dm_put_live_table(md, srcu_idx);
+       return r;
+}
+
+static int dm_pr_release(struct block_device *bdev, u64 key, enum pr_type type)
+{
+       struct mapped_device *md = bdev->bd_disk->private_data;
+       const struct pr_ops *ops;
+       struct dm_target *tgt;
+       fmode_t mode;
+       int srcu_idx, r;
+
+       r = dm_get_live_table_for_ioctl(md, &tgt, &bdev, &mode, &srcu_idx);
+       if (r < 0)
+               return r;
+
+       ops = bdev->bd_disk->fops->pr_ops;
+       if (ops && ops->pr_release)
+               r = ops->pr_release(bdev, key, type);
+       else
+               r = -EOPNOTSUPP;
+
+       dm_put_live_table(md, srcu_idx);
+       return r;
+}
+
+static int dm_pr_preempt(struct block_device *bdev, u64 old_key, u64 new_key,
+               enum pr_type type, bool abort)
+{
+       struct mapped_device *md = bdev->bd_disk->private_data;
+       const struct pr_ops *ops;
+       struct dm_target *tgt;
+       fmode_t mode;
+       int srcu_idx, r;
+
+       r = dm_get_live_table_for_ioctl(md, &tgt, &bdev, &mode, &srcu_idx);
+       if (r < 0)
+               return r;
+
+       ops = bdev->bd_disk->fops->pr_ops;
+       if (ops && ops->pr_preempt)
+               r = ops->pr_preempt(bdev, old_key, new_key, type, abort);
+       else
+               r = -EOPNOTSUPP;
+
+       dm_put_live_table(md, srcu_idx);
+       return r;
+}
+
+static int dm_pr_clear(struct block_device *bdev, u64 key)
+{
+       struct mapped_device *md = bdev->bd_disk->private_data;
+       const struct pr_ops *ops;
+       struct dm_target *tgt;
+       fmode_t mode;
+       int srcu_idx, r;
+
+       r = dm_get_live_table_for_ioctl(md, &tgt, &bdev, &mode, &srcu_idx);
+       if (r < 0)
+               return r;
+
+       ops = bdev->bd_disk->fops->pr_ops;
+       if (ops && ops->pr_clear)
+               r = ops->pr_clear(bdev, key);
+       else
+               r = -EOPNOTSUPP;
+
+       dm_put_live_table(md, srcu_idx);
+       return r;
+}
+
+static const struct pr_ops dm_pr_ops = {
+       .pr_register    = dm_pr_register,
+       .pr_reserve     = dm_pr_reserve,
+       .pr_release     = dm_pr_release,
+       .pr_preempt     = dm_pr_preempt,
+       .pr_clear       = dm_pr_clear,
+};
+
 static const struct block_device_operations dm_blk_dops = {
        .open = dm_blk_open,
        .release = dm_blk_close,
        .ioctl = dm_blk_ioctl,
        .getgeo = dm_blk_getgeo,
+       .pr_ops = &dm_pr_ops,
        .owner = THIS_MODULE
 };
 
index d34611e35a30f10995d19cc4ae80aeb4a9547211..30afd0a23c4b0d3b0c70b5d2778f3988f01d03a2 100644 (file)
@@ -267,9 +267,9 @@ enum {
 #define DM_DEV_SET_GEOMETRY    _IOWR(DM_IOCTL, DM_DEV_SET_GEOMETRY_CMD, struct dm_ioctl)
 
 #define DM_VERSION_MAJOR       4
-#define DM_VERSION_MINOR       33
+#define DM_VERSION_MINOR       34
 #define DM_VERSION_PATCHLEVEL  0
-#define DM_VERSION_EXTRA       "-ioctl (2015-8-18)"
+#define DM_VERSION_EXTRA       "-ioctl (2015-10-28)"
 
 /* Status bits */
 #define DM_READONLY_FLAG       (1 << 0) /* In/Out */