[v2] mtd: Fix mtdblock for >4GB MTD devices

Message ID 20170222021558.710-1-ytht.net@gmail.com
State New
Headers show

Commit Message

Lepton Wu Feb. 22, 2017, 2:15 a.m.
Change to use loff_t instead of unsigned long in some functions
to make sure mtdblock can handle offset bigger than 4G in 32 bits mode.

Signed-off-by: Lepton Wu <ytht.net@gmail.com>
---
 Changes in v2:
  - Make the commit message more clearer and fix some format issues.

 drivers/mtd/mtdblock.c    | 35 ++++++++++++++++++-----------------
 drivers/mtd/mtdblock_ro.c |  4 ++--
 2 files changed, 20 insertions(+), 19 deletions(-)

Comments

Marek Vasut Feb. 27, 2017, 9:31 a.m. | #1
On 02/22/2017 03:15 AM, Lepton Wu wrote:
> Change to use loff_t instead of unsigned long in some functions
> to make sure mtdblock can handle offset bigger than 4G in 32 bits mode.
> 
> Signed-off-by: Lepton Wu <ytht.net@gmail.com>
> ---
>  Changes in v2:
>   - Make the commit message more clearer and fix some format issues.
> 
>  drivers/mtd/mtdblock.c    | 35 ++++++++++++++++++-----------------
>  drivers/mtd/mtdblock_ro.c |  4 ++--
>  2 files changed, 20 insertions(+), 19 deletions(-)
> 
> diff --git a/drivers/mtd/mtdblock.c b/drivers/mtd/mtdblock.c
> index bb4c14f83c75..373c0edca803 100644
> --- a/drivers/mtd/mtdblock.c
> +++ b/drivers/mtd/mtdblock.c
> @@ -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)

Can the length be 64bit too now ?

[...]
Lepton Wu March 1, 2017, 4:14 a.m. | #2
If checking some calling side,  the len is from cache_size of struct
mtdblk_dev, it's defined as unsigned int now. So it's not 64bit yet.

BTW, seems it's just block size (512) at some other calling side.

(Sorry for previous same content email, just found out it's html
format and rejected by mail list)

On Mon, Feb 27, 2017 at 1:31 AM, Marek Vasut <marek.vasut@gmail.com> wrote:
> On 02/22/2017 03:15 AM, Lepton Wu wrote:
>> Change to use loff_t instead of unsigned long in some functions
>> to make sure mtdblock can handle offset bigger than 4G in 32 bits mode.
>>
>> Signed-off-by: Lepton Wu <ytht.net@gmail.com>
>> ---
>>  Changes in v2:
>>   - Make the commit message more clearer and fix some format issues.
>>
>>  drivers/mtd/mtdblock.c    | 35 ++++++++++++++++++-----------------
>>  drivers/mtd/mtdblock_ro.c |  4 ++--
>>  2 files changed, 20 insertions(+), 19 deletions(-)
>>
>> diff --git a/drivers/mtd/mtdblock.c b/drivers/mtd/mtdblock.c
>> index bb4c14f83c75..373c0edca803 100644
>> --- a/drivers/mtd/mtdblock.c
>> +++ b/drivers/mtd/mtdblock.c
>> @@ -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)
>
> Can the length be 64bit too now ?
>
> [...]
>
> --
> Best regards,
> Marek Vasut
Marek Vasut March 13, 2017, 5:07 a.m. | #3
On 03/01/2017 05:14 AM, lepton wrote:
> If checking some calling side,  the len is from cache_size of struct
> mtdblk_dev, it's defined as unsigned int now. So it's not 64bit yet.

Ummm ... since you're top-posting, I have no clue which part do you
refer to , sorry.

> BTW, seems it's just block size (512) at some other calling side.
> 
> (Sorry for previous same content email, just found out it's html
> format and rejected by mail list)
> 
> On Mon, Feb 27, 2017 at 1:31 AM, Marek Vasut <marek.vasut@gmail.com> wrote:
>> On 02/22/2017 03:15 AM, Lepton Wu wrote:
>>> Change to use loff_t instead of unsigned long in some functions
>>> to make sure mtdblock can handle offset bigger than 4G in 32 bits mode.
>>>
>>> Signed-off-by: Lepton Wu <ytht.net@gmail.com>
>>> ---
>>>  Changes in v2:
>>>   - Make the commit message more clearer and fix some format issues.
>>>
>>>  drivers/mtd/mtdblock.c    | 35 ++++++++++++++++++-----------------
>>>  drivers/mtd/mtdblock_ro.c |  4 ++--
>>>  2 files changed, 20 insertions(+), 19 deletions(-)
>>>
>>> diff --git a/drivers/mtd/mtdblock.c b/drivers/mtd/mtdblock.c
>>> index bb4c14f83c75..373c0edca803 100644
>>> --- a/drivers/mtd/mtdblock.c
>>> +++ b/drivers/mtd/mtdblock.c
>>> @@ -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)
>>
>> Can the length be 64bit too now ?
>>
>> [...]
>>
>> --
>> Best regards,
>> Marek Vasut

Patch

diff --git a/drivers/mtd/mtdblock.c b/drivers/mtd/mtdblock.c
index bb4c14f83c75..373c0edca803 100644
--- a/drivers/mtd/mtdblock.c
+++ b/drivers/mtd/mtdblock.c
@@ -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",
-			mtd->name, pos, len);
+	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)
diff --git a/drivers/mtd/mtdblock_ro.c b/drivers/mtd/mtdblock_ro.c
index fb5dc89369de..92829e3fb3b7 100644
--- a/drivers/mtd/mtdblock_ro.c
+++ b/drivers/mtd/mtdblock_ro.c
@@ -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;
 }