diff options
Diffstat (limited to 'drivers/md/dm-ioctl.c')
-rw-r--r-- | drivers/md/dm-ioctl.c | 32 |
1 files changed, 21 insertions, 11 deletions
diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c index 0693b6f54b7d..65826bdac00c 100644 --- a/drivers/md/dm-ioctl.c +++ b/drivers/md/dm-ioctl.c | |||
@@ -244,9 +244,9 @@ static void __hash_remove(struct hash_cell *hc) | |||
244 | dm_table_put(table); | 244 | dm_table_put(table); |
245 | } | 245 | } |
246 | 246 | ||
247 | dm_put(hc->md); | ||
248 | if (hc->new_map) | 247 | if (hc->new_map) |
249 | dm_table_put(hc->new_map); | 248 | dm_table_put(hc->new_map); |
249 | dm_put(hc->md); | ||
250 | free_cell(hc); | 250 | free_cell(hc); |
251 | } | 251 | } |
252 | 252 | ||
@@ -985,33 +985,43 @@ static int table_load(struct dm_ioctl *param, size_t param_size) | |||
985 | int r; | 985 | int r; |
986 | struct hash_cell *hc; | 986 | struct hash_cell *hc; |
987 | struct dm_table *t; | 987 | struct dm_table *t; |
988 | struct mapped_device *md; | ||
989 | |||
990 | md = find_device(param); | ||
991 | if (!md) | ||
992 | return -ENXIO; | ||
988 | 993 | ||
989 | r = dm_table_create(&t, get_mode(param), param->target_count); | 994 | r = dm_table_create(&t, get_mode(param), param->target_count, md); |
990 | if (r) | 995 | if (r) |
991 | return r; | 996 | goto out; |
992 | 997 | ||
993 | r = populate_table(t, param, param_size); | 998 | r = populate_table(t, param, param_size); |
994 | if (r) { | 999 | if (r) { |
995 | dm_table_put(t); | 1000 | dm_table_put(t); |
996 | return r; | 1001 | goto out; |
997 | } | 1002 | } |
998 | 1003 | ||
999 | down_write(&_hash_lock); | 1004 | down_write(&_hash_lock); |
1000 | hc = __find_device_hash_cell(param); | 1005 | hc = dm_get_mdptr(md); |
1001 | if (!hc) { | 1006 | if (!hc || hc->md != md) { |
1002 | DMWARN("device doesn't appear to be in the dev hash table."); | 1007 | DMWARN("device has been removed from the dev hash table."); |
1003 | up_write(&_hash_lock); | ||
1004 | dm_table_put(t); | 1008 | dm_table_put(t); |
1005 | return -ENXIO; | 1009 | up_write(&_hash_lock); |
1010 | r = -ENXIO; | ||
1011 | goto out; | ||
1006 | } | 1012 | } |
1007 | 1013 | ||
1008 | if (hc->new_map) | 1014 | if (hc->new_map) |
1009 | dm_table_put(hc->new_map); | 1015 | dm_table_put(hc->new_map); |
1010 | hc->new_map = t; | 1016 | hc->new_map = t; |
1017 | up_write(&_hash_lock); | ||
1018 | |||
1011 | param->flags |= DM_INACTIVE_PRESENT_FLAG; | 1019 | param->flags |= DM_INACTIVE_PRESENT_FLAG; |
1020 | r = __dev_status(md, param); | ||
1021 | |||
1022 | out: | ||
1023 | dm_put(md); | ||
1012 | 1024 | ||
1013 | r = __dev_status(hc->md, param); | ||
1014 | up_write(&_hash_lock); | ||
1015 | return r; | 1025 | return r; |
1016 | } | 1026 | } |
1017 | 1027 | ||