diff options
Diffstat (limited to 'drivers/md/dm-ioctl.c')
-rw-r--r-- | drivers/md/dm-ioctl.c | 15 |
1 files changed, 15 insertions, 0 deletions
diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c index 3fd8f0e169e7..4702f380cb45 100644 --- a/drivers/md/dm-ioctl.c +++ b/drivers/md/dm-ioctl.c | |||
@@ -1189,6 +1189,21 @@ static int table_load(struct dm_ioctl *param, size_t param_size) | |||
1189 | goto out; | 1189 | goto out; |
1190 | } | 1190 | } |
1191 | 1191 | ||
1192 | /* Protect md->type against concurrent table loads. */ | ||
1193 | dm_lock_md_type(md); | ||
1194 | if (dm_get_md_type(md) == DM_TYPE_NONE) | ||
1195 | /* Initial table load: acquire type of table. */ | ||
1196 | dm_set_md_type(md, dm_table_get_type(t)); | ||
1197 | else if (dm_get_md_type(md) != dm_table_get_type(t)) { | ||
1198 | DMWARN("can't change device type after initial table load."); | ||
1199 | dm_table_destroy(t); | ||
1200 | dm_unlock_md_type(md); | ||
1201 | r = -EINVAL; | ||
1202 | goto out; | ||
1203 | } | ||
1204 | dm_unlock_md_type(md); | ||
1205 | |||
1206 | /* stage inactive table */ | ||
1192 | down_write(&_hash_lock); | 1207 | down_write(&_hash_lock); |
1193 | hc = dm_get_mdptr(md); | 1208 | hc = dm_get_mdptr(md); |
1194 | if (!hc || hc->md != md) { | 1209 | if (!hc || hc->md != md) { |