diff options
Diffstat (limited to 'drivers/md/dm.c')
-rw-r--r-- | drivers/md/dm.c | 37 |
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 | */ | ||
2143 | void dm_lock_md_type(struct mapped_device *md) | ||
2144 | { | ||
2145 | mutex_lock(&md->type_lock); | ||
2146 | } | ||
2147 | |||
2148 | void dm_unlock_md_type(struct mapped_device *md) | ||
2149 | { | ||
2150 | mutex_unlock(&md->type_lock); | ||
2151 | } | ||
2152 | |||
2153 | void dm_set_md_type(struct mapped_device *md, unsigned type) | ||
2154 | { | ||
2155 | md->type = type; | ||
2156 | } | ||
2157 | |||
2158 | unsigned dm_get_md_type(struct mapped_device *md) | ||
2159 | { | ||
2160 | return md->type; | ||
2161 | } | ||
2162 | |||
2133 | static struct mapped_device *dm_find_md(dev_t dev) | 2163 | static 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 | ||
2452 | out: | 2475 | out: |