summary refs log tree commit diff
path: root/drivers/mtd
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-08-13 17:42:11 -0600
committerLinus Torvalds <torvalds@linux-foundation.org>2014-08-13 17:42:11 -0600
commit89838b80bbbf9774cf010905851db7913c9331f0 (patch)
tree4d47f408fc90c2f575f5741093fdf34dc9f74b1e /drivers/mtd
parentf6f993328b2abcab86a3c99d7bd9f2066ab03d36 (diff)
parent25601a3c9737fed554169759582c690b98ead5d4 (diff)
downloadlinux-89838b80bbbf9774cf010905851db7913c9331f0.tar.gz
Merge tag 'upstream-3.17-rc1' of git://git.infradead.org/linux-ubifs
Pull UBI/UBIFS changes from Artem Bityutskiy:
 "No significant changes, mostly small fixes here and there.  The more
  important fixes are:

   - UBI deleted list items while iterating the list with
     'list_for_each_entry'
   - The UBI block driver did not work properly with very large UBI
     volumes"

* tag 'upstream-3.17-rc1' of git://git.infradead.org/linux-ubifs: (21 commits)
  UBIFS: Add log overlap assertions
  Revert "UBIFS: add a log overlap assertion"
  UBI: bugfix in ubi_wl_flush()
  UBI: block: Avoid disk size integer overflow
  UBI: block: Set disk_capacity out of the mutex
  UBI: block: Make ubiblock_resize return something
  UBIFS: add a log overlap assertion
  UBIFS: remove unnecessary check
  UBIFS: remove mst_mutex
  UBIFS: kernel-doc warning fix
  UBI: init_volumes: Ignore volumes with no LEBs
  UBIFS: replace seq_printf by seq_puts
  UBIFS: replace count*size kzalloc by kcalloc
  UBIFS: kernel-doc warning fix
  UBIFS: fix error path in create_default_filesystem()
  UBIFS: fix spelling of "scanned"
  UBIFS: fix some comments
  UBIFS: remove useless @ecc in struct ubifs_scan_leb
  UBIFS: remove useless statements
  UBIFS: Add missing break statements in dbg_chk_pnode()
  ...
Diffstat (limited to 'drivers/mtd')
-rw-r--r--drivers/mtd/ubi/block.c18
-rw-r--r--drivers/mtd/ubi/vtbl.c2
-rw-r--r--drivers/mtd/ubi/wl.c4
3 files changed, 15 insertions, 9 deletions
diff --git a/drivers/mtd/ubi/block.c b/drivers/mtd/ubi/block.c
index 8457df7ec5af..33c64955d4d7 100644
--- a/drivers/mtd/ubi/block.c
+++ b/drivers/mtd/ubi/block.c
@@ -378,9 +378,11 @@ int ubiblock_create(struct ubi_volume_info *vi)
 {
 	struct ubiblock *dev;
 	struct gendisk *gd;
-	int disk_capacity;
+	u64 disk_capacity = ((u64)vi->size * vi->usable_leb_size) >> 9;
 	int ret;
 
+	if ((sector_t)disk_capacity != disk_capacity)
+		return -EFBIG;
 	/* Check that the volume isn't already handled */
 	mutex_lock(&devices_mutex);
 	if (find_dev_nolock(vi->ubi_num, vi->vol_id)) {
@@ -412,7 +414,6 @@ int ubiblock_create(struct ubi_volume_info *vi)
 	gd->first_minor = dev->ubi_num * UBI_MAX_VOLUMES + dev->vol_id;
 	gd->private_data = dev;
 	sprintf(gd->disk_name, "ubiblock%d_%d", dev->ubi_num, dev->vol_id);
-	disk_capacity = (vi->size * vi->usable_leb_size) >> 9;
 	set_capacity(gd, disk_capacity);
 	dev->gd = gd;
 
@@ -498,11 +499,16 @@ int ubiblock_remove(struct ubi_volume_info *vi)
 	return 0;
 }
 
-static void ubiblock_resize(struct ubi_volume_info *vi)
+static int ubiblock_resize(struct ubi_volume_info *vi)
 {
 	struct ubiblock *dev;
-	int disk_capacity;
+	u64 disk_capacity = ((u64)vi->size * vi->usable_leb_size) >> 9;
 
+	if ((sector_t)disk_capacity != disk_capacity) {
+		ubi_warn("%s: the volume is too big, cannot resize (%d LEBs)",
+			 dev->gd->disk_name, vi->size);
+		return -EFBIG;
+	}
 	/*
 	 * Need to lock the device list until we stop using the device,
 	 * otherwise the device struct might get released in
@@ -512,15 +518,15 @@ static void ubiblock_resize(struct ubi_volume_info *vi)
 	dev = find_dev_nolock(vi->ubi_num, vi->vol_id);
 	if (!dev) {
 		mutex_unlock(&devices_mutex);
-		return;
+		return -ENODEV;
 	}
 
 	mutex_lock(&dev->dev_mutex);
-	disk_capacity = (vi->size * vi->usable_leb_size) >> 9;
 	set_capacity(dev->gd, disk_capacity);
 	ubi_msg("%s resized to %d LEBs", dev->gd->disk_name, vi->size);
 	mutex_unlock(&dev->dev_mutex);
 	mutex_unlock(&devices_mutex);
+	return 0;
 }
 
 static int ubiblock_notify(struct notifier_block *nb,
diff --git a/drivers/mtd/ubi/vtbl.c b/drivers/mtd/ubi/vtbl.c
index d77b1c1d7c72..07cac5f9ffb8 100644
--- a/drivers/mtd/ubi/vtbl.c
+++ b/drivers/mtd/ubi/vtbl.c
@@ -591,7 +591,7 @@ static int init_volumes(struct ubi_device *ubi,
 
 		/* Static volumes only */
 		av = ubi_find_av(ai, i);
-		if (!av) {
+		if (!av || !av->leb_count) {
 			/*
 			 * No eraseblocks belonging to this volume found. We
 			 * don't actually know whether this static volume is
diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c
index 0f3425dac910..20f491713145 100644
--- a/drivers/mtd/ubi/wl.c
+++ b/drivers/mtd/ubi/wl.c
@@ -1718,12 +1718,12 @@ int ubi_wl_flush(struct ubi_device *ubi, int vol_id, int lnum)
 	       vol_id, lnum, ubi->works_count);
 
 	while (found) {
-		struct ubi_work *wrk;
+		struct ubi_work *wrk, *tmp;
 		found = 0;
 
 		down_read(&ubi->work_sem);
 		spin_lock(&ubi->wl_lock);
-		list_for_each_entry(wrk, &ubi->works, list) {
+		list_for_each_entry_safe(wrk, tmp, &ubi->works, list) {
 			if ((vol_id == UBI_ALL || wrk->vol_id == vol_id) &&
 			    (lnum == UBI_ALL || wrk->lnum == lnum)) {
 				list_del(&wrk->list);