]>
Commit | Line | Data |
---|---|---|
00e5a55c BS |
1 | From: Hannes Reinecke <hare@suse.de> |
2 | Subject: dm multipath devices are not getting created for readonly devices | |
3 | References: bnc#382705 | |
4 | ||
5 | Currently we cannot create device-mapper tables for multipath devices | |
6 | whenever they are read-only. | |
7 | This patch modifies the device-mapper to set the 'READ-ONLY' flag | |
8 | automatically whenever a read-only is added to the table. | |
9 | ||
10 | Signed-off-by: Hannes Reinecke <hare@suse.de> | |
11 | ||
12 | --- | |
13 | drivers/md/dm-table.c | 10 +++++++++- | |
14 | drivers/md/dm.c | 18 ++++++++++++++++-- | |
15 | 2 files changed, 25 insertions(+), 3 deletions(-) | |
16 | ||
17 | --- a/drivers/md/dm.c | |
18 | +++ b/drivers/md/dm.c | |
19 | @@ -310,16 +310,25 @@ static void __exit dm_exit(void) | |
20 | static int dm_blk_open(struct inode *inode, struct file *file) | |
21 | { | |
22 | struct mapped_device *md; | |
23 | + int retval = 0; | |
24 | ||
25 | spin_lock(&_minor_lock); | |
26 | ||
27 | md = inode->i_bdev->bd_disk->private_data; | |
28 | - if (!md) | |
29 | + if (!md) { | |
30 | + retval = -ENXIO; | |
31 | goto out; | |
32 | + } | |
33 | ||
34 | if (test_bit(DMF_FREEING, &md->flags) || | |
35 | test_bit(DMF_DELETING, &md->flags)) { | |
36 | md = NULL; | |
37 | + retval = -ENXIO; | |
38 | + goto out; | |
39 | + } | |
40 | + if (md->disk->policy && (file->f_mode & FMODE_WRITE)) { | |
41 | + md = NULL; | |
42 | + retval = -EROFS; | |
43 | goto out; | |
44 | } | |
45 | ||
46 | @@ -329,7 +338,7 @@ static int dm_blk_open(struct inode *ino | |
47 | out: | |
48 | spin_unlock(&_minor_lock); | |
49 | ||
50 | - return md ? 0 : -ENXIO; | |
51 | + return retval; | |
52 | } | |
53 | ||
54 | static int dm_blk_close(struct inode *inode, struct file *file) | |
55 | @@ -1901,6 +1910,11 @@ static int __bind(struct mapped_device * | |
56 | write_lock(&md->map_lock); | |
57 | md->map = t; | |
58 | dm_table_set_restrictions(t, q); | |
59 | + if (!(dm_table_get_mode(t) & FMODE_WRITE)) { | |
60 | + set_disk_ro(md->disk, 1); | |
61 | + } else { | |
62 | + set_disk_ro(md->disk, 0); | |
63 | + } | |
64 | write_unlock(&md->map_lock); | |
65 | ||
66 | return 0; | |
67 | --- a/drivers/md/dm-table.c | |
68 | +++ b/drivers/md/dm-table.c | |
69 | @@ -451,11 +451,19 @@ static int __table_get_device(struct dm_ | |
70 | dd->mode = mode; | |
71 | dd->bdev = NULL; | |
72 | ||
73 | - if ((r = open_dev(dd, dev, t->md))) { | |
74 | + r = open_dev(dd, dev, t->md); | |
75 | + if (r == -EROFS) { | |
76 | + dd->mode &= ~FMODE_WRITE; | |
77 | + r = open_dev(dd, dev, t->md); | |
78 | + } | |
79 | + if (r) { | |
80 | kfree(dd); | |
81 | return r; | |
82 | } | |
83 | ||
84 | + if (dd->mode != mode) | |
85 | + t->mode = dd->mode; | |
86 | + | |
87 | format_dev_t(dd->name, dev); | |
88 | ||
89 | atomic_set(&dd->count, 0); |