aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md/dm-ioctl.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/md/dm-ioctl.c')
-rw-r--r--drivers/md/dm-ioctl.c32
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
1022out:
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