Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 84286
b: refs/heads/master
c: 4ccf8cf
h: refs/heads/master
v: v3
  • Loading branch information
Artem Bityutskiy authored and Artem Bityutskiy committed Jan 25, 2008
1 parent 3002a2c commit b57e79f
Show file tree
Hide file tree
Showing 8 changed files with 122 additions and 27 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 896c0c06aa30147630e9a75949b6ae2014c841fc
refs/heads/master: 4ccf8cffa963c7b5bdc6d455ea9417084ee49aa8
69 changes: 64 additions & 5 deletions trunk/drivers/mtd/ubi/build.c
Original file line number Diff line number Diff line change
Expand Up @@ -366,9 +366,6 @@ static int uif_init(struct ubi_device *ubi)
int i, err;
dev_t dev;

mutex_init(&ubi->volumes_mutex);
spin_lock_init(&ubi->volumes_lock);

sprintf(ubi->ubi_name, UBI_NAME_STR "%d", ubi->ubi_num);

/*
Expand Down Expand Up @@ -623,6 +620,58 @@ static int io_init(struct ubi_device *ubi)
return 0;
}

/**
* autoresize - re-size the volume which has the "auto-resize" flag set.
* @ubi: UBI device description object
* @vol_id: ID of the volume to re-size
*
* This function re-sizes the volume marked by the @UBI_VTBL_AUTORESIZE_FLG in
* the volume table to the largest possible size. See comments in ubi-header.h
* for more description of the flag. Returns zero in case of success and a
* negative error code in case of failure.
*/
static int autoresize(struct ubi_device *ubi, int vol_id)
{
struct ubi_volume_desc desc;
struct ubi_volume *vol = ubi->volumes[vol_id];
int err, old_reserved_pebs = vol->reserved_pebs;

/*
* Clear the auto-resize flag in the volume in-memory copy of the
* volume table, and 'ubi_resize_volume()' will propogate this change
* to the flash.
*/
ubi->vtbl[vol_id].flags &= ~UBI_VTBL_AUTORESIZE_FLG;

if (ubi->avail_pebs == 0) {
struct ubi_vtbl_record vtbl_rec;

/*
* No avalilable PEBs to re-size the volume, clear the flag on
* flash and exit.
*/
memcpy(&vtbl_rec, &ubi->vtbl[vol_id],
sizeof(struct ubi_vtbl_record));
err = ubi_change_vtbl_record(ubi, vol_id, &vtbl_rec);
if (err)
ubi_err("cannot clean auto-resize flag for volume %d",
vol_id);
} else {
desc.vol = vol;
err = ubi_resize_volume(&desc,
old_reserved_pebs + ubi->avail_pebs);
if (err)
ubi_err("cannot auto-resize volume %d", vol_id);
}

if (err)
return err;

ubi_msg("volume %d (\"%s\") re-sized from %d to %d LEBs", vol_id,
vol->name, old_reserved_pebs, vol->reserved_pebs);
return 0;
}

