diff options
Diffstat (limited to 'drivers/md/dm-ioctl.c')
| -rw-r--r-- | drivers/md/dm-ioctl.c | 207 |
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 | ||
| 250 | static void dm_hash_remove_all(int keep_open_devices) | 250 | static 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 | |||
| 256 | retry: | ||
| 257 | dev_skipped = 0; | ||
| 255 | 258 | ||
| 256 | down_write(&_hash_lock); | 259 | down_write(&_hash_lock); |
| 257 | 260 | ||
| 258 | retry: | ||
| 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 | ||
| 288 | static int dm_hash_rename(uint32_t cookie, uint32_t *flags, const char *old, | 298 | static 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 | */ |
| 576 | static int __dev_status(struct mapped_device *md, struct dm_ioctl *param) | 588 | static 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 | ||
| 624 | static int dev_create(struct dm_ioctl *param, size_t param_size) | 634 | static 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, ¶m->flags, param->name, | 798 | return 0; |
| 780 | new_name); | ||
| 781 | } | 799 | } |
| 782 | 800 | ||
| 783 | static int dev_set_geometry(struct dm_ioctl *param, size_t param_size) | 801 | static 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 | ||
| 870 | out: | ||
| 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 | */ |
| 936 | static int dev_status(struct dm_ioctl *param, size_t param_size) | 956 | static 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 | */ |
| 1020 | static int dev_wait(struct dm_ioctl *param, size_t param_size) | 1040 | static 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: | 1071 | out: |
| 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 | ||
| 1124 | static 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 | |||
| 1137 | static int table_load(struct dm_ioctl *param, size_t param_size) | 1137 | static 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 | ||
| 1191 | out: | 1200 | out: |
| 1192 | dm_put(md); | 1201 | dm_put(md); |
| @@ -1196,7 +1205,6 @@ out: | |||
| 1196 | 1205 | ||
| 1197 | static int table_clear(struct dm_ioctl *param, size_t param_size) | 1206 | static 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 | ||
| 1266 | static int table_deps(struct dm_ioctl *param, size_t param_size) | 1275 | static 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 | */ |
| 1295 | static int table_status(struct dm_ioctl *param, size_t param_size) | 1301 | static 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 | ||
| 1315 | out: | ||
| 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 | ||
| 1595 | static const struct file_operations _ctl_fops = { | 1594 | static 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 | ||
| 1601 | static struct miscdevice _dm_misc = { | 1601 | static 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 | ||
| 1608 | MODULE_ALIAS_MISCDEV(MAPPER_CTRL_MINOR); | ||
| 1609 | MODULE_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 | */ |
