Skip to contentSkip to conversation

Make mtdblock can handle partition bigger than 4G.

PATCH In review Lepton Wu 2 participants 2 messages Feb 17, 2017 – Feb 18, 2017 Memory technology devices (MTD)

lore
Share & tools
lore

Lepton Wu

author
#0 lore raw

PATCH 1/1 Make mtdblock can handle partition bigger than 4G.

---
 drivers/mtd/mtdblock.c    | 33 +++++++++++++++++----------------
 drivers/mtd/mtdblock_ro.c |  4 ++--
 2 files changed, 19 insertions(+), 18 deletions(-)
drivers/mtd/mtdblock.c +17 -16
index bb4c14f83c75..3d2da76287a7 100644
@@ -61,8 +61,8 @@ static void erase_callback(struct erase_info *done)
 	wake_up(wait_q);
 }
 
-static int erase_write (struct mtd_info *mtd, unsigned long pos,
-			int len, const char *buf)
+static int erase_write(struct mtd_info *mtd, loff_t pos, int len,
+		       const char *buf)
 {
 	struct erase_info erase;
 	DECLARE_WAITQUEUE(wait, current);
@@ -88,8 +88,7 @@ static int erase_write (struct mtd_info *mtd, unsigned long pos,
 	if (ret) {
 		set_current_state(TASK_RUNNING);
 		remove_wait_queue(&wait_q, &wait);
-		printk (KERN_WARNING "mtdblock: erase of region [0x%lx, 0x%x] "
-				     "on \"%s\" failed\n",
+		pr_warn("mtdblock: erase of region [0x%llx, 0x%x] on \"%s\" failed\n",
 			pos, len, mtd->name);
 		return ret;
 	}
@@ -139,23 +138,24 @@ static int write_cached_data (struct mtdblk_dev *mtdblk)
 }
 
 
-static int do_cached_write (struct mtdblk_dev *mtdblk, unsigned long pos,
-			    int len, const char *buf)
+static int do_cached_write(struct mtdblk_dev *mtdblk, loff_t pos,
+			   int len, const char *buf)
 {
 	struct mtd_info *mtd = mtdblk->mbd.mtd;
 	unsigned int sect_size = mtdblk->cache_size;
 	size_t retlen;
 	int ret;
 
-	pr_debug("mtdblock: write on \"%s\" at 0x%lx, size 0x%x\n",
+	pr_debug("mtdblock: write on \"%s\" at 0x%llx, size 0x%x\n",
 		mtd->name, pos, len);
 
 	if (!sect_size)
 		return mtd_write(mtd, pos, len, &retlen, buf);
 
 	while (len > 0) {
-		unsigned long sect_start = (pos/sect_size)*sect_size;
-		unsigned int offset = pos - sect_start;
+		unsigned int offset;
+		loff_t sect_start =
+			div_u64_rem(pos, sect_size, &offset) * sect_size;
 		unsigned int size = sect_size - offset;
 		if( size > len )
 			size = len;
@@ -209,23 +209,24 @@ static int do_cached_write (struct mtdblk_dev *mtdblk, unsigned long pos,
 }
 
 
-static int do_cached_read (struct mtdblk_dev *mtdblk, unsigned long pos,
-			   int len, char *buf)
+static int do_cached_read(struct mtdblk_dev *mtdblk, loff_t pos,
+			  int len, char *buf)
 {
 	struct mtd_info *mtd = mtdblk->mbd.mtd;
 	unsigned int sect_size = mtdblk->cache_size;
 	size_t retlen;
 	int ret;
 
-	pr_debug("mtdblock: read on \"%s\" at 0x%lx, size 0x%x\n",
+	pr_debug("mtdblock: read on \"%s\" at 0x%llx, size 0x%x\n",
 			mtd->name, pos, len);
 
 	if (!sect_size)
 		return mtd_read(mtd, pos, len, &retlen, buf);
 
 	while (len > 0) {
-		unsigned long sect_start = (pos/sect_size)*sect_size;
-		unsigned int offset = pos - sect_start;
+		unsigned int offset;
+		loff_t sect_start =
+			div_u64_rem(pos, sect_size, &offset) * sect_size;
 		unsigned int size = sect_size - offset;
 		if (size > len)
 			size = len;
@@ -259,7 +260,7 @@ static int mtdblock_readsect(struct mtd_blktrans_dev *dev,
 			      unsigned long block, char *buf)
 {
 	struct mtdblk_dev *mtdblk = container_of(dev, struct mtdblk_dev, mbd);
-	return do_cached_read(mtdblk, block<<9, 512, buf);
+	return do_cached_read(mtdblk, (loff_t)block<<9, 512, buf);
 }
 
 static int mtdblock_writesect(struct mtd_blktrans_dev *dev,
@@ -275,7 +276,7 @@ static int mtdblock_writesect(struct mtd_blktrans_dev *dev,
 		 * return -EAGAIN sometimes, but why bother?
 		 */
 	}
-	return do_cached_write(mtdblk, block<<9, 512, buf);
+	return do_cached_write(mtdblk, (loff_t)block<<9, 512, buf);
 }
 
 static int mtdblock_open(struct mtd_blktrans_dev *mbd)
drivers/mtd/mtdblock_ro.c +2 -2
index fb5dc89369de..92829e3fb3b7 100644
@@ -31,7 +31,7 @@ static int mtdblock_readsect(struct mtd_blktrans_dev *dev,
 {
 	size_t retlen;
 
-	if (mtd_read(dev->mtd, (block * 512), 512, &retlen, buf))
+	if (mtd_read(dev->mtd, (loff_t)block << 9, 512, &retlen, buf))
 		return 1;
 	return 0;
 }
@@ -41,7 +41,7 @@ static int mtdblock_writesect(struct mtd_blktrans_dev *dev,
 {
 	size_t retlen;
 
-	if (mtd_write(dev->mtd, (block * 512), 512, &retlen, buf))
+	if (mtd_write(dev->mtd, (loff_t)block << 9, 512, &retlen, buf))
 		return 1;
 	return 0;
 }
Signature · 1 line
2.11.0.483.g087da7b7c-goog
#1 lore raw

Hi Lepton,

On Fri, 17 Feb 2017 15:37:33 -0800
Lepton Wu <[email protected]> wrote:

Can you please add a commit message and prefix the subject with 'mtd: '. Something like 'mtd: Fix mtdblock for >4GB MTD devices'.

Quoted 68 lines
---
 drivers/mtd/mtdblock.c    | 33 +++++++++++++++++----------------
 drivers/mtd/mtdblock_ro.c |  4 ++--
 2 files changed, 19 insertions(+), 18 deletions(-)
drivers/mtd/mtdblock.c +10 -11
index bb4c14f83c75..3d2da76287a7 100644
@@ -61,8 +61,8 @@ static void erase_callback(struct erase_info *done)
 	wake_up(wait_q);
 }
 
-static int erase_write (struct mtd_info *mtd, unsigned long pos,
-			int len, const char *buf)
+static int erase_write(struct mtd_info *mtd, loff_t pos, int len,
+		       const char *buf)
 {
 	struct erase_info erase;
 	DECLARE_WAITQUEUE(wait, current);
@@ -88,8 +88,7 @@ static int erase_write (struct mtd_info *mtd, unsigned long pos,
 	if (ret) {
 		set_current_state(TASK_RUNNING);
 		remove_wait_queue(&wait_q, &wait);
-		printk (KERN_WARNING "mtdblock: erase of region [0x%lx, 0x%x] "
-				     "on \"%s\" failed\n",
+		pr_warn("mtdblock: erase of region [0x%llx, 0x%x] on \"%s\" failed\n",
 			pos, len, mtd->name);
 		return ret;
 	}
@@ -139,23 +138,24 @@ static int write_cached_data (struct mtdblk_dev *mtdblk)
 }
 
 
-static int do_cached_write (struct mtdblk_dev *mtdblk, unsigned long pos,
-			    int len, const char *buf)
+static int do_cached_write(struct mtdblk_dev *mtdblk, loff_t pos,
+			   int len, const char *buf)
 {
 	struct mtd_info *mtd = mtdblk->mbd.mtd;
 	unsigned int sect_size = mtdblk->cache_size;
 	size_t retlen;
 	int ret;
 
-	pr_debug("mtdblock: write on \"%s\" at 0x%lx, size 0x%x\n",
+	pr_debug("mtdblock: write on \"%s\" at 0x%llx, size 0x%x\n",
 		mtd->name, pos, len);
 
 	if (!sect_size)
 		return mtd_write(mtd, pos, len, &retlen, buf);
 
 	while (len > 0) {
-		unsigned long sect_start = (pos/sect_size)*sect_size;
-		unsigned int offset = pos - sect_start;
+		unsigned int offset;
+		loff_t sect_start =
+			div_u64_rem(pos, sect_size, &offset) * sect_size;
 		unsigned int size = sect_size - offset;
 		if( size > len )
 			size = len;
@@ -209,23 +209,24 @@ static int do_cached_write (struct mtdblk_dev *mtdblk, unsigned long pos,
 }
 
 
-static int do_cached_read (struct mtdblk_dev *mtdblk, unsigned long pos,
-			   int len, char *buf)
+static int do_cached_read(struct mtdblk_dev *mtdblk, loff_t pos,

drivers/mtd/mtdblock.c static int do_cached_write (struct mtdblk_dev *mtdblk, unsigned long pos, · line 221

Quoted 10 lines
drivers/mtd/mtdblock.c +2 -1
+			  int len, char *buf)
 {
 	struct mtd_info *mtd = mtdblk->mbd.mtd;
 	unsigned int sect_size = mtdblk->cache_size;
 	size_t retlen;
 	int ret;
 
-	pr_debug("mtdblock: read on \"%s\" at 0x%lx, size 0x%x\n",
+	pr_debug("mtdblock: read on \"%s\" at 0x%llx, size 0x%x\n",
 			mtd->name, pos, len);

Align the parameters on the open parenthesis.

Quoted 14 lines
drivers/mtd/mtdblock.c +3 -2
 	if (!sect_size)
 		return mtd_read(mtd, pos, len, &retlen, buf);
 
 	while (len > 0) {
-		unsigned long sect_start = (pos/sect_size)*sect_size;
-		unsigned int offset = pos - sect_start;
+		unsigned int offset;
+		loff_t sect_start =
+			div_u64_rem(pos, sect_size, &offset) * sect_size;
 		unsigned int size = sect_size - offset;
 		if (size > len)
 			size = len;

drivers/mtd/mtdblock.c static int mtdblock_readsect(struct mtd_blktrans_dev *dev, · line 263

Quoted 5 lines
drivers/mtd/mtdblock.c +1 -1
@@ -259,7 +260,7 @@ static int mtdblock_readsect(struct mtd_blktrans_dev *dev,
 			      unsigned long block, char *buf)
 {
 	struct mtdblk_dev *mtdblk = container_of(dev, struct mtdblk_dev, mbd);
-	return do_cached_read(mtdblk, block<<9, 512, buf);
+	return do_cached_read(mtdblk, (loff_t)block<<9, 512, buf);
					      ^ block << 9

drivers/mtd/mtdblock.c static int mtdblock_writesect(struct mtd_blktrans_dev *dev, · line 279

Quoted 9 lines
drivers/mtd/mtdblock.c +1 -1
 }
 
 static int mtdblock_writesect(struct mtd_blktrans_dev *dev,
@@ -275,7 +276,7 @@ static int mtdblock_writesect(struct mtd_blktrans_dev *dev,
 		 * return -EAGAIN sometimes, but why bother?
 		 */
 	}
-	return do_cached_write(mtdblk, block<<9, 512, buf);
+	return do_cached_write(mtdblk, (loff_t)block<<9, 512, buf);

Ditto.

Quoted 25 lines
drivers/mtd/mtdblock.c +0 -0
 }
 
 static int mtdblock_open(struct mtd_blktrans_dev *mbd)
drivers/mtd/mtdblock_ro.c +2 -2
index fb5dc89369de..92829e3fb3b7 100644
@@ -31,7 +31,7 @@ static int mtdblock_readsect(struct mtd_blktrans_dev *dev,
 {
 	size_t retlen;
 
-	if (mtd_read(dev->mtd, (block * 512), 512, &retlen, buf))
+	if (mtd_read(dev->mtd, (loff_t)block << 9, 512, &retlen, buf))
 		return 1;
 	return 0;
 }
@@ -41,7 +41,7 @@ static int mtdblock_writesect(struct mtd_blktrans_dev *dev,
 {
 	size_t retlen;
 
-	if (mtd_write(dev->mtd, (block * 512), 512, &retlen, buf))
+	if (mtd_write(dev->mtd, (loff_t)block << 9, 512, &retlen, buf))
 		return 1;
 	return 0;
 }