/**
* ubi_attach_mtd_dev - attach an MTD device.
* @mtd_dev: MTD device description object
Expand Down Expand Up @@ -699,6 +748,12 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, int vid_hdr_offset)
ubi->mtd = mtd;
ubi->ubi_num = ubi_num;
ubi->vid_hdr_offset = vid_hdr_offset;
ubi->autoresize_vol_id = -1;

mutex_init(&ubi->buf_mutex);
mutex_init(&ubi->ckvol_mutex);
mutex_init(&ubi->volumes_mutex);
spin_lock_init(&ubi->volumes_lock);

dbg_msg("attaching mtd%d to ubi%d: VID header offset %d",
mtd->index, ubi_num, vid_hdr_offset);
Expand All @@ -707,8 +762,6 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, int vid_hdr_offset)
if (err)
goto out_free;

mutex_init(&ubi->buf_mutex);
mutex_init(&ubi->ckvol_mutex);
ubi->peb_buf1 = vmalloc(ubi->peb_size);
if (!ubi->peb_buf1)
goto out_free;
Expand All @@ -730,6 +783,12 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, int vid_hdr_offset)
goto out_free;
}

if (ubi->autoresize_vol_id != -1) {
err = autoresize(ubi, ubi->autoresize_vol_id);
if (err)
goto out_detach;
}

err = uif_init(ubi);
if (err)
goto out_detach;
Expand Down
15 changes: 0 additions & 15 deletions trunk/drivers/mtd/ubi/eba.c
Original file line number Diff line number Diff line change
Expand Up @@ -341,9 +341,6 @@ int ubi_eba_unmap_leb(struct ubi_device *ubi, struct ubi_volume *vol,
{
int err, pnum, vol_id = vol->vol_id;

ubi_assert(ubi->ref_count > 0);
ubi_assert(vol->ref_count > 0);

if (ubi->ro_mode)
return -EROFS;

Expand Down Expand Up @@ -392,9 +389,6 @@ int ubi_eba_read_leb(struct ubi_device *ubi, struct ubi_volume *vol, int lnum,
struct ubi_vid_hdr *vid_hdr;
uint32_t uninitialized_var(crc);

ubi_assert(ubi->ref_count > 0);
ubi_assert(vol->ref_count > 0);

err = leb_read_lock(ubi, vol_id, lnum);
if (err)
return err;
Expand Down Expand Up @@ -618,9 +612,6 @@ int ubi_eba_write_leb(struct ubi_device *ubi, struct ubi_volume *vol, int lnum,
int err, pnum, tries = 0, vol_id = vol->vol_id;
struct ubi_vid_hdr *vid_hdr;

ubi_assert(ubi->ref_count > 0);
ubi_assert(vol->ref_count > 0);

if (ubi->ro_mode)
return -EROFS;

Expand Down Expand Up @@ -754,9 +745,6 @@ int ubi_eba_write_leb_st(struct ubi_device *ubi, struct ubi_volume *vol,
struct ubi_vid_hdr *vid_hdr;
uint32_t crc;

ubi_assert(ubi->ref_count > 0);
ubi_assert(vol->ref_count > 0);

if (ubi->ro_mode)
return -EROFS;

Expand Down Expand Up @@ -871,9 +859,6 @@ int ubi_eba_atomic_leb_change(struct ubi_device *ubi, struct ubi_volume *vol,
struct ubi_vid_hdr *vid_hdr;
uint32_t crc;

ubi_assert(ubi->ref_count > 0);
ubi_assert(vol->ref_count > 0);

if (ubi->ro_mode)
return -EROFS;

Expand Down
6 changes: 5 additions & 1 deletion trunk/drivers/mtd/ubi/ubi.h
Original file line number Diff line number Diff line change
Expand Up @@ -250,9 +250,11 @@ struct ubi_wl_entry;
* @rsvd_pebs: count of reserved physical eraseblocks
* @avail_pebs: count of available physical eraseblocks
* @beb_rsvd_pebs: how many physical eraseblocks are reserved for bad PEB
* handling
* handling
* @beb_rsvd_level: normal level of PEBs reserved for bad PEB handling
*
* @autoresize_vol_id: ID of the volume which has to be auto-resized at the end
* of UBI ititializetion
* @vtbl_slots: how many slots are available in the volume table
* @vtbl_size: size of the volume table in bytes
* @vtbl: in-RAM volume table copy
Expand Down Expand Up @@ -333,12 +335,14 @@ struct ubi_device {
int beb_rsvd_pebs;
int beb_rsvd_level;

int autoresize_vol_id;
int vtbl_slots;
int vtbl_size;
struct ubi_vtbl_record *vtbl;
struct mutex volumes_mutex;

int max_ec;
/* TODO: mean_ec is not updated run-time, fix */
int mean_ec;

/* EBA unit's stuff */
Expand Down
2 changes: 0 additions & 2 deletions trunk/drivers/mtd/ubi/vmt.c
Original file line number Diff line number Diff line change
Expand Up @@ -497,8 +497,6 @@ int ubi_resize_volume(struct ubi_volume_desc *desc, int reserved_pebs)

dbg_msg("re-size volume %d to from %d to %d PEBs",
vol_id, vol->reserved_pebs, reserved_pebs);
ubi_assert(desc->mode == UBI_EXCLUSIVE);
ubi_assert(vol == ubi->volumes[vol_id]);

if (vol->vol_type == UBI_STATIC_VOLUME &&
reserved_pebs < vol->used_ebs) {
Expand Down
11 changes: 11 additions & 0 deletions trunk/drivers/mtd/ubi/vtbl.c
Original file line number Diff line number Diff line change
Expand Up @@ -514,6 +514,17 @@ static int init_volumes(struct ubi_device *ubi, const struct ubi_scan_info *si,
vol->name[vol->name_len] = '\0';
vol->vol_id = i;

if (vtbl[i].flags & UBI_VTBL_AUTORESIZE_FLG) {
/* Auto re-size flag may be set only for one volume */
if (ubi->autoresize_vol_id != -1) {
ubi_err("more then one auto-resize volume (%d "
"and %d)", ubi->autoresize_vol_id, i);
return -EINVAL;
}

ubi->autoresize_vol_id = i;
}

ubi_assert(!ubi->volumes[i]);
ubi->volumes[i] = vol;
ubi->vol_count += 1;
Expand Down
1 change: 0 additions & 1 deletion trunk/drivers/mtd/ubi/wl.c
Original file line number Diff line number Diff line change
Expand Up @@ -1303,7 +1303,6 @@ int ubi_wl_flush(struct ubi_device *ubi)
* Make sure all the works which have been done in parallel are
* finished.
*/
ubi_assert(ubi->ref_count > 0);
down_write(&ubi->work_sem);
up_write(&ubi->work_sem);

Expand Down
43 changes: 41 additions & 2 deletions trunk/include/mtd/ubi-header.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,43 @@ enum {
UBI_VID_STATIC = 2
};

/*
* Volume flags used in the volume table record.
*
* @UBI_VTBL_AUTORESIZE_FLG: auto-resize this volume
*
* %UBI_VTBL_AUTORESIZE_FLG flag can be set only for one volume in the volume
* table. UBI automatically re-sizes the volume which has this flag and makes
* the volume to be of largest possible size. This means that if after the
* initialization UBI finds out that there are available physical eraseblocks
* present on the device, it automatically appends all of them to the volume
* (the physical eraseblocks reserved for bad eraseblocks handling and other
* reserved physical eraseblocks are not taken). So, if there is a volume with
* the %UBI_VTBL_AUTORESIZE_FLG flag set, the amount of available logical
* eraseblocks will be zero after UBI is loaded, because all of them will be
* reserved for this volume. Note, the %UBI_VTBL_AUTORESIZE_FLG bit is cleared
* after the volume had been initialized.
*
* The auto-resize feature is useful for device production purposes. For
* example, different NAND flash chips may have different amount of initial bad
* eraseblocks, depending of particular chip instance. Manufacturers of NAND
* chips usually guarantee that the amount of initial bad eraseblocks does not
* exceed certain percent, e.g. 2%. When one creates an UBI image which will be
* flashed to the end devices in production, he does not know the exact amount
* of good physical eraseblocks the NAND chip on the device will have, but this
* number is required to calculate the volume sized and put them to the volume
* table of the UBI image. In this case, one of the volumes (e.g., the one
* which will store the root file system) is marked as "auto-resizable", and
* UBI will adjust its size on the first boot if needed.
*
* Note, first UBI reserves some amount of physical eraseblocks for bad
* eraseblock handling, and then re-sizes the volume, not vice-versa. This
* means that the pool of reserved physical eraseblocks will always be present.
*/
enum {
UBI_VTBL_AUTORESIZE_FLG = 0x01,
};

/*
* Compatibility constants used by internal volumes.
*
Expand Down Expand Up @@ -289,7 +326,8 @@ struct ubi_vid_hdr {
* @upd_marker: if volume update was started but not finished
* @name_len: volume name length
* @name: the volume name
* @padding2: reserved, zeroes
* @flags: volume flags (%UBI_VTBL_AUTORESIZE_FLG)
* @padding: reserved, zeroes
* @crc: a CRC32 checksum of the record
*
* The volume table records are stored in the volume table, which is stored in
Expand Down Expand Up @@ -324,7 +362,8 @@ struct ubi_vtbl_record {
__u8 upd_marker;
__be16 name_len;
__u8 name[UBI_VOL_NAME_MAX+1];
__u8 padding2[24];
__u8 flags;
__u8 padding[23];
__be32 crc;
} __attribute__ ((packed));

Expand Down

0 comments on commit b57e79f

Please sign in to comment.