aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd/ubi/block.c
diff options
context:
space:
mode:
authorEzequiel Garcia <ezequiel.garcia@free-electrons.com>2014-08-29 17:42:28 -0400
committerArtem Bityutskiy <artem.bityutskiy@linux.intel.com>2014-09-16 12:02:04 -0400
commit978d6496758d19de2431ebf163337fc7b92f8c45 (patch)
treed76c5d973218365a957a174979d2cb8e14e2c0ef /drivers/mtd/ubi/block.c
parent3df770725339c41d1cd9be4da4ca0d968119d8ad (diff)
UBI: block: Fix block device size setting
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: 9d54c8a33eec ("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+
Diffstat (limited to 'drivers/mtd/ubi/block.c')
-rw-r--r--drivers/mtd/ubi/block.c11
1 files changed, 6 insertions, 5 deletions
diff --git a/drivers/mtd/ubi/block.c b/drivers/mtd/ubi/block.c
index 518792b7634d..581784485376 100644
--- a/drivers/mtd/ubi/block.c
+++ b/drivers/mtd/ubi/block.c
@@ -188,8 +188,9 @@ static int ubiblock_read_to_buf(struct ubiblock *dev, char *buffer,
188 188
189 ret = ubi_read(dev->desc, leb, buffer, offset, len); 189 ret = ubi_read(dev->desc, leb, buffer, offset, len);
190 if (ret) { 190 if (ret) {
191 ubi_err("%s ubi_read error %d", 191 ubi_err("%s: error %d while reading from LEB %d (offset %d, "
192 dev->gd->disk_name, ret); 192 "length %d)", dev->gd->disk_name, ret, leb, offset,
193 len);
193 return ret; 194 return ret;
194 } 195 }
195 return 0; 196 return 0;
@@ -378,7 +379,7 @@ int ubiblock_create(struct ubi_volume_info *vi)
378{ 379{
379 struct ubiblock *dev; 380 struct ubiblock *dev;
380 struct gendisk *gd; 381 struct gendisk *gd;
381 u64 disk_capacity = ((u64)vi->size * vi->usable_leb_size) >> 9; 382 u64 disk_capacity = vi->used_bytes >> 9;
382 int ret; 383 int ret;
383 384
384 if ((sector_t)disk_capacity != disk_capacity) 385 if ((sector_t)disk_capacity != disk_capacity)
@@ -502,7 +503,7 @@ int ubiblock_remove(struct ubi_volume_info *vi)
502static int ubiblock_resize(struct ubi_volume_info *vi) 503static int ubiblock_resize(struct ubi_volume_info *vi)
503{ 504{
504 struct ubiblock *dev; 505 struct ubiblock *dev;
505 u64 disk_capacity = ((u64)vi->size * vi->usable_leb_size) >> 9; 506 u64 disk_capacity = vi->used_bytes >> 9;
506 507
507 /* 508 /*
508 * Need to lock the device list until we stop using the device, 509 * Need to lock the device list until we stop using the device,
@@ -524,7 +525,7 @@ static int ubiblock_resize(struct ubi_volume_info *vi)
524 525
525 mutex_lock(&dev->dev_mutex); 526 mutex_lock(&dev->dev_mutex);
526 set_capacity(dev->gd, disk_capacity); 527 set_capacity(dev->gd, disk_capacity);
527 ubi_msg("%s resized to %d LEBs", dev->gd->disk_name, vi->size); 528 ubi_msg("%s resized to %lld bytes", dev->gd->disk_name, vi->used_bytes);
528 mutex_unlock(&dev->dev_mutex); 529 mutex_unlock(&dev->dev_mutex);
529 mutex_unlock(&devices_mutex); 530 mutex_unlock(&devices_mutex);
530 return 0; 531 return 0;