diff options
author | Artem Bityutskiy <Artem.Bityutskiy@nokia.com> | 2007-12-17 10:08:55 -0500 |
---|---|---|
committer | Artem Bityutskiy <Artem.Bityutskiy@nokia.com> | 2007-12-26 12:15:16 -0500 |
commit | 40e4d0c1660f8ee01ea4ed570297b32c35c70aa3 (patch) | |
tree | d1fbdf8b790ebc002302259e9f0d507d5a508855 /drivers/mtd/ubi | |
parent | d05c77a816974c09f8c7e8f48e5b9f7b59dafdf3 (diff) |
UBI: tweak volumes locking some more
Make the code more consistent by requiring the caller to lock the
ubi->volume_mutex, because this is what we do for updates.
Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
Diffstat (limited to 'drivers/mtd/ubi')
-rw-r--r-- | drivers/mtd/ubi/cdev.c | 13 | ||||
-rw-r--r-- | drivers/mtd/ubi/vmt.c | 20 |
2 files changed, 17 insertions, 16 deletions
diff --git a/drivers/mtd/ubi/cdev.c b/drivers/mtd/ubi/cdev.c index 35d34b675c7..22c15a388f2 100644 --- a/drivers/mtd/ubi/cdev.c +++ b/drivers/mtd/ubi/cdev.c | |||
@@ -605,7 +605,9 @@ static int ubi_cdev_ioctl(struct inode *inode, struct file *file, | |||
605 | 605 | ||
606 | req.name[req.name_len] = '\0'; | 606 | req.name[req.name_len] = '\0'; |
607 | 607 | ||
608 | mutex_lock(&ubi->volumes_mutex); | ||
608 | err = ubi_create_volume(ubi, &req); | 609 | err = ubi_create_volume(ubi, &req); |
610 | mutex_unlock(&ubi->volumes_mutex); | ||
609 | if (err) | 611 | if (err) |
610 | break; | 612 | break; |
611 | 613 | ||
@@ -634,11 +636,14 @@ static int ubi_cdev_ioctl(struct inode *inode, struct file *file, | |||
634 | break; | 636 | break; |
635 | } | 637 | } |
636 | 638 | ||
639 | mutex_lock(&ubi->volumes_mutex); | ||
637 | err = ubi_remove_volume(desc); | 640 | err = ubi_remove_volume(desc); |
641 | mutex_unlock(&ubi->volumes_mutex); | ||
642 | |||
638 | /* | 643 | /* |
639 | * The volume is deleted, and the 'struct ubi_volume' object | 644 | * The volume is deleted (unless an error occurred), and the |
640 | * will be freed when 'ubi_close_volume()' will call | 645 | * 'struct ubi_volume' object will be freed when |
641 | * 'put_device()'. | 646 | * 'ubi_close_volume()' will call 'put_device()'. |
642 | */ | 647 | */ |
643 | ubi_close_volume(desc); | 648 | ubi_close_volume(desc); |
644 | break; | 649 | break; |
@@ -673,7 +678,9 @@ static int ubi_cdev_ioctl(struct inode *inode, struct file *file, | |||
673 | pebs = !!do_div(tmp, desc->vol->usable_leb_size); | 678 | pebs = !!do_div(tmp, desc->vol->usable_leb_size); |
674 | pebs += tmp; | 679 | pebs += tmp; |
675 | 680 | ||
681 | mutex_lock(&ubi->volumes_mutex); | ||
676 | err = ubi_resize_volume(desc, pebs); | 682 | err = ubi_resize_volume(desc, pebs); |
683 | mutex_unlock(&ubi->volumes_mutex); | ||
677 | ubi_close_volume(desc); | 684 | ubi_close_volume(desc); |
678 | break; | 685 | break; |
679 | } | 686 | } |
diff --git a/drivers/mtd/ubi/vmt.c b/drivers/mtd/ubi/vmt.c index 18ef1e1da49..3ed63dc3738 100644 --- a/drivers/mtd/ubi/vmt.c +++ b/drivers/mtd/ubi/vmt.c | |||
@@ -189,7 +189,8 @@ static void volume_sysfs_close(struct ubi_volume *vol) | |||
189 | * This function creates volume described by @req. If @req->vol_id id | 189 | * This function creates volume described by @req. If @req->vol_id id |
190 | * %UBI_VOL_NUM_AUTO, this function automatically assign ID to the new volume | 190 | * %UBI_VOL_NUM_AUTO, this function automatically assign ID to the new volume |
191 | * and saves it in @req->vol_id. Returns zero in case of success and a negative | 191 | * and saves it in @req->vol_id. Returns zero in case of success and a negative |
192 | * error code in case of failure. | 192 | * error code in case of failure. Note, the caller has to have the |
193 | * @ubi->volumes_mutex locked. | ||
193 | */ | 194 | */ |
194 | int ubi_create_volume(struct ubi_device *ubi, struct ubi_mkvol_req *req) | 195 | int ubi_create_volume(struct ubi_device *ubi, struct ubi_mkvol_req *req) |
195 | { | 196 | { |
@@ -206,7 +207,6 @@ int ubi_create_volume(struct ubi_device *ubi, struct ubi_mkvol_req *req) | |||
206 | if (!vol) | 207 | if (!vol) |
207 | return -ENOMEM; | 208 | return -ENOMEM; |
208 | 209 | ||
209 | mutex_lock(&ubi->volumes_mutex); | ||
210 | spin_lock(&ubi->volumes_lock); | 210 | spin_lock(&ubi->volumes_lock); |
211 | if (vol_id == UBI_VOL_NUM_AUTO) { | 211 | if (vol_id == UBI_VOL_NUM_AUTO) { |
212 | /* Find unused volume ID */ | 212 | /* Find unused volume ID */ |
@@ -356,7 +356,6 @@ int ubi_create_volume(struct ubi_device *ubi, struct ubi_mkvol_req *req) | |||
356 | spin_unlock(&ubi->volumes_lock); | 356 | spin_unlock(&ubi->volumes_lock); |
357 | 357 | ||
358 | paranoid_check_volumes(ubi); | 358 | paranoid_check_volumes(ubi); |
359 | mutex_unlock(&ubi->volumes_mutex); | ||
360 | return 0; | 359 | return 0; |
361 | 360 | ||
362 | out_sysfs: | 361 | out_sysfs: |
@@ -383,7 +382,6 @@ out_acc: | |||
383 | ubi->avail_pebs += vol->reserved_pebs; | 382 | ubi->avail_pebs += vol->reserved_pebs; |
384 | out_unlock: | 383 | out_unlock: |
385 | spin_unlock(&ubi->volumes_lock); | 384 | spin_unlock(&ubi->volumes_lock); |
386 | mutex_unlock(&ubi->volumes_mutex); | ||
387 | if (dont_free) | 385 | if (dont_free) |
388 | put_device(&vol->dev); | 386 | put_device(&vol->dev); |
389 | else | 387 | else |
@@ -398,7 +396,8 @@ out_unlock: | |||
398 | * | 396 | * |
399 | * This function removes volume described by @desc. The volume has to be opened | 397 | * This function removes volume described by @desc. The volume has to be opened |
400 | * in "exclusive" mode. Returns zero in case of success and a negative error | 398 | * in "exclusive" mode. Returns zero in case of success and a negative error |
401 | * code in case of failure. | 399 | * code in case of failure. The caller has to have the @ubi->volumes_mutex |
400 | * locked. | ||
402 | */ | 401 | */ |
403 | int ubi_remove_volume(struct ubi_volume_desc *desc) | 402 | int ubi_remove_volume(struct ubi_volume_desc *desc) |
404 | { | 403 | { |
@@ -413,7 +412,6 @@ int ubi_remove_volume(struct ubi_volume_desc *desc) | |||
413 | if (ubi->ro_mode) | 412 | if (ubi->ro_mode) |
414 | return -EROFS; | 413 | return -EROFS; |
415 | 414 | ||
416 | mutex_lock(&ubi->volumes_mutex); | ||
417 | spin_lock(&ubi->volumes_lock); | 415 | spin_lock(&ubi->volumes_lock); |
418 | if (vol->ref_count > 1) { | 416 | if (vol->ref_count > 1) { |
419 | /* | 417 | /* |
@@ -461,7 +459,6 @@ int ubi_remove_volume(struct ubi_volume_desc *desc) | |||
461 | spin_unlock(&ubi->volumes_lock); | 459 | spin_unlock(&ubi->volumes_lock); |
462 | 460 | ||
463 | paranoid_check_volumes(ubi); | 461 | paranoid_check_volumes(ubi); |
464 | mutex_unlock(&ubi->volumes_mutex); | ||
465 | return 0; | 462 | return 0; |
466 | 463 | ||
467 | out_err: | 464 | out_err: |
@@ -470,7 +467,6 @@ out_err: | |||
470 | ubi->volumes[vol_id] = vol; | 467 | ubi->volumes[vol_id] = vol; |
471 | out_unlock: | 468 | out_unlock: |
472 | spin_unlock(&ubi->volumes_lock); | 469 | spin_unlock(&ubi->volumes_lock); |
473 | mutex_unlock(&ubi->volumes_mutex); | ||
474 | return err; | 470 | return err; |
475 | } | 471 | } |
476 | 472 | ||
@@ -479,8 +475,9 @@ out_unlock: | |||
479 | * @desc: volume descriptor | 475 | * @desc: volume descriptor |
480 | * @reserved_pebs: new size in physical eraseblocks | 476 | * @reserved_pebs: new size in physical eraseblocks |
481 | * | 477 | * |
482 | * This function returns zero in case of success, and a negative error code in | 478 | * This function re-sizes the volume and returns zero in case of success, and a |
483 | * case of failure. | 479 | * negative error code in case of failure. The caller has to have the |
480 | * @ubi->volumes_mutex locked. | ||
484 | */ | 481 | */ |
485 | int ubi_resize_volume(struct ubi_volume_desc *desc, int reserved_pebs) | 482 | int ubi_resize_volume(struct ubi_volume_desc *desc, int reserved_pebs) |
486 | { | 483 | { |
@@ -516,7 +513,6 @@ int ubi_resize_volume(struct ubi_volume_desc *desc, int reserved_pebs) | |||
516 | for (i = 0; i < reserved_pebs; i++) | 513 | for (i = 0; i < reserved_pebs; i++) |
517 | new_mapping[i] = UBI_LEB_UNMAPPED; | 514 | new_mapping[i] = UBI_LEB_UNMAPPED; |
518 | 515 | ||
519 | mutex_lock(&ubi->volumes_mutex); | ||
520 | spin_lock(&ubi->volumes_lock); | 516 | spin_lock(&ubi->volumes_lock); |
521 | if (vol->ref_count > 1) { | 517 | if (vol->ref_count > 1) { |
522 | spin_unlock(&ubi->volumes_lock); | 518 | spin_unlock(&ubi->volumes_lock); |
@@ -587,7 +583,6 @@ int ubi_resize_volume(struct ubi_volume_desc *desc, int reserved_pebs) | |||
587 | } | 583 | } |
588 | 584 | ||
589 | paranoid_check_volumes(ubi); | 585 | paranoid_check_volumes(ubi); |
590 | mutex_unlock(&ubi->volumes_mutex); | ||
591 | return 0; | 586 | return 0; |
592 | 587 | ||
593 | out_acc: | 588 | out_acc: |
@@ -599,7 +594,6 @@ out_acc: | |||
599 | } | 594 | } |
600 | out_free: | 595 | out_free: |
601 | kfree(new_mapping); | 596 | kfree(new_mapping); |
602 | mutex_unlock(&ubi->volumes_mutex); | ||
603 | return err; | 597 | return err; |
604 | } | 598 | } |
605 | 599 | ||