91 lines
2.2 KiB
Plaintext
91 lines
2.2 KiB
Plaintext
From: Hannes Reinecke <hare@suse.de>
|
|
Subject: dm multipath devices are not getting created for readonly devices
|
|
References: bnc#382705
|
|
Patch-mainline: not yet
|
|
|
|
Currently we cannot create device-mapper tables for multipath devices
|
|
whenever they are read-only.
|
|
This patch modifies the device-mapper to set the 'READ-ONLY' flag
|
|
automatically whenever a read-only is added to the table.
|
|
|
|
Signed-off-by: Hannes Reinecke <hare@suse.de>
|
|
|
|
---
|
|
drivers/md/dm-table.c | 10 +++++++++-
|
|
drivers/md/dm.c | 18 ++++++++++++++++--
|
|
2 files changed, 25 insertions(+), 3 deletions(-)
|
|
|
|
--- a/drivers/md/dm-table.c
|
|
+++ b/drivers/md/dm-table.c
|
|
@@ -462,11 +462,19 @@ static int __table_get_device(struct dm_
|
|
dd->dm_dev.mode = mode;
|
|
dd->dm_dev.bdev = NULL;
|
|
|
|
- if ((r = open_dev(dd, dev, t->md))) {
|
|
+ r = open_dev(dd, dev, t->md);
|
|
+ if (r == -EROFS) {
|
|
+ dd->dm_dev.mode &= ~FMODE_WRITE;
|
|
+ r = open_dev(dd, dev, t->md);
|
|
+ }
|
|
+ if (r) {
|
|
kfree(dd);
|
|
return r;
|
|
}
|
|
|
|
+ if (dd->dm_dev.mode != mode)
|
|
+ t->mode = dd->dm_dev.mode;
|
|
+
|
|
format_dev_t(dd->dm_dev.name, dev);
|
|
|
|
atomic_set(&dd->count, 0);
|
|
--- a/drivers/md/dm.c
|
|
+++ b/drivers/md/dm.c
|
|
@@ -337,16 +337,25 @@ int dm_deleting_md(struct mapped_device
|
|
static int dm_blk_open(struct block_device *bdev, fmode_t mode)
|
|
{
|
|
struct mapped_device *md;
|
|
+ int retval = 0;
|
|
|
|
spin_lock(&_minor_lock);
|
|
|
|
md = bdev->bd_disk->private_data;
|
|
- if (!md)
|
|
+ if (!md) {
|
|
+ retval = -ENXIO;
|
|
goto out;
|
|
+ }
|
|
|
|
if (test_bit(DMF_FREEING, &md->flags) ||
|
|
dm_deleting_md(md)) {
|
|
md = NULL;
|
|
+ retval = -ENXIO;
|
|
+ goto out;
|
|
+ }
|
|
+ if (get_disk_ro(md->disk) && (mode & FMODE_WRITE)) {
|
|
+ md = NULL;
|
|
+ retval = -EROFS;
|
|
goto out;
|
|
}
|
|
|
|
@@ -356,7 +365,7 @@ static int dm_blk_open(struct block_devi
|
|
out:
|
|
spin_unlock(&_minor_lock);
|
|
|
|
- return md ? 0 : -ENXIO;
|
|
+ return retval;
|
|
}
|
|
|
|
static int dm_blk_close(struct gendisk *disk, fmode_t mode)
|
|
@@ -2093,6 +2102,11 @@ static struct dm_table *__bind(struct ma
|
|
old_map = md->map;
|
|
md->map = t;
|
|
dm_table_set_restrictions(t, q, limits);
|
|
+ if (!(dm_table_get_mode(t) & FMODE_WRITE)) {
|
|
+ set_disk_ro(md->disk, 1);
|
|
+ } else {
|
|
+ set_disk_ro(md->disk, 0);
|
|
+ }
|
|
write_unlock_irqrestore(&md->map_lock, flags);
|
|
|
|
return old_map;
|