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.c207
1 files changed, 105 insertions, 102 deletions
diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c
index d7500e1c26f2..3e39193e5036 100644
--- a/drivers/md/dm-ioctl.c
+++ b/drivers/md/dm-ioctl.c
@@ -249,55 +249,66 @@ static void __hash_remove(struct hash_cell *hc)
249 249
250static void dm_hash_remove_all(int keep_open_devices) 250static void dm_hash_remove_all(int keep_open_devices)
251{ 251{
252 int i, dev_skipped, dev_removed; 252 int i, dev_skipped;
253 struct hash_cell *hc; 253 struct hash_cell *hc;
254 struct list_head *tmp, *n; 254 struct mapped_device *md;
255
256retry:
257 dev_skipped = 0;
255 258
256 down_write(&_hash_lock); 259 down_write(&_hash_lock);
257 260
258retry:
259 dev_skipped = dev_removed = 0;
260 for (i = 0; i < NUM_BUCKETS; i++) { 261 for (i = 0; i < NUM_BUCKETS; i++) {
261 list_for_each_safe (tmp, n, _name_buckets + i) { 262 list_for_each_entry(hc, _name_buckets + i, name_list) {
262 hc = list_entry(tmp, struct hash_cell, name_list); 263 md = hc->md;
264 dm_get(md);
263 265
264 if (keep_open_devices && 266 if (keep_open_devices && dm_lock_for_deletion(md)) {
265 dm_lock_for_deletion(hc->md)) { 267 dm_put(md);
266 dev_skipped++; 268 dev_skipped++;
267 continue; 269 continue;
268 } 270 }
271
269 __hash_remove(hc); 272 __hash_remove(hc);
270 dev_removed = 1;
271 }
272 }
273 273
274 /* 274 up_write(&_hash_lock);
275 * Some mapped devices may be using other mapped devices, so if any
276 * still exist, repeat until we make no further progress.
277 */
278 if (dev_skipped) {
279 if (dev_removed)
280 goto retry;
281 275
282 DMWARN("remove_all left %d open device(s)", dev_skipped); 276 dm_put(md);
277 if (likely(keep_open_devices))
278 dm_destroy(md);
279 else
280 dm_destroy_immediate(md);
281
282 /*
283 * Some mapped devices may be using other mapped
284 * devices, so repeat until we make no further
285 * progress. If a new mapped device is created
286 * here it will also get removed.
287 */
288 goto retry;
289 }
283 } 290 }
284 291
285 up_write(&_hash_lock); 292 up_write(&_hash_lock);
293
294 if (dev_skipped)
295 DMWARN("remove_all left %d open device(s)", dev_skipped);
286} 296}
287 297
288static int dm_hash_rename(uint32_t cookie, uint32_t *flags, const char *old, 298static struct mapped_device *dm_hash_rename(struct dm_ioctl *param,
289 const char *new) 299 const char *new)
290{ 300{
291 char *new_name, *old_name; 301 char *new_name, *old_name;
292 struct hash_cell *hc; 302 struct hash_cell *hc;
293 struct dm_table *table; 303 struct dm_table *table;
304 struct mapped_device *md;
294 305
295 /* 306 /*
296 * duplicate new. 307 * duplicate new.
297 */ 308 */
298 new_name = kstrdup(new, GFP_KERNEL); 309 new_name = kstrdup(new, GFP_KERNEL);
299 if (!new_name) 310 if (!new_name)
300 return -ENOMEM; 311 return ERR_PTR(-ENOMEM);
301 312
302 down_write(&_hash_lock); 313 down_write(&_hash_lock);
303 314
@@ -306,24 +317,24 @@ static int dm_hash_rename(uint32_t cookie, uint32_t *flags, const char *old,
306 */ 317 */
307 hc = __get_name_cell(new); 318 hc = __get_name_cell(new);
308 if (hc) { 319 if (hc) {
309 DMWARN("asked to rename to an already existing name %s -> %s", 320 DMWARN("asked to rename to an already-existing name %s -> %s",
310 old, new); 321 param->name, new);
311 dm_put(hc->md); 322 dm_put(hc->md);
312 up_write(&_hash_lock); 323 up_write(&_hash_lock);
313 kfree(new_name); 324 kfree(new_name);
314 return -EBUSY; 325 return ERR_PTR(-EBUSY);
315 } 326 }
316 327
317 /* 328 /*
318 * Is there such a device as 'old' ? 329 * Is there such a device as 'old' ?
319 */ 330 */
320 hc = __get_name_cell(old); 331 hc = __get_name_cell(param->name);
321 if (!hc) { 332 if (!hc) {
322 DMWARN("asked to rename a non existent device %s -> %s", 333 DMWARN("asked to rename a non-existent device %s -> %s",
323 old, new); 334 param->name, new);
324 up_write(&_hash_lock); 335 up_write(&_hash_lock);
325 kfree(new_name); 336 kfree(new_name);
326 return -ENXIO; 337 return ERR_PTR(-ENXIO);
327 } 338 }
328 339
329 /* 340 /*
@@ -345,13 +356,14 @@ static int dm_hash_rename(uint32_t cookie, uint32_t *flags, const char *old,
345 dm_table_put(table); 356 dm_table_put(table);
346 } 357 }
347 358
348 if (!dm_kobject_uevent(hc->md, KOBJ_CHANGE, cookie)) 359 if (!dm_kobject_uevent(hc->md, KOBJ_CHANGE, param->event_nr))
349 *flags |= DM_UEVENT_GENERATED_FLAG; 360 param->flags |= DM_UEVENT_GENERATED_FLAG;
350 361
351 dm_put(hc->md); 362 md = hc->md;
352 up_write(&_hash_lock); 363 up_write(&_hash_lock);
353 kfree(old_name); 364 kfree(old_name);
354 return 0; 365
366 return md;
355} 367}
356 368
357/*----------------------------------------------------------------- 369/*-----------------------------------------------------------------
@@ -573,7 +585,7 @@ static struct dm_table *dm_get_live_or_inactive_table(struct mapped_device *md,
573 * Fills in a dm_ioctl structure, ready for sending back to 585 * Fills in a dm_ioctl structure, ready for sending back to
574 * userland. 586 * userland.
575 */ 587 */
576static int __dev_status(struct mapped_device *md, struct dm_ioctl *param) 588static void __dev_status(struct mapped_device *md, struct dm_ioctl *param)
577{ 589{
578 struct gendisk *disk = dm_disk(md); 590 struct gendisk *disk = dm_disk(md);
579 struct dm_table *table; 591 struct dm_table *table;
@@ -617,8 +629,6 @@ static int __dev_status(struct mapped_device *md, struct dm_ioctl *param)
617 dm_table_put(table); 629 dm_table_put(table);
618 } 630 }
619 } 631 }
620
621 return 0;
622} 632}
623 633
624static int dev_create(struct dm_ioctl *param, size_t param_size) 634static int dev_create(struct dm_ioctl *param, size_t param_size)
@@ -640,15 +650,17 @@ static int dev_create(struct dm_ioctl *param, size_t param_size)
640 r = dm_hash_insert(param->name, *param->uuid ? param->uuid : NULL, md); 650 r = dm_hash_insert(param->name, *param->uuid ? param->uuid : NULL, md);
641 if (r) { 651 if (r) {
642 dm_put(md); 652 dm_put(md);
653 dm_destroy(md);
643 return r; 654 return r;
644 } 655 }
645 656
646 param->flags &= ~DM_INACTIVE_PRESENT_FLAG; 657 param->flags &= ~DM_INACTIVE_PRESENT_FLAG;
647 658
648 r = __dev_status(md, param); 659 __dev_status(md, param);
660
649 dm_put(md); 661 dm_put(md);
650 662
651 return r; 663 return 0;
652} 664}
653 665
654/* 666/*
@@ -742,6 +754,7 @@ static int dev_remove(struct dm_ioctl *param, size_t param_size)
742 param->flags |= DM_UEVENT_GENERATED_FLAG; 754 param->flags |= DM_UEVENT_GENERATED_FLAG;
743 755
744 dm_put(md); 756 dm_put(md);
757 dm_destroy(md);
745 return 0; 758 return 0;
746} 759}
747 760
@@ -762,6 +775,7 @@ static int dev_rename(struct dm_ioctl *param, size_t param_size)
762{ 775{
763 int r; 776 int r;
764 char *new_name = (char *) param + param->data_start; 777 char *new_name = (char *) param + param->data_start;
778 struct mapped_device *md;
765 779
766 if (new_name < param->data || 780 if (new_name < param->data ||
767 invalid_str(new_name, (void *) param + param_size) || 781 invalid_str(new_name, (void *) param + param_size) ||
@@ -774,10 +788,14 @@ static int dev_rename(struct dm_ioctl *param, size_t param_size)
774 if (r) 788 if (r)
775 return r; 789 return r;
776 790
777 param->data_size = 0; 791 md = dm_hash_rename(param, new_name);
792 if (IS_ERR(md))
793 return PTR_ERR(md);
794
795 __dev_status(md, param);
796 dm_put(md);
778 797
779 return dm_hash_rename(param->event_nr, &param->flags, param->name, 798 return 0;
780 new_name);
781} 799}
782 800
783static int dev_set_geometry(struct dm_ioctl *param, size_t param_size) 801static int dev_set_geometry(struct dm_ioctl *param, size_t param_size)
@@ -818,8 +836,6 @@ static int dev_set_geometry(struct dm_ioctl *param, size_t param_size)
818 geometry.start = indata[3]; 836 geometry.start = indata[3];
819 837
820 r = dm_set_geometry(md, &geometry); 838 r = dm_set_geometry(md, &geometry);
821 if (!r)
822 r = __dev_status(md, param);
823 839
824 param->data_size = 0; 840 param->data_size = 0;
825 841
@@ -843,13 +859,17 @@ static int do_suspend(struct dm_ioctl *param)
843 if (param->flags & DM_NOFLUSH_FLAG) 859 if (param->flags & DM_NOFLUSH_FLAG)
844 suspend_flags |= DM_SUSPEND_NOFLUSH_FLAG; 860 suspend_flags |= DM_SUSPEND_NOFLUSH_FLAG;
845 861
846 if (!dm_suspended_md(md)) 862 if (!dm_suspended_md(md)) {
847 r = dm_suspend(md, suspend_flags); 863 r = dm_suspend(md, suspend_flags);
864 if (r)
865 goto out;
866 }
848 867
849 if (!r) 868 __dev_status(md, param);
850 r = __dev_status(md, param);
851 869
870out:
852 dm_put(md); 871 dm_put(md);
872
853 return r; 873 return r;
854} 874}
855 875
@@ -911,7 +931,7 @@ static int do_resume(struct dm_ioctl *param)
911 dm_table_destroy(old_map); 931 dm_table_destroy(old_map);
912 932
913 if (!r) 933 if (!r)
914 r = __dev_status(md, param); 934 __dev_status(md, param);
915 935
916 dm_put(md); 936 dm_put(md);
917 return r; 937 return r;
@@ -935,16 +955,16 @@ static int dev_suspend(struct dm_ioctl *param, size_t param_size)
935 */ 955 */
936static int dev_status(struct dm_ioctl *param, size_t param_size) 956static int dev_status(struct dm_ioctl *param, size_t param_size)
937{ 957{
938 int r;
939 struct mapped_device *md; 958 struct mapped_device *md;
940 959
941 md = find_device(param); 960 md = find_device(param);
942 if (!md) 961 if (!md)
943 return -ENXIO; 962 return -ENXIO;
944 963
945 r = __dev_status(md, param); 964 __dev_status(md, param);
946 dm_put(md); 965 dm_put(md);
947 return r; 966
967 return 0;
948} 968}
949 969
950/* 970/*
@@ -1019,7 +1039,7 @@ static void retrieve_status(struct dm_table *table,
1019 */ 1039 */
1020static int dev_wait(struct dm_ioctl *param, size_t param_size) 1040static int dev_wait(struct dm_ioctl *param, size_t param_size)
1021{ 1041{
1022 int r; 1042 int r = 0;
1023 struct mapped_device *md; 1043 struct mapped_device *md;
1024 struct dm_table *table; 1044 struct dm_table *table;
1025 1045
@@ -1040,9 +1060,7 @@ static int dev_wait(struct dm_ioctl *param, size_t param_size)
1040 * changed to trigger the event, so we may as well tell 1060 * changed to trigger the event, so we may as well tell
1041 * him and save an ioctl. 1061 * him and save an ioctl.
1042 */ 1062 */
1043 r = __dev_status(md, param); 1063 __dev_status(md, param);
1044 if (r)
1045 goto out;
1046 1064
1047 table = dm_get_live_or_inactive_table(md, param); 1065 table = dm_get_live_or_inactive_table(md, param);
1048 if (table) { 1066 if (table) {
@@ -1050,8 +1068,9 @@ static int dev_wait(struct dm_ioctl *param, size_t param_size)
1050 dm_table_put(table); 1068 dm_table_put(table);
1051 } 1069 }
1052 1070
1053 out: 1071out:
1054 dm_put(md); 1072 dm_put(md);
1073
1055 return r; 1074 return r;
1056} 1075}
1057 1076
@@ -1112,28 +1131,9 @@ static int populate_table(struct dm_table *table,
1112 next = spec->next; 1131 next = spec->next;
1113 } 1132 }
1114 1133
1115 r = dm_table_set_type(table);
1116 if (r) {
1117 DMWARN("unable to set table type");
1118 return r;
1119 }
1120
1121 return dm_table_complete(table); 1134 return dm_table_complete(table);
1122} 1135}
1123 1136
1124static int table_prealloc_integrity(struct dm_table *t,
1125 struct mapped_device *md)
1126{
1127 struct list_head *devices = dm_table_get_devices(t);
1128 struct dm_dev_internal *dd;
1129
1130 list_for_each_entry(dd, devices, list)
1131 if (bdev_get_integrity(dd->dm_dev.bdev))
1132 return blk_integrity_register(dm_disk(md), NULL);
1133
1134 return 0;
1135}
1136
1137static int table_load(struct dm_ioctl *param, size_t param_size) 1137static int table_load(struct dm_ioctl *param, size_t param_size)
1138{ 1138{
1139 int r; 1139 int r;
@@ -1155,21 +1155,30 @@ static int table_load(struct dm_ioctl *param, size_t param_size)
1155 goto out; 1155 goto out;
1156 } 1156 }
1157 1157
1158 r = table_prealloc_integrity(t, md); 1158 /* Protect md->type and md->queue against concurrent table loads. */
1159 if (r) { 1159 dm_lock_md_type(md);
1160 DMERR("%s: could not register integrity profile.", 1160 if (dm_get_md_type(md) == DM_TYPE_NONE)
1161 dm_device_name(md)); 1161 /* Initial table load: acquire type of table. */
1162 dm_set_md_type(md, dm_table_get_type(t));
1163 else if (dm_get_md_type(md) != dm_table_get_type(t)) {
1164 DMWARN("can't change device type after initial table load.");
1162 dm_table_destroy(t); 1165 dm_table_destroy(t);
1166 dm_unlock_md_type(md);
1167 r = -EINVAL;
1163 goto out; 1168 goto out;
1164 } 1169 }
1165 1170
1166 r = dm_table_alloc_md_mempools(t); 1171 /* setup md->queue to reflect md's type (may block) */
1172 r = dm_setup_md_queue(md);
1167 if (r) { 1173 if (r) {
1168 DMWARN("unable to allocate mempools for this table"); 1174 DMWARN("unable to set up device queue for new table.");
1169 dm_table_destroy(t); 1175 dm_table_destroy(t);
1176 dm_unlock_md_type(md);
1170 goto out; 1177 goto out;
1171 } 1178 }
1179 dm_unlock_md_type(md);
1172 1180
1181 /* stage inactive table */
1173 down_write(&_hash_lock); 1182 down_write(&_hash_lock);
1174 hc = dm_get_mdptr(md); 1183 hc = dm_get_mdptr(md);
1175 if (!hc || hc->md != md) { 1184 if (!hc || hc->md != md) {
@@ -1186,7 +1195,7 @@ static int table_load(struct dm_ioctl *param, size_t param_size)
1186 up_write(&_hash_lock); 1195 up_write(&_hash_lock);
1187 1196
1188 param->flags |= DM_INACTIVE_PRESENT_FLAG; 1197 param->flags |= DM_INACTIVE_PRESENT_FLAG;
1189 r = __dev_status(md, param); 1198 __dev_status(md, param);
1190 1199
1191out: 1200out:
1192 dm_put(md); 1201 dm_put(md);
@@ -1196,7 +1205,6 @@ out:
1196 1205
1197static int table_clear(struct dm_ioctl *param, size_t param_size) 1206static int table_clear(struct dm_ioctl *param, size_t param_size)
1198{ 1207{
1199 int r;
1200 struct hash_cell *hc; 1208 struct hash_cell *hc;
1201 struct mapped_device *md; 1209 struct mapped_device *md;
1202 1210
@@ -1216,11 +1224,12 @@ static int table_clear(struct dm_ioctl *param, size_t param_size)
1216 1224
1217 param->flags &= ~DM_INACTIVE_PRESENT_FLAG; 1225 param->flags &= ~DM_INACTIVE_PRESENT_FLAG;
1218 1226
1219 r = __dev_status(hc->md, param); 1227 __dev_status(hc->md, param);
1220 md = hc->md; 1228 md = hc->md;
1221 up_write(&_hash_lock); 1229 up_write(&_hash_lock);
1222 dm_put(md); 1230 dm_put(md);
1223 return r; 1231
1232 return 0;
1224} 1233}
1225 1234
1226/* 1235/*
@@ -1265,7 +1274,6 @@ static void retrieve_deps(struct dm_table *table,
1265 1274
1266static int table_deps(struct dm_ioctl *param, size_t param_size) 1275static int table_deps(struct dm_ioctl *param, size_t param_size)
1267{ 1276{
1268 int r = 0;
1269 struct mapped_device *md; 1277 struct mapped_device *md;
1270 struct dm_table *table; 1278 struct dm_table *table;
1271 1279
@@ -1273,9 +1281,7 @@ static int table_deps(struct dm_ioctl *param, size_t param_size)
1273 if (!md) 1281 if (!md)
1274 return -ENXIO; 1282 return -ENXIO;
1275 1283
1276 r = __dev_status(md, param); 1284 __dev_status(md, param);
1277 if (r)
1278 goto out;
1279 1285
1280 table = dm_get_live_or_inactive_table(md, param); 1286 table = dm_get_live_or_inactive_table(md, param);
1281 if (table) { 1287 if (table) {
@@ -1283,9 +1289,9 @@ static int table_deps(struct dm_ioctl *param, size_t param_size)
1283 dm_table_put(table); 1289 dm_table_put(table);
1284 } 1290 }
1285 1291
1286 out:
1287 dm_put(md); 1292 dm_put(md);
1288 return r; 1293
1294 return 0;
1289} 1295}
1290 1296
1291/* 1297/*
@@ -1294,7 +1300,6 @@ static int table_deps(struct dm_ioctl *param, size_t param_size)
1294 */ 1300 */
1295static int table_status(struct dm_ioctl *param, size_t param_size) 1301static int table_status(struct dm_ioctl *param, size_t param_size)
1296{ 1302{
1297 int r;
1298 struct mapped_device *md; 1303 struct mapped_device *md;
1299 struct dm_table *table; 1304 struct dm_table *table;
1300 1305
@@ -1302,9 +1307,7 @@ static int table_status(struct dm_ioctl *param, size_t param_size)
1302 if (!md) 1307 if (!md)
1303 return -ENXIO; 1308 return -ENXIO;
1304 1309
1305 r = __dev_status(md, param); 1310 __dev_status(md, param);
1306 if (r)
1307 goto out;
1308 1311
1309 table = dm_get_live_or_inactive_table(md, param); 1312 table = dm_get_live_or_inactive_table(md, param);
1310 if (table) { 1313 if (table) {
@@ -1312,9 +1315,9 @@ static int table_status(struct dm_ioctl *param, size_t param_size)
1312 dm_table_put(table); 1315 dm_table_put(table);
1313 } 1316 }
1314 1317
1315out:
1316 dm_put(md); 1318 dm_put(md);
1317 return r; 1319
1320 return 0;
1318} 1321}
1319 1322
1320/* 1323/*
@@ -1333,10 +1336,6 @@ static int target_message(struct dm_ioctl *param, size_t param_size)
1333 if (!md) 1336 if (!md)
1334 return -ENXIO; 1337 return -ENXIO;
1335 1338
1336 r = __dev_status(md, param);
1337 if (r)
1338 goto out;
1339
1340 if (tmsg < (struct dm_target_msg *) param->data || 1339 if (tmsg < (struct dm_target_msg *) param->data ||
1341 invalid_str(tmsg->message, (void *) param + param_size)) { 1340 invalid_str(tmsg->message, (void *) param + param_size)) {
1342 DMWARN("Invalid target message parameters."); 1341 DMWARN("Invalid target message parameters.");
@@ -1593,18 +1592,22 @@ static long dm_compat_ctl_ioctl(struct file *file, uint command, ulong u)
1593#endif 1592#endif
1594 1593
1595static const struct file_operations _ctl_fops = { 1594static const struct file_operations _ctl_fops = {
1595 .open = nonseekable_open,
1596 .unlocked_ioctl = dm_ctl_ioctl, 1596 .unlocked_ioctl = dm_ctl_ioctl,
1597 .compat_ioctl = dm_compat_ctl_ioctl, 1597 .compat_ioctl = dm_compat_ctl_ioctl,
1598 .owner = THIS_MODULE, 1598 .owner = THIS_MODULE,
1599}; 1599};
1600 1600
1601static struct miscdevice _dm_misc = { 1601static struct miscdevice _dm_misc = {
1602 .minor = MISC_DYNAMIC_MINOR, 1602 .minor = MAPPER_CTRL_MINOR,
1603 .name = DM_NAME, 1603 .name = DM_NAME,
1604 .nodename = "mapper/control", 1604 .nodename = DM_DIR "/" DM_CONTROL_NODE,
1605 .fops = &_ctl_fops 1605 .fops = &_ctl_fops
1606}; 1606};
1607 1607
1608MODULE_ALIAS_MISCDEV(MAPPER_CTRL_MINOR);
1609MODULE_ALIAS("devname:" DM_DIR "/" DM_CONTROL_NODE);
1610
1608/* 1611/*
1609 * Create misc character device and link to DM_DIR/control. 1612 * Create misc character device and link to DM_DIR/control.
1610 */ 1613 */