diff options
-rw-r--r-- | drivers/mtd/ubi/block.c | 42 |
1 files changed, 26 insertions, 16 deletions
diff --git a/drivers/mtd/ubi/block.c b/drivers/mtd/ubi/block.c index b210fdb31c98..b1fc28f63882 100644 --- a/drivers/mtd/ubi/block.c +++ b/drivers/mtd/ubi/block.c | |||
@@ -99,6 +99,8 @@ struct ubiblock { | |||
99 | 99 | ||
100 | /* Linked list of all ubiblock instances */ | 100 | /* Linked list of all ubiblock instances */ |
101 | static LIST_HEAD(ubiblock_devices); | 101 | static LIST_HEAD(ubiblock_devices); |
102 | static DEFINE_IDR(ubiblock_minor_idr); | ||
103 | /* Protects ubiblock_devices and ubiblock_minor_idr */ | ||
102 | static DEFINE_MUTEX(devices_mutex); | 104 | static DEFINE_MUTEX(devices_mutex); |
103 | static int ubiblock_major; | 105 | static int ubiblock_major; |
104 | 106 | ||
@@ -351,8 +353,6 @@ static const struct blk_mq_ops ubiblock_mq_ops = { | |||
351 | .init_request = ubiblock_init_request, | 353 | .init_request = ubiblock_init_request, |
352 | }; | 354 | }; |
353 | 355 | ||
354 | static DEFINE_IDR(ubiblock_minor_idr); | ||
355 | |||
356 | int ubiblock_create(struct ubi_volume_info *vi) | 356 | int ubiblock_create(struct ubi_volume_info *vi) |
357 | { | 357 | { |
358 | struct ubiblock *dev; | 358 | struct ubiblock *dev; |
@@ -365,14 +365,15 @@ int ubiblock_create(struct ubi_volume_info *vi) | |||
365 | /* Check that the volume isn't already handled */ | 365 | /* Check that the volume isn't already handled */ |
366 | mutex_lock(&devices_mutex); | 366 | mutex_lock(&devices_mutex); |
367 | if (find_dev_nolock(vi->ubi_num, vi->vol_id)) { | 367 | if (find_dev_nolock(vi->ubi_num, vi->vol_id)) { |
368 | mutex_unlock(&devices_mutex); | 368 | ret = -EEXIST; |
369 | return -EEXIST; | 369 | goto out_unlock; |
370 | } | 370 | } |
371 | mutex_unlock(&devices_mutex); | ||
372 | 371 | ||
373 | dev = kzalloc(sizeof(struct ubiblock), GFP_KERNEL); | 372 | dev = kzalloc(sizeof(struct ubiblock), GFP_KERNEL); |
374 | if (!dev) | 373 | if (!dev) { |
375 | return -ENOMEM; | 374 | ret = -ENOMEM; |
375 | goto out_unlock; | ||
376 | } | ||
376 | 377 | ||
377 | mutex_init(&dev->dev_mutex); | 378 | mutex_init(&dev->dev_mutex); |
378 | 379 | ||
@@ -437,14 +438,13 @@ int ubiblock_create(struct ubi_volume_info *vi) | |||
437 | goto out_free_queue; | 438 | goto out_free_queue; |
438 | } | 439 | } |
439 | 440 | ||
440 | mutex_lock(&devices_mutex); | ||
441 | list_add_tail(&dev->list, &ubiblock_devices); | 441 | list_add_tail(&dev->list, &ubiblock_devices); |
442 | mutex_unlock(&devices_mutex); | ||
443 | 442 | ||
444 | /* Must be the last step: anyone can call file ops from now on */ | 443 | /* Must be the last step: anyone can call file ops from now on */ |
445 | add_disk(dev->gd); | 444 | add_disk(dev->gd); |
446 | dev_info(disk_to_dev(dev->gd), "created from ubi%d:%d(%s)", | 445 | dev_info(disk_to_dev(dev->gd), "created from ubi%d:%d(%s)", |
447 | dev->ubi_num, dev->vol_id, vi->name); | 446 | dev->ubi_num, dev->vol_id, vi->name); |
447 | mutex_unlock(&devices_mutex); | ||
448 | return 0; | 448 | return 0; |
449 | 449 | ||
450 | out_free_queue: | 450 | out_free_queue: |
@@ -457,6 +457,8 @@ out_put_disk: | |||
457 | put_disk(dev->gd); | 457 | put_disk(dev->gd); |
458 | out_free_dev: | 458 | out_free_dev: |
459 | kfree(dev); | 459 | kfree(dev); |
460 | out_unlock: | ||
461 | mutex_unlock(&devices_mutex); | ||
460 | 462 | ||
461 | return ret; | 463 | return ret; |
462 | } | 464 | } |
@@ -478,30 +480,36 @@ static void ubiblock_cleanup(struct ubiblock *dev) | |||
478 | int ubiblock_remove(struct ubi_volume_info *vi) | 480 | int ubiblock_remove(struct ubi_volume_info *vi) |
479 | { | 481 | { |
480 | struct ubiblock *dev; | 482 | struct ubiblock *dev; |
483 | int ret; | ||
481 | 484 | ||
482 | mutex_lock(&devices_mutex); | 485 | mutex_lock(&devices_mutex); |
483 | dev = find_dev_nolock(vi->ubi_num, vi->vol_id); | 486 | dev = find_dev_nolock(vi->ubi_num, vi->vol_id); |
484 | if (!dev) { | 487 | if (!dev) { |
485 | mutex_unlock(&devices_mutex); | 488 | ret = -ENODEV; |
486 | return -ENODEV; | 489 | goto out_unlock; |
487 | } | 490 | } |
488 | 491 | ||
489 | /* Found a device, let's lock it so we can check if it's busy */ | 492 | /* Found a device, let's lock it so we can check if it's busy */ |
490 | mutex_lock(&dev->dev_mutex); | 493 | mutex_lock(&dev->dev_mutex); |
491 | if (dev->refcnt > 0) { | 494 | if (dev->refcnt > 0) { |
492 | mutex_unlock(&dev->dev_mutex); | 495 | ret = -EBUSY; |
493 | mutex_unlock(&devices_mutex); | 496 | goto out_unlock_dev; |
494 | return -EBUSY; | ||
495 | } | 497 | } |
496 | 498 | ||
497 | /* Remove from device list */ | 499 | /* Remove from device list */ |
498 | list_del(&dev->list); | 500 | list_del(&dev->list); |
499 | mutex_unlock(&devices_mutex); | ||
500 | |||
501 | ubiblock_cleanup(dev); | 501 | ubiblock_cleanup(dev); |
502 | mutex_unlock(&dev->dev_mutex); | 502 | mutex_unlock(&dev->dev_mutex); |
503 | mutex_unlock(&devices_mutex); | ||
504 | |||
503 | kfree(dev); | 505 | kfree(dev); |
504 | return 0; | 506 | return 0; |
507 | |||
508 | out_unlock_dev: | ||
509 | mutex_unlock(&dev->dev_mutex); | ||
510 | out_unlock: | ||
511 | mutex_unlock(&devices_mutex); | ||
512 | return ret; | ||
505 | } | 513 | } |
506 | 514 | ||
507 | static int ubiblock_resize(struct ubi_volume_info *vi) | 515 | static int ubiblock_resize(struct ubi_volume_info *vi) |
@@ -630,6 +638,7 @@ static void ubiblock_remove_all(void) | |||
630 | struct ubiblock *next; | 638 | struct ubiblock *next; |
631 | struct ubiblock *dev; | 639 | struct ubiblock *dev; |
632 | 640 | ||
641 | mutex_lock(&devices_mutex); | ||
633 | list_for_each_entry_safe(dev, next, &ubiblock_devices, list) { | 642 | list_for_each_entry_safe(dev, next, &ubiblock_devices, list) { |
634 | /* The module is being forcefully removed */ | 643 | /* The module is being forcefully removed */ |
635 | WARN_ON(dev->desc); | 644 | WARN_ON(dev->desc); |
@@ -638,6 +647,7 @@ static void ubiblock_remove_all(void) | |||
638 | ubiblock_cleanup(dev); | 647 | ubiblock_cleanup(dev); |
639 | kfree(dev); | 648 | kfree(dev); |
640 | } | 649 | } |
650 | mutex_unlock(&devices_mutex); | ||
641 | } | 651 | } |
642 | 652 | ||
643 | int __init ubiblock_init(void) | 653 | int __init ubiblock_init(void) |