aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd/ubi/vmt.c
diff options
context:
space:
mode:
authorArtem Bityutskiy <Artem.Bityutskiy@nokia.com>2008-07-13 14:47:47 -0400
committerArtem Bityutskiy <Artem.Bityutskiy@nokia.com>2008-07-24 06:34:46 -0400
commitf40ac9cdf6991287f19bdafe9b0752ee40137908 (patch)
treea49120d5be3729feaa40880962f29e3679c1800e /drivers/mtd/ubi/vmt.c
parentc8566350a3229ca505b84313c65d1403b4d0cbfc (diff)
UBI: implement multiple volumes rename
Quite useful ioctl which allows to make atomic system upgrades. The idea belongs to Richard Titmuss <richard_titmuss@logitech.com> Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
Diffstat (limited to 'drivers/mtd/ubi/vmt.c')
-rw-r--r--drivers/mtd/ubi/vmt.c57
1 files changed, 49 insertions, 8 deletions
diff --git a/drivers/mtd/ubi/vmt.c b/drivers/mtd/ubi/vmt.c
index 2cd886a5adac..4be4014c70df 100644
--- a/drivers/mtd/ubi/vmt.c
+++ b/drivers/mtd/ubi/vmt.c
@@ -402,13 +402,14 @@ out_unlock:
402/** 402/**
403 * ubi_remove_volume - remove volume. 403 * ubi_remove_volume - remove volume.
404 * @desc: volume descriptor 404 * @desc: volume descriptor
405 * @no_vtbl: do not change volume table if not zero
405 * 406 *
406 * This function removes volume described by @desc. The volume has to be opened 407 * This function removes volume described by @desc. The volume has to be opened
407 * in "exclusive" mode. Returns zero in case of success and a negative error 408 * in "exclusive" mode. Returns zero in case of success and a negative error
408 * code in case of failure. The caller has to have the @ubi->volumes_mutex 409 * code in case of failure. The caller has to have the @ubi->volumes_mutex
409 * locked. 410 * locked.
410 */ 411 */
411int ubi_remove_volume(struct ubi_volume_desc *desc) 412int ubi_remove_volume(struct ubi_volume_desc *desc, int no_vtbl)
412{ 413{
413 struct ubi_volume *vol = desc->vol; 414 struct ubi_volume *vol = desc->vol;
414 struct ubi_device *ubi = vol->ubi; 415 struct ubi_device *ubi = vol->ubi;
@@ -437,9 +438,11 @@ int ubi_remove_volume(struct ubi_volume_desc *desc)
437 if (err) 438 if (err)
438 goto out_err; 439 goto out_err;
439 440
440 err = ubi_change_vtbl_record(ubi, vol_id, NULL); 441 if (!no_vtbl) {
441 if (err) 442 err = ubi_change_vtbl_record(ubi, vol_id, NULL);
442 goto out_err; 443 if (err)
444 goto out_err;
445 }
443 446
444 for (i = 0; i < vol->reserved_pebs; i++) { 447 for (i = 0; i < vol->reserved_pebs; i++) {
445 err = ubi_eba_unmap_leb(ubi, vol, i); 448 err = ubi_eba_unmap_leb(ubi, vol, i);
@@ -465,7 +468,8 @@ int ubi_remove_volume(struct ubi_volume_desc *desc)
465 ubi->vol_count -= 1; 468 ubi->vol_count -= 1;
466 spin_unlock(&ubi->volumes_lock); 469 spin_unlock(&ubi->volumes_lock);
467 470
468 err = paranoid_check_volumes(ubi); 471 if (!no_vtbl)
472 err = paranoid_check_volumes(ubi);
469 return err; 473 return err;
470 474
471out_err: 475out_err:
@@ -602,6 +606,44 @@ out_free:
602} 606}
603 607
604/** 608/**
609 * ubi_rename_volumes - re-name UBI volumes.
610 * @ubi: UBI device description object
611 * @renam_list: list of &struct ubi_rename_entry objects
612 *
613 * This function re-names or removes volumes specified in the re-name list.
614 * Returns zero in case of success and a negative error code in case of
615 * failure.
616 */
617int ubi_rename_volumes(struct ubi_device *ubi, struct list_head *rename_list)
618{
619 int err;
620 struct ubi_rename_entry *re;
621
622 err = ubi_vtbl_rename_volumes(ubi, rename_list);
623 if (err)
624 return err;
625
626 list_for_each_entry(re, rename_list, list) {
627 if (re->remove) {
628 err = ubi_remove_volume(re->desc, 1);
629 if (err)
630 break;
631 } else {
632 struct ubi_volume *vol = re->desc->vol;
633
634 spin_lock(&ubi->volumes_lock);
635 vol->name_len = re->new_name_len;
636 memcpy(vol->name, re->new_name, re->new_name_len + 1);
637 spin_unlock(&ubi->volumes_lock);
638 }
639 }
640
641 if (!err)
642 paranoid_check_volumes(ubi);
643 return err;
644}
645
646/**
605 * ubi_add_volume - add volume. 647 * ubi_add_volume - add volume.
606 * @ubi: UBI device description object 648 * @ubi: UBI device description object
607 * @vol: volume description object 649 * @vol: volume description object
@@ -826,10 +868,9 @@ static int paranoid_check_volume(struct ubi_device *ubi, int vol_id)
826 868
827fail: 869fail:
828 ubi_err("paranoid check failed for volume %d", vol_id); 870 ubi_err("paranoid check failed for volume %d", vol_id);
829 if (vol) { 871 if (vol)
830 ubi_dbg_dump_vol_info(vol); 872 ubi_dbg_dump_vol_info(vol);
831 ubi_dbg_dump_vtbl_record(&ubi->vtbl[vol_id], vol_id); 873 ubi_dbg_dump_vtbl_record(&ubi->vtbl[vol_id], vol_id);
832 }
833 spin_unlock(&ubi->volumes_lock); 874 spin_unlock(&ubi->volumes_lock);
834 return -EINVAL; 875 return -EINVAL;
835} 876}