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 ---