From: Sergei Shtepa <sergei.shtepa@veeam.com> To: <Damien.LeMoal@wdc.com>, <snitzer@redhat.com>, <hare@suse.de>, <ming.lei@redhat.com>, <agk@redhat.com>, <corbet@lwn.net>, <axboe@kernel.dk>, <jack@suse.cz>, <johannes.thumshirn@wdc.com>, <gregkh@linuxfoundation.org>, <koct9i@gmail.com>, <steve@sk2.org>, <dm-devel@redhat.com>, <linux-block@vger.kernel.org>, <linux-doc@vger.kernel.org>, <linux-kernel@vger.kernel.org> Cc: <sergei.shtepa@veeam.com>, <pavgel.tide@veeam.com> Subject: [PATCH v4 5/6] dm: add 'noexcl' option for dm-linear Date: Wed, 3 Feb 2021 18:53:57 +0300 [thread overview] Message-ID: <1612367638-3794-6-git-send-email-sergei.shtepa@veeam.com> (raw) In-Reply-To: <1612367638-3794-1-git-send-email-sergei.shtepa@veeam.com> The 'noexcl' option allow to open underlying block-device without FMODE_EXCL. Signed-off-by: Sergei Shtepa <sergei.shtepa@veeam.com> --- drivers/md/dm-linear.c | 14 +++++++++++++- drivers/md/dm-table.c | 12 +++++++----- drivers/md/dm.c | 24 +++++++++++++++++------- drivers/md/dm.h | 2 +- include/linux/device-mapper.h | 7 +++++++ 5 files changed, 45 insertions(+), 14 deletions(-) diff --git a/drivers/md/dm-linear.c b/drivers/md/dm-linear.c index 00774b5d7668..b16d89802b9d 100644 --- a/drivers/md/dm-linear.c +++ b/drivers/md/dm-linear.c @@ -33,7 +33,7 @@ static int linear_ctr(struct dm_target *ti, unsigned int argc, char **argv) char dummy; int ret; - if (argc != 2) { + if ((argc < 2) || (argc > 3)) { ti->error = "Invalid argument count"; return -EINVAL; } @@ -51,6 +51,18 @@ static int linear_ctr(struct dm_target *ti, unsigned int argc, char **argv) } lc->start = tmp; + ti->non_exclusive = false; + if (argc > 2) { + if (strcmp("noexcl", argv[2]) == 0) + ti->non_exclusive = true; + else if (strcmp("excl", argv[2]) == 0) + ti->non_exclusive = false; + else { + ti->error = "Invalid exclusive option"; + return -EINVAL; + } + } + ret = dm_get_device(ti, argv[0], dm_table_get_mode(ti->table), &lc->dev); if (ret) { ti->error = "Device lookup failed"; diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c index 4acf2342f7ad..f15bc2171f25 100644 --- a/drivers/md/dm-table.c +++ b/drivers/md/dm-table.c @@ -322,7 +322,7 @@ static int device_area_is_invalid(struct dm_target *ti, struct dm_dev *dev, * device and not to touch the existing bdev field in case * it is accessed concurrently. */ -static int upgrade_mode(struct dm_dev_internal *dd, fmode_t new_mode, +static int upgrade_mode(struct dm_dev_internal *dd, fmode_t new_mode, bool non_exclusive, struct mapped_device *md) { int r; @@ -330,7 +330,7 @@ static int upgrade_mode(struct dm_dev_internal *dd, fmode_t new_mode, old_dev = dd->dm_dev; - r = dm_get_table_device(md, dd->dm_dev->bdev->bd_dev, + r = dm_get_table_device(md, dd->dm_dev->bdev->bd_dev, non_exclusive, dd->dm_dev->mode | new_mode, &new_dev); if (r) return r; @@ -387,7 +387,8 @@ int dm_get_device(struct dm_target *ti, const char *path, fmode_t mode, if (!dd) return -ENOMEM; - if ((r = dm_get_table_device(t->md, dev, mode, &dd->dm_dev))) { + r = dm_get_table_device(t->md, dev, mode, ti->non_exclusive, &dd->dm_dev); + if (r) { kfree(dd); return r; } @@ -396,8 +397,9 @@ int dm_get_device(struct dm_target *ti, const char *path, fmode_t mode, list_add(&dd->list, &t->devices); goto out; - } else if (dd->dm_dev->mode != (mode | dd->dm_dev->mode)) { - r = upgrade_mode(dd, mode, t->md); + } else if ((dd->dm_dev->mode != (mode | dd->dm_dev->mode)) && + (dd->dm_dev->non_exclusive != ti->non_exclusive)) { + r = upgrade_mode(dd, mode, ti->non_exclusive, t->md); if (r) return r; } diff --git a/drivers/md/dm.c b/drivers/md/dm.c index 0b184dfec233..c34c75467399 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c @@ -1107,6 +1107,7 @@ static int open_table_device(struct table_device *td, dev_t dev, td->dm_dev.bdev = bdev; td->dm_dev.dax_dev = dax_get_by_host(bdev->bd_disk->disk_name); + td->dm_dev.non_exclusive = non_exclusive; return 0; } @@ -1118,33 +1119,41 @@ static void close_table_device(struct table_device *td, struct mapped_device *md if (!td->dm_dev.bdev) return; - bd_unlink_disk_holder(td->dm_dev.bdev, dm_disk(md)); - blkdev_put(td->dm_dev.bdev, td->dm_dev.mode | FMODE_EXCL); + if (td->dm_dev.non_exclusive) + blkdev_put(td->dm_dev.bdev, td->dm_dev.mode); + else { + bd_unlink_disk_holder(td->dm_dev.bdev, dm_disk(md)); + blkdev_put(td->dm_dev.bdev, td->dm_dev.mode | FMODE_EXCL); + } + put_dax(td->dm_dev.dax_dev); td->dm_dev.bdev = NULL; td->dm_dev.dax_dev = NULL; + td->dm_dev.non_exclusive = false; } static struct table_device *find_table_device(struct list_head *l, dev_t dev, - fmode_t mode) + fmode_t mode, bool non_exclusive) { struct table_device *td; list_for_each_entry(td, l, list) - if (td->dm_dev.bdev->bd_dev == dev && td->dm_dev.mode == mode) + if (td->dm_dev.bdev->bd_dev == dev && + td->dm_dev.mode == mode && + td->dm_dev.non_exclusive == non_exclusive) return td; return NULL; } -int dm_get_table_device(struct mapped_device *md, dev_t dev, fmode_t mode, +int dm_get_table_device(struct mapped_device *md, dev_t dev, fmode_t mode, bool non_exclusive, struct dm_dev **result) { int r; struct table_device *td; mutex_lock(&md->table_devices_lock); - td = find_table_device(&md->table_devices, dev, mode); + td = find_table_device(&md->table_devices, dev, mode, non_exclusive); if (!td) { td = kmalloc_node(sizeof(*td), GFP_KERNEL, md->numa_node_id); if (!td) { @@ -1155,7 +1164,8 @@ int dm_get_table_device(struct mapped_device *md, dev_t dev, fmode_t mode, td->dm_dev.mode = mode; td->dm_dev.bdev = NULL; - if ((r = open_table_device(td, dev, md))) { + r = open_table_device(td, dev, md, non_exclusive); + if (r) { mutex_unlock(&md->table_devices_lock); kfree(td); return r; diff --git a/drivers/md/dm.h b/drivers/md/dm.h index fffe1e289c53..7bf20fb2de74 100644 --- a/drivers/md/dm.h +++ b/drivers/md/dm.h @@ -179,7 +179,7 @@ int dm_open_count(struct mapped_device *md); int dm_lock_for_deletion(struct mapped_device *md, bool mark_deferred, bool only_deferred); int dm_cancel_deferred_remove(struct mapped_device *md); int dm_request_based(struct mapped_device *md); -int dm_get_table_device(struct mapped_device *md, dev_t dev, fmode_t mode, +int dm_get_table_device(struct mapped_device *md, dev_t dev, fmode_t mode, bool non_exclusive, struct dm_dev **result); void dm_put_table_device(struct mapped_device *md, struct dm_dev *d); diff --git a/include/linux/device-mapper.h b/include/linux/device-mapper.h index 61a66fb8ebb3..70002363bfc0 100644 --- a/include/linux/device-mapper.h +++ b/include/linux/device-mapper.h @@ -150,6 +150,7 @@ struct dm_dev { struct block_device *bdev; struct dax_device *dax_dev; fmode_t mode; + bool non_exclusive; char name[16]; }; @@ -325,6 +326,12 @@ struct dm_target { * whether or not its underlying devices have support. */ bool discards_supported:1; + + /* + * Set if this target needs to open device without FMODE_EXCL + * mode. + */ + bool non_exclusive:1; }; void *dm_per_bio_data(struct bio *bio, size_t data_size); -- 2.20.1
WARNING: multiple messages have this Message-ID (diff)
From: Sergei Shtepa <sergei.shtepa@veeam.com> To: <Damien.LeMoal@wdc.com>, <snitzer@redhat.com>, <hare@suse.de>, <ming.lei@redhat.com>, <agk@redhat.com>, <corbet@lwn.net>, <axboe@kernel.dk>, <jack@suse.cz>, <johannes.thumshirn@wdc.com>, <gregkh@linuxfoundation.org>, <koct9i@gmail.com>, <steve@sk2.org>, <dm-devel@redhat.com>, <linux-block@vger.kernel.org>, <linux-doc@vger.kernel.org>, <linux-kernel@vger.kernel.org> Cc: pavgel.tide@veeam.com, sergei.shtepa@veeam.com Subject: [dm-devel] [PATCH v4 5/6] dm: add 'noexcl' option for dm-linear Date: Wed, 3 Feb 2021 18:53:57 +0300 [thread overview] Message-ID: <1612367638-3794-6-git-send-email-sergei.shtepa@veeam.com> (raw) In-Reply-To: <1612367638-3794-1-git-send-email-sergei.shtepa@veeam.com> The 'noexcl' option allow to open underlying block-device without FMODE_EXCL. Signed-off-by: Sergei Shtepa <sergei.shtepa@veeam.com> --- drivers/md/dm-linear.c | 14 +++++++++++++- drivers/md/dm-table.c | 12 +++++++----- drivers/md/dm.c | 24 +++++++++++++++++------- drivers/md/dm.h | 2 +- include/linux/device-mapper.h | 7 +++++++ 5 files changed, 45 insertions(+), 14 deletions(-) diff --git a/drivers/md/dm-linear.c b/drivers/md/dm-linear.c index 00774b5d7668..b16d89802b9d 100644 --- a/drivers/md/dm-linear.c +++ b/drivers/md/dm-linear.c @@ -33,7 +33,7 @@ static int linear_ctr(struct dm_target *ti, unsigned int argc, char **argv) char dummy; int ret; - if (argc != 2) { + if ((argc < 2) || (argc > 3)) { ti->error = "Invalid argument count"; return -EINVAL; } @@ -51,6 +51,18 @@ static int linear_ctr(struct dm_target *ti, unsigned int argc, char **argv) } lc->start = tmp; + ti->non_exclusive = false; + if (argc > 2) { + if (strcmp("noexcl", argv[2]) == 0) + ti->non_exclusive = true; + else if (strcmp("excl", argv[2]) == 0) + ti->non_exclusive = false; + else { + ti->error = "Invalid exclusive option"; + return -EINVAL; + } + } + ret = dm_get_device(ti, argv[0], dm_table_get_mode(ti->table), &lc->dev); if (ret) { ti->error = "Device lookup failed"; diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c index 4acf2342f7ad..f15bc2171f25 100644 --- a/drivers/md/dm-table.c +++ b/drivers/md/dm-table.c @@ -322,7 +322,7 @@ static int device_area_is_invalid(struct dm_target *ti, struct dm_dev *dev, * device and not to touch the existing bdev field in case * it is accessed concurrently. */ -static int upgrade_mode(struct dm_dev_internal *dd, fmode_t new_mode, +static int upgrade_mode(struct dm_dev_internal *dd, fmode_t new_mode, bool non_exclusive, struct mapped_device *md) { int r; @@ -330,7 +330,7 @@ static int upgrade_mode(struct dm_dev_internal *dd, fmode_t new_mode, old_dev = dd->dm_dev; - r = dm_get_table_device(md, dd->dm_dev->bdev->bd_dev, + r = dm_get_table_device(md, dd->dm_dev->bdev->bd_dev, non_exclusive, dd->dm_dev->mode | new_mode, &new_dev); if (r) return r; @@ -387,7 +387,8 @@ int dm_get_device(struct dm_target *ti, const char *path, fmode_t mode, if (!dd) return -ENOMEM; - if ((r = dm_get_table_device(t->md, dev, mode, &dd->dm_dev))) { + r = dm_get_table_device(t->md, dev, mode, ti->non_exclusive, &dd->dm_dev); + if (r) { kfree(dd); return r; } @@ -396,8 +397,9 @@ int dm_get_device(struct dm_target *ti, const char *path, fmode_t mode, list_add(&dd->list, &t->devices); goto out; - } else if (dd->dm_dev->mode != (mode | dd->dm_dev->mode)) { - r = upgrade_mode(dd, mode, t->md); + } else if ((dd->dm_dev->mode != (mode | dd->dm_dev->mode)) && + (dd->dm_dev->non_exclusive != ti->non_exclusive)) { + r = upgrade_mode(dd, mode, ti->non_exclusive, t->md); if (r) return r; } diff --git a/drivers/md/dm.c b/drivers/md/dm.c index 0b184dfec233..c34c75467399 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c @@ -1107,6 +1107,7 @@ static int open_table_device(struct table_device *td, dev_t dev, td->dm_dev.bdev = bdev; td->dm_dev.dax_dev = dax_get_by_host(bdev->bd_disk->disk_name); + td->dm_dev.non_exclusive = non_exclusive; return 0; } @@ -1118,33 +1119,41 @@ static void close_table_device(struct table_device *td, struct mapped_device *md if (!td->dm_dev.bdev) return; - bd_unlink_disk_holder(td->dm_dev.bdev, dm_disk(md)); - blkdev_put(td->dm_dev.bdev, td->dm_dev.mode | FMODE_EXCL); + if (td->dm_dev.non_exclusive) + blkdev_put(td->dm_dev.bdev, td->dm_dev.mode); + else { + bd_unlink_disk_holder(td->dm_dev.bdev, dm_disk(md)); + blkdev_put(td->dm_dev.bdev, td->dm_dev.mode | FMODE_EXCL); + } + put_dax(td->dm_dev.dax_dev); td->dm_dev.bdev = NULL; td->dm_dev.dax_dev = NULL; + td->dm_dev.non_exclusive = false; } static struct table_device *find_table_device(struct list_head *l, dev_t dev, - fmode_t mode) + fmode_t mode, bool non_exclusive) { struct table_device *td; list_for_each_entry(td, l, list) - if (td->dm_dev.bdev->bd_dev == dev && td->dm_dev.mode == mode) + if (td->dm_dev.bdev->bd_dev == dev && + td->dm_dev.mode == mode && + td->dm_dev.non_exclusive == non_exclusive) return td; return NULL; } -int dm_get_table_device(struct mapped_device *md, dev_t dev, fmode_t mode, +int dm_get_table_device(struct mapped_device *md, dev_t dev, fmode_t mode, bool non_exclusive, struct dm_dev **result) { int r; struct table_device *td; mutex_lock(&md->table_devices_lock); - td = find_table_device(&md->table_devices, dev, mode); + td = find_table_device(&md->table_devices, dev, mode, non_exclusive); if (!td) { td = kmalloc_node(sizeof(*td), GFP_KERNEL, md->numa_node_id); if (!td) { @@ -1155,7 +1164,8 @@ int dm_get_table_device(struct mapped_device *md, dev_t dev, fmode_t mode, td->dm_dev.mode = mode; td->dm_dev.bdev = NULL; - if ((r = open_table_device(td, dev, md))) { + r = open_table_device(td, dev, md, non_exclusive); + if (r) { mutex_unlock(&md->table_devices_lock); kfree(td); return r; diff --git a/drivers/md/dm.h b/drivers/md/dm.h index fffe1e289c53..7bf20fb2de74 100644 --- a/drivers/md/dm.h +++ b/drivers/md/dm.h @@ -179,7 +179,7 @@ int dm_open_count(struct mapped_device *md); int dm_lock_for_deletion(struct mapped_device *md, bool mark_deferred, bool only_deferred); int dm_cancel_deferred_remove(struct mapped_device *md); int dm_request_based(struct mapped_device *md); -int dm_get_table_device(struct mapped_device *md, dev_t dev, fmode_t mode, +int dm_get_table_device(struct mapped_device *md, dev_t dev, fmode_t mode, bool non_exclusive, struct dm_dev **result); void dm_put_table_device(struct mapped_device *md, struct dm_dev *d); diff --git a/include/linux/device-mapper.h b/include/linux/device-mapper.h index 61a66fb8ebb3..70002363bfc0 100644 --- a/include/linux/device-mapper.h +++ b/include/linux/device-mapper.h @@ -150,6 +150,7 @@ struct dm_dev { struct block_device *bdev; struct dax_device *dax_dev; fmode_t mode; + bool non_exclusive; char name[16]; }; @@ -325,6 +326,12 @@ struct dm_target { * whether or not its underlying devices have support. */ bool discards_supported:1; + + /* + * Set if this target needs to open device without FMODE_EXCL + * mode. + */ + bool non_exclusive:1; }; void *dm_per_bio_data(struct bio *bio, size_t data_size); -- 2.20.1 -- dm-devel mailing list dm-devel@redhat.com https://www.redhat.com/mailman/listinfo/dm-devel
next prev parent reply other threads:[~2021-02-03 15:57 UTC|newest] Thread overview: 28+ messages / expand[flat|nested] mbox.gz Atom feed top 2021-02-03 15:53 [PATCH v4 0/6] block-layer interposer Sergei Shtepa 2021-02-03 15:53 ` [dm-devel] " Sergei Shtepa 2021-02-03 15:53 ` [PATCH v4 1/6] docs: device-mapper: add remap_and_filter Sergei Shtepa 2021-02-03 15:53 ` [dm-devel] " Sergei Shtepa 2021-02-04 4:15 ` Randy Dunlap 2021-02-04 4:15 ` [dm-devel] " Randy Dunlap 2021-02-04 9:44 ` Sergei Shtepa 2021-02-04 9:44 ` [dm-devel] " Sergei Shtepa 2021-02-03 15:53 ` [PATCH v4 2/6] block: add blk_interposer Sergei Shtepa 2021-02-03 15:53 ` [dm-devel] " Sergei Shtepa 2021-02-03 16:18 ` Mike Snitzer 2021-02-03 16:18 ` [dm-devel] " Mike Snitzer 2021-02-04 10:06 ` Sergei Shtepa 2021-02-04 10:06 ` [dm-devel] " Sergei Shtepa 2021-02-03 15:53 ` [PATCH v4 3/6] block: add blk_mq_is_queue_frozen() Sergei Shtepa 2021-02-03 15:53 ` [dm-devel] " Sergei Shtepa 2021-02-03 16:09 ` Mike Snitzer 2021-02-03 16:09 ` [dm-devel] " Mike Snitzer 2021-02-03 15:53 ` [PATCH v4 4/6] dm: new ioctl DM_DEV_REMAP_CMD Sergei Shtepa 2021-02-03 15:53 ` [dm-devel] " Sergei Shtepa 2021-02-03 16:00 ` Greg KH 2021-02-03 16:00 ` [dm-devel] " Greg KH 2021-02-03 19:46 ` kernel test robot 2021-02-03 15:53 ` Sergei Shtepa [this message] 2021-02-03 15:53 ` [dm-devel] [PATCH v4 5/6] dm: add 'noexcl' option for dm-linear Sergei Shtepa 2021-02-03 20:25 ` kernel test robot 2021-02-03 15:53 ` [PATCH v4 6/6] docs: device-mapper: " Sergei Shtepa 2021-02-03 15:53 ` [dm-devel] " Sergei Shtepa
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=1612367638-3794-6-git-send-email-sergei.shtepa@veeam.com \ --to=sergei.shtepa@veeam.com \ --cc=Damien.LeMoal@wdc.com \ --cc=agk@redhat.com \ --cc=axboe@kernel.dk \ --cc=corbet@lwn.net \ --cc=dm-devel@redhat.com \ --cc=gregkh@linuxfoundation.org \ --cc=hare@suse.de \ --cc=jack@suse.cz \ --cc=johannes.thumshirn@wdc.com \ --cc=koct9i@gmail.com \ --cc=linux-block@vger.kernel.org \ --cc=linux-doc@vger.kernel.org \ --cc=linux-kernel@vger.kernel.org \ --cc=ming.lei@redhat.com \ --cc=pavgel.tide@veeam.com \ --cc=snitzer@redhat.com \ --cc=steve@sk2.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.