diff options
Diffstat (limited to 'drivers/mtd/ubi/build.c')
-rw-r--r-- | drivers/mtd/ubi/build.c | 69 |
1 files changed, 64 insertions, 5 deletions
diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c index 8b4573559dfe..4e761e957de8 100644 --- a/drivers/mtd/ubi/build.c +++ b/drivers/mtd/ubi/build.c | |||
@@ -366,9 +366,6 @@ static int uif_init(struct ubi_device *ubi) | |||
366 | int i, err; | 366 | int i, err; |
367 | dev_t dev; | 367 | dev_t dev; |
368 | 368 | ||
369 | mutex_init(&ubi->volumes_mutex); | ||
370 | spin_lock_init(&ubi->volumes_lock); | ||
371 | |||
372 | sprintf(ubi->ubi_name, UBI_NAME_STR "%d", ubi->ubi_num); | 369 | sprintf(ubi->ubi_name, UBI_NAME_STR "%d", ubi->ubi_num); |
373 | 370 | ||
374 | /* | 371 | /* |
@@ -624,6 +621,58 @@ static int io_init(struct ubi_device *ubi) | |||
624 | } | 621 | } |
625 | 622 | ||
626 | /** | 623 | /** |
624 | * autoresize - re-size the volume which has the "auto-resize" flag set. | ||
625 | * @ubi: UBI device description object | ||
626 | * @vol_id: ID of the volume to re-size | ||
627 | * | ||
628 | * This function re-sizes the volume marked by the @UBI_VTBL_AUTORESIZE_FLG in | ||
629 | * the volume table to the largest possible size. See comments in ubi-header.h | ||
630 | * for more description of the flag. Returns zero in case of success and a | ||
631 | * negative error code in case of failure. | ||
632 | */ | ||
633 | static int autoresize(struct ubi_device *ubi, int vol_id) | ||
634 | { | ||
635 | struct ubi_volume_desc desc; | ||
636 | struct ubi_volume *vol = ubi->volumes[vol_id]; | ||
637 | int err, old_reserved_pebs = vol->reserved_pebs; | ||
638 | |||
639 | /* | ||
640 | * Clear the auto-resize flag in the volume in-memory copy of the | ||
641 | * volume table, and 'ubi_resize_volume()' will propogate this change | ||
642 | * to the flash. | ||
643 | */ | ||
644 | ubi->vtbl[vol_id].flags &= ~UBI_VTBL_AUTORESIZE_FLG; | ||
645 | |||
646 | if (ubi->avail_pebs == 0) { | ||
647 | struct ubi_vtbl_record vtbl_rec; | ||
648 | |||
649 | /* | ||
650 | * No avalilable PEBs to re-size the volume, clear the flag on | ||
651 | * flash and exit. | ||
652 | */ | ||
653 | memcpy(&vtbl_rec, &ubi->vtbl[vol_id], | ||
654 | sizeof(struct ubi_vtbl_record)); | ||
655 | err = ubi_change_vtbl_record(ubi, vol_id, &vtbl_rec); | ||
656 | if (err) | ||
657 | ubi_err("cannot clean auto-resize flag for volume %d", | ||
658 | vol_id); | ||
659 | } else { | ||
660 | desc.vol = vol; | ||
661 | err = ubi_resize_volume(&desc, | ||
662 | old_reserved_pebs + ubi->avail_pebs); | ||
663 | if (err) | ||
664 | ubi_err("cannot auto-resize volume %d", vol_id); | ||
665 | } | ||
666 | |||
667 | if (err) | ||
668 | return err; | ||
669 | |||
670 | ubi_msg("volume %d (\"%s\") re-sized from %d to %d LEBs", vol_id, | ||
671 | vol->name, old_reserved_pebs, vol->reserved_pebs); | ||
672 | return 0; | ||
673 | } | ||
674 | |||
675 | /** | ||
627 | * ubi_attach_mtd_dev - attach an MTD device. | 676 | * ubi_attach_mtd_dev - attach an MTD device. |
628 | * @mtd_dev: MTD device description object | 677 | * @mtd_dev: MTD device description object |
629 | * @ubi_num: number to assign to the new UBI device | 678 | * @ubi_num: number to assign to the new UBI device |
@@ -699,6 +748,12 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, int vid_hdr_offset) | |||
699 | ubi->mtd = mtd; | 748 | ubi->mtd = mtd; |
700 | ubi->ubi_num = ubi_num; | 749 | ubi->ubi_num = ubi_num; |
701 | ubi->vid_hdr_offset = vid_hdr_offset; | 750 | ubi->vid_hdr_offset = vid_hdr_offset; |
751 | ubi->autoresize_vol_id = -1; | ||
752 | |||
753 | mutex_init(&ubi->buf_mutex); | ||
754 | mutex_init(&ubi->ckvol_mutex); | ||
755 | mutex_init(&ubi->volumes_mutex); | ||
756 | spin_lock_init(&ubi->volumes_lock); | ||
702 | 757 | ||
703 | dbg_msg("attaching mtd%d to ubi%d: VID header offset %d", | 758 | dbg_msg("attaching mtd%d to ubi%d: VID header offset %d", |
704 | mtd->index, ubi_num, vid_hdr_offset); | 759 | mtd->index, ubi_num, vid_hdr_offset); |
@@ -707,8 +762,6 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, int vid_hdr_offset) | |||
707 | if (err) | 762 | if (err) |
708 | goto out_free; | 763 | goto out_free; |
709 | 764 | ||
710 | mutex_init(&ubi->buf_mutex); | ||
711 | mutex_init(&ubi->ckvol_mutex); | ||
712 | ubi->peb_buf1 = vmalloc(ubi->peb_size); | 765 | ubi->peb_buf1 = vmalloc(ubi->peb_size); |
713 | if (!ubi->peb_buf1) | 766 | if (!ubi->peb_buf1) |
714 | goto out_free; | 767 | goto out_free; |
@@ -730,6 +783,12 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, int vid_hdr_offset) | |||
730 | goto out_free; | 783 | goto out_free; |
731 | } | 784 | } |
732 | 785 | ||
786 | if (ubi->autoresize_vol_id != -1) { | ||
787 | err = autoresize(ubi, ubi->autoresize_vol_id); | ||
788 | if (err) | ||
789 | goto out_detach; | ||
790 | } | ||
791 | |||
733 | err = uif_init(ubi); | 792 | err = uif_init(ubi); |
734 | if (err) | 793 | if (err) |
735 | goto out_detach; | 794 | goto out_detach; |