aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md/dm.c
diff options
context:
space:
mode:
authorMike Snitzer <snitzer@redhat.com>2010-08-11 23:14:01 -0400
committerAlasdair G Kergon <agk@redhat.com>2010-08-11 23:14:01 -0400
commita5664dad7e1a278d2915c2bf79cf42250e12d7db (patch)
tree3bdbe17f12376c63ea05100c2597757e01dc95e2 /drivers/md/dm.c
parent708e929513502fb050c0a3c3ee267cab5b056ded (diff)
dm ioctl: make bio or request based device type immutable
Determine whether a mapped device is bio-based or request-based when loading its first (inactive) table and don't allow that to be changed later. This patch performs different device initialisation in each of the two cases. (We don't think it's necessary to add code to support changing between the two types.) Allowed md->type transitions: DM_TYPE_NONE to DM_TYPE_BIO_BASED DM_TYPE_NONE to DM_TYPE_REQUEST_BASED We now prevent table_load from replacing the inactive table with a conflicting type of table even after an explicit table_clear. Introduce 'type_lock' into the struct mapped_device to protect md->type and to prepare for the next patch that will change the queue initialization and allocate memory while md->type_lock is held. Signed-off-by: Mike Snitzer <snitzer@redhat.com> Acked-by: Kiyoshi Ueda <k-ueda@ct.jp.nec.com> Signed-off-by: Alasdair G Kergon <agk@redhat.com> drivers/md/dm-ioctl.c | 15 +++++++++++++++ drivers/md/dm.c | 37 ++++++++++++++++++++++++++++++------- drivers/md/dm.h | 5 +++++ include/linux/dm-ioctl.h | 4 ++-- 4 files changed, 52 insertions(+), 9 deletions(-)
Diffstat (limited to 'drivers/md/dm.c')
-rw-r--r--drivers/md/dm.c37
1 files changed, 30 insertions, 7 deletions
diff --git a/drivers/md/dm.c b/drivers/md/dm.c
index f3cc5d99fe8d..345e94c10c65 100644
--- a/drivers/md/dm.c
+++ b/drivers/md/dm.c
@@ -125,6 +125,10 @@ struct mapped_device {
125 unsigned long flags; 125 unsigned long flags;
126 126
127 struct request_queue *queue; 127 struct request_queue *queue;
128 unsigned type;
129 /* Protect type against concurrent access. */
130 struct mutex type_lock;
131
128 struct gendisk *disk; 132 struct gendisk *disk;
129 char name[16]; 133 char name[16];
130 134
@@ -1877,8 +1881,10 @@ static struct mapped_device *alloc_dev(int minor)
1877 if (r < 0) 1881 if (r < 0)
1878 goto bad_minor; 1882 goto bad_minor;
1879 1883
1884 md->type = DM_TYPE_NONE;
1880 init_rwsem(&md->io_lock); 1885 init_rwsem(&md->io_lock);
1881 mutex_init(&md->suspend_lock); 1886 mutex_init(&md->suspend_lock);
1887 mutex_init(&md->type_lock);
1882 spin_lock_init(&md->deferred_lock); 1888 spin_lock_init(&md->deferred_lock);
1883 spin_lock_init(&md->barrier_error_lock); 1889 spin_lock_init(&md->barrier_error_lock);
1884 rwlock_init(&md->map_lock); 1890 rwlock_init(&md->map_lock);
@@ -2130,6 +2136,30 @@ int dm_create(int minor, struct mapped_device **result)
2130 return 0; 2136 return 0;
2131} 2137}
2132 2138
2139/*
2140 * Functions to manage md->type.
2141 * All are required to hold md->type_lock.
2142 */
2143void dm_lock_md_type(struct mapped_device *md)
2144{
2145 mutex_lock(&md->type_lock);
2146}
2147
2148void dm_unlock_md_type(struct mapped_device *md)
2149{
2150 mutex_unlock(&md->type_lock);
2151}
2152
2153void dm_set_md_type(struct mapped_device *md, unsigned type)
2154{
2155 md->type = type;
2156}
2157
2158unsigned dm_get_md_type(struct mapped_device *md)
2159{
2160 return md->type;
2161}
2162
2133static struct mapped_device *dm_find_md(dev_t dev) 2163static struct mapped_device *dm_find_md(dev_t dev)
2134{ 2164{
2135 struct mapped_device *md; 2165 struct mapped_device *md;
@@ -2440,13 +2470,6 @@ struct dm_table *dm_swap_table(struct mapped_device *md, struct dm_table *table)
2440 goto out; 2470 goto out;
2441 } 2471 }
2442 2472
2443 /* cannot change the device type, once a table is bound */
2444 if (md->map &&
2445 (dm_table_get_type(md->map) != dm_table_get_type(table))) {
2446 DMWARN("can't change the device type after a table is bound");
2447 goto out;
2448 }
2449
2450 map = __bind(md, table, &limits); 2473 map = __bind(md, table, &limits);
2451 2474
2452out: 2475out: