@@ -1205,13 +1205,6 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to,
dbg_wl("copy LEB %d:%d, PEB %d to PEB %d", vol_id, lnum, from, to);
- if (vid_hdr->vol_type == UBI_VID_STATIC) {
- data_size = be32_to_cpu(vid_hdr->data_size);
- aldata_size = ALIGN(data_size, ubi->min_io_size);
- } else
- data_size = aldata_size =
- ubi->leb_size - be32_to_cpu(vid_hdr->data_pad);
-
idx = vol_id2idx(ubi, vol_id);
spin_lock(&ubi->volumes_lock);
/*
@@ -1261,6 +1254,13 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to,
goto out_unlock_leb;
}
+ if (vid_hdr->vol_type == UBI_VID_STATIC) {
+ data_size = be32_to_cpu(vid_hdr->data_size);
+ aldata_size = ALIGN(data_size, ubi->min_io_size);
+ } else
+ data_size = aldata_size =
+ vol->leb_size - be32_to_cpu(vid_hdr->data_pad);
+
/*
* OK, now the LEB is locked and we can safely start moving it. Since
* this function utilizes the @ubi->peb_buf buffer which is shared
@@ -306,6 +306,7 @@ struct ubi_eba_leb_desc {
*
* @reserved_pebs: how many physical eraseblocks are reserved for this volume
* @vol_type: volume type (%UBI_DYNAMIC_VOLUME or %UBI_STATIC_VOLUME)
+ * @leb_size: logical eraseblock size
* @usable_leb_size: logical eraseblock size without padding
* @used_ebs: how many logical eraseblocks in this volume contain data
* @last_eb_bytes: how many bytes are stored in the last logical eraseblock
@@ -355,6 +356,7 @@ struct ubi_volume {
int reserved_pebs;
int vol_type;
+ int leb_size;
int usable_leb_size;
int used_ebs;
int last_eb_bytes;
@@ -133,7 +133,7 @@ int ubi_start_update(struct ubi_device *ubi, struct ubi_volume *vol,
ubi_assert(!vol->updating && !vol->changing_leb);
vol->updating = 1;
- vol->upd_buf = vmalloc(ubi->leb_size);
+ vol->upd_buf = vmalloc(vol->leb_size);
if (!vol->upd_buf)
return -ENOMEM;
@@ -207,8 +207,17 @@ int ubi_create_volume(struct ubi_device *ubi, struct ubi_mkvol_req *req)
goto out_unlock;
}
+ /*
+ * Volume LEB size is currently PEB size - (size reserved for the EC
+ * and VID headers). This will change with MLC/TLC NAND support and
+ * the LEB consolidation concept.
+ */
+ vol->leb_size = ubi->leb_size;
+
/* Calculate how many eraseblocks are requested */
- vol->usable_leb_size = ubi->leb_size - ubi->leb_size % req->alignment;
+ vol->alignment = req->alignment;
+ vol->data_pad = vol->leb_size % vol->alignment;
+ vol->usable_leb_size = vol->leb_size - vol->data_pad;
vol->reserved_pebs = div_u64(req->bytes + vol->usable_leb_size - 1,
vol->usable_leb_size);
@@ -227,8 +236,6 @@ int ubi_create_volume(struct ubi_device *ubi, struct ubi_mkvol_req *req)
spin_unlock(&ubi->volumes_lock);
vol->vol_id = vol_id;
- vol->alignment = req->alignment;
- vol->data_pad = ubi->leb_size % vol->alignment;
vol->vol_type = req->vol_type;
vol->name_len = req->name_len;
memcpy(vol->name, req->name, vol->name_len);
@@ -675,7 +682,7 @@ static int self_check_volume(struct ubi_device *ubi, int vol_id)
ubi_err(ubi, "negative values");
goto fail;
}
- if (vol->alignment > ubi->leb_size || vol->alignment == 0) {
+ if (vol->alignment > vol->leb_size || vol->alignment == 0) {
ubi_err(ubi, "bad alignment");
goto fail;
}
@@ -686,7 +693,7 @@ static int self_check_volume(struct ubi_device *ubi, int vol_id)
goto fail;
}
- n = ubi->leb_size % vol->alignment;
+ n = vol->leb_size % vol->alignment;
if (vol->data_pad != n) {
ubi_err(ubi, "bad data_pad, has to be %lld", n);
goto fail;
@@ -708,8 +715,8 @@ static int self_check_volume(struct ubi_device *ubi, int vol_id)
goto fail;
}
- n = ubi->leb_size - vol->data_pad;
- if (vol->usable_leb_size != ubi->leb_size - vol->data_pad) {
+ n = vol->leb_size - vol->data_pad;
+ if (vol->usable_leb_size != n) {
ubi_err(ubi, "bad usable_leb_size, has to be %lld", n);
goto fail;
}
@@ -555,7 +555,8 @@ static int init_volumes(struct ubi_device *ubi,
vol->vol_type = vtbl[i].vol_type == UBI_VID_DYNAMIC ?
UBI_DYNAMIC_VOLUME : UBI_STATIC_VOLUME;
vol->name_len = be16_to_cpu(vtbl[i].name_len);
- vol->usable_leb_size = ubi->leb_size - vol->data_pad;
+ vol->leb_size = ubi->leb_size;
+ vol->usable_leb_size = vol->leb_size - vol->data_pad;
memcpy(vol->name, vtbl[i].name, vol->name_len);
vol->name[vol->name_len] = '\0';
vol->vol_id = i;
@@ -632,11 +633,12 @@ static int init_volumes(struct ubi_device *ubi,
vol->vol_type = UBI_DYNAMIC_VOLUME;
vol->name_len = sizeof(UBI_LAYOUT_VOLUME_NAME) - 1;
memcpy(vol->name, UBI_LAYOUT_VOLUME_NAME, vol->name_len + 1);
- vol->usable_leb_size = ubi->leb_size;
vol->used_ebs = vol->reserved_pebs;
vol->last_eb_bytes = vol->reserved_pebs;
+ vol->leb_size = ubi->leb_size;
+ vol->usable_leb_size = vol->leb_size;
vol->used_bytes =
- (long long)vol->used_ebs * (ubi->leb_size - vol->data_pad);
+ (long long)vol->used_ebs * (vol->leb_size - vol->data_pad);
vol->vol_id = UBI_LAYOUT_VOLUME_ID;
vol->ref_count = 1;
The LEB size is currently common to all volumes attached to a UBI device, but the introduction of MLC NAND support and 'MLC safe' dynamic volumes forces us to tweak the LEB size per volume. In case of 'MLC safe' volumes, the LEB size should be set to (peb_size / bits_per_cells) - ec_and_vid_align_size This commit only adds a leb_size field to struct ubi_volume and makes use of it where appropriate. Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com> --- drivers/mtd/ubi/eba.c | 14 +++++++------- drivers/mtd/ubi/ubi.h | 2 ++ drivers/mtd/ubi/upd.c | 2 +- drivers/mtd/ubi/vmt.c | 21 ++++++++++++++------- drivers/mtd/ubi/vtbl.c | 8 +++++--- 5 files changed, 29 insertions(+), 18 deletions(-)