dm-ioctl.c (220cd058d9b66b940105e0a32324f06d557deba7) | dm-ioctl.c (83d5e5b0af907d46d241a86d9e44003b3f0accbd) |
---|---|
1/* 2 * Copyright (C) 2001, 2002 Sistina Software (UK) Limited. 3 * Copyright (C) 2004 - 2006 Red Hat, Inc. All rights reserved. 4 * 5 * This file is released under the GPL. 6 */ 7 8#include "dm.h" --- 22 unchanged lines hidden (view full) --- 31 struct list_head uuid_list; 32 33 char *name; 34 char *uuid; 35 struct mapped_device *md; 36 struct dm_table *new_map; 37}; 38 | 1/* 2 * Copyright (C) 2001, 2002 Sistina Software (UK) Limited. 3 * Copyright (C) 2004 - 2006 Red Hat, Inc. All rights reserved. 4 * 5 * This file is released under the GPL. 6 */ 7 8#include "dm.h" --- 22 unchanged lines hidden (view full) --- 31 struct list_head uuid_list; 32 33 char *name; 34 char *uuid; 35 struct mapped_device *md; 36 struct dm_table *new_map; 37}; 38 |
39/* 40 * A dummy definition to make RCU happy. 41 * struct dm_table should never be dereferenced in this file. 42 */ 43struct dm_table { 44 int undefined__; 45}; 46 |
|
39struct vers_iter { 40 size_t param_size; 41 struct dm_target_versions *vers, *old_vers; 42 char *end; 43 uint32_t flags; 44}; 45 46 --- 190 unchanged lines hidden (view full) --- 237 return 0; 238 239 bad: 240 up_write(&_hash_lock); 241 free_cell(cell); 242 return -EBUSY; 243} 244 | 47struct vers_iter { 48 size_t param_size; 49 struct dm_target_versions *vers, *old_vers; 50 char *end; 51 uint32_t flags; 52}; 53 54 --- 190 unchanged lines hidden (view full) --- 245 return 0; 246 247 bad: 248 up_write(&_hash_lock); 249 free_cell(cell); 250 return -EBUSY; 251} 252 |
245static void __hash_remove(struct hash_cell *hc) | 253static struct dm_table *__hash_remove(struct hash_cell *hc) |
246{ 247 struct dm_table *table; | 254{ 255 struct dm_table *table; |
256 int srcu_idx; |
|
248 249 /* remove from the dev hash */ 250 list_del(&hc->uuid_list); 251 list_del(&hc->name_list); 252 mutex_lock(&dm_hash_cells_mutex); 253 dm_set_mdptr(hc->md, NULL); 254 mutex_unlock(&dm_hash_cells_mutex); 255 | 257 258 /* remove from the dev hash */ 259 list_del(&hc->uuid_list); 260 list_del(&hc->name_list); 261 mutex_lock(&dm_hash_cells_mutex); 262 dm_set_mdptr(hc->md, NULL); 263 mutex_unlock(&dm_hash_cells_mutex); 264 |
256 table = dm_get_live_table(hc->md); 257 if (table) { | 265 table = dm_get_live_table(hc->md, &srcu_idx); 266 if (table) |
258 dm_table_event(table); | 267 dm_table_event(table); |
259 dm_table_put(table); 260 } | 268 dm_put_live_table(hc->md, srcu_idx); |
261 | 269 |
270 table = NULL; |
|
262 if (hc->new_map) | 271 if (hc->new_map) |
263 dm_table_destroy(hc->new_map); | 272 table = hc->new_map; |
264 dm_put(hc->md); 265 free_cell(hc); | 273 dm_put(hc->md); 274 free_cell(hc); |
275 276 return table; |
|
266} 267 268static void dm_hash_remove_all(int keep_open_devices) 269{ 270 int i, dev_skipped; 271 struct hash_cell *hc; 272 struct mapped_device *md; | 277} 278 279static void dm_hash_remove_all(int keep_open_devices) 280{ 281 int i, dev_skipped; 282 struct hash_cell *hc; 283 struct mapped_device *md; |
284 struct dm_table *t; |
|
273 274retry: 275 dev_skipped = 0; 276 277 down_write(&_hash_lock); 278 279 for (i = 0; i < NUM_BUCKETS; i++) { 280 list_for_each_entry(hc, _name_buckets + i, name_list) { 281 md = hc->md; 282 dm_get(md); 283 284 if (keep_open_devices && dm_lock_for_deletion(md)) { 285 dm_put(md); 286 dev_skipped++; 287 continue; 288 } 289 | 285 286retry: 287 dev_skipped = 0; 288 289 down_write(&_hash_lock); 290 291 for (i = 0; i < NUM_BUCKETS; i++) { 292 list_for_each_entry(hc, _name_buckets + i, name_list) { 293 md = hc->md; 294 dm_get(md); 295 296 if (keep_open_devices && dm_lock_for_deletion(md)) { 297 dm_put(md); 298 dev_skipped++; 299 continue; 300 } 301 |
290 __hash_remove(hc); | 302 t = __hash_remove(hc); |
291 292 up_write(&_hash_lock); 293 | 303 304 up_write(&_hash_lock); 305 |
306 if (t) { 307 dm_sync_table(md); 308 dm_table_destroy(t); 309 } |
|
294 dm_put(md); 295 if (likely(keep_open_devices)) 296 dm_destroy(md); 297 else 298 dm_destroy_immediate(md); 299 300 /* 301 * Some mapped devices may be using other mapped --- 49 unchanged lines hidden (view full) --- 351static struct mapped_device *dm_hash_rename(struct dm_ioctl *param, 352 const char *new) 353{ 354 char *new_data, *old_name = NULL; 355 struct hash_cell *hc; 356 struct dm_table *table; 357 struct mapped_device *md; 358 unsigned change_uuid = (param->flags & DM_UUID_FLAG) ? 1 : 0; | 310 dm_put(md); 311 if (likely(keep_open_devices)) 312 dm_destroy(md); 313 else 314 dm_destroy_immediate(md); 315 316 /* 317 * Some mapped devices may be using other mapped --- 49 unchanged lines hidden (view full) --- 367static struct mapped_device *dm_hash_rename(struct dm_ioctl *param, 368 const char *new) 369{ 370 char *new_data, *old_name = NULL; 371 struct hash_cell *hc; 372 struct dm_table *table; 373 struct mapped_device *md; 374 unsigned change_uuid = (param->flags & DM_UUID_FLAG) ? 1 : 0; |
375 int srcu_idx; |
|
359 360 /* 361 * duplicate new. 362 */ 363 new_data = kstrdup(new, GFP_KERNEL); 364 if (!new_data) 365 return ERR_PTR(-ENOMEM); 366 --- 46 unchanged lines hidden (view full) --- 413 if (change_uuid) 414 __set_cell_uuid(hc, new_data); 415 else 416 old_name = __change_cell_name(hc, new_data); 417 418 /* 419 * Wake up any dm event waiters. 420 */ | 376 377 /* 378 * duplicate new. 379 */ 380 new_data = kstrdup(new, GFP_KERNEL); 381 if (!new_data) 382 return ERR_PTR(-ENOMEM); 383 --- 46 unchanged lines hidden (view full) --- 430 if (change_uuid) 431 __set_cell_uuid(hc, new_data); 432 else 433 old_name = __change_cell_name(hc, new_data); 434 435 /* 436 * Wake up any dm event waiters. 437 */ |
421 table = dm_get_live_table(hc->md); 422 if (table) { | 438 table = dm_get_live_table(hc->md, &srcu_idx); 439 if (table) |
423 dm_table_event(table); | 440 dm_table_event(table); |
424 dm_table_put(table); 425 } | 441 dm_put_live_table(hc->md, srcu_idx); |
426 427 if (!dm_kobject_uevent(hc->md, KOBJ_CHANGE, param->event_nr)) 428 param->flags |= DM_UEVENT_GENERATED_FLAG; 429 430 md = hc->md; 431 up_write(&_hash_lock); 432 kfree(old_name); 433 --- 181 unchanged lines hidden (view full) --- 615 return 0; 616} 617 618/* 619 * On successful return, the caller must not attempt to acquire 620 * _hash_lock without first calling dm_table_put, because dm_table_destroy 621 * waits for this dm_table_put and could be called under this lock. 622 */ | 442 443 if (!dm_kobject_uevent(hc->md, KOBJ_CHANGE, param->event_nr)) 444 param->flags |= DM_UEVENT_GENERATED_FLAG; 445 446 md = hc->md; 447 up_write(&_hash_lock); 448 kfree(old_name); 449 --- 181 unchanged lines hidden (view full) --- 631 return 0; 632} 633 634/* 635 * On successful return, the caller must not attempt to acquire 636 * _hash_lock without first calling dm_table_put, because dm_table_destroy 637 * waits for this dm_table_put and could be called under this lock. 638 */ |
623static struct dm_table *dm_get_inactive_table(struct mapped_device *md) | 639static struct dm_table *dm_get_inactive_table(struct mapped_device *md, int *srcu_idx) |
624{ 625 struct hash_cell *hc; 626 struct dm_table *table = NULL; 627 | 640{ 641 struct hash_cell *hc; 642 struct dm_table *table = NULL; 643 |
644 /* increment rcu count, we don't care about the table pointer */ 645 dm_get_live_table(md, srcu_idx); 646 |
|
628 down_read(&_hash_lock); 629 hc = dm_get_mdptr(md); 630 if (!hc || hc->md != md) { 631 DMWARN("device has been removed from the dev hash table."); 632 goto out; 633 } 634 635 table = hc->new_map; | 647 down_read(&_hash_lock); 648 hc = dm_get_mdptr(md); 649 if (!hc || hc->md != md) { 650 DMWARN("device has been removed from the dev hash table."); 651 goto out; 652 } 653 654 table = hc->new_map; |
636 if (table) 637 dm_table_get(table); | |
638 639out: 640 up_read(&_hash_lock); 641 642 return table; 643} 644 645static struct dm_table *dm_get_live_or_inactive_table(struct mapped_device *md, | 655 656out: 657 up_read(&_hash_lock); 658 659 return table; 660} 661 662static struct dm_table *dm_get_live_or_inactive_table(struct mapped_device *md, |
646 struct dm_ioctl *param) | 663 struct dm_ioctl *param, 664 int *srcu_idx) |
647{ 648 return (param->flags & DM_QUERY_INACTIVE_TABLE_FLAG) ? | 665{ 666 return (param->flags & DM_QUERY_INACTIVE_TABLE_FLAG) ? |
649 dm_get_inactive_table(md) : dm_get_live_table(md); | 667 dm_get_inactive_table(md, srcu_idx) : dm_get_live_table(md, srcu_idx); |
650} 651 652/* 653 * Fills in a dm_ioctl structure, ready for sending back to 654 * userland. 655 */ 656static void __dev_status(struct mapped_device *md, struct dm_ioctl *param) 657{ 658 struct gendisk *disk = dm_disk(md); 659 struct dm_table *table; | 668} 669 670/* 671 * Fills in a dm_ioctl structure, ready for sending back to 672 * userland. 673 */ 674static void __dev_status(struct mapped_device *md, struct dm_ioctl *param) 675{ 676 struct gendisk *disk = dm_disk(md); 677 struct dm_table *table; |
678 int srcu_idx; |
|
660 661 param->flags &= ~(DM_SUSPEND_FLAG | DM_READONLY_FLAG | 662 DM_ACTIVE_PRESENT_FLAG); 663 664 if (dm_suspended_md(md)) 665 param->flags |= DM_SUSPEND_FLAG; 666 667 param->dev = huge_encode_dev(disk_devt(disk)); 668 669 /* 670 * Yes, this will be out of date by the time it gets back 671 * to userland, but it is still very useful for 672 * debugging. 673 */ 674 param->open_count = dm_open_count(md); 675 676 param->event_nr = dm_get_event_nr(md); 677 param->target_count = 0; 678 | 679 680 param->flags &= ~(DM_SUSPEND_FLAG | DM_READONLY_FLAG | 681 DM_ACTIVE_PRESENT_FLAG); 682 683 if (dm_suspended_md(md)) 684 param->flags |= DM_SUSPEND_FLAG; 685 686 param->dev = huge_encode_dev(disk_devt(disk)); 687 688 /* 689 * Yes, this will be out of date by the time it gets back 690 * to userland, but it is still very useful for 691 * debugging. 692 */ 693 param->open_count = dm_open_count(md); 694 695 param->event_nr = dm_get_event_nr(md); 696 param->target_count = 0; 697 |
679 table = dm_get_live_table(md); | 698 table = dm_get_live_table(md, &srcu_idx); |
680 if (table) { 681 if (!(param->flags & DM_QUERY_INACTIVE_TABLE_FLAG)) { 682 if (get_disk_ro(disk)) 683 param->flags |= DM_READONLY_FLAG; 684 param->target_count = dm_table_get_num_targets(table); 685 } | 699 if (table) { 700 if (!(param->flags & DM_QUERY_INACTIVE_TABLE_FLAG)) { 701 if (get_disk_ro(disk)) 702 param->flags |= DM_READONLY_FLAG; 703 param->target_count = dm_table_get_num_targets(table); 704 } |
686 dm_table_put(table); | |
687 688 param->flags |= DM_ACTIVE_PRESENT_FLAG; 689 } | 705 706 param->flags |= DM_ACTIVE_PRESENT_FLAG; 707 } |
708 dm_put_live_table(md, srcu_idx); |
|
690 691 if (param->flags & DM_QUERY_INACTIVE_TABLE_FLAG) { | 709 710 if (param->flags & DM_QUERY_INACTIVE_TABLE_FLAG) { |
692 table = dm_get_inactive_table(md); | 711 int srcu_idx; 712 table = dm_get_inactive_table(md, &srcu_idx); |
693 if (table) { 694 if (!(dm_table_get_mode(table) & FMODE_WRITE)) 695 param->flags |= DM_READONLY_FLAG; 696 param->target_count = dm_table_get_num_targets(table); | 713 if (table) { 714 if (!(dm_table_get_mode(table) & FMODE_WRITE)) 715 param->flags |= DM_READONLY_FLAG; 716 param->target_count = dm_table_get_num_targets(table); |
697 dm_table_put(table); | |
698 } | 717 } |
718 dm_put_live_table(md, srcu_idx); |
|
699 } 700} 701 702static int dev_create(struct dm_ioctl *param, size_t param_size) 703{ 704 int r, m = DM_ANY_MINOR; 705 struct mapped_device *md; 706 --- 84 unchanged lines hidden (view full) --- 791 return md; 792} 793 794static int dev_remove(struct dm_ioctl *param, size_t param_size) 795{ 796 struct hash_cell *hc; 797 struct mapped_device *md; 798 int r; | 719 } 720} 721 722static int dev_create(struct dm_ioctl *param, size_t param_size) 723{ 724 int r, m = DM_ANY_MINOR; 725 struct mapped_device *md; 726 --- 84 unchanged lines hidden (view full) --- 811 return md; 812} 813 814static int dev_remove(struct dm_ioctl *param, size_t param_size) 815{ 816 struct hash_cell *hc; 817 struct mapped_device *md; 818 int r; |
819 struct dm_table *t; |
|
799 800 down_write(&_hash_lock); 801 hc = __find_device_hash_cell(param); 802 803 if (!hc) { 804 DMDEBUG_LIMIT("device doesn't appear to be in the dev hash table."); 805 up_write(&_hash_lock); 806 return -ENXIO; --- 7 unchanged lines hidden (view full) --- 814 r = dm_lock_for_deletion(md); 815 if (r) { 816 DMDEBUG_LIMIT("unable to remove open device %s", hc->name); 817 up_write(&_hash_lock); 818 dm_put(md); 819 return r; 820 } 821 | 820 821 down_write(&_hash_lock); 822 hc = __find_device_hash_cell(param); 823 824 if (!hc) { 825 DMDEBUG_LIMIT("device doesn't appear to be in the dev hash table."); 826 up_write(&_hash_lock); 827 return -ENXIO; --- 7 unchanged lines hidden (view full) --- 835 r = dm_lock_for_deletion(md); 836 if (r) { 837 DMDEBUG_LIMIT("unable to remove open device %s", hc->name); 838 up_write(&_hash_lock); 839 dm_put(md); 840 return r; 841 } 842 |
822 __hash_remove(hc); | 843 t = __hash_remove(hc); |
823 up_write(&_hash_lock); 824 | 844 up_write(&_hash_lock); 845 |
846 if (t) { 847 dm_sync_table(md); 848 dm_table_destroy(t); 849 } 850 |
|
825 if (!dm_kobject_uevent(md, KOBJ_REMOVE, param->event_nr)) 826 param->flags |= DM_UEVENT_GENERATED_FLAG; 827 828 dm_put(md); 829 dm_destroy(md); 830 return 0; 831} 832 --- 148 unchanged lines hidden (view full) --- 981 suspend_flags &= ~DM_SUSPEND_LOCKFS_FLAG; 982 if (param->flags & DM_NOFLUSH_FLAG) 983 suspend_flags |= DM_SUSPEND_NOFLUSH_FLAG; 984 if (!dm_suspended_md(md)) 985 dm_suspend(md, suspend_flags); 986 987 old_map = dm_swap_table(md, new_map); 988 if (IS_ERR(old_map)) { | 851 if (!dm_kobject_uevent(md, KOBJ_REMOVE, param->event_nr)) 852 param->flags |= DM_UEVENT_GENERATED_FLAG; 853 854 dm_put(md); 855 dm_destroy(md); 856 return 0; 857} 858 --- 148 unchanged lines hidden (view full) --- 1007 suspend_flags &= ~DM_SUSPEND_LOCKFS_FLAG; 1008 if (param->flags & DM_NOFLUSH_FLAG) 1009 suspend_flags |= DM_SUSPEND_NOFLUSH_FLAG; 1010 if (!dm_suspended_md(md)) 1011 dm_suspend(md, suspend_flags); 1012 1013 old_map = dm_swap_table(md, new_map); 1014 if (IS_ERR(old_map)) { |
1015 dm_sync_table(md); |
|
989 dm_table_destroy(new_map); 990 dm_put(md); 991 return PTR_ERR(old_map); 992 } 993 994 if (dm_table_get_mode(new_map) & FMODE_WRITE) 995 set_disk_ro(dm_disk(md), 0); 996 else 997 set_disk_ro(dm_disk(md), 1); 998 } 999 1000 if (dm_suspended_md(md)) { 1001 r = dm_resume(md); 1002 if (!r && !dm_kobject_uevent(md, KOBJ_CHANGE, param->event_nr)) 1003 param->flags |= DM_UEVENT_GENERATED_FLAG; 1004 } 1005 | 1016 dm_table_destroy(new_map); 1017 dm_put(md); 1018 return PTR_ERR(old_map); 1019 } 1020 1021 if (dm_table_get_mode(new_map) & FMODE_WRITE) 1022 set_disk_ro(dm_disk(md), 0); 1023 else 1024 set_disk_ro(dm_disk(md), 1); 1025 } 1026 1027 if (dm_suspended_md(md)) { 1028 r = dm_resume(md); 1029 if (!r && !dm_kobject_uevent(md, KOBJ_CHANGE, param->event_nr)) 1030 param->flags |= DM_UEVENT_GENERATED_FLAG; 1031 } 1032 |
1033 /* 1034 * Since dm_swap_table synchronizes RCU, nobody should be in 1035 * read-side critical section already. 1036 */ |
|
1006 if (old_map) 1007 dm_table_destroy(old_map); 1008 1009 if (!r) 1010 __dev_status(md, param); 1011 1012 dm_put(md); 1013 return r; --- 106 unchanged lines hidden (view full) --- 1120/* 1121 * Wait for a device to report an event 1122 */ 1123static int dev_wait(struct dm_ioctl *param, size_t param_size) 1124{ 1125 int r = 0; 1126 struct mapped_device *md; 1127 struct dm_table *table; | 1037 if (old_map) 1038 dm_table_destroy(old_map); 1039 1040 if (!r) 1041 __dev_status(md, param); 1042 1043 dm_put(md); 1044 return r; --- 106 unchanged lines hidden (view full) --- 1151/* 1152 * Wait for a device to report an event 1153 */ 1154static int dev_wait(struct dm_ioctl *param, size_t param_size) 1155{ 1156 int r = 0; 1157 struct mapped_device *md; 1158 struct dm_table *table; |
1159 int srcu_idx; |
|
1128 1129 md = find_device(param); 1130 if (!md) 1131 return -ENXIO; 1132 1133 /* 1134 * Wait for a notification event 1135 */ --- 4 unchanged lines hidden (view full) --- 1140 1141 /* 1142 * The userland program is going to want to know what 1143 * changed to trigger the event, so we may as well tell 1144 * him and save an ioctl. 1145 */ 1146 __dev_status(md, param); 1147 | 1160 1161 md = find_device(param); 1162 if (!md) 1163 return -ENXIO; 1164 1165 /* 1166 * Wait for a notification event 1167 */ --- 4 unchanged lines hidden (view full) --- 1172 1173 /* 1174 * The userland program is going to want to know what 1175 * changed to trigger the event, so we may as well tell 1176 * him and save an ioctl. 1177 */ 1178 __dev_status(md, param); 1179 |
1148 table = dm_get_live_or_inactive_table(md, param); 1149 if (table) { | 1180 table = dm_get_live_or_inactive_table(md, param, &srcu_idx); 1181 if (table) |
1150 retrieve_status(table, param, param_size); | 1182 retrieve_status(table, param, param_size); |
1151 dm_table_put(table); 1152 } | 1183 dm_put_live_table(md, srcu_idx); |
1153 1154out: 1155 dm_put(md); 1156 1157 return r; 1158} 1159 1160static inline fmode_t get_mode(struct dm_ioctl *param) --- 55 unchanged lines hidden (view full) --- 1216 1217 return dm_table_complete(table); 1218} 1219 1220static int table_load(struct dm_ioctl *param, size_t param_size) 1221{ 1222 int r; 1223 struct hash_cell *hc; | 1184 1185out: 1186 dm_put(md); 1187 1188 return r; 1189} 1190 1191static inline fmode_t get_mode(struct dm_ioctl *param) --- 55 unchanged lines hidden (view full) --- 1247 1248 return dm_table_complete(table); 1249} 1250 1251static int table_load(struct dm_ioctl *param, size_t param_size) 1252{ 1253 int r; 1254 struct hash_cell *hc; |
1224 struct dm_table *t; | 1255 struct dm_table *t, *old_map = NULL; |
1225 struct mapped_device *md; 1226 struct target_type *immutable_target_type; 1227 1228 md = find_device(param); 1229 if (!md) 1230 return -ENXIO; 1231 1232 r = dm_table_create(&t, get_mode(param), param->target_count, md); --- 39 unchanged lines hidden (view full) --- 1272 } 1273 dm_unlock_md_type(md); 1274 1275 /* stage inactive table */ 1276 down_write(&_hash_lock); 1277 hc = dm_get_mdptr(md); 1278 if (!hc || hc->md != md) { 1279 DMWARN("device has been removed from the dev hash table."); | 1256 struct mapped_device *md; 1257 struct target_type *immutable_target_type; 1258 1259 md = find_device(param); 1260 if (!md) 1261 return -ENXIO; 1262 1263 r = dm_table_create(&t, get_mode(param), param->target_count, md); --- 39 unchanged lines hidden (view full) --- 1303 } 1304 dm_unlock_md_type(md); 1305 1306 /* stage inactive table */ 1307 down_write(&_hash_lock); 1308 hc = dm_get_mdptr(md); 1309 if (!hc || hc->md != md) { 1310 DMWARN("device has been removed from the dev hash table."); |
1280 dm_table_destroy(t); | |
1281 up_write(&_hash_lock); | 1311 up_write(&_hash_lock); |
1312 dm_table_destroy(t); |
|
1282 r = -ENXIO; 1283 goto out; 1284 } 1285 1286 if (hc->new_map) | 1313 r = -ENXIO; 1314 goto out; 1315 } 1316 1317 if (hc->new_map) |
1287 dm_table_destroy(hc->new_map); | 1318 old_map = hc->new_map; |
1288 hc->new_map = t; 1289 up_write(&_hash_lock); 1290 1291 param->flags |= DM_INACTIVE_PRESENT_FLAG; 1292 __dev_status(md, param); 1293 1294out: | 1319 hc->new_map = t; 1320 up_write(&_hash_lock); 1321 1322 param->flags |= DM_INACTIVE_PRESENT_FLAG; 1323 __dev_status(md, param); 1324 1325out: |
1326 if (old_map) { 1327 dm_sync_table(md); 1328 dm_table_destroy(old_map); 1329 } 1330 |
|
1295 dm_put(md); 1296 1297 return r; 1298} 1299 1300static int table_clear(struct dm_ioctl *param, size_t param_size) 1301{ 1302 struct hash_cell *hc; 1303 struct mapped_device *md; | 1331 dm_put(md); 1332 1333 return r; 1334} 1335 1336static int table_clear(struct dm_ioctl *param, size_t param_size) 1337{ 1338 struct hash_cell *hc; 1339 struct mapped_device *md; |
1340 struct dm_table *old_map = NULL; |
|
1304 1305 down_write(&_hash_lock); 1306 1307 hc = __find_device_hash_cell(param); 1308 if (!hc) { 1309 DMDEBUG_LIMIT("device doesn't appear to be in the dev hash table."); 1310 up_write(&_hash_lock); 1311 return -ENXIO; 1312 } 1313 1314 if (hc->new_map) { | 1341 1342 down_write(&_hash_lock); 1343 1344 hc = __find_device_hash_cell(param); 1345 if (!hc) { 1346 DMDEBUG_LIMIT("device doesn't appear to be in the dev hash table."); 1347 up_write(&_hash_lock); 1348 return -ENXIO; 1349 } 1350 1351 if (hc->new_map) { |
1315 dm_table_destroy(hc->new_map); | 1352 old_map = hc->new_map; |
1316 hc->new_map = NULL; 1317 } 1318 1319 param->flags &= ~DM_INACTIVE_PRESENT_FLAG; 1320 1321 __dev_status(hc->md, param); 1322 md = hc->md; 1323 up_write(&_hash_lock); | 1353 hc->new_map = NULL; 1354 } 1355 1356 param->flags &= ~DM_INACTIVE_PRESENT_FLAG; 1357 1358 __dev_status(hc->md, param); 1359 md = hc->md; 1360 up_write(&_hash_lock); |
1361 if (old_map) { 1362 dm_sync_table(md); 1363 dm_table_destroy(old_map); 1364 } |
|
1324 dm_put(md); 1325 1326 return 0; 1327} 1328 1329/* 1330 * Retrieves a list of devices used by a particular dm device. 1331 */ --- 33 unchanged lines hidden (view full) --- 1365 1366 param->data_size = param->data_start + needed; 1367} 1368 1369static int table_deps(struct dm_ioctl *param, size_t param_size) 1370{ 1371 struct mapped_device *md; 1372 struct dm_table *table; | 1365 dm_put(md); 1366 1367 return 0; 1368} 1369 1370/* 1371 * Retrieves a list of devices used by a particular dm device. 1372 */ --- 33 unchanged lines hidden (view full) --- 1406 1407 param->data_size = param->data_start + needed; 1408} 1409 1410static int table_deps(struct dm_ioctl *param, size_t param_size) 1411{ 1412 struct mapped_device *md; 1413 struct dm_table *table; |
1414 int srcu_idx; |
|
1373 1374 md = find_device(param); 1375 if (!md) 1376 return -ENXIO; 1377 1378 __dev_status(md, param); 1379 | 1415 1416 md = find_device(param); 1417 if (!md) 1418 return -ENXIO; 1419 1420 __dev_status(md, param); 1421 |
1380 table = dm_get_live_or_inactive_table(md, param); 1381 if (table) { | 1422 table = dm_get_live_or_inactive_table(md, param, &srcu_idx); 1423 if (table) |
1382 retrieve_deps(table, param, param_size); | 1424 retrieve_deps(table, param, param_size); |
1383 dm_table_put(table); 1384 } | 1425 dm_put_live_table(md, srcu_idx); |
1385 1386 dm_put(md); 1387 1388 return 0; 1389} 1390 1391/* 1392 * Return the status of a device as a text string for each 1393 * target. 1394 */ 1395static int table_status(struct dm_ioctl *param, size_t param_size) 1396{ 1397 struct mapped_device *md; 1398 struct dm_table *table; | 1426 1427 dm_put(md); 1428 1429 return 0; 1430} 1431 1432/* 1433 * Return the status of a device as a text string for each 1434 * target. 1435 */ 1436static int table_status(struct dm_ioctl *param, size_t param_size) 1437{ 1438 struct mapped_device *md; 1439 struct dm_table *table; |
1440 int srcu_idx; |
|
1399 1400 md = find_device(param); 1401 if (!md) 1402 return -ENXIO; 1403 1404 __dev_status(md, param); 1405 | 1441 1442 md = find_device(param); 1443 if (!md) 1444 return -ENXIO; 1445 1446 __dev_status(md, param); 1447 |
1406 table = dm_get_live_or_inactive_table(md, param); 1407 if (table) { | 1448 table = dm_get_live_or_inactive_table(md, param, &srcu_idx); 1449 if (table) |
1408 retrieve_status(table, param, param_size); | 1450 retrieve_status(table, param, param_size); |
1409 dm_table_put(table); 1410 } | 1451 dm_put_live_table(md, srcu_idx); |
1411 1412 dm_put(md); 1413 1414 return 0; 1415} 1416 1417static bool buffer_test_overflow(char *result, unsigned maxlen) 1418{ --- 19 unchanged lines hidden (view full) --- 1438 int r, argc; 1439 char **argv; 1440 struct mapped_device *md; 1441 struct dm_table *table; 1442 struct dm_target *ti; 1443 struct dm_target_msg *tmsg = (void *) param + param->data_start; 1444 size_t maxlen; 1445 char *result = get_result_buffer(param, param_size, &maxlen); | 1452 1453 dm_put(md); 1454 1455 return 0; 1456} 1457 1458static bool buffer_test_overflow(char *result, unsigned maxlen) 1459{ --- 19 unchanged lines hidden (view full) --- 1479 int r, argc; 1480 char **argv; 1481 struct mapped_device *md; 1482 struct dm_table *table; 1483 struct dm_target *ti; 1484 struct dm_target_msg *tmsg = (void *) param + param->data_start; 1485 size_t maxlen; 1486 char *result = get_result_buffer(param, param_size, &maxlen); |
1487 int srcu_idx; |
|
1446 1447 md = find_device(param); 1448 if (!md) 1449 return -ENXIO; 1450 1451 if (tmsg < (struct dm_target_msg *) param->data || 1452 invalid_str(tmsg->message, (void *) param + param_size)) { 1453 DMWARN("Invalid target message parameters."); --- 11 unchanged lines hidden (view full) --- 1465 DMWARN("Empty message received."); 1466 goto out_argv; 1467 } 1468 1469 r = message_for_md(md, argc, argv, result, maxlen); 1470 if (r <= 1) 1471 goto out_argv; 1472 | 1488 1489 md = find_device(param); 1490 if (!md) 1491 return -ENXIO; 1492 1493 if (tmsg < (struct dm_target_msg *) param->data || 1494 invalid_str(tmsg->message, (void *) param + param_size)) { 1495 DMWARN("Invalid target message parameters."); --- 11 unchanged lines hidden (view full) --- 1507 DMWARN("Empty message received."); 1508 goto out_argv; 1509 } 1510 1511 r = message_for_md(md, argc, argv, result, maxlen); 1512 if (r <= 1) 1513 goto out_argv; 1514 |
1473 table = dm_get_live_table(md); | 1515 table = dm_get_live_table(md, &srcu_idx); |
1474 if (!table) | 1516 if (!table) |
1475 goto out_argv; | 1517 goto out_table; |
1476 1477 if (dm_deleting_md(md)) { 1478 r = -ENXIO; 1479 goto out_table; 1480 } 1481 1482 ti = dm_table_find_target(table, tmsg->sector); 1483 if (!dm_target_is_valid(ti)) { 1484 DMWARN("Target message sector outside device."); 1485 r = -EINVAL; 1486 } else if (ti->type->message) 1487 r = ti->type->message(ti, argc, argv); 1488 else { 1489 DMWARN("Target type does not support messages"); 1490 r = -EINVAL; 1491 } 1492 1493 out_table: | 1518 1519 if (dm_deleting_md(md)) { 1520 r = -ENXIO; 1521 goto out_table; 1522 } 1523 1524 ti = dm_table_find_target(table, tmsg->sector); 1525 if (!dm_target_is_valid(ti)) { 1526 DMWARN("Target message sector outside device."); 1527 r = -EINVAL; 1528 } else if (ti->type->message) 1529 r = ti->type->message(ti, argc, argv); 1530 else { 1531 DMWARN("Target type does not support messages"); 1532 r = -EINVAL; 1533 } 1534 1535 out_table: |
1494 dm_table_put(table); | 1536 dm_put_live_table(md, srcu_idx); |
1495 out_argv: 1496 kfree(argv); 1497 out: 1498 if (r >= 0) 1499 __dev_status(md, param); 1500 1501 if (r == 1) { 1502 param->flags |= DM_DATA_OUT_FLAG; --- 380 unchanged lines hidden --- | 1537 out_argv: 1538 kfree(argv); 1539 out: 1540 if (r >= 0) 1541 __dev_status(md, param); 1542 1543 if (r == 1) { 1544 param->flags |= DM_DATA_OUT_FLAG; --- 380 unchanged lines hidden --- |