Skip to content

Commit

Permalink
UBI: block: Fix block device size setting
Browse files Browse the repository at this point in the history
We are currently taking the block device size from the ubi_volume_info.size
field. However, this is not the amount of data in the volume, but the
number of reserved physical eraseblocks, and hence leads to an incorrect
representation of the volume.

In particular, this produces I/O errors on static volumes as the block
interface may attempt to read unmapped PEBs:

$ cat /dev/ubiblock0_0 > /dev/null
UBI error: ubiblock_read_to_buf: ubiblock0_0 ubi_read error -22
end_request: I/O error, dev ubiblock0_0, sector 9536
Buffer I/O error on device ubiblock0_0, logical block 2384
[snip]

Fix this by using the ubi_volume_info.used_bytes field which is set to the
actual number of data bytes for both static and dynamic volumes.

While here, improve the error message to be less stupid and more useful:
UBI error: ubiblock_read_to_buf: ubiblock0_1 ubi_read error -9 on LEB=0, off=15872, len=512

It's worth noticing that the 512-byte sector representation of the volume
is only correct if the volume size is multiple of 512-bytes. This is true for
virtually any NAND device, given eraseblocks and pages are 512-byte multiple
and hence so is the LEB size.

Artem: tweak the error message and make it look more like other UBI error
messages.

Fixes: 9d54c8a ("UBI: R/O block driver on top of UBI volumes")
Signed-off-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
Signed-off-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
Cc: stable@vger.kernel.org # v3.15+
  • Loading branch information
Ezequiel Garcia authored and Artem Bityutskiy committed Sep 16, 2014
1 parent 3df7707 commit 978d649
Showing 1 changed file with 6 additions and 5 deletions.
11 changes: 6 additions & 5 deletions drivers/mtd/ubi/block.c
Original file line number Diff line number Diff line change
Expand Up @@ -188,8 +188,9 @@ static int ubiblock_read_to_buf(struct ubiblock *dev, char *buffer,

ret = ubi_read(dev->desc, leb, buffer, offset, len);
if (ret) {
ubi_err("%s ubi_read error %d",
dev->gd->disk_name, ret);
ubi_err("%s: error %d while reading from LEB %d (offset %d, "
"length %d)", dev->gd->disk_name, ret, leb, offset,
len);
return ret;
}
return 0;
Expand Down Expand Up @@ -378,7 +379,7 @@ int ubiblock_create(struct ubi_volume_info *vi)
{
struct ubiblock *dev;
struct gendisk *gd;
u64 disk_capacity = ((u64)vi->size * vi->usable_leb_size) >> 9;
u64 disk_capacity = vi->used_bytes >> 9;
int ret;

if ((sector_t)disk_capacity != disk_capacity)
Expand Down Expand Up @@ -502,7 +503,7 @@ int ubiblock_remove(struct ubi_volume_info *vi)
static int ubiblock_resize(struct ubi_volume_info *vi)
{
struct ubiblock *dev;
u64 disk_capacity = ((u64)vi->size * vi->usable_leb_size) >> 9;
u64 disk_capacity = vi->used_bytes >> 9;

/*
* Need to lock the device list until we stop using the device,
Expand All @@ -524,7 +525,7 @@ static int ubiblock_resize(struct ubi_volume_info *vi)

mutex_lock(&dev->dev_mutex);
set_capacity(dev->gd, disk_capacity);
ubi_msg("%s resized to %d LEBs", dev->gd->disk_name, vi->size);
ubi_msg("%s resized to %lld bytes", dev->gd->disk_name, vi->used_bytes);
mutex_unlock(&dev->dev_mutex);
mutex_unlock(&devices_mutex);
return 0;
Expand Down

0 comments on commit 978d649

Please sign in to comment.