All of lore.kernel.org
 help / color / mirror / Atom feed
* [U-Boot] [PATCH] LaCie kirkwood boards: allow disk > 2TB
@ 2013-06-10 13:30 Frederic Leroy
  2013-06-10 13:44 ` Simon Guinot
  2013-06-13 11:33 ` Albert ARIBAUD
  0 siblings, 2 replies; 24+ messages in thread
From: Frederic Leroy @ 2013-06-10 13:30 UTC (permalink / raw)
  To: u-boot

From: Fr?d?ric Leroy <fredo@starox.org>

For big disk support, we need LBA addressing on 64 bits
---
 include/configs/lacie_kw.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/include/configs/lacie_kw.h b/include/configs/lacie_kw.h
index 09b5798..847afcd 100644
--- a/include/configs/lacie_kw.h
+++ b/include/configs/lacie_kw.h
@@ -111,6 +111,7 @@
 #define CONFIG_ENV_SPI_MAX_HZ           20000000 /* 20Mhz */
 #define CONFIG_SYS_IDE_MAXBUS           1
 #define CONFIG_SYS_IDE_MAXDEVICE        1
+#define CONFIG_SYS_64BIT_LBA /* Allow disk > 2.1TB */
 #if defined(CONFIG_D2NET_V2)
 #define CONFIG_SYS_PROMPT		"d2v2> "
 #elif defined(CONFIG_NET2BIG_V2)
-- 
1.8.1.2

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [U-Boot] [PATCH] LaCie kirkwood boards: allow disk > 2TB
  2013-06-10 13:30 [U-Boot] [PATCH] LaCie kirkwood boards: allow disk > 2TB Frederic Leroy
@ 2013-06-10 13:44 ` Simon Guinot
  2013-06-10 14:20   ` Frédéric Leroy
  2013-06-13 11:33 ` Albert ARIBAUD
  1 sibling, 1 reply; 24+ messages in thread
From: Simon Guinot @ 2013-06-10 13:44 UTC (permalink / raw)
  To: u-boot

On Mon, Jun 10, 2013 at 03:30:53PM +0200, Frederic Leroy wrote:
> From: Fr?d?ric Leroy <fredo@starox.org>
> 
> For big disk support, we need LBA addressing on 64 bits
> ---
>  include/configs/lacie_kw.h | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/include/configs/lacie_kw.h b/include/configs/lacie_kw.h
> index 09b5798..847afcd 100644
> --- a/include/configs/lacie_kw.h
> +++ b/include/configs/lacie_kw.h
> @@ -111,6 +111,7 @@
>  #define CONFIG_ENV_SPI_MAX_HZ           20000000 /* 20Mhz */
>  #define CONFIG_SYS_IDE_MAXBUS           1
>  #define CONFIG_SYS_IDE_MAXDEVICE        1
> +#define CONFIG_SYS_64BIT_LBA /* Allow disk > 2.1TB */

Hi Frederic,

I see a comment at disk/part_efi.c:25. It claims that maximum size of
addressable storage is limited to 2TB even with CONFIG_SYS_64BIT_LBA
enabled. Is that not true anymore ?

Regards,

Simon

>  #if defined(CONFIG_D2NET_V2)
>  #define CONFIG_SYS_PROMPT		"d2v2> "
>  #elif defined(CONFIG_NET2BIG_V2)
> -- 
> 1.8.1.2
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: Digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20130610/3fde4311/attachment.pgp>

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [U-Boot] [PATCH] LaCie kirkwood boards: allow disk > 2TB
  2013-06-10 13:44 ` Simon Guinot
@ 2013-06-10 14:20   ` Frédéric Leroy
  2013-06-10 14:29     ` Simon Guinot
  0 siblings, 1 reply; 24+ messages in thread
From: Frédéric Leroy @ 2013-06-10 14:20 UTC (permalink / raw)
  To: u-boot


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Le 10/06/2013 15:44, Simon Guinot a ?crit :
> On Mon, Jun 10, 2013 at 03:30:53PM +0200, Frederic Leroy wrote:
> > From: Fr?d?ric Leroy <fredo@starox.org>
> >
> > For big disk support, we need LBA addressing on 64 bits
> > ---
> >  include/configs/lacie_kw.h | 1 +
> >  1 file changed, 1 insertion(+)
> >
> > diff --git a/include/configs/lacie_kw.h b/include/configs/lacie_kw.h
> > index 09b5798..847afcd 100644
> > --- a/include/configs/lacie_kw.h
> > +++ b/include/configs/lacie_kw.h
> > @@ -111,6 +111,7 @@
> >  #define CONFIG_ENV_SPI_MAX_HZ           20000000 /* 20Mhz */
> >  #define CONFIG_SYS_IDE_MAXBUS           1
> >  #define CONFIG_SYS_IDE_MAXDEVICE        1
> > +#define CONFIG_SYS_64BIT_LBA /* Allow disk > 2.1TB */
>
> Hi Frederic,
>
> I see a comment at disk/part_efi.c:25. It claims that maximum size of
> addressable storage is limited to 2TB even with CONFIG_SYS_64BIT_LBA
> enabled. Is that not true anymore ?
I didn't see this comment.
With my patch, the "ide reset" command recognize nicely a 3TB harddrive.
Else, it reports the size % 2TB and then u-boot reports error in the GPT.

I can read the GPT and boot from a loaded file from the first partition.
However, an "ext2ls" on a partition at the end of the disk outputs garbage.

At least, the patch allow to use the first 2 TB for booting.

Regards,

- -- 
Fr?d?ric
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.12 (GNU/Linux)
Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/

iQGcBAEBAgAGBQJRteDBAAoJEJVX96CfzRSe7CsMAJF7A6b29E4jTH9p2uBSLYDZ
Rg1Oeag0J9UI44LKfhAjexfDP0I0gF8B+IB4ZQ1VZiKeNL3Udocy+J57KBzoefi1
SY39c8uw8qWszxJqxdZ0n+MGNMRL3cKsOaNtG5Jf81knohl5OVjmiscdzy/0MNB/
+zPB3tsydAjPnR1B8J655jqXlcH0Cd23BX7cJoufnJN6jfaiPdBsurobIfKkLwrO
Pd1WLxcaZN+GwqRnYJkB6Y4yuYZwfLelhBkqUDVJy/dF38YBHzjHUmq1YUdS7ret
flMexv1UrqWO6QCVQ95e3nTFmRkH2Dqyi8JkyfMHFzuhOzidRtSYSxVS9ArqdRA8
7fHRshEA6FY62tiQ4aMZ9vj0tq3Vjy0QZKkOfpwUw338oVHyeCdpVJR3O4vkzzqh
NGIjA+fmJMTWT69J7Is53ZmheoSK0Ih/LEvyMYXyzSJsq+qodKqYsDwYfaHsVbjK
ti9yaCwozotaJoauB2bXWM8AjJfnE8Y2U0/AHOjX6g==
=Nisn
-----END PGP SIGNATURE-----

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [U-Boot] [PATCH] LaCie kirkwood boards: allow disk > 2TB
  2013-06-10 14:20   ` Frédéric Leroy
@ 2013-06-10 14:29     ` Simon Guinot
  2013-06-10 14:48       ` Albert ARIBAUD
  0 siblings, 1 reply; 24+ messages in thread
From: Simon Guinot @ 2013-06-10 14:29 UTC (permalink / raw)
  To: u-boot

On Mon, Jun 10, 2013 at 04:20:49PM +0200, Fr?d?ric Leroy wrote:
> 
> Le 10/06/2013 15:44, Simon Guinot a ?crit :
> > On Mon, Jun 10, 2013 at 03:30:53PM +0200, Frederic Leroy wrote:
> > > From: Fr?d?ric Leroy <fredo@starox.org>
> > >
> > > For big disk support, we need LBA addressing on 64 bits
> > > ---
> > >  include/configs/lacie_kw.h | 1 +
> > >  1 file changed, 1 insertion(+)
> > >
> > > diff --git a/include/configs/lacie_kw.h b/include/configs/lacie_kw.h
> > > index 09b5798..847afcd 100644
> > > --- a/include/configs/lacie_kw.h
> > > +++ b/include/configs/lacie_kw.h
> > > @@ -111,6 +111,7 @@
> > >  #define CONFIG_ENV_SPI_MAX_HZ           20000000 /* 20Mhz */
> > >  #define CONFIG_SYS_IDE_MAXBUS           1
> > >  #define CONFIG_SYS_IDE_MAXDEVICE        1
> > > +#define CONFIG_SYS_64BIT_LBA /* Allow disk > 2.1TB */
> >
> > Hi Frederic,
> >
> > I see a comment at disk/part_efi.c:25. It claims that maximum size of
> > addressable storage is limited to 2TB even with CONFIG_SYS_64BIT_LBA
> > enabled. Is that not true anymore ?
> I didn't see this comment.
> With my patch, the "ide reset" command recognize nicely a 3TB harddrive.
> Else, it reports the size % 2TB and then u-boot reports error in the GPT.
> 
> I can read the GPT and boot from a loaded file from the first partition.
> However, an "ext2ls" on a partition at the end of the disk outputs garbage.
> 
> At least, the patch allow to use the first 2 TB for booting.

Acked-by: Simon Guinot <simon.guinot@sequanux.org>

I add Prafulla to the Cc recipient. He is the one who will pick your
patch eventually.

Regards,

Simon
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: Digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20130610/09454864/attachment.pgp>

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [U-Boot] [PATCH] LaCie kirkwood boards: allow disk > 2TB
  2013-06-10 14:29     ` Simon Guinot
@ 2013-06-10 14:48       ` Albert ARIBAUD
  0 siblings, 0 replies; 24+ messages in thread
From: Albert ARIBAUD @ 2013-06-10 14:48 UTC (permalink / raw)
  To: u-boot

Hi Simon,

On Mon, 10 Jun 2013 16:29:26 +0200, Simon Guinot
<simon.guinot@sequanux.org> wrote:

> On Mon, Jun 10, 2013 at 04:20:49PM +0200, Fr?d?ric Leroy wrote:
> > 
> > Le 10/06/2013 15:44, Simon Guinot a ?crit :
> > > On Mon, Jun 10, 2013 at 03:30:53PM +0200, Frederic Leroy wrote:
> > > > From: Fr?d?ric Leroy <fredo@starox.org>
> > > >
> > > > For big disk support, we need LBA addressing on 64 bits
> > > > ---
> > > >  include/configs/lacie_kw.h | 1 +
> > > >  1 file changed, 1 insertion(+)
> > > >
> > > > diff --git a/include/configs/lacie_kw.h b/include/configs/lacie_kw.h
> > > > index 09b5798..847afcd 100644
> > > > --- a/include/configs/lacie_kw.h
> > > > +++ b/include/configs/lacie_kw.h
> > > > @@ -111,6 +111,7 @@
> > > >  #define CONFIG_ENV_SPI_MAX_HZ           20000000 /* 20Mhz */
> > > >  #define CONFIG_SYS_IDE_MAXBUS           1
> > > >  #define CONFIG_SYS_IDE_MAXDEVICE        1
> > > > +#define CONFIG_SYS_64BIT_LBA /* Allow disk > 2.1TB */
> > >
> > > Hi Frederic,
> > >
> > > I see a comment at disk/part_efi.c:25. It claims that maximum size of
> > > addressable storage is limited to 2TB even with CONFIG_SYS_64BIT_LBA
> > > enabled. Is that not true anymore ?
> > I didn't see this comment.
> > With my patch, the "ide reset" command recognize nicely a 3TB harddrive.
> > Else, it reports the size % 2TB and then u-boot reports error in the GPT.
> > 
> > I can read the GPT and boot from a loaded file from the first partition.
> > However, an "ext2ls" on a partition at the end of the disk outputs garbage.
> > 
> > At least, the patch allow to use the first 2 TB for booting.
> 
> Acked-by: Simon Guinot <simon.guinot@sequanux.org>
> 
> I add Prafulla to the Cc recipient. He is the one who will pick your
> patch eventually.

Not necessarily, as this is only a target configuration change, not a
SoC change -- actually, nothing in the patch is related to Marvell SoCs.
This patch could go directly in mainline even, but usually I do the
picking up if it's an ARM target.

> Regards,
> 
> Simon

Amicalement,
-- 
Albert.

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [U-Boot] [PATCH] LaCie kirkwood boards: allow disk > 2TB
  2013-06-10 13:30 [U-Boot] [PATCH] LaCie kirkwood boards: allow disk > 2TB Frederic Leroy
  2013-06-10 13:44 ` Simon Guinot
@ 2013-06-13 11:33 ` Albert ARIBAUD
  2013-06-13 13:03   ` Frédéric Leroy
  1 sibling, 1 reply; 24+ messages in thread
From: Albert ARIBAUD @ 2013-06-13 11:33 UTC (permalink / raw)
  To: u-boot

Hi Frederic,

On Mon, 10 Jun 2013 15:30:53 +0200, Frederic Leroy <fredo@starox.org>
wrote:

> From: Fr?d?ric Leroy <fredo@starox.org>
> 
> For big disk support, we need LBA addressing on 64 bits
> ---
>  include/configs/lacie_kw.h | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/include/configs/lacie_kw.h b/include/configs/lacie_kw.h
> index 09b5798..847afcd 100644
> --- a/include/configs/lacie_kw.h
> +++ b/include/configs/lacie_kw.h
> @@ -111,6 +111,7 @@
>  #define CONFIG_ENV_SPI_MAX_HZ           20000000 /* 20Mhz */
>  #define CONFIG_SYS_IDE_MAXBUS           1
>  #define CONFIG_SYS_IDE_MAXDEVICE        1
> +#define CONFIG_SYS_64BIT_LBA /* Allow disk > 2.1TB */
>  #if defined(CONFIG_D2NET_V2)
>  #define CONFIG_SYS_PROMPT		"d2v2> "
>  #elif defined(CONFIG_NET2BIG_V2)

With gcc version 4.7.2 (Ubuntu/Linaro 4.7.2-2ubuntu1) this patch causes
the following warning for all boards:

cmd_ide.c:992:4: warning: right shift count >= width of type [enabled
by default]

Amicalement,
-- 
Albert.

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [U-Boot] [PATCH] LaCie kirkwood boards: allow disk > 2TB
  2013-06-13 11:33 ` Albert ARIBAUD
@ 2013-06-13 13:03   ` Frédéric Leroy
  2013-06-13 13:21     ` Albert ARIBAUD
  2013-06-13 20:32     ` Sascha Silbe
  0 siblings, 2 replies; 24+ messages in thread
From: Frédéric Leroy @ 2013-06-13 13:03 UTC (permalink / raw)
  To: u-boot

Le 13/06/2013 13:33, Albert ARIBAUD a ?crit :
> With gcc version 4.7.2 (Ubuntu/Linaro 4.7.2-2ubuntu1) this patch causes
> the following warning for all boards:
>
> cmd_ide.c:992:4: warning: right shift count >= width of type [enabled
> by default]
>
> Amicalement,

I will  convert every ide block number to 64 bit for disk and partitions.
I guess CONFIG_LBA48 is also broken in common/cmd_ide.c :

ulong ide_write(int device, ulong blknr, lbaint_t blkcnt, const void
*buffer)
{
    ulong n = 0;
    unsigned char c;

#ifdef CONFIG_LBA48
    unsigned char lba48 = 0;

    if (blknr & 0x0000fffff0000000ULL) {                          <= issue
        /* more than 28 bits used, use 48bit mode */
        lba48 = 1;
    }
#endif

I hope this won't break anything, it is a big change impacting everybody :(

Sinc?rement,

-- 
Fr?d?ric

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [U-Boot] [PATCH] LaCie kirkwood boards: allow disk > 2TB
  2013-06-13 13:03   ` Frédéric Leroy
@ 2013-06-13 13:21     ` Albert ARIBAUD
  2013-06-13 13:36       ` Frédéric Leroy
  2013-06-13 20:32     ` Sascha Silbe
  1 sibling, 1 reply; 24+ messages in thread
From: Albert ARIBAUD @ 2013-06-13 13:21 UTC (permalink / raw)
  To: u-boot

Hi Fr?d?ric,

On Thu, 13 Jun 2013 15:03:49 +0200, Fr?d?ric Leroy <fredo@starox.org>
wrote:

> Le 13/06/2013 13:33, Albert ARIBAUD a ?crit :
> > With gcc version 4.7.2 (Ubuntu/Linaro 4.7.2-2ubuntu1) this patch causes
> > the following warning for all boards:
> >
> > cmd_ide.c:992:4: warning: right shift count >= width of type [enabled
> > by default]
> >
> > Amicalement,
> 
> I will  convert every ide block number to 64 bit for disk and partitions.

Be careful that some struct fields representing sector / block number
might be 32-bit for an external reason, e.g. in partition tables.

> I guess CONFIG_LBA48 is also broken in common/cmd_ide.c :
> 
> ulong ide_write(int device, ulong blknr, lbaint_t blkcnt, const void
> *buffer)
> {
>     ulong n = 0;
>     unsigned char c;
> 
> #ifdef CONFIG_LBA48
>     unsigned char lba48 = 0;
> 
>     if (blknr & 0x0000fffff0000000ULL) {                          <= issue
>         /* more than 28 bits used, use 48bit mode */
>         lba48 = 1;
>     }
> #endif

How is this broken exactly, and what is the fix?

> I hope this won't break anything, it is a big change impacting everybody :(

It would affect everybody but within a well-delimited feature, which is
disk access. Tests on a few targets with disks of various sizes should
be enough.

> Sinc?rement,

Amicalement,
-- 
Albert.

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [U-Boot] [PATCH] LaCie kirkwood boards: allow disk > 2TB
  2013-06-13 13:21     ` Albert ARIBAUD
@ 2013-06-13 13:36       ` Frédéric Leroy
  0 siblings, 0 replies; 24+ messages in thread
From: Frédéric Leroy @ 2013-06-13 13:36 UTC (permalink / raw)
  To: u-boot

Le 13/06/2013 15:21, Albert ARIBAUD a ?crit :

> > I guess CONFIG_LBA48 is also broken in common/cmd_ide.c :
> > 
> > ulong ide_write(int device, ulong blknr, lbaint_t blkcnt, const void
> > *buffer)
> > {
> >     ulong n = 0;
> >     unsigned char c;
> > 
> > #ifdef CONFIG_LBA48
> >     unsigned char lba48 = 0;
> > 
> >     if (blknr & 0x0000fffff0000000ULL) {                          <= issue
> >         /* more than 28 bits used, use 48bit mode */
> >         lba48 = 1;
> >     }
> > #endif
>
> How is this broken exactly, and what is the fix?

If you have a device with 0x100000000 blocks and a target architecture
with sizeof(ulong)=32, then it will fail to switch to lba48.
The right thing to do is to use lbaint_t instead of ulong blknr.

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [U-Boot] [PATCH] LaCie kirkwood boards: allow disk > 2TB
  2013-06-13 13:03   ` Frédéric Leroy
  2013-06-13 13:21     ` Albert ARIBAUD
@ 2013-06-13 20:32     ` Sascha Silbe
  2013-06-14 11:07       ` [U-Boot] [PATCH] Fix block device accesses beyond 2TiB Sascha Silbe
  1 sibling, 1 reply; 24+ messages in thread
From: Sascha Silbe @ 2013-06-13 20:32 UTC (permalink / raw)
  To: u-boot

Fr?d?ric Leroy <fredo@starox.org> writes:

> I will  convert every ide block number to 64 bit for disk and partitions.
> I guess CONFIG_LBA48 is also broken in common/cmd_ide.c :

FWIW, I have a patch pending for this already. But it's necessarily
pretty invasive and I'm not even sure yet that I've found all places
that need to be adapted. It works fine on CuBox Pro and builds without
warnings for all ARM boards and sandbox (or at least MAKEALL succeeds
with -Werror added to a few places).

Not sure whether I'll get around to working on it this weekend, but I'll
try to at least post the patch tomorrow so others can test it.

Sascha
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 489 bytes
Desc: not available
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20130613/b53c9747/attachment.pgp>

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [U-Boot] [PATCH] Fix block device accesses beyond 2TiB
  2013-06-13 20:32     ` Sascha Silbe
@ 2013-06-14 11:07       ` Sascha Silbe
  2013-06-17 20:26         ` Marek Vasut
  2013-06-26 20:25         ` [U-Boot] Fix block device " Tom Rini
  0 siblings, 2 replies; 24+ messages in thread
From: Sascha Silbe @ 2013-06-14 11:07 UTC (permalink / raw)
  To: u-boot

With CONFIG_SYS_64BIT_LBA, lbaint_t gets defined as a 64-bit type,
which is required to represent block numbers for storage devices that
exceed 2TiB (the block size usually is 512B), e.g. recent hard drives.

For some obscure reason, the current U-Boot code uses lbaint_t for the
number of blocks to read (a rather optimistic estimation of how RAM
sizes will evolve), but not for the starting address. Trying to access
blocks beyond the 2TiB boundary will simply wrap around and read a
block within the 0..2TiB range.

We now use lbaint_t for block start addresses, too. This required
changes to all block drivers as the signature of block_read(),
block_write() and block_erase() in block_dev_desc_t changed.

Signed-off-by: Sascha Silbe <t-uboot@infra-silbe.de>
---
Functionality tested on CuBox Pro with a Western Digital WD30EFRX hard
disk (3TB). Build tested for all arm boards and sandbox.

Testing on other boards and architectures would be appreciated.

Fixes for typos, style errors etc. are explicitly out of scope for
this patch, even those checkpatch complains about because they appear
on or near lines touched by the patch. They are unrelated to the issue
at hand and can be fixed up later. Mixing in unrelated changes would
just make harder to revert any problematic change.

 common/cmd_ide.c     | 14 +++++++-------
 common/usb_storage.c |  8 ++++----
 drivers/mmc/mmc.c    | 17 +++++++++--------
 include/ide.h        |  5 +++--
 include/part.h       |  6 +++---
 5 files changed, 26 insertions(+), 24 deletions(-)

diff --git a/common/cmd_ide.c b/common/cmd_ide.c
index 78b4aa7..59e95df 100644
--- a/common/cmd_ide.c
+++ b/common/cmd_ide.c
@@ -830,7 +830,7 @@ static void ide_ident(block_dev_desc_t *dev_desc)
 
 /* ------------------------------------------------------------------------- */
 
-ulong ide_read(int device, ulong blknr, lbaint_t blkcnt, void *buffer)
+ulong ide_read(int device, lbaint_t blknr, lbaint_t blkcnt, void *buffer)
 {
 	ulong n = 0;
 	unsigned char c;
@@ -844,7 +844,7 @@ ulong ide_read(int device, ulong blknr, lbaint_t blkcnt, void *buffer)
 		lba48 = 1;
 	}
 #endif
-	debug("ide_read dev %d start %lX, blocks " LBAF " buffer at %lX\n",
+	debug("ide_read dev %d start " LBAF ", blocks " LBAF " buffer at %lX\n",
 	      device, blknr, blkcnt, (ulong) buffer);
 
 	ide_led(DEVICE_LED(device), 1);	/* LED on       */
@@ -934,8 +934,8 @@ ulong ide_read(int device, ulong blknr, lbaint_t blkcnt, void *buffer)
 
 		if ((c & (ATA_STAT_DRQ | ATA_STAT_BUSY | ATA_STAT_ERR)) !=
 		    ATA_STAT_DRQ) {
-			printf("Error (no IRQ) dev %d blk %ld: status %#02x\n",
-				device, blknr, c);
+			printf("Error (no IRQ) dev %d blk " LBAF ": status "
+			       "%#02x\n", device, blknr, c);
 			break;
 		}
 
@@ -954,7 +954,7 @@ IDE_READ_E:
 /* ------------------------------------------------------------------------- */
 
 
-ulong ide_write(int device, ulong blknr, lbaint_t blkcnt, const void *buffer)
+ulong ide_write(int device, lbaint_t blknr, lbaint_t blkcnt, const void *buffer)
 {
 	ulong n = 0;
 	unsigned char c;
@@ -1022,8 +1022,8 @@ ulong ide_write(int device, ulong blknr, lbaint_t blkcnt, const void *buffer)
 
 		if ((c & (ATA_STAT_DRQ | ATA_STAT_BUSY | ATA_STAT_ERR)) !=
 		    ATA_STAT_DRQ) {
-			printf("Error (no IRQ) dev %d blk %ld: status %#02x\n",
-				device, blknr, c);
+			printf("Error (no IRQ) dev %d blk " LBAF ": status "
+				"%#02x\n", device, blknr, c);
 			goto WR_OUT;
 		}
 
diff --git a/common/usb_storage.c b/common/usb_storage.c
index 457970f..4599d03 100644
--- a/common/usb_storage.c
+++ b/common/usb_storage.c
@@ -170,9 +170,9 @@ int usb_stor_get_info(struct usb_device *dev, struct us_data *us,
 		      block_dev_desc_t *dev_desc);
 int usb_storage_probe(struct usb_device *dev, unsigned int ifnum,
 		      struct us_data *ss);
-unsigned long usb_stor_read(int device, unsigned long blknr,
+unsigned long usb_stor_read(int device, lbaint_t blknr,
 			    lbaint_t blkcnt, void *buffer);
-unsigned long usb_stor_write(int device, unsigned long blknr,
+unsigned long usb_stor_write(int device, lbaint_t blknr,
 			     lbaint_t blkcnt, const void *buffer);
 struct usb_device * usb_get_dev_index(int index);
 void uhci_show_temp_int_td(void);
@@ -1054,7 +1054,7 @@ static void usb_bin_fixup(struct usb_device_descriptor descriptor,
 }
 #endif /* CONFIG_USB_BIN_FIXUP */
 
-unsigned long usb_stor_read(int device, unsigned long blknr,
+unsigned long usb_stor_read(int device, lbaint_t blknr,
 			    lbaint_t blkcnt, void *buffer)
 {
 	lbaint_t start, blks;
@@ -1127,7 +1127,7 @@ retry_it:
 	return blkcnt;
 }
 
-unsigned long usb_stor_write(int device, unsigned long blknr,
+unsigned long usb_stor_write(int device, lbaint_t blknr,
 				lbaint_t blkcnt, const void *buffer)
 {
 	lbaint_t start, blks;
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index 0a2f535..3b01434 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -254,7 +254,7 @@ err_out:
 }
 
 static unsigned long
-mmc_berase(int dev_num, unsigned long start, lbaint_t blkcnt)
+mmc_berase(int dev_num, lbaint_t start, lbaint_t blkcnt)
 {
 	int err = 0;
 	struct mmc *mmc = find_mmc_device(dev_num);
@@ -266,7 +266,8 @@ mmc_berase(int dev_num, unsigned long start, lbaint_t blkcnt)
 
 	if ((start % mmc->erase_grp_size) || (blkcnt % mmc->erase_grp_size))
 		printf("\n\nCaution! Your devices Erase group is 0x%x\n"
-			"The erase range would be change to 0x%lx~0x%lx\n\n",
+		       "The erase range would be change to "
+		       "0x" LBAF "~0x" LBAF "\n\n",
 		       mmc->erase_grp_size, start & ~(mmc->erase_grp_size - 1),
 		       ((start + blkcnt + mmc->erase_grp_size)
 		       & ~(mmc->erase_grp_size - 1)) - 1);
@@ -289,14 +290,14 @@ mmc_berase(int dev_num, unsigned long start, lbaint_t blkcnt)
 }
 
 static ulong
-mmc_write_blocks(struct mmc *mmc, ulong start, lbaint_t blkcnt, const void*src)
+mmc_write_blocks(struct mmc *mmc, lbaint_t start, lbaint_t blkcnt, const void*src)
 {
 	struct mmc_cmd cmd;
 	struct mmc_data data;
 	int timeout = 1000;
 
 	if ((start + blkcnt) > mmc->block_dev.lba) {
-		printf("MMC: block number 0x%lx exceeds max(0x%lx)\n",
+		printf("MMC: block number 0x" LBAF " exceeds max(0x" LBAF ")\n",
 			start + blkcnt, mmc->block_dev.lba);
 		return 0;
 	}
@@ -344,7 +345,7 @@ mmc_write_blocks(struct mmc *mmc, ulong start, lbaint_t blkcnt, const void*src)
 }
 
 static ulong
-mmc_bwrite(int dev_num, ulong start, lbaint_t blkcnt, const void*src)
+mmc_bwrite(int dev_num, lbaint_t start, lbaint_t blkcnt, const void*src)
 {
 	lbaint_t cur, blocks_todo = blkcnt;
 
@@ -367,7 +368,7 @@ mmc_bwrite(int dev_num, ulong start, lbaint_t blkcnt, const void*src)
 	return blkcnt;
 }
 
-static int mmc_read_blocks(struct mmc *mmc, void *dst, ulong start,
+static int mmc_read_blocks(struct mmc *mmc, void *dst, lbaint_t start,
 			   lbaint_t blkcnt)
 {
 	struct mmc_cmd cmd;
@@ -406,7 +407,7 @@ static int mmc_read_blocks(struct mmc *mmc, void *dst, ulong start,
 	return blkcnt;
 }
 
-static ulong mmc_bread(int dev_num, ulong start, lbaint_t blkcnt, void *dst)
+static ulong mmc_bread(int dev_num, lbaint_t start, lbaint_t blkcnt, void *dst)
 {
 	lbaint_t cur, blocks_todo = blkcnt;
 
@@ -418,7 +419,7 @@ static ulong mmc_bread(int dev_num, ulong start, lbaint_t blkcnt, void *dst)
 		return 0;
 
 	if ((start + blkcnt) > mmc->block_dev.lba) {
-		printf("MMC: block number 0x%lx exceeds max(0x%lx)\n",
+		printf("MMC: block number 0x" LBAF " exceeds max(0x" LBAF ")\n",
 			start + blkcnt, mmc->block_dev.lba);
 		return 0;
 	}
diff --git a/include/ide.h b/include/ide.h
index afea85c..f691a74 100644
--- a/include/ide.h
+++ b/include/ide.h
@@ -54,8 +54,9 @@ typedef ulong lbaint_t;
  */
 
 void ide_init(void);
-ulong ide_read(int device, ulong blknr, lbaint_t blkcnt, void *buffer);
-ulong ide_write(int device, ulong blknr, lbaint_t blkcnt, const void *buffer);
+ulong ide_read(int device, lbaint_t blknr, lbaint_t blkcnt, void *buffer);
+ulong ide_write(int device, lbaint_t blknr, lbaint_t blkcnt,
+		const void *buffer);
 
 #ifdef CONFIG_IDE_PREINIT
 int ide_preinit(void);
diff --git a/include/part.h b/include/part.h
index f7c7cc5..35c1c5b 100644
--- a/include/part.h
+++ b/include/part.h
@@ -43,15 +43,15 @@ typedef struct block_dev_desc {
 	char		product[20+1];	/* IDE Serial no, SCSI product */
 	char		revision[8+1];	/* firmware revision */
 	unsigned long	(*block_read)(int dev,
-				      unsigned long start,
+				      lbaint_t start,
 				      lbaint_t blkcnt,
 				      void *buffer);
 	unsigned long	(*block_write)(int dev,
-				       unsigned long start,
+				       lbaint_t start,
 				       lbaint_t blkcnt,
 				       const void *buffer);
 	unsigned long   (*block_erase)(int dev,
-				       unsigned long start,
+				       lbaint_t start,
 				       lbaint_t blkcnt);
 	void		*priv;		/* driver private struct pointer */
 }block_dev_desc_t;
-- 
1.8.2.1

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [U-Boot] [PATCH] Fix block device accesses beyond 2TiB
  2013-06-14 11:07       ` [U-Boot] [PATCH] Fix block device accesses beyond 2TiB Sascha Silbe
@ 2013-06-17 20:26         ` Marek Vasut
  2013-06-22 10:07           ` Albert ARIBAUD
  2013-06-26 20:25         ` [U-Boot] Fix block device " Tom Rini
  1 sibling, 1 reply; 24+ messages in thread
From: Marek Vasut @ 2013-06-17 20:26 UTC (permalink / raw)
  To: u-boot

Hello Sascha,

> With CONFIG_SYS_64BIT_LBA, lbaint_t gets defined as a 64-bit type,
> which is required to represent block numbers for storage devices that
> exceed 2TiB (the block size usually is 512B), e.g. recent hard drives.
> 
> For some obscure reason, the current U-Boot code uses lbaint_t for the
> number of blocks to read (a rather optimistic estimation of how RAM
> sizes will evolve), but not for the starting address. Trying to access
> blocks beyond the 2TiB boundary will simply wrap around and read a
> block within the 0..2TiB range.
> 
> We now use lbaint_t for block start addresses, too. This required
> changes to all block drivers as the signature of block_read(),
> block_write() and block_erase() in block_dev_desc_t changed.
> 
> Signed-off-by: Sascha Silbe <t-uboot@infra-silbe.de>
> ---
> Functionality tested on CuBox Pro with a Western Digital WD30EFRX hard
> disk (3TB). Build tested for all arm boards and sandbox.
> 
> Testing on other boards and architectures would be appreciated.
> 
> Fixes for typos, style errors etc. are explicitly out of scope for
> this patch, even those checkpatch complains about because they appear
> on or near lines touched by the patch. They are unrelated to the issue
> at hand and can be fixed up later. Mixing in unrelated changes would
> just make harder to revert any problematic change.

Quick review looks OK.

Best regards,
Marek Vasut

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [U-Boot] [PATCH] Fix block device accesses beyond 2TiB
  2013-06-17 20:26         ` Marek Vasut
@ 2013-06-22 10:07           ` Albert ARIBAUD
       [not found]             ` <51C598A6.8040406@starox.org>
  0 siblings, 1 reply; 24+ messages in thread
From: Albert ARIBAUD @ 2013-06-22 10:07 UTC (permalink / raw)
  To: u-boot

On Mon, 17 Jun 2013 22:26:00 +0200, Marek Vasut <marex@denx.de> wrote:

> Hello Sascha,
> 
> > With CONFIG_SYS_64BIT_LBA, lbaint_t gets defined as a 64-bit type,
> > which is required to represent block numbers for storage devices that
> > exceed 2TiB (the block size usually is 512B), e.g. recent hard drives.
> > 
> > For some obscure reason, the current U-Boot code uses lbaint_t for the
> > number of blocks to read (a rather optimistic estimation of how RAM
> > sizes will evolve), but not for the starting address. Trying to access
> > blocks beyond the 2TiB boundary will simply wrap around and read a
> > block within the 0..2TiB range.
> > 
> > We now use lbaint_t for block start addresses, too. This required
> > changes to all block drivers as the signature of block_read(),
> > block_write() and block_erase() in block_dev_desc_t changed.
> > 
> > Signed-off-by: Sascha Silbe <t-uboot@infra-silbe.de>
> > ---
> > Functionality tested on CuBox Pro with a Western Digital WD30EFRX hard
> > disk (3TB). Build tested for all arm boards and sandbox.
> > 
> > Testing on other boards and architectures would be appreciated.
> > 
> > Fixes for typos, style errors etc. are explicitly out of scope for
> > this patch, even those checkpatch complains about because they appear
> > on or near lines touched by the patch. They are unrelated to the issue
> > at hand and can be fixed up later. Mixing in unrelated changes would
> > just make harder to revert any problematic change.
> 
> Quick review looks OK.
> 
> Best regards,
> Marek Vasut

Anyone could test Sascha's patch? Especially Fr?d?dic, can you test it
and see how this works with your enabling 64-bit LBA on LaCie kirkwood
products?

Amicalement,
-- 
Albert.

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [U-Boot] [PATCH] Fix block device accesses beyond 2TiB
       [not found]             ` <51C598A6.8040406@starox.org>
@ 2013-06-22 15:31               ` Albert ARIBAUD
  2013-06-24  9:46                 ` Frédéric Leroy
  0 siblings, 1 reply; 24+ messages in thread
From: Albert ARIBAUD @ 2013-06-22 15:31 UTC (permalink / raw)
  To: u-boot

Hi Fr?d?ric,

On Sat, 22 Jun 2013 14:29:26 +0200, Fr?d?ric Leroy <fredo@starox.org>
wrote:

> Hello Albert, Sascha, Marek
> 
> Le 22/06/2013 12:07, Albert ARIBAUD a ?crit :
> > > Quick review looks OK.
> > > 
> > > Best regards,
> > > Marek Vasut
> >
> > Anyone could test Sascha's patch? Especially Fr?d?dic, can you test it
> > and see how this works with your enabling 64-bit LBA on LaCie kirkwood
> > products?
> >
> > Amicalement,
> 
> I applied Sascha patch with 64-bit LBA enabled.
> I verifyed it by using the "ide read" command.
> Logs are attached for u-boot tests, with and without the patch.
> I added the output of dd of the same block on a linux machine in order
> to verify the content.
> There is still issues to access file on a ext fs beyond the 2.1 limit
> (see end of logs).
> 
> However, the patch issues no warning at compile time and fixes the ide
> block layer.

OK -- anyone has any idea why Sasha's patch fixes reading from "far"
blocks but does not fix ex2ls? Frankly, I'd prefer it if the patch
fixed it all. :)

> Best regards,

Amicalement,
-- 
Albert.

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [U-Boot] [PATCH] Fix block device accesses beyond 2TiB
  2013-06-22 15:31               ` Albert ARIBAUD
@ 2013-06-24  9:46                 ` Frédéric Leroy
  2013-06-24 21:13                   ` Sascha Silbe
  0 siblings, 1 reply; 24+ messages in thread
From: Frédéric Leroy @ 2013-06-24  9:46 UTC (permalink / raw)
  To: u-boot

Le 22/06/2013 17:31, Albert ARIBAUD a ?crit :
> Hi Fr?d?ric,
>
> > However, the patch issues no warning at compile time and fixes the ide
> > block layer.
>
> OK -- anyone has any idea why Sasha's patch fixes reading from "far"
> blocks but does not fix ex2ls? Frankly, I'd prefer it if the patch
> fixed it all. :)

I did a quick look.
Ext2 code use "unsigned long" for the partition offset and "int" for
sector computation.
I will try to fix it, and try to test the other fs ( ext4, xfs, fat).
I would see one patch for the ide code, and one or more patch for the fs
code.
IMHO, Sascha patch can be applied as.

Regards,

-- 
Frederic Leroy

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [U-Boot] [PATCH] Fix block device accesses beyond 2TiB
  2013-06-24  9:46                 ` Frédéric Leroy
@ 2013-06-24 21:13                   ` Sascha Silbe
  2013-06-24 21:26                     ` [U-Boot] [PATCH] Fix ext2/ext4 filesystem " Frederic Leroy
  0 siblings, 1 reply; 24+ messages in thread
From: Sascha Silbe @ 2013-06-24 21:13 UTC (permalink / raw)
  To: u-boot

Fr?d?ric Leroy <fredo@starox.org> writes:

> Le 22/06/2013 17:31, Albert ARIBAUD a ?crit :
>> > However, the patch issues no warning at compile time and fixes the ide
>> > block layer.
>>
>> OK -- anyone has any idea why Sasha's patch fixes reading from "far"
>> blocks but does not fix ex2ls? Frankly, I'd prefer it if the patch
>> fixed it all. :)

Thanks to Fr?d?ric for testing and to Marek for the quick review.


[...]
> Ext2 code use "unsigned long" for the partition offset and "int" for
> sector computation.
> I will try to fix it, and try to test the other fs ( ext4, xfs, fat).
> I would see one patch for the ide code, and one or more patch for the fs
> code.
> IMHO, Sascha patch can be applied as.

While the IDE layer fix isn't enough for most use cases (storage devices
in the TiB range are usually used with file systems rather than raw
partitions), I agree that the file system level fixes should happen in
separate patches.

Tom, do you consider this a bug fix worth landing in v2013.07 or an
intrusive change (possibly even a feature as it never worked before)
that would go into v2013.10 instead?

If it's considered a bug fix, it would probably be a good idea to land
my patch ASAP rather than waiting for the FS level fixes. In the
"feature" case we can wait and include both IDE and FS fixes in a single
patch set once someone gets around to do the FS fixes.

Sascha
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 489 bytes
Desc: not available
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20130624/f87d97c6/attachment.pgp>

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [U-Boot] [PATCH] Fix ext2/ext4 filesystem accesses beyond 2TiB
  2013-06-24 21:13                   ` Sascha Silbe
@ 2013-06-24 21:26                     ` Frederic Leroy
  2013-06-24 22:26                       ` Sascha Silbe
  0 siblings, 1 reply; 24+ messages in thread
From: Frederic Leroy @ 2013-06-24 21:26 UTC (permalink / raw)
  To: u-boot

From: Fr?d?ric Leroy <fredo@starox.org>

With CONFIG_SYS_64BIT_LBA, lbaint_t gets defined as a 64-bit type,
which is required to represent block numbers for storage devices that
exceed 2TiB (the block size usually is 512B), e.g. recent hard drives

We now use lbaint_t for partition offset to reflect the lbaint_t change,
and access partitions beyond or crossing the 2.1TiB limit.
This required changes to signature of ext4fs_devread(), and type of all
variables relatives to block sector.

ext2/ext4 fs uses logical block represented by a 32 bit value. Logical
block is a multiple of device block sector. To avoid overflow problem
when calling ext4fs_devread(), we need to cast the sector parameter.
---

This patch applies on top of Sascha one.
It has been tested with CONFIG_SYS_64BIT_LBA disabled on a small
disk and CONFIG_SYS_64BIT_LBA enabled on a 3TB disk on a LaCie 
arm platform. Moreover, CONFIG_CMD_EXT4 and CONFIG_FS_EXT4 was enabled.
Both compilation issue no warning.

For the 3TB setup, 3 partition have been created beyond the 2.1TiB limit.
One partition ext2, one ext4, and one vfat. Each one filled with an 
uImage kernel.
For all partition, commands fatls and ext2ls did work, as well as loading
and booting uImage.

 common/cmd_disk.c      |  2 +-
 disk/part_efi.c        |  4 ++--
 fs/ext4/dev.c          |  8 ++++----
 fs/ext4/ext4_common.c  | 40 ++++++++++++++++++++--------------------
 fs/ext4/ext4_journal.c | 12 ++++++------
 fs/ext4/ext4_write.c   | 38 +++++++++++++++++++-------------------
 fs/ext4/ext4fs.c       | 14 +++++++-------
 include/ext4fs.h       |  2 +-
 include/ext_common.h   |  2 +-
 include/ide.h          |  2 ++
 include/part.h         |  4 ++--
 11 files changed, 65 insertions(+), 63 deletions(-)

diff --git a/common/cmd_disk.c b/common/cmd_disk.c
index ee4e215..809e231 100644
--- a/common/cmd_disk.c
+++ b/common/cmd_disk.c
@@ -67,7 +67,7 @@ int common_diskboot(cmd_tbl_t *cmdtp, const char *intf, int argc,
 	       "Name: %.32s  Type: %.32s\n", intf, dev, part, info.name,
 	       info.type);
 
-	debug("First Block: %ld,  # of blocks: %ld, Block Size: %ld\n",
+	debug("First Block: " LBAFu ",  # of blocks: " LBAFu ", Block Size: %ld\n",
 	      info.start, info.size, info.blksz);
 
 	if (dev_desc->block_read(dev, info.start, 1, (ulong *) addr) != 1) {
diff --git a/disk/part_efi.c b/disk/part_efi.c
index fb5e9f0..5c426fe 100644
--- a/disk/part_efi.c
+++ b/disk/part_efi.c
@@ -200,7 +200,7 @@ int get_partition_info_efi(block_dev_desc_t * dev_desc, int part,
 	uuid_string(gpt_pte[part - 1].unique_partition_guid.b, info->uuid);
 #endif
 
-	debug("%s: start 0x%lX, size 0x%lX, name %s", __func__,
+	debug("%s: start 0x" LBAF ", size 0x" LBAF ", name %s", __func__,
 		info->start, info->size, info->name);
 
 	/* Remember to free pte */
@@ -431,7 +431,7 @@ int gpt_fill_pte(gpt_header *gpt_h, gpt_entry *gpt_e,
 			gpt_e[i].partition_name[k] =
 				(efi_char16_t)(partitions[i].name[k]);
 
-		debug("%s: name: %s offset[%d]: 0x%x size[%d]: 0x%lx\n",
+		debug("%s: name: %s offset[%d]: 0x%x size[%d]: 0x" LBAF "\n",
 		      __func__, partitions[i].name, i,
 		      offset, i, partitions[i].size);
 	}
diff --git a/fs/ext4/dev.c b/fs/ext4/dev.c
index 81b7633..7296118 100644
--- a/fs/ext4/dev.c
+++ b/fs/ext4/dev.c
@@ -42,7 +42,7 @@
 #include <ext_common.h>
 #include "ext4_common.h"
 
-unsigned long part_offset;
+lbaint_t part_offset;
 
 static block_dev_desc_t *ext4fs_block_dev_desc;
 static disk_partition_t *part_info;
@@ -58,7 +58,7 @@ void ext4fs_set_blk_dev(block_dev_desc_t *rbdd, disk_partition_t *info)
 		get_fs()->dev_desc->log2blksz;
 }
 
-int ext4fs_devread(int sector, int byte_offset, int byte_len, char *buf)
+int ext4fs_devread(lbaint_t sector, int byte_offset, int byte_len, char *buf)
 {
 	unsigned block_len;
 	int log2blksz = ext4fs_block_dev_desc->log2blksz;
@@ -74,7 +74,7 @@ int ext4fs_devread(int sector, int byte_offset, int byte_len, char *buf)
 	if ((sector < 0) ||
 	    ((sector + ((byte_offset + byte_len - 1) >> log2blksz))
 	     >= part_info->size)) {
-		printf("%s read outside partition %d\n", __func__, sector);
+		printf("%s read outside partition " LBAFu "\n", __func__, sector);
 		return 0;
 	}
 
@@ -82,7 +82,7 @@ int ext4fs_devread(int sector, int byte_offset, int byte_len, char *buf)
 	sector += byte_offset >> log2blksz;
 	byte_offset &= ext4fs_block_dev_desc->blksz - 1;
 
-	debug(" <%d, %d, %d>\n", sector, byte_offset, byte_len);
+	debug(" <" LBAFu ", %d, %d>\n", sector, byte_offset, byte_len);
 
 	if (byte_offset != 0) {
 		/* read first part which isn't aligned with start of sector */
diff --git a/fs/ext4/ext4_common.c b/fs/ext4/ext4_common.c
index 58880b4..61b1ca1 100644
--- a/fs/ext4/ext4_common.c
+++ b/fs/ext4/ext4_common.c
@@ -84,7 +84,7 @@ void put_ext4(uint64_t off, void *buf, uint32_t size)
 
 	if ((startblock + (size >> log2blksz)) >
 	    (part_offset + fs->total_sect)) {
-		printf("part_offset is %lu\n", part_offset);
+		printf("part_offset is " LBAFu "\n", part_offset);
 		printf("total_sector is %llu\n", fs->total_sect);
 		printf("error: overflow occurs\n");
 		return;
@@ -405,7 +405,7 @@ restart:
 		previous_blknr = root_blknr;
 	}
 
-	status = ext4fs_devread(first_block_no_of_root
+	status = ext4fs_devread((lbaint_t)first_block_no_of_root
 				* fs->sect_perblk,
 				0, fs->blksz, root_first_block_buffer);
 	if (status == 0)
@@ -545,7 +545,7 @@ static int search_dir(struct ext2_inode *parent_inode, char *dirname)
 		if (!block_buffer)
 			goto fail;
 
-		status = ext4fs_devread(blknr * fs->sect_perblk,
+		status = ext4fs_devread((lbaint_t)blknr * fs->sect_perblk,
 					0, fs->blksz, (char *)block_buffer);
 		if (status == 0)
 			goto fail;
@@ -783,7 +783,7 @@ static int check_filename(char *filename, unsigned int blknr)
 	if (!root_first_block_buffer)
 		return -ENOMEM;
 	root_first_block_addr = root_first_block_buffer;
-	status = ext4fs_devread(first_block_no_of_root *
+	status = ext4fs_devread((lbaint_t)first_block_no_of_root *
 				fs->sect_perblk, 0,
 				fs->blksz, root_first_block_buffer);
 	if (status == 0)
@@ -895,7 +895,7 @@ long int ext4fs_get_new_blk_no(void)
 				fs->first_pass_bbmap++;
 				bgd[i].free_blocks--;
 				fs->sb->free_blocks--;
-				status = ext4fs_devread(bgd[i].block_id *
+				status = ext4fs_devread((lbaint_t)bgd[i].block_id *
 							fs->sect_perblk, 0,
 							fs->blksz,
 							journal_buffer);
@@ -957,7 +957,7 @@ restart:
 		/* journal backup */
 		if (prev_bg_bitmap_index != bg_idx) {
 			memset(journal_buffer, '\0', fs->blksz);
-			status = ext4fs_devread(bgd[bg_idx].block_id
+			status = ext4fs_devread((lbaint_t)bgd[bg_idx].block_id
 						* fs->sect_perblk,
 						0, fs->blksz, journal_buffer);
 			if (status == 0)
@@ -1026,7 +1026,7 @@ int ext4fs_get_new_inode_no(void)
 				bgd[i].free_inodes--;
 				bgd[i].bg_itable_unused--;
 				fs->sb->free_inodes--;
-				status = ext4fs_devread(bgd[i].inode_id *
+				status = ext4fs_devread((lbaint_t)bgd[i].inode_id *
 							fs->sect_perblk, 0,
 							fs->blksz,
 							journal_buffer);
@@ -1067,7 +1067,7 @@ restart:
 		/* journal backup */
 		if (prev_inode_bitmap_index != ibmap_idx) {
 			memset(journal_buffer, '\0', fs->blksz);
-			status = ext4fs_devread(bgd[ibmap_idx].inode_id
+			status = ext4fs_devread((lbaint_t)bgd[ibmap_idx].inode_id
 						* fs->sect_perblk,
 						0, fs->blksz, journal_buffer);
 			if (status == 0)
@@ -1129,7 +1129,7 @@ static void alloc_single_indirect_block(struct ext2_inode *file_inode,
 		(*no_blks_reqd)++;
 		debug("SIPB %ld: %u\n", si_blockno, *total_remaining_blocks);
 
-		status = ext4fs_devread(si_blockno * fs->sect_perblk,
+		status = ext4fs_devread((lbaint_t)si_blockno * fs->sect_perblk,
 					0, fs->blksz, (char *)si_buffer);
 		memset(si_buffer, '\0', fs->blksz);
 		if (status == 0)
@@ -1193,7 +1193,7 @@ static void alloc_double_indirect_block(struct ext2_inode *file_inode,
 		debug("DIPB %ld: %u\n", di_blockno_parent,
 		      *total_remaining_blocks);
 
-		status = ext4fs_devread(di_blockno_parent *
+		status = ext4fs_devread((lbaint_t)di_blockno_parent *
 					fs->sect_perblk, 0,
 					fs->blksz, (char *)di_parent_buffer);
 
@@ -1224,7 +1224,7 @@ static void alloc_double_indirect_block(struct ext2_inode *file_inode,
 			debug("DICB %ld: %u\n", di_blockno_child,
 			      *total_remaining_blocks);
 
-			status = ext4fs_devread(di_blockno_child *
+			status = ext4fs_devread((lbaint_t)di_blockno_child *
 						fs->sect_perblk, 0,
 						fs->blksz,
 						(char *)di_child_buff);
@@ -1447,7 +1447,7 @@ static struct ext4_extent_header *ext4fs_get_extent_block
 		block = le32_to_cpu(index[i].ei_leaf_hi);
 		block = (block << 32) + le32_to_cpu(index[i].ei_leaf_lo);
 
-		if (ext4fs_devread(block << log2_blksz, 0, fs->blksz, buf))
+		if (ext4fs_devread((lbaint_t)block << log2_blksz, 0, fs->blksz, buf))
 			ext_block = (struct ext4_extent_header *)buf;
 		else
 			return 0;
@@ -1470,7 +1470,7 @@ static int ext4fs_blockgroup
 	debug("ext4fs read %d group descriptor (blkno %ld blkoff %u)\n",
 	      group, blkno, blkoff);
 
-	return ext4fs_devread(blkno << (LOG2_BLOCK_SIZE(data) - log2blksz),
+	return ext4fs_devread((lbaint_t)blkno << (LOG2_BLOCK_SIZE(data) - log2blksz),
 			      blkoff, sizeof(struct ext2_block_group),
 			      (char *)blkgrp);
 }
@@ -1497,7 +1497,7 @@ int ext4fs_read_inode(struct ext2_data *data, int ino, struct ext2_inode *inode)
 	    (ino % __le32_to_cpu(sblock->inodes_per_group)) / inodes_per_block;
 	blkoff = (ino % inodes_per_block) * fs->inodesz;
 	/* Read the inode. */
-	status = ext4fs_devread(blkno << (LOG2_BLOCK_SIZE(data) - log2blksz),
+	status = ext4fs_devread((lbaint_t)blkno << (LOG2_BLOCK_SIZE(data) - log2blksz),
 				blkoff,
 				sizeof(struct ext2_inode), (char *)inode);
 	if (status == 0)
@@ -1597,7 +1597,7 @@ long int read_allocated_block(struct ext2_inode *inode, int fileblock)
 		if ((__le32_to_cpu(inode->b.blocks.indir_block) <<
 		     log2_blksz) != ext4fs_indir1_blkno) {
 			status =
-			    ext4fs_devread(__le32_to_cpu
+			    ext4fs_devread((lbaint_t)__le32_to_cpu
 					   (inode->b.blocks.
 					    indir_block) << log2_blksz, 0,
 					   blksz, (char *)ext4fs_indir1_block);
@@ -1646,7 +1646,7 @@ long int read_allocated_block(struct ext2_inode *inode, int fileblock)
 		if ((__le32_to_cpu(inode->b.blocks.double_indir_block) <<
 		     log2_blksz) != ext4fs_indir1_blkno) {
 			status =
-			    ext4fs_devread(__le32_to_cpu
+			    ext4fs_devread((lbaint_t)__le32_to_cpu
 					   (inode->b.blocks.
 					    double_indir_block) << log2_blksz,
 					   0, blksz,
@@ -1686,7 +1686,7 @@ long int read_allocated_block(struct ext2_inode *inode, int fileblock)
 		}
 		if ((__le32_to_cpu(ext4fs_indir1_block[rblock / perblock]) <<
 		     log2_blksz) != ext4fs_indir2_blkno) {
-			status = ext4fs_devread(__le32_to_cpu
+			status = ext4fs_devread((lbaint_t)__le32_to_cpu
 						(ext4fs_indir1_block
 						 [rblock /
 						  perblock]) << log2_blksz, 0,
@@ -1738,7 +1738,7 @@ long int read_allocated_block(struct ext2_inode *inode, int fileblock)
 		if ((__le32_to_cpu(inode->b.blocks.triple_indir_block) <<
 		     log2_blksz) != ext4fs_indir1_blkno) {
 			status = ext4fs_devread
-			    (__le32_to_cpu(inode->b.blocks.triple_indir_block)
+			    ((lbaint_t)__le32_to_cpu(inode->b.blocks.triple_indir_block)
 			     << log2_blksz, 0, blksz,
 			     (char *)ext4fs_indir1_block);
 			if (status == 0) {
@@ -1778,7 +1778,7 @@ long int read_allocated_block(struct ext2_inode *inode, int fileblock)
 						       perblock_parent]) <<
 		     log2_blksz)
 		    != ext4fs_indir2_blkno) {
-			status = ext4fs_devread(__le32_to_cpu
+			status = ext4fs_devread((lbaint_t)__le32_to_cpu
 						(ext4fs_indir1_block
 						 [rblock /
 						  perblock_parent]) <<
@@ -1823,7 +1823,7 @@ long int read_allocated_block(struct ext2_inode *inode, int fileblock)
 						       perblock_child]) <<
 		     log2_blksz) != ext4fs_indir3_blkno) {
 			status =
-			    ext4fs_devread(__le32_to_cpu
+			    ext4fs_devread((lbaint_t)__le32_to_cpu
 					   (ext4fs_indir2_block
 					    [(rblock / perblock_child)
 					     % (blksz / 4)]) << log2_blksz, 0,
diff --git a/fs/ext4/ext4_journal.c b/fs/ext4/ext4_journal.c
index 81aa5fc..85081df 100644
--- a/fs/ext4/ext4_journal.c
+++ b/fs/ext4/ext4_journal.c
@@ -360,7 +360,7 @@ void recover_transaction(int prev_desc_logical_no)
 			  (struct ext2_inode *)&inode_journal);
 	blknr = read_allocated_block((struct ext2_inode *)
 				     &inode_journal, i);
-	ext4fs_devread(blknr * fs->sect_perblk, 0, fs->blksz, temp_buff);
+	ext4fs_devread((lbaint_t)blknr * fs->sect_perblk, 0, fs->blksz, temp_buff);
 	p_jdb = (char *)temp_buff;
 	jdb = (struct journal_header_t *) temp_buff;
 	ofs = sizeof(struct journal_header_t);
@@ -384,7 +384,7 @@ void recover_transaction(int prev_desc_logical_no)
 				continue;
 		}
 		blknr = read_allocated_block(&inode_journal, i);
-		ext4fs_devread(blknr * fs->sect_perblk, 0,
+		ext4fs_devread((lbaint_t)blknr * fs->sect_perblk, 0,
 			       fs->blksz, metadata_buff);
 		put_ext4((uint64_t)(be32_to_cpu(tag->block) * fs->blksz),
 			 metadata_buff, (uint32_t) fs->blksz);
@@ -431,7 +431,7 @@ int ext4fs_check_journal_state(int recovery_flag)
 
 	ext4fs_read_inode(ext4fs_root, EXT2_JOURNAL_INO, &inode_journal);
 	blknr = read_allocated_block(&inode_journal, EXT2_JOURNAL_SUPERBLOCK);
-	ext4fs_devread(blknr * fs->sect_perblk, 0, fs->blksz, temp_buff);
+	ext4fs_devread((lbaint_t)blknr * fs->sect_perblk, 0, fs->blksz, temp_buff);
 	jsb = (struct journal_superblock_t *) temp_buff;
 
 	if (fs->sb->feature_incompat & EXT3_FEATURE_INCOMPAT_RECOVER) {
@@ -455,7 +455,7 @@ int ext4fs_check_journal_state(int recovery_flag)
 	while (1) {
 		blknr = read_allocated_block(&inode_journal, i);
 		memset(temp_buff1, '\0', fs->blksz);
-		ext4fs_devread(blknr * fs->sect_perblk,
+		ext4fs_devread((lbaint_t)blknr * fs->sect_perblk,
 			       0, fs->blksz, temp_buff1);
 		jdb = (struct journal_header_t *) temp_buff1;
 
@@ -574,7 +574,7 @@ static void update_descriptor_block(long int blknr)
 	ext4fs_read_inode(ext4fs_root, EXT2_JOURNAL_INO, &inode_journal);
 	jsb_blknr = read_allocated_block(&inode_journal,
 					 EXT2_JOURNAL_SUPERBLOCK);
-	ext4fs_devread(jsb_blknr * fs->sect_perblk, 0, fs->blksz, temp_buff);
+	ext4fs_devread((lbaint_t)jsb_blknr * fs->sect_perblk, 0, fs->blksz, temp_buff);
 	jsb = (struct journal_superblock_t *) temp_buff;
 
 	jdb.h_blocktype = cpu_to_be32(EXT3_JOURNAL_DESCRIPTOR_BLOCK);
@@ -624,7 +624,7 @@ static void update_commit_block(long int blknr)
 	ext4fs_read_inode(ext4fs_root, EXT2_JOURNAL_INO, &inode_journal);
 	jsb_blknr = read_allocated_block(&inode_journal,
 					 EXT2_JOURNAL_SUPERBLOCK);
-	ext4fs_devread(jsb_blknr * fs->sect_perblk, 0, fs->blksz, temp_buff);
+	ext4fs_devread((lbaint_t)jsb_blknr * fs->sect_perblk, 0, fs->blksz, temp_buff);
 	jsb = (struct journal_superblock_t *) temp_buff;
 
 	jdb.h_blocktype = cpu_to_be32(EXT3_JOURNAL_COMMIT_BLOCK);
diff --git a/fs/ext4/ext4_write.c b/fs/ext4/ext4_write.c
index 0c1f62b..8dfa1ae 100644
--- a/fs/ext4/ext4_write.c
+++ b/fs/ext4/ext4_write.c
@@ -88,7 +88,7 @@ int ext4fs_get_bgdtable(void)
 	if (!fs->gdtable)
 		return -ENOMEM;
 	/* read the group descriptor table */
-	status = ext4fs_devread(fs->gdtable_blkno * fs->sect_perblk, 0,
+	status = ext4fs_devread((lbaint_t)fs->gdtable_blkno * fs->sect_perblk, 0,
 				fs->blksz * fs->no_blk_pergdt, fs->gdtable);
 	if (status == 0)
 		goto fail;
@@ -142,7 +142,7 @@ static void delete_single_indirect_block(struct ext2_inode *inode)
 		/* journal backup */
 		if (prev_bg_bmap_idx != bg_idx) {
 			status =
-			    ext4fs_devread(bgd[bg_idx].block_id *
+			    ext4fs_devread((lbaint_t)bgd[bg_idx].block_id *
 					   fs->sect_perblk, 0, fs->blksz,
 					   journal_buffer);
 			if (status == 0)
@@ -186,7 +186,7 @@ static void delete_double_indirect_block(struct ext2_inode *inode)
 		}
 		DIB_start_addr = (unsigned int *)di_buffer;
 		blknr = inode->b.blocks.double_indir_block;
-		status = ext4fs_devread(blknr * fs->sect_perblk, 0, fs->blksz,
+		status = ext4fs_devread((lbaint_t)blknr * fs->sect_perblk, 0, fs->blksz,
 					(char *)di_buffer);
 		for (i = 0; i < fs->blksz / sizeof(int); i++) {
 			if (*di_buffer == 0)
@@ -208,7 +208,7 @@ static void delete_double_indirect_block(struct ext2_inode *inode)
 			fs->sb->free_blocks++;
 			/* journal backup */
 			if (prev_bg_bmap_idx != bg_idx) {
-				status = ext4fs_devread(bgd[bg_idx].block_id
+				status = ext4fs_devread((lbaint_t)bgd[bg_idx].block_id
 							* fs->sect_perblk, 0,
 							fs->blksz,
 							journal_buffer);
@@ -238,7 +238,7 @@ static void delete_double_indirect_block(struct ext2_inode *inode)
 		/* journal backup */
 		if (prev_bg_bmap_idx != bg_idx) {
 			memset(journal_buffer, '\0', fs->blksz);
-			status = ext4fs_devread(bgd[bg_idx].block_id *
+			status = ext4fs_devread((lbaint_t)bgd[bg_idx].block_id *
 						fs->sect_perblk, 0, fs->blksz,
 						journal_buffer);
 			if (status == 0)
@@ -287,7 +287,7 @@ static void delete_triple_indirect_block(struct ext2_inode *inode)
 		}
 		tib_start_addr = (unsigned int *)tigp_buffer;
 		blknr = inode->b.blocks.triple_indir_block;
-		status = ext4fs_devread(blknr * fs->sect_perblk, 0, fs->blksz,
+		status = ext4fs_devread((lbaint_t)blknr * fs->sect_perblk, 0, fs->blksz,
 					(char *)tigp_buffer);
 		for (i = 0; i < fs->blksz / sizeof(int); i++) {
 			if (*tigp_buffer == 0)
@@ -298,7 +298,7 @@ static void delete_triple_indirect_block(struct ext2_inode *inode)
 			if (!tip_buffer)
 				goto fail;
 			tipb_start_addr = (unsigned int *)tip_buffer;
-			status = ext4fs_devread((*tigp_buffer) *
+			status = ext4fs_devread((lbaint_t)(*tigp_buffer) *
 						fs->sect_perblk, 0, fs->blksz,
 						(char *)tip_buffer);
 			for (j = 0; j < fs->blksz / sizeof(int); j++) {
@@ -325,7 +325,7 @@ static void delete_triple_indirect_block(struct ext2_inode *inode)
 				if (prev_bg_bmap_idx != bg_idx) {
 					status =
 					    ext4fs_devread(
-							bgd[bg_idx].block_id *
+							(lbaint_t)bgd[bg_idx].block_id *
 							fs->sect_perblk, 0,
 							fs->blksz,
 							journal_buffer);
@@ -365,7 +365,7 @@ static void delete_triple_indirect_block(struct ext2_inode *inode)
 			if (prev_bg_bmap_idx != bg_idx) {
 				memset(journal_buffer, '\0', fs->blksz);
 				status =
-				    ext4fs_devread(bgd[bg_idx].block_id *
+				    ext4fs_devread((lbaint_t)bgd[bg_idx].block_id *
 						   fs->sect_perblk, 0,
 						   fs->blksz, journal_buffer);
 				if (status == 0)
@@ -394,7 +394,7 @@ static void delete_triple_indirect_block(struct ext2_inode *inode)
 		/* journal backup */
 		if (prev_bg_bmap_idx != bg_idx) {
 			memset(journal_buffer, '\0', fs->blksz);
-			status = ext4fs_devread(bgd[bg_idx].block_id *
+			status = ext4fs_devread((lbaint_t)bgd[bg_idx].block_id *
 						fs->sect_perblk, 0, fs->blksz,
 						journal_buffer);
 			if (status == 0)
@@ -480,7 +480,7 @@ static int ext4fs_delete_file(int inodeno)
 			/* journal backup */
 			if (prev_bg_bmap_idx != bg_idx) {
 				status =
-				    ext4fs_devread(bgd[bg_idx].block_id *
+				    ext4fs_devread((lbaint_t)bgd[bg_idx].block_id *
 						   fs->sect_perblk, 0,
 						   fs->blksz, journal_buffer);
 				if (status == 0)
@@ -524,7 +524,7 @@ static int ext4fs_delete_file(int inodeno)
 			/* journal backup */
 			if (prev_bg_bmap_idx != bg_idx) {
 				memset(journal_buffer, '\0', fs->blksz);
-				status = ext4fs_devread(bgd[bg_idx].block_id
+				status = ext4fs_devread((lbaint_t)bgd[bg_idx].block_id
 							* fs->sect_perblk,
 							0, fs->blksz,
 							journal_buffer);
@@ -555,7 +555,7 @@ static int ext4fs_delete_file(int inodeno)
 	if (!read_buffer)
 		goto fail;
 	start_block_address = read_buffer;
-	status = ext4fs_devread(blkno * fs->sect_perblk,
+	status = ext4fs_devread((lbaint_t)blkno * fs->sect_perblk,
 				0, fs->blksz, read_buffer);
 	if (status == 0)
 		goto fail;
@@ -578,7 +578,7 @@ static int ext4fs_delete_file(int inodeno)
 	fs->sb->free_inodes++;
 	/* journal backup */
 	memset(journal_buffer, '\0', fs->blksz);
-	status = ext4fs_devread(bgd[ibmap_idx].inode_id *
+	status = ext4fs_devread((lbaint_t)bgd[ibmap_idx].inode_id *
 				fs->sect_perblk, 0, fs->blksz, journal_buffer);
 	if (status == 0)
 		goto fail;
@@ -653,7 +653,7 @@ int ext4fs_init(void)
 
 	for (i = 0; i < fs->no_blkgrp; i++) {
 		status =
-		    ext4fs_devread(fs->bgd[i].block_id * fs->sect_perblk, 0,
+		    ext4fs_devread((lbaint_t)fs->bgd[i].block_id * fs->sect_perblk, 0,
 				   fs->blksz, (char *)fs->blk_bmaps[i]);
 		if (status == 0)
 			goto fail;
@@ -670,7 +670,7 @@ int ext4fs_init(void)
 	}
 
 	for (i = 0; i < fs->no_blkgrp; i++) {
-		status = ext4fs_devread(fs->bgd[i].inode_id * fs->sect_perblk,
+		status = ext4fs_devread((lbaint_t)fs->bgd[i].inode_id * fs->sect_perblk,
 					0, fs->blksz,
 					(char *)fs->inode_bmaps[i]);
 		if (status == 0)
@@ -710,7 +710,7 @@ void ext4fs_deinit(void)
 				  &inode_journal);
 		blknr = read_allocated_block(&inode_journal,
 					EXT2_JOURNAL_SUPERBLOCK);
-		ext4fs_devread(blknr * fs->sect_perblk, 0, fs->blksz,
+		ext4fs_devread((lbaint_t)blknr * fs->sect_perblk, 0, fs->blksz,
 			       temp_buff);
 		jsb = (struct journal_superblock_t *)temp_buff;
 		jsb->s_start = cpu_to_be32(0);
@@ -934,7 +934,7 @@ int ext4fs_write(const char *fname, unsigned char *buffer,
 			(inodeno % __le32_to_cpu(sblock->inodes_per_group)) /
 			inodes_per_block;
 	blkoff = (inodeno % inodes_per_block) * fs->inodesz;
-	ext4fs_devread(itable_blkno * fs->sect_perblk, 0, fs->blksz, temp_ptr);
+	ext4fs_devread((lbaint_t)itable_blkno * fs->sect_perblk, 0, fs->blksz, temp_ptr);
 	if (ext4fs_log_journal(temp_ptr, itable_blkno))
 		goto fail;
 
@@ -954,7 +954,7 @@ int ext4fs_write(const char *fname, unsigned char *buffer,
 	blkoff = (parent_inodeno % inodes_per_block) * fs->inodesz;
 	if (parent_itable_blkno != itable_blkno) {
 		memset(temp_ptr, '\0', fs->blksz);
-		ext4fs_devread(parent_itable_blkno * fs->sect_perblk,
+		ext4fs_devread((lbaint_t)parent_itable_blkno * fs->sect_perblk,
 			       0, fs->blksz, temp_ptr);
 		if (ext4fs_log_journal(temp_ptr, parent_itable_blkno))
 			goto fail;
diff --git a/fs/ext4/ext4fs.c b/fs/ext4/ext4fs.c
index 1954afb..20ff10f 100644
--- a/fs/ext4/ext4fs.c
+++ b/fs/ext4/ext4fs.c
@@ -62,16 +62,16 @@ int ext4fs_read_file(struct ext2fs_node *node, int pos,
 {
 	struct ext_filesystem *fs = get_fs();
 	int i;
-	int blockcnt;
+	lbaint_t blockcnt;
 	int log2blksz = fs->dev_desc->log2blksz;
 	int log2_fs_blocksize = LOG2_BLOCK_SIZE(node->data) - log2blksz;
 	int blocksize = (1 << (log2_fs_blocksize + log2blksz));
 	unsigned int filesize = __le32_to_cpu(node->inode.size);
-	int previous_block_number = -1;
-	int delayed_start = 0;
-	int delayed_extent = 0;
-	int delayed_skipfirst = 0;
-	int delayed_next = 0;
+	lbaint_t previous_block_number = -1;
+	lbaint_t delayed_start = 0;
+	lbaint_t delayed_extent = 0;
+	lbaint_t delayed_skipfirst = 0;
+	lbaint_t delayed_next = 0;
 	char *delayed_buf = NULL;
 	short status;
 
@@ -82,7 +82,7 @@ int ext4fs_read_file(struct ext2fs_node *node, int pos,
 	blockcnt = ((len + pos) + blocksize - 1) / blocksize;
 
 	for (i = pos / blocksize; i < blockcnt; i++) {
-		int blknr;
+		lbaint_t blknr;
 		int blockoff = pos % blocksize;
 		int blockend = blocksize;
 		int skipfirst = 0;
diff --git a/include/ext4fs.h b/include/ext4fs.h
index 379f7eb..2429380 100644
--- a/include/ext4fs.h
+++ b/include/ext4fs.h
@@ -135,7 +135,7 @@ int ext4fs_mount(unsigned part_length);
 void ext4fs_close(void);
 int ext4fs_ls(const char *dirname);
 void ext4fs_free_node(struct ext2fs_node *node, struct ext2fs_node *currroot);
-int ext4fs_devread(int sector, int byte_offset, int byte_len, char *buf);
+int ext4fs_devread(lbaint_t sector, int byte_offset, int byte_len, char *buf);
 void ext4fs_set_blk_dev(block_dev_desc_t *rbdd, disk_partition_t *info);
 long int read_allocated_block(struct ext2_inode *inode, int fileblock);
 int ext4fs_probe(block_dev_desc_t *fs_dev_desc,
diff --git a/include/ext_common.h b/include/ext_common.h
index 78a7808..694e49f 100644
--- a/include/ext_common.h
+++ b/include/ext_common.h
@@ -180,7 +180,7 @@ struct ext2_data {
 	struct ext2fs_node diropen;
 };
 
-extern unsigned long part_offset;
+extern lbaint_t part_offset;
 
 int do_ext2ls(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
 int do_ext2load(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
diff --git a/include/ide.h b/include/ide.h
index f691a74..24c29f9 100644
--- a/include/ide.h
+++ b/include/ide.h
@@ -44,9 +44,11 @@ extern ulong ide_bus_offset[];
 #ifdef CONFIG_SYS_64BIT_LBA
 typedef uint64_t lbaint_t;
 #define LBAF "%llx"
+#define LBAFu "%llu"
 #else
 typedef ulong lbaint_t;
 #define LBAF "%lx"
+#define LBAFu "%lu"
 #endif
 
 /*
diff --git a/include/part.h b/include/part.h
index 35c1c5b..8388ba8 100644
--- a/include/part.h
+++ b/include/part.h
@@ -97,8 +97,8 @@ typedef struct block_dev_desc {
 #define DEV_TYPE_OPDISK		0x07	/* optical disk */
 
 typedef struct disk_partition {
-	ulong	start;		/* # of first block in partition	*/
-	ulong	size;		/* number of blocks in partition	*/
+	lbaint_t	start;		/* # of first block in partition	*/
+	lbaint_t	size;		/* number of blocks in partition	*/
 	ulong	blksz;		/* block size in bytes			*/
 	uchar	name[32];	/* partition name			*/
 	uchar	type[32];	/* string type description		*/
-- 
1.8.1.2

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [U-Boot] [PATCH] Fix ext2/ext4 filesystem accesses beyond 2TiB
  2013-06-24 21:26                     ` [U-Boot] [PATCH] Fix ext2/ext4 filesystem " Frederic Leroy
@ 2013-06-24 22:26                       ` Sascha Silbe
  2013-06-25  6:10                         ` Frederic Leroy
  0 siblings, 1 reply; 24+ messages in thread
From: Sascha Silbe @ 2013-06-24 22:26 UTC (permalink / raw)
  To: u-boot

Frederic Leroy <fredo@starox.org> writes:

> From: Fr?d?ric Leroy <fredo@starox.org>
>
> With CONFIG_SYS_64BIT_LBA, lbaint_t gets defined as a 64-bit type,
> which is required to represent block numbers for storage devices that
> exceed 2TiB (the block size usually is 512B), e.g. recent hard drives
>
> We now use lbaint_t for partition offset to reflect the lbaint_t change,
> and access partitions beyond or crossing the 2.1TiB limit.
> This required changes to signature of ext4fs_devread(), and type of all
> variables relatives to block sector.
>
> ext2/ext4 fs uses logical block represented by a 32 bit value. Logical
> block is a multiple of device block sector. To avoid overflow problem
> when calling ext4fs_devread(), we need to cast the sector parameter.

Thanks for the patch!

Reading a file on an ext4 file system located on a partition starting
beyond the 2TiB limit on a SATA hard disk attached to a CuBox Pro
works fine now.

Tested-by: Sascha Silbe <t-uboot@infra-silbe.de>


You'll probably have to add your Signed-off-by before your patch can be
merged.

A minor nitpick: The limit is at 2TiB (2^41 Bytes), which is roughly
2.2TB (2.2 * 10^12 Bytes).

Sascha
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 489 bytes
Desc: not available
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20130625/9632c389/attachment.pgp>

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [U-Boot] [PATCH] Fix ext2/ext4 filesystem accesses beyond 2TiB
  2013-06-24 22:26                       ` Sascha Silbe
@ 2013-06-25  6:10                         ` Frederic Leroy
  2013-06-25 20:42                           ` Sascha Silbe
  0 siblings, 1 reply; 24+ messages in thread
From: Frederic Leroy @ 2013-06-25  6:10 UTC (permalink / raw)
  To: u-boot

From: Fr?d?ric Leroy <fredo@starox.org>

With CONFIG_SYS_64BIT_LBA, lbaint_t gets defined as a 64-bit type,
which is required to represent block numbers for storage devices that
exceed 2TiB (the block size usually is 512B), e.g. recent hard drives

We now use lbaint_t for partition offset to reflect the lbaint_t change,
and access partitions beyond or crossing the 2TiB limit.
This required changes to signature of ext4fs_devread(), and type of all
variables relatives to block sector.

ext2/ext4 fs uses logical block represented by a 32 bit value. Logical
block is a multiple of device block sector. To avoid overflow problem
when calling ext4fs_devread(), we need to cast the sector parameter.

Signed-off-by: Fr?d?ric Leroy <fredo@starox.org>
---

Added Signed-off-by and fix 2.1TiB value in the comment.

Thanks Sascha :)

 common/cmd_disk.c      |  2 +-
 disk/part_efi.c        |  4 ++--
 fs/ext4/dev.c          |  8 ++++----
 fs/ext4/ext4_common.c  | 40 ++++++++++++++++++++--------------------
 fs/ext4/ext4_journal.c | 12 ++++++------
 fs/ext4/ext4_write.c   | 38 +++++++++++++++++++-------------------
 fs/ext4/ext4fs.c       | 14 +++++++-------
 include/ext4fs.h       |  2 +-
 include/ext_common.h   |  2 +-
 include/ide.h          |  2 ++
 include/part.h         |  4 ++--
 11 files changed, 65 insertions(+), 63 deletions(-)

diff --git a/common/cmd_disk.c b/common/cmd_disk.c
index ee4e215..809e231 100644
--- a/common/cmd_disk.c
+++ b/common/cmd_disk.c
@@ -67,7 +67,7 @@ int common_diskboot(cmd_tbl_t *cmdtp, const char *intf, int argc,
 	       "Name: %.32s  Type: %.32s\n", intf, dev, part, info.name,
 	       info.type);
 
-	debug("First Block: %ld,  # of blocks: %ld, Block Size: %ld\n",
+	debug("First Block: " LBAFu ",  # of blocks: " LBAFu ", Block Size: %ld\n",
 	      info.start, info.size, info.blksz);
 
 	if (dev_desc->block_read(dev, info.start, 1, (ulong *) addr) != 1) {
diff --git a/disk/part_efi.c b/disk/part_efi.c
index fb5e9f0..5c426fe 100644
--- a/disk/part_efi.c
+++ b/disk/part_efi.c
@@ -200,7 +200,7 @@ int get_partition_info_efi(block_dev_desc_t * dev_desc, int part,
 	uuid_string(gpt_pte[part - 1].unique_partition_guid.b, info->uuid);
 #endif
 
-	debug("%s: start 0x%lX, size 0x%lX, name %s", __func__,
+	debug("%s: start 0x" LBAF ", size 0x" LBAF ", name %s", __func__,
 		info->start, info->size, info->name);
 
 	/* Remember to free pte */
@@ -431,7 +431,7 @@ int gpt_fill_pte(gpt_header *gpt_h, gpt_entry *gpt_e,
 			gpt_e[i].partition_name[k] =
 				(efi_char16_t)(partitions[i].name[k]);
 
-		debug("%s: name: %s offset[%d]: 0x%x size[%d]: 0x%lx\n",
+		debug("%s: name: %s offset[%d]: 0x%x size[%d]: 0x" LBAF "\n",
 		      __func__, partitions[i].name, i,
 		      offset, i, partitions[i].size);
 	}
diff --git a/fs/ext4/dev.c b/fs/ext4/dev.c
index 81b7633..7296118 100644
--- a/fs/ext4/dev.c
+++ b/fs/ext4/dev.c
@@ -42,7 +42,7 @@
 #include <ext_common.h>
 #include "ext4_common.h"
 
-unsigned long part_offset;
+lbaint_t part_offset;
 
 static block_dev_desc_t *ext4fs_block_dev_desc;
 static disk_partition_t *part_info;
@@ -58,7 +58,7 @@ void ext4fs_set_blk_dev(block_dev_desc_t *rbdd, disk_partition_t *info)
 		get_fs()->dev_desc->log2blksz;
 }
 
-int ext4fs_devread(int sector, int byte_offset, int byte_len, char *buf)
+int ext4fs_devread(lbaint_t sector, int byte_offset, int byte_len, char *buf)
 {
 	unsigned block_len;
 	int log2blksz = ext4fs_block_dev_desc->log2blksz;
@@ -74,7 +74,7 @@ int ext4fs_devread(int sector, int byte_offset, int byte_len, char *buf)
 	if ((sector < 0) ||
 	    ((sector + ((byte_offset + byte_len - 1) >> log2blksz))
 	     >= part_info->size)) {
-		printf("%s read outside partition %d\n", __func__, sector);
+		printf("%s read outside partition " LBAFu "\n", __func__, sector);
 		return 0;
 	}
 
@@ -82,7 +82,7 @@ int ext4fs_devread(int sector, int byte_offset, int byte_len, char *buf)
 	sector += byte_offset >> log2blksz;
 	byte_offset &= ext4fs_block_dev_desc->blksz - 1;
 
-	debug(" <%d, %d, %d>\n", sector, byte_offset, byte_len);
+	debug(" <" LBAFu ", %d, %d>\n", sector, byte_offset, byte_len);
 
 	if (byte_offset != 0) {
 		/* read first part which isn't aligned with start of sector */
diff --git a/fs/ext4/ext4_common.c b/fs/ext4/ext4_common.c
index 58880b4..61b1ca1 100644
--- a/fs/ext4/ext4_common.c
+++ b/fs/ext4/ext4_common.c
@@ -84,7 +84,7 @@ void put_ext4(uint64_t off, void *buf, uint32_t size)
 
 	if ((startblock + (size >> log2blksz)) >
 	    (part_offset + fs->total_sect)) {
-		printf("part_offset is %lu\n", part_offset);
+		printf("part_offset is " LBAFu "\n", part_offset);
 		printf("total_sector is %llu\n", fs->total_sect);
 		printf("error: overflow occurs\n");
 		return;
@@ -405,7 +405,7 @@ restart:
 		previous_blknr = root_blknr;
 	}
 
-	status = ext4fs_devread(first_block_no_of_root
+	status = ext4fs_devread((lbaint_t)first_block_no_of_root
 				* fs->sect_perblk,
 				0, fs->blksz, root_first_block_buffer);
 	if (status == 0)
@@ -545,7 +545,7 @@ static int search_dir(struct ext2_inode *parent_inode, char *dirname)
 		if (!block_buffer)
 			goto fail;
 
-		status = ext4fs_devread(blknr * fs->sect_perblk,
+		status = ext4fs_devread((lbaint_t)blknr * fs->sect_perblk,
 					0, fs->blksz, (char *)block_buffer);
 		if (status == 0)
 			goto fail;
@@ -783,7 +783,7 @@ static int check_filename(char *filename, unsigned int blknr)
 	if (!root_first_block_buffer)
 		return -ENOMEM;
 	root_first_block_addr = root_first_block_buffer;
-	status = ext4fs_devread(first_block_no_of_root *
+	status = ext4fs_devread((lbaint_t)first_block_no_of_root *
 				fs->sect_perblk, 0,
 				fs->blksz, root_first_block_buffer);
 	if (status == 0)
@@ -895,7 +895,7 @@ long int ext4fs_get_new_blk_no(void)
 				fs->first_pass_bbmap++;
 				bgd[i].free_blocks--;
 				fs->sb->free_blocks--;
-				status = ext4fs_devread(bgd[i].block_id *
+				status = ext4fs_devread((lbaint_t)bgd[i].block_id *
 							fs->sect_perblk, 0,
 							fs->blksz,
 							journal_buffer);
@@ -957,7 +957,7 @@ restart:
 		/* journal backup */
 		if (prev_bg_bitmap_index != bg_idx) {
 			memset(journal_buffer, '\0', fs->blksz);
-			status = ext4fs_devread(bgd[bg_idx].block_id
+			status = ext4fs_devread((lbaint_t)bgd[bg_idx].block_id
 						* fs->sect_perblk,
 						0, fs->blksz, journal_buffer);
 			if (status == 0)
@@ -1026,7 +1026,7 @@ int ext4fs_get_new_inode_no(void)
 				bgd[i].free_inodes--;
 				bgd[i].bg_itable_unused--;
 				fs->sb->free_inodes--;
-				status = ext4fs_devread(bgd[i].inode_id *
+				status = ext4fs_devread((lbaint_t)bgd[i].inode_id *
 							fs->sect_perblk, 0,
 							fs->blksz,
 							journal_buffer);
@@ -1067,7 +1067,7 @@ restart:
 		/* journal backup */
 		if (prev_inode_bitmap_index != ibmap_idx) {
 			memset(journal_buffer, '\0', fs->blksz);
-			status = ext4fs_devread(bgd[ibmap_idx].inode_id
+			status = ext4fs_devread((lbaint_t)bgd[ibmap_idx].inode_id
 						* fs->sect_perblk,
 						0, fs->blksz, journal_buffer);
 			if (status == 0)
@@ -1129,7 +1129,7 @@ static void alloc_single_indirect_block(struct ext2_inode *file_inode,
 		(*no_blks_reqd)++;
 		debug("SIPB %ld: %u\n", si_blockno, *total_remaining_blocks);
 
-		status = ext4fs_devread(si_blockno * fs->sect_perblk,
+		status = ext4fs_devread((lbaint_t)si_blockno * fs->sect_perblk,
 					0, fs->blksz, (char *)si_buffer);
 		memset(si_buffer, '\0', fs->blksz);
 		if (status == 0)
@@ -1193,7 +1193,7 @@ static void alloc_double_indirect_block(struct ext2_inode *file_inode,
 		debug("DIPB %ld: %u\n", di_blockno_parent,
 		      *total_remaining_blocks);
 
-		status = ext4fs_devread(di_blockno_parent *
+		status = ext4fs_devread((lbaint_t)di_blockno_parent *
 					fs->sect_perblk, 0,
 					fs->blksz, (char *)di_parent_buffer);
 
@@ -1224,7 +1224,7 @@ static void alloc_double_indirect_block(struct ext2_inode *file_inode,
 			debug("DICB %ld: %u\n", di_blockno_child,
 			      *total_remaining_blocks);
 
-			status = ext4fs_devread(di_blockno_child *
+			status = ext4fs_devread((lbaint_t)di_blockno_child *
 						fs->sect_perblk, 0,
 						fs->blksz,
 						(char *)di_child_buff);
@@ -1447,7 +1447,7 @@ static struct ext4_extent_header *ext4fs_get_extent_block
 		block = le32_to_cpu(index[i].ei_leaf_hi);
 		block = (block << 32) + le32_to_cpu(index[i].ei_leaf_lo);
 
-		if (ext4fs_devread(block << log2_blksz, 0, fs->blksz, buf))
+		if (ext4fs_devread((lbaint_t)block << log2_blksz, 0, fs->blksz, buf))
 			ext_block = (struct ext4_extent_header *)buf;
 		else
 			return 0;
@@ -1470,7 +1470,7 @@ static int ext4fs_blockgroup
 	debug("ext4fs read %d group descriptor (blkno %ld blkoff %u)\n",
 	      group, blkno, blkoff);
 
-	return ext4fs_devread(blkno << (LOG2_BLOCK_SIZE(data) - log2blksz),
+	return ext4fs_devread((lbaint_t)blkno << (LOG2_BLOCK_SIZE(data) - log2blksz),
 			      blkoff, sizeof(struct ext2_block_group),
 			      (char *)blkgrp);
 }
@@ -1497,7 +1497,7 @@ int ext4fs_read_inode(struct ext2_data *data, int ino, struct ext2_inode *inode)
 	    (ino % __le32_to_cpu(sblock->inodes_per_group)) / inodes_per_block;
 	blkoff = (ino % inodes_per_block) * fs->inodesz;
 	/* Read the inode. */
-	status = ext4fs_devread(blkno << (LOG2_BLOCK_SIZE(data) - log2blksz),
+	status = ext4fs_devread((lbaint_t)blkno << (LOG2_BLOCK_SIZE(data) - log2blksz),
 				blkoff,
 				sizeof(struct ext2_inode), (char *)inode);
 	if (status == 0)
@@ -1597,7 +1597,7 @@ long int read_allocated_block(struct ext2_inode *inode, int fileblock)
 		if ((__le32_to_cpu(inode->b.blocks.indir_block) <<
 		     log2_blksz) != ext4fs_indir1_blkno) {
 			status =
-			    ext4fs_devread(__le32_to_cpu
+			    ext4fs_devread((lbaint_t)__le32_to_cpu
 					   (inode->b.blocks.
 					    indir_block) << log2_blksz, 0,
 					   blksz, (char *)ext4fs_indir1_block);
@@ -1646,7 +1646,7 @@ long int read_allocated_block(struct ext2_inode *inode, int fileblock)
 		if ((__le32_to_cpu(inode->b.blocks.double_indir_block) <<
 		     log2_blksz) != ext4fs_indir1_blkno) {
 			status =
-			    ext4fs_devread(__le32_to_cpu
+			    ext4fs_devread((lbaint_t)__le32_to_cpu
 					   (inode->b.blocks.
 					    double_indir_block) << log2_blksz,
 					   0, blksz,
@@ -1686,7 +1686,7 @@ long int read_allocated_block(struct ext2_inode *inode, int fileblock)
 		}
 		if ((__le32_to_cpu(ext4fs_indir1_block[rblock / perblock]) <<
 		     log2_blksz) != ext4fs_indir2_blkno) {
-			status = ext4fs_devread(__le32_to_cpu
+			status = ext4fs_devread((lbaint_t)__le32_to_cpu
 						(ext4fs_indir1_block
 						 [rblock /
 						  perblock]) << log2_blksz, 0,
@@ -1738,7 +1738,7 @@ long int read_allocated_block(struct ext2_inode *inode, int fileblock)
 		if ((__le32_to_cpu(inode->b.blocks.triple_indir_block) <<
 		     log2_blksz) != ext4fs_indir1_blkno) {
 			status = ext4fs_devread
-			    (__le32_to_cpu(inode->b.blocks.triple_indir_block)
+			    ((lbaint_t)__le32_to_cpu(inode->b.blocks.triple_indir_block)
 			     << log2_blksz, 0, blksz,
 			     (char *)ext4fs_indir1_block);
 			if (status == 0) {
@@ -1778,7 +1778,7 @@ long int read_allocated_block(struct ext2_inode *inode, int fileblock)
 						       perblock_parent]) <<
 		     log2_blksz)
 		    != ext4fs_indir2_blkno) {
-			status = ext4fs_devread(__le32_to_cpu
+			status = ext4fs_devread((lbaint_t)__le32_to_cpu
 						(ext4fs_indir1_block
 						 [rblock /
 						  perblock_parent]) <<
@@ -1823,7 +1823,7 @@ long int read_allocated_block(struct ext2_inode *inode, int fileblock)
 						       perblock_child]) <<
 		     log2_blksz) != ext4fs_indir3_blkno) {
 			status =
-			    ext4fs_devread(__le32_to_cpu
+			    ext4fs_devread((lbaint_t)__le32_to_cpu
 					   (ext4fs_indir2_block
 					    [(rblock / perblock_child)
 					     % (blksz / 4)]) << log2_blksz, 0,
diff --git a/fs/ext4/ext4_journal.c b/fs/ext4/ext4_journal.c
index 81aa5fc..85081df 100644
--- a/fs/ext4/ext4_journal.c
+++ b/fs/ext4/ext4_journal.c
@@ -360,7 +360,7 @@ void recover_transaction(int prev_desc_logical_no)
 			  (struct ext2_inode *)&inode_journal);
 	blknr = read_allocated_block((struct ext2_inode *)
 				     &inode_journal, i);
-	ext4fs_devread(blknr * fs->sect_perblk, 0, fs->blksz, temp_buff);
+	ext4fs_devread((lbaint_t)blknr * fs->sect_perblk, 0, fs->blksz, temp_buff);
 	p_jdb = (char *)temp_buff;
 	jdb = (struct journal_header_t *) temp_buff;
 	ofs = sizeof(struct journal_header_t);
@@ -384,7 +384,7 @@ void recover_transaction(int prev_desc_logical_no)
 				continue;
 		}
 		blknr = read_allocated_block(&inode_journal, i);
-		ext4fs_devread(blknr * fs->sect_perblk, 0,
+		ext4fs_devread((lbaint_t)blknr * fs->sect_perblk, 0,
 			       fs->blksz, metadata_buff);
 		put_ext4((uint64_t)(be32_to_cpu(tag->block) * fs->blksz),
 			 metadata_buff, (uint32_t) fs->blksz);
@@ -431,7 +431,7 @@ int ext4fs_check_journal_state(int recovery_flag)
 
 	ext4fs_read_inode(ext4fs_root, EXT2_JOURNAL_INO, &inode_journal);
 	blknr = read_allocated_block(&inode_journal, EXT2_JOURNAL_SUPERBLOCK);
-	ext4fs_devread(blknr * fs->sect_perblk, 0, fs->blksz, temp_buff);
+	ext4fs_devread((lbaint_t)blknr * fs->sect_perblk, 0, fs->blksz, temp_buff);
 	jsb = (struct journal_superblock_t *) temp_buff;
 
 	if (fs->sb->feature_incompat & EXT3_FEATURE_INCOMPAT_RECOVER) {
@@ -455,7 +455,7 @@ int ext4fs_check_journal_state(int recovery_flag)
 	while (1) {
 		blknr = read_allocated_block(&inode_journal, i);
 		memset(temp_buff1, '\0', fs->blksz);
-		ext4fs_devread(blknr * fs->sect_perblk,
+		ext4fs_devread((lbaint_t)blknr * fs->sect_perblk,
 			       0, fs->blksz, temp_buff1);
 		jdb = (struct journal_header_t *) temp_buff1;
 
@@ -574,7 +574,7 @@ static void update_descriptor_block(long int blknr)
 	ext4fs_read_inode(ext4fs_root, EXT2_JOURNAL_INO, &inode_journal);
 	jsb_blknr = read_allocated_block(&inode_journal,
 					 EXT2_JOURNAL_SUPERBLOCK);
-	ext4fs_devread(jsb_blknr * fs->sect_perblk, 0, fs->blksz, temp_buff);
+	ext4fs_devread((lbaint_t)jsb_blknr * fs->sect_perblk, 0, fs->blksz, temp_buff);
 	jsb = (struct journal_superblock_t *) temp_buff;
 
 	jdb.h_blocktype = cpu_to_be32(EXT3_JOURNAL_DESCRIPTOR_BLOCK);
@@ -624,7 +624,7 @@ static void update_commit_block(long int blknr)
 	ext4fs_read_inode(ext4fs_root, EXT2_JOURNAL_INO, &inode_journal);
 	jsb_blknr = read_allocated_block(&inode_journal,
 					 EXT2_JOURNAL_SUPERBLOCK);
-	ext4fs_devread(jsb_blknr * fs->sect_perblk, 0, fs->blksz, temp_buff);
+	ext4fs_devread((lbaint_t)jsb_blknr * fs->sect_perblk, 0, fs->blksz, temp_buff);
 	jsb = (struct journal_superblock_t *) temp_buff;
 
 	jdb.h_blocktype = cpu_to_be32(EXT3_JOURNAL_COMMIT_BLOCK);
diff --git a/fs/ext4/ext4_write.c b/fs/ext4/ext4_write.c
index 0c1f62b..8dfa1ae 100644
--- a/fs/ext4/ext4_write.c
+++ b/fs/ext4/ext4_write.c
@@ -88,7 +88,7 @@ int ext4fs_get_bgdtable(void)
 	if (!fs->gdtable)
 		return -ENOMEM;
 	/* read the group descriptor table */
-	status = ext4fs_devread(fs->gdtable_blkno * fs->sect_perblk, 0,
+	status = ext4fs_devread((lbaint_t)fs->gdtable_blkno * fs->sect_perblk, 0,
 				fs->blksz * fs->no_blk_pergdt, fs->gdtable);
 	if (status == 0)
 		goto fail;
@@ -142,7 +142,7 @@ static void delete_single_indirect_block(struct ext2_inode *inode)
 		/* journal backup */
 		if (prev_bg_bmap_idx != bg_idx) {
 			status =
-			    ext4fs_devread(bgd[bg_idx].block_id *
+			    ext4fs_devread((lbaint_t)bgd[bg_idx].block_id *
 					   fs->sect_perblk, 0, fs->blksz,
 					   journal_buffer);
 			if (status == 0)
@@ -186,7 +186,7 @@ static void delete_double_indirect_block(struct ext2_inode *inode)
 		}
 		DIB_start_addr = (unsigned int *)di_buffer;
 		blknr = inode->b.blocks.double_indir_block;
-		status = ext4fs_devread(blknr * fs->sect_perblk, 0, fs->blksz,
+		status = ext4fs_devread((lbaint_t)blknr * fs->sect_perblk, 0, fs->blksz,
 					(char *)di_buffer);
 		for (i = 0; i < fs->blksz / sizeof(int); i++) {
 			if (*di_buffer == 0)
@@ -208,7 +208,7 @@ static void delete_double_indirect_block(struct ext2_inode *inode)
 			fs->sb->free_blocks++;
 			/* journal backup */
 			if (prev_bg_bmap_idx != bg_idx) {
-				status = ext4fs_devread(bgd[bg_idx].block_id
+				status = ext4fs_devread((lbaint_t)bgd[bg_idx].block_id
 							* fs->sect_perblk, 0,
 							fs->blksz,
 							journal_buffer);
@@ -238,7 +238,7 @@ static void delete_double_indirect_block(struct ext2_inode *inode)
 		/* journal backup */
 		if (prev_bg_bmap_idx != bg_idx) {
 			memset(journal_buffer, '\0', fs->blksz);
-			status = ext4fs_devread(bgd[bg_idx].block_id *
+			status = ext4fs_devread((lbaint_t)bgd[bg_idx].block_id *
 						fs->sect_perblk, 0, fs->blksz,
 						journal_buffer);
 			if (status == 0)
@@ -287,7 +287,7 @@ static void delete_triple_indirect_block(struct ext2_inode *inode)
 		}
 		tib_start_addr = (unsigned int *)tigp_buffer;
 		blknr = inode->b.blocks.triple_indir_block;
-		status = ext4fs_devread(blknr * fs->sect_perblk, 0, fs->blksz,
+		status = ext4fs_devread((lbaint_t)blknr * fs->sect_perblk, 0, fs->blksz,
 					(char *)tigp_buffer);
 		for (i = 0; i < fs->blksz / sizeof(int); i++) {
 			if (*tigp_buffer == 0)
@@ -298,7 +298,7 @@ static void delete_triple_indirect_block(struct ext2_inode *inode)
 			if (!tip_buffer)
 				goto fail;
 			tipb_start_addr = (unsigned int *)tip_buffer;
-			status = ext4fs_devread((*tigp_buffer) *
+			status = ext4fs_devread((lbaint_t)(*tigp_buffer) *
 						fs->sect_perblk, 0, fs->blksz,
 						(char *)tip_buffer);
 			for (j = 0; j < fs->blksz / sizeof(int); j++) {
@@ -325,7 +325,7 @@ static void delete_triple_indirect_block(struct ext2_inode *inode)
 				if (prev_bg_bmap_idx != bg_idx) {
 					status =
 					    ext4fs_devread(
-							bgd[bg_idx].block_id *
+							(lbaint_t)bgd[bg_idx].block_id *
 							fs->sect_perblk, 0,
 							fs->blksz,
 							journal_buffer);
@@ -365,7 +365,7 @@ static void delete_triple_indirect_block(struct ext2_inode *inode)
 			if (prev_bg_bmap_idx != bg_idx) {
 				memset(journal_buffer, '\0', fs->blksz);
 				status =
-				    ext4fs_devread(bgd[bg_idx].block_id *
+				    ext4fs_devread((lbaint_t)bgd[bg_idx].block_id *
 						   fs->sect_perblk, 0,
 						   fs->blksz, journal_buffer);
 				if (status == 0)
@@ -394,7 +394,7 @@ static void delete_triple_indirect_block(struct ext2_inode *inode)
 		/* journal backup */
 		if (prev_bg_bmap_idx != bg_idx) {
 			memset(journal_buffer, '\0', fs->blksz);
-			status = ext4fs_devread(bgd[bg_idx].block_id *
+			status = ext4fs_devread((lbaint_t)bgd[bg_idx].block_id *
 						fs->sect_perblk, 0, fs->blksz,
 						journal_buffer);
 			if (status == 0)
@@ -480,7 +480,7 @@ static int ext4fs_delete_file(int inodeno)
 			/* journal backup */
 			if (prev_bg_bmap_idx != bg_idx) {
 				status =
-				    ext4fs_devread(bgd[bg_idx].block_id *
+				    ext4fs_devread((lbaint_t)bgd[bg_idx].block_id *
 						   fs->sect_perblk, 0,
 						   fs->blksz, journal_buffer);
 				if (status == 0)
@@ -524,7 +524,7 @@ static int ext4fs_delete_file(int inodeno)
 			/* journal backup */
 			if (prev_bg_bmap_idx != bg_idx) {
 				memset(journal_buffer, '\0', fs->blksz);
-				status = ext4fs_devread(bgd[bg_idx].block_id
+				status = ext4fs_devread((lbaint_t)bgd[bg_idx].block_id
 							* fs->sect_perblk,
 							0, fs->blksz,
 							journal_buffer);
@@ -555,7 +555,7 @@ static int ext4fs_delete_file(int inodeno)
 	if (!read_buffer)
 		goto fail;
 	start_block_address = read_buffer;
-	status = ext4fs_devread(blkno * fs->sect_perblk,
+	status = ext4fs_devread((lbaint_t)blkno * fs->sect_perblk,
 				0, fs->blksz, read_buffer);
 	if (status == 0)
 		goto fail;
@@ -578,7 +578,7 @@ static int ext4fs_delete_file(int inodeno)
 	fs->sb->free_inodes++;
 	/* journal backup */
 	memset(journal_buffer, '\0', fs->blksz);
-	status = ext4fs_devread(bgd[ibmap_idx].inode_id *
+	status = ext4fs_devread((lbaint_t)bgd[ibmap_idx].inode_id *
 				fs->sect_perblk, 0, fs->blksz, journal_buffer);
 	if (status == 0)
 		goto fail;
@@ -653,7 +653,7 @@ int ext4fs_init(void)
 
 	for (i = 0; i < fs->no_blkgrp; i++) {
 		status =
-		    ext4fs_devread(fs->bgd[i].block_id * fs->sect_perblk, 0,
+		    ext4fs_devread((lbaint_t)fs->bgd[i].block_id * fs->sect_perblk, 0,
 				   fs->blksz, (char *)fs->blk_bmaps[i]);
 		if (status == 0)
 			goto fail;
@@ -670,7 +670,7 @@ int ext4fs_init(void)
 	}
 
 	for (i = 0; i < fs->no_blkgrp; i++) {
-		status = ext4fs_devread(fs->bgd[i].inode_id * fs->sect_perblk,
+		status = ext4fs_devread((lbaint_t)fs->bgd[i].inode_id * fs->sect_perblk,
 					0, fs->blksz,
 					(char *)fs->inode_bmaps[i]);
 		if (status == 0)
@@ -710,7 +710,7 @@ void ext4fs_deinit(void)
 				  &inode_journal);
 		blknr = read_allocated_block(&inode_journal,
 					EXT2_JOURNAL_SUPERBLOCK);
-		ext4fs_devread(blknr * fs->sect_perblk, 0, fs->blksz,
+		ext4fs_devread((lbaint_t)blknr * fs->sect_perblk, 0, fs->blksz,
 			       temp_buff);
 		jsb = (struct journal_superblock_t *)temp_buff;
 		jsb->s_start = cpu_to_be32(0);
@@ -934,7 +934,7 @@ int ext4fs_write(const char *fname, unsigned char *buffer,
 			(inodeno % __le32_to_cpu(sblock->inodes_per_group)) /
 			inodes_per_block;
 	blkoff = (inodeno % inodes_per_block) * fs->inodesz;
-	ext4fs_devread(itable_blkno * fs->sect_perblk, 0, fs->blksz, temp_ptr);
+	ext4fs_devread((lbaint_t)itable_blkno * fs->sect_perblk, 0, fs->blksz, temp_ptr);
 	if (ext4fs_log_journal(temp_ptr, itable_blkno))
 		goto fail;
 
@@ -954,7 +954,7 @@ int ext4fs_write(const char *fname, unsigned char *buffer,
 	blkoff = (parent_inodeno % inodes_per_block) * fs->inodesz;
 	if (parent_itable_blkno != itable_blkno) {
 		memset(temp_ptr, '\0', fs->blksz);
-		ext4fs_devread(parent_itable_blkno * fs->sect_perblk,
+		ext4fs_devread((lbaint_t)parent_itable_blkno * fs->sect_perblk,
 			       0, fs->blksz, temp_ptr);
 		if (ext4fs_log_journal(temp_ptr, parent_itable_blkno))
 			goto fail;
diff --git a/fs/ext4/ext4fs.c b/fs/ext4/ext4fs.c
index 1954afb..20ff10f 100644
--- a/fs/ext4/ext4fs.c
+++ b/fs/ext4/ext4fs.c
@@ -62,16 +62,16 @@ int ext4fs_read_file(struct ext2fs_node *node, int pos,
 {
 	struct ext_filesystem *fs = get_fs();
 	int i;
-	int blockcnt;
+	lbaint_t blockcnt;
 	int log2blksz = fs->dev_desc->log2blksz;
 	int log2_fs_blocksize = LOG2_BLOCK_SIZE(node->data) - log2blksz;
 	int blocksize = (1 << (log2_fs_blocksize + log2blksz));
 	unsigned int filesize = __le32_to_cpu(node->inode.size);
-	int previous_block_number = -1;
-	int delayed_start = 0;
-	int delayed_extent = 0;
-	int delayed_skipfirst = 0;
-	int delayed_next = 0;
+	lbaint_t previous_block_number = -1;
+	lbaint_t delayed_start = 0;
+	lbaint_t delayed_extent = 0;
+	lbaint_t delayed_skipfirst = 0;
+	lbaint_t delayed_next = 0;
 	char *delayed_buf = NULL;
 	short status;
 
@@ -82,7 +82,7 @@ int ext4fs_read_file(struct ext2fs_node *node, int pos,
 	blockcnt = ((len + pos) + blocksize - 1) / blocksize;
 
 	for (i = pos / blocksize; i < blockcnt; i++) {
-		int blknr;
+		lbaint_t blknr;
 		int blockoff = pos % blocksize;
 		int blockend = blocksize;
 		int skipfirst = 0;
diff --git a/include/ext4fs.h b/include/ext4fs.h
index 379f7eb..2429380 100644
--- a/include/ext4fs.h
+++ b/include/ext4fs.h
@@ -135,7 +135,7 @@ int ext4fs_mount(unsigned part_length);
 void ext4fs_close(void);
 int ext4fs_ls(const char *dirname);
 void ext4fs_free_node(struct ext2fs_node *node, struct ext2fs_node *currroot);
-int ext4fs_devread(int sector, int byte_offset, int byte_len, char *buf);
+int ext4fs_devread(lbaint_t sector, int byte_offset, int byte_len, char *buf);
 void ext4fs_set_blk_dev(block_dev_desc_t *rbdd, disk_partition_t *info);
 long int read_allocated_block(struct ext2_inode *inode, int fileblock);
 int ext4fs_probe(block_dev_desc_t *fs_dev_desc,
diff --git a/include/ext_common.h b/include/ext_common.h
index 78a7808..694e49f 100644
--- a/include/ext_common.h
+++ b/include/ext_common.h
@@ -180,7 +180,7 @@ struct ext2_data {
 	struct ext2fs_node diropen;
 };
 
-extern unsigned long part_offset;
+extern lbaint_t part_offset;
 
 int do_ext2ls(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
 int do_ext2load(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
diff --git a/include/ide.h b/include/ide.h
index f691a74..24c29f9 100644
--- a/include/ide.h
+++ b/include/ide.h
@@ -44,9 +44,11 @@ extern ulong ide_bus_offset[];
 #ifdef CONFIG_SYS_64BIT_LBA
 typedef uint64_t lbaint_t;
 #define LBAF "%llx"
+#define LBAFu "%llu"
 #else
 typedef ulong lbaint_t;
 #define LBAF "%lx"
+#define LBAFu "%lu"
 #endif
 
 /*
diff --git a/include/part.h b/include/part.h
index 35c1c5b..8388ba8 100644
--- a/include/part.h
+++ b/include/part.h
@@ -97,8 +97,8 @@ typedef struct block_dev_desc {
 #define DEV_TYPE_OPDISK		0x07	/* optical disk */
 
 typedef struct disk_partition {
-	ulong	start;		/* # of first block in partition	*/
-	ulong	size;		/* number of blocks in partition	*/
+	lbaint_t	start;		/* # of first block in partition	*/
+	lbaint_t	size;		/* number of blocks in partition	*/
 	ulong	blksz;		/* block size in bytes			*/
 	uchar	name[32];	/* partition name			*/
 	uchar	type[32];	/* string type description		*/
-- 
1.8.1.2

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [U-Boot] [PATCH] Fix ext2/ext4 filesystem accesses beyond 2TiB
  2013-06-25  6:10                         ` Frederic Leroy
@ 2013-06-25 20:42                           ` Sascha Silbe
  2013-06-26 16:11                             ` [U-Boot] [PATCH v2] " Frédéric Leroy
  0 siblings, 1 reply; 24+ messages in thread
From: Sascha Silbe @ 2013-06-25 20:42 UTC (permalink / raw)
  To: u-boot

Frederic Leroy <fredo@starox.org> writes:

[...]
>  disk/part_efi.c        |  4 ++--

While testing the CuBox patches using buildman, I noticed a warning in
disk/part_iso.c. The following patch should fix it:

diff --git a/disk/part_iso.c b/disk/part_iso.c
index cc323b0..e15e1b9 100644
--- a/disk/part_iso.c
+++ b/disk/part_iso.c
@@ -249,7 +249,7 @@ void print_part_iso(block_dev_desc_t * dev_desc)
        printf("Part   Start     Sect x Size Type\n");
        i=0;
        do {
-               printf (" %2d %8ld %8ld %6ld %.32s\n",
+               printf (" %2d " LBAFu " " LBAFu " %6ld %.32s\n",
                        i, info.start, info.size, info.blksz, info.type);
                i++;
        } while (get_partition_info_iso_verb(dev_desc,i,&info,0)!=-1);


Sascha
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 489 bytes
Desc: not available
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20130625/3c1175f2/attachment.pgp>

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [U-Boot] [PATCH v2] Fix ext2/ext4 filesystem accesses beyond 2TiB
  2013-06-25 20:42                           ` Sascha Silbe
@ 2013-06-26 16:11                             ` Frédéric Leroy
  2013-07-11 10:41                               ` Albert ARIBAUD
  2013-07-16 14:37                               ` [U-Boot] [U-Boot, " Tom Rini
  0 siblings, 2 replies; 24+ messages in thread
From: Frédéric Leroy @ 2013-06-26 16:11 UTC (permalink / raw)
  To: u-boot

With CONFIG_SYS_64BIT_LBA, lbaint_t gets defined as a 64-bit type,
which is required to represent block numbers for storage devices that
exceed 2TiB (the block size usually is 512B), e.g. recent hard drives

We now use lbaint_t for partition offset to reflect the lbaint_t change,
and access partitions beyond or crossing the 2.1TiB limit.
This required changes to signature of ext4fs_devread(), and type of all
variables relatives to block sector.

ext2/ext4 fs uses logical block represented by a 32 bit value. Logical
block is a multiple of device block sector. To avoid overflow problem
when calling ext4fs_devread(), we need to cast the sector parameter.

Signed-off-by: Fr?d?ric Leroy <fredo@starox.org>
---

Changes in v2 :
	- Fix warning in disk/part_efi.c by Sascha Silbe
	- Fix lines over 80 characters
	- Move LBAFu to LBAFU to avoid camel case

 common/cmd_disk.c      |  3 ++-
 disk/part_efi.c        |  6 +++---
 disk/part_iso.c        |  4 ++--
 fs/ext4/dev.c          |  9 +++++----
 fs/ext4/ext4_common.c  | 48 +++++++++++++++++++++++++++---------------------
 fs/ext4/ext4_journal.c | 19 ++++++++++++-------
 fs/ext4/ext4_write.c   | 50 +++++++++++++++++++++++++++++---------------------
 fs/ext4/ext4fs.c       | 14 +++++++-------
 include/ext4fs.h       |  2 +-
 include/ext_common.h   |  2 +-
 include/ide.h          |  2 ++
 include/part.h         |  4 ++--
 12 files changed, 93 insertions(+), 70 deletions(-)

diff --git a/common/cmd_disk.c b/common/cmd_disk.c
index ee4e215..8c4d0bd 100644
--- a/common/cmd_disk.c
+++ b/common/cmd_disk.c
@@ -67,7 +67,8 @@ int common_diskboot(cmd_tbl_t *cmdtp, const char *intf, int argc,
 	       "Name: %.32s  Type: %.32s\n", intf, dev, part, info.name,
 	       info.type);
 
-	debug("First Block: %ld,  # of blocks: %ld, Block Size: %ld\n",
+	debug("First Block: " LBAFU ",  # of blocks: " LBAFU
+	      ", Block Size: %ld\n",
 	      info.start, info.size, info.blksz);
 
 	if (dev_desc->block_read(dev, info.start, 1, (ulong *) addr) != 1) {
diff --git a/disk/part_efi.c b/disk/part_efi.c
index fb5e9f0..732bdb5 100644
--- a/disk/part_efi.c
+++ b/disk/part_efi.c
@@ -200,8 +200,8 @@ int get_partition_info_efi(block_dev_desc_t * dev_desc, int part,
 	uuid_string(gpt_pte[part - 1].unique_partition_guid.b, info->uuid);
 #endif
 
-	debug("%s: start 0x%lX, size 0x%lX, name %s", __func__,
-		info->start, info->size, info->name);
+	debug("%s: start 0x" LBAF ", size 0x" LBAF ", name %s", __func__,
+	      info->start, info->size, info->name);
 
 	/* Remember to free pte */
 	free(gpt_pte);
@@ -431,7 +431,7 @@ int gpt_fill_pte(gpt_header *gpt_h, gpt_entry *gpt_e,
 			gpt_e[i].partition_name[k] =
 				(efi_char16_t)(partitions[i].name[k]);
 
-		debug("%s: name: %s offset[%d]: 0x%x size[%d]: 0x%lx\n",
+		debug("%s: name: %s offset[%d]: 0x%x size[%d]: 0x" LBAF "\n",
 		      __func__, partitions[i].name, i,
 		      offset, i, partitions[i].size);
 	}
diff --git a/disk/part_iso.c b/disk/part_iso.c
index cc323b0..a050c44 100644
--- a/disk/part_iso.c
+++ b/disk/part_iso.c
@@ -249,8 +249,8 @@ void print_part_iso(block_dev_desc_t * dev_desc)
 	printf("Part   Start     Sect x Size Type\n");
 	i=0;
 	do {
-		printf (" %2d %8ld %8ld %6ld %.32s\n",
-			i, info.start, info.size, info.blksz, info.type);
+		printf(" %2d " LBAFU " " LBAFU " %6ld %.32s\n",
+		       i, info.start, info.size, info.blksz, info.type);
 		i++;
 	} while (get_partition_info_iso_verb(dev_desc,i,&info,0)!=-1);
 }
diff --git a/fs/ext4/dev.c b/fs/ext4/dev.c
index 81b7633..2cd182c 100644
--- a/fs/ext4/dev.c
+++ b/fs/ext4/dev.c
@@ -42,7 +42,7 @@
 #include <ext_common.h>
 #include "ext4_common.h"
 
-unsigned long part_offset;
+lbaint_t part_offset;
 
 static block_dev_desc_t *ext4fs_block_dev_desc;
 static disk_partition_t *part_info;
@@ -58,7 +58,7 @@ void ext4fs_set_blk_dev(block_dev_desc_t *rbdd, disk_partition_t *info)
 		get_fs()->dev_desc->log2blksz;
 }
 
-int ext4fs_devread(int sector, int byte_offset, int byte_len, char *buf)
+int ext4fs_devread(lbaint_t sector, int byte_offset, int byte_len, char *buf)
 {
 	unsigned block_len;
 	int log2blksz = ext4fs_block_dev_desc->log2blksz;
@@ -74,7 +74,8 @@ int ext4fs_devread(int sector, int byte_offset, int byte_len, char *buf)
 	if ((sector < 0) ||
 	    ((sector + ((byte_offset + byte_len - 1) >> log2blksz))
 	     >= part_info->size)) {
-		printf("%s read outside partition %d\n", __func__, sector);
+		printf("%s read outside partition " LBAFU "\n", __func__,
+		       sector);
 		return 0;
 	}
 
@@ -82,7 +83,7 @@ int ext4fs_devread(int sector, int byte_offset, int byte_len, char *buf)
 	sector += byte_offset >> log2blksz;
 	byte_offset &= ext4fs_block_dev_desc->blksz - 1;
 
-	debug(" <%d, %d, %d>\n", sector, byte_offset, byte_len);
+	debug(" <" LBAFU ", %d, %d>\n", sector, byte_offset, byte_len);
 
 	if (byte_offset != 0) {
 		/* read first part which isn't aligned with start of sector */
diff --git a/fs/ext4/ext4_common.c b/fs/ext4/ext4_common.c
index 58880b4..2776293 100644
--- a/fs/ext4/ext4_common.c
+++ b/fs/ext4/ext4_common.c
@@ -84,7 +84,7 @@ void put_ext4(uint64_t off, void *buf, uint32_t size)
 
 	if ((startblock + (size >> log2blksz)) >
 	    (part_offset + fs->total_sect)) {
-		printf("part_offset is %lu\n", part_offset);
+		printf("part_offset is " LBAFU "\n", part_offset);
 		printf("total_sector is %llu\n", fs->total_sect);
 		printf("error: overflow occurs\n");
 		return;
@@ -405,7 +405,7 @@ restart:
 		previous_blknr = root_blknr;
 	}
 
-	status = ext4fs_devread(first_block_no_of_root
+	status = ext4fs_devread((lbaint_t)first_block_no_of_root
 				* fs->sect_perblk,
 				0, fs->blksz, root_first_block_buffer);
 	if (status == 0)
@@ -545,7 +545,7 @@ static int search_dir(struct ext2_inode *parent_inode, char *dirname)
 		if (!block_buffer)
 			goto fail;
 
-		status = ext4fs_devread(blknr * fs->sect_perblk,
+		status = ext4fs_devread((lbaint_t)blknr * fs->sect_perblk,
 					0, fs->blksz, (char *)block_buffer);
 		if (status == 0)
 			goto fail;
@@ -783,7 +783,7 @@ static int check_filename(char *filename, unsigned int blknr)
 	if (!root_first_block_buffer)
 		return -ENOMEM;
 	root_first_block_addr = root_first_block_buffer;
-	status = ext4fs_devread(first_block_no_of_root *
+	status = ext4fs_devread((lbaint_t)first_block_no_of_root *
 				fs->sect_perblk, 0,
 				fs->blksz, root_first_block_buffer);
 	if (status == 0)
@@ -895,7 +895,8 @@ long int ext4fs_get_new_blk_no(void)
 				fs->first_pass_bbmap++;
 				bgd[i].free_blocks--;
 				fs->sb->free_blocks--;
-				status = ext4fs_devread(bgd[i].block_id *
+				status = ext4fs_devread((lbaint_t)
+							bgd[i].block_id *
 							fs->sect_perblk, 0,
 							fs->blksz,
 							journal_buffer);
@@ -957,7 +958,7 @@ restart:
 		/* journal backup */
 		if (prev_bg_bitmap_index != bg_idx) {
 			memset(journal_buffer, '\0', fs->blksz);
-			status = ext4fs_devread(bgd[bg_idx].block_id
+			status = ext4fs_devread((lbaint_t)bgd[bg_idx].block_id
 						* fs->sect_perblk,
 						0, fs->blksz, journal_buffer);
 			if (status == 0)
@@ -1026,7 +1027,8 @@ int ext4fs_get_new_inode_no(void)
 				bgd[i].free_inodes--;
 				bgd[i].bg_itable_unused--;
 				fs->sb->free_inodes--;
-				status = ext4fs_devread(bgd[i].inode_id *
+				status = ext4fs_devread((lbaint_t)
+							bgd[i].inode_id *
 							fs->sect_perblk, 0,
 							fs->blksz,
 							journal_buffer);
@@ -1067,7 +1069,8 @@ restart:
 		/* journal backup */
 		if (prev_inode_bitmap_index != ibmap_idx) {
 			memset(journal_buffer, '\0', fs->blksz);
-			status = ext4fs_devread(bgd[ibmap_idx].inode_id
+			status = ext4fs_devread((lbaint_t)
+						bgd[ibmap_idx].inode_id
 						* fs->sect_perblk,
 						0, fs->blksz, journal_buffer);
 			if (status == 0)
@@ -1129,7 +1132,7 @@ static void alloc_single_indirect_block(struct ext2_inode *file_inode,
 		(*no_blks_reqd)++;
 		debug("SIPB %ld: %u\n", si_blockno, *total_remaining_blocks);
 
-		status = ext4fs_devread(si_blockno * fs->sect_perblk,
+		status = ext4fs_devread((lbaint_t)si_blockno * fs->sect_perblk,
 					0, fs->blksz, (char *)si_buffer);
 		memset(si_buffer, '\0', fs->blksz);
 		if (status == 0)
@@ -1193,7 +1196,7 @@ static void alloc_double_indirect_block(struct ext2_inode *file_inode,
 		debug("DIPB %ld: %u\n", di_blockno_parent,
 		      *total_remaining_blocks);
 
-		status = ext4fs_devread(di_blockno_parent *
+		status = ext4fs_devread((lbaint_t)di_blockno_parent *
 					fs->sect_perblk, 0,
 					fs->blksz, (char *)di_parent_buffer);
 
@@ -1224,7 +1227,7 @@ static void alloc_double_indirect_block(struct ext2_inode *file_inode,
 			debug("DICB %ld: %u\n", di_blockno_child,
 			      *total_remaining_blocks);
 
-			status = ext4fs_devread(di_blockno_child *
+			status = ext4fs_devread((lbaint_t)di_blockno_child *
 						fs->sect_perblk, 0,
 						fs->blksz,
 						(char *)di_child_buff);
@@ -1447,7 +1450,8 @@ static struct ext4_extent_header *ext4fs_get_extent_block
 		block = le32_to_cpu(index[i].ei_leaf_hi);
 		block = (block << 32) + le32_to_cpu(index[i].ei_leaf_lo);
 
-		if (ext4fs_devread(block << log2_blksz, 0, fs->blksz, buf))
+		if (ext4fs_devread((lbaint_t)block << log2_blksz, 0, fs->blksz,
+				   buf))
 			ext_block = (struct ext4_extent_header *)buf;
 		else
 			return 0;
@@ -1470,7 +1474,8 @@ static int ext4fs_blockgroup
 	debug("ext4fs read %d group descriptor (blkno %ld blkoff %u)\n",
 	      group, blkno, blkoff);
 
-	return ext4fs_devread(blkno << (LOG2_BLOCK_SIZE(data) - log2blksz),
+	return ext4fs_devread((lbaint_t)blkno <<
+			      (LOG2_BLOCK_SIZE(data) - log2blksz),
 			      blkoff, sizeof(struct ext2_block_group),
 			      (char *)blkgrp);
 }
@@ -1497,8 +1502,8 @@ int ext4fs_read_inode(struct ext2_data *data, int ino, struct ext2_inode *inode)
 	    (ino % __le32_to_cpu(sblock->inodes_per_group)) / inodes_per_block;
 	blkoff = (ino % inodes_per_block) * fs->inodesz;
 	/* Read the inode. */
-	status = ext4fs_devread(blkno << (LOG2_BLOCK_SIZE(data) - log2blksz),
-				blkoff,
+	status = ext4fs_devread((lbaint_t)blkno << (LOG2_BLOCK_SIZE(data) -
+				log2blksz), blkoff,
 				sizeof(struct ext2_inode), (char *)inode);
 	if (status == 0)
 		return 0;
@@ -1597,7 +1602,7 @@ long int read_allocated_block(struct ext2_inode *inode, int fileblock)
 		if ((__le32_to_cpu(inode->b.blocks.indir_block) <<
 		     log2_blksz) != ext4fs_indir1_blkno) {
 			status =
-			    ext4fs_devread(__le32_to_cpu
+			    ext4fs_devread((lbaint_t)__le32_to_cpu
 					   (inode->b.blocks.
 					    indir_block) << log2_blksz, 0,
 					   blksz, (char *)ext4fs_indir1_block);
@@ -1646,7 +1651,7 @@ long int read_allocated_block(struct ext2_inode *inode, int fileblock)
 		if ((__le32_to_cpu(inode->b.blocks.double_indir_block) <<
 		     log2_blksz) != ext4fs_indir1_blkno) {
 			status =
-			    ext4fs_devread(__le32_to_cpu
+			    ext4fs_devread((lbaint_t)__le32_to_cpu
 					   (inode->b.blocks.
 					    double_indir_block) << log2_blksz,
 					   0, blksz,
@@ -1686,7 +1691,7 @@ long int read_allocated_block(struct ext2_inode *inode, int fileblock)
 		}
 		if ((__le32_to_cpu(ext4fs_indir1_block[rblock / perblock]) <<
 		     log2_blksz) != ext4fs_indir2_blkno) {
-			status = ext4fs_devread(__le32_to_cpu
+			status = ext4fs_devread((lbaint_t)__le32_to_cpu
 						(ext4fs_indir1_block
 						 [rblock /
 						  perblock]) << log2_blksz, 0,
@@ -1738,7 +1743,8 @@ long int read_allocated_block(struct ext2_inode *inode, int fileblock)
 		if ((__le32_to_cpu(inode->b.blocks.triple_indir_block) <<
 		     log2_blksz) != ext4fs_indir1_blkno) {
 			status = ext4fs_devread
-			    (__le32_to_cpu(inode->b.blocks.triple_indir_block)
+			    ((lbaint_t)
+			     __le32_to_cpu(inode->b.blocks.triple_indir_block)
 			     << log2_blksz, 0, blksz,
 			     (char *)ext4fs_indir1_block);
 			if (status == 0) {
@@ -1778,7 +1784,7 @@ long int read_allocated_block(struct ext2_inode *inode, int fileblock)
 						       perblock_parent]) <<
 		     log2_blksz)
 		    != ext4fs_indir2_blkno) {
-			status = ext4fs_devread(__le32_to_cpu
+			status = ext4fs_devread((lbaint_t)__le32_to_cpu
 						(ext4fs_indir1_block
 						 [rblock /
 						  perblock_parent]) <<
@@ -1823,7 +1829,7 @@ long int read_allocated_block(struct ext2_inode *inode, int fileblock)
 						       perblock_child]) <<
 		     log2_blksz) != ext4fs_indir3_blkno) {
 			status =
-			    ext4fs_devread(__le32_to_cpu
+			    ext4fs_devread((lbaint_t)__le32_to_cpu
 					   (ext4fs_indir2_block
 					    [(rblock / perblock_child)
 					     % (blksz / 4)]) << log2_blksz, 0,
diff --git a/fs/ext4/ext4_journal.c b/fs/ext4/ext4_journal.c
index 81aa5fc..a540367 100644
--- a/fs/ext4/ext4_journal.c
+++ b/fs/ext4/ext4_journal.c
@@ -360,7 +360,8 @@ void recover_transaction(int prev_desc_logical_no)
 			  (struct ext2_inode *)&inode_journal);
 	blknr = read_allocated_block((struct ext2_inode *)
 				     &inode_journal, i);
-	ext4fs_devread(blknr * fs->sect_perblk, 0, fs->blksz, temp_buff);
+	ext4fs_devread((lbaint_t)blknr * fs->sect_perblk, 0, fs->blksz,
+		       temp_buff);
 	p_jdb = (char *)temp_buff;
 	jdb = (struct journal_header_t *) temp_buff;
 	ofs = sizeof(struct journal_header_t);
@@ -384,7 +385,7 @@ void recover_transaction(int prev_desc_logical_no)
 				continue;
 		}
 		blknr = read_allocated_block(&inode_journal, i);
-		ext4fs_devread(blknr * fs->sect_perblk, 0,
+		ext4fs_devread((lbaint_t)blknr * fs->sect_perblk, 0,
 			       fs->blksz, metadata_buff);
 		put_ext4((uint64_t)(be32_to_cpu(tag->block) * fs->blksz),
 			 metadata_buff, (uint32_t) fs->blksz);
@@ -431,7 +432,8 @@ int ext4fs_check_journal_state(int recovery_flag)
 
 	ext4fs_read_inode(ext4fs_root, EXT2_JOURNAL_INO, &inode_journal);
 	blknr = read_allocated_block(&inode_journal, EXT2_JOURNAL_SUPERBLOCK);
-	ext4fs_devread(blknr * fs->sect_perblk, 0, fs->blksz, temp_buff);
+	ext4fs_devread((lbaint_t)blknr * fs->sect_perblk, 0, fs->blksz,
+		       temp_buff);
 	jsb = (struct journal_superblock_t *) temp_buff;
 
 	if (fs->sb->feature_incompat & EXT3_FEATURE_INCOMPAT_RECOVER) {
@@ -455,7 +457,7 @@ int ext4fs_check_journal_state(int recovery_flag)
 	while (1) {
 		blknr = read_allocated_block(&inode_journal, i);
 		memset(temp_buff1, '\0', fs->blksz);
-		ext4fs_devread(blknr * fs->sect_perblk,
+		ext4fs_devread((lbaint_t)blknr * fs->sect_perblk,
 			       0, fs->blksz, temp_buff1);
 		jdb = (struct journal_header_t *) temp_buff1;
 
@@ -574,7 +576,8 @@ static void update_descriptor_block(long int blknr)
 	ext4fs_read_inode(ext4fs_root, EXT2_JOURNAL_INO, &inode_journal);
 	jsb_blknr = read_allocated_block(&inode_journal,
 					 EXT2_JOURNAL_SUPERBLOCK);
-	ext4fs_devread(jsb_blknr * fs->sect_perblk, 0, fs->blksz, temp_buff);
+	ext4fs_devread((lbaint_t)jsb_blknr * fs->sect_perblk, 0, fs->blksz,
+		       temp_buff);
 	jsb = (struct journal_superblock_t *) temp_buff;
 
 	jdb.h_blocktype = cpu_to_be32(EXT3_JOURNAL_DESCRIPTOR_BLOCK);
@@ -621,10 +624,12 @@ static void update_commit_block(long int blknr)
 	if (!temp_buff)
 		return;
 
-	ext4fs_read_inode(ext4fs_root, EXT2_JOURNAL_INO, &inode_journal);
+	ext4fs_read_inode(ext4fs_root, EXT2_JOURNAL_INO,
+			  &inode_journal);
 	jsb_blknr = read_allocated_block(&inode_journal,
 					 EXT2_JOURNAL_SUPERBLOCK);
-	ext4fs_devread(jsb_blknr * fs->sect_perblk, 0, fs->blksz, temp_buff);
+	ext4fs_devread((lbaint_t)jsb_blknr * fs->sect_perblk, 0, fs->blksz,
+		       temp_buff);
 	jsb = (struct journal_superblock_t *) temp_buff;
 
 	jdb.h_blocktype = cpu_to_be32(EXT3_JOURNAL_COMMIT_BLOCK);
diff --git a/fs/ext4/ext4_write.c b/fs/ext4/ext4_write.c
index 0c1f62b..501b95a 100644
--- a/fs/ext4/ext4_write.c
+++ b/fs/ext4/ext4_write.c
@@ -88,8 +88,8 @@ int ext4fs_get_bgdtable(void)
 	if (!fs->gdtable)
 		return -ENOMEM;
 	/* read the group descriptor table */
-	status = ext4fs_devread(fs->gdtable_blkno * fs->sect_perblk, 0,
-				fs->blksz * fs->no_blk_pergdt, fs->gdtable);
+	status = ext4fs_devread((lbaint_t)fs->gdtable_blkno * fs->sect_perblk,
+				0, fs->blksz * fs->no_blk_pergdt, fs->gdtable);
 	if (status == 0)
 		goto fail;
 
@@ -142,7 +142,7 @@ static void delete_single_indirect_block(struct ext2_inode *inode)
 		/* journal backup */
 		if (prev_bg_bmap_idx != bg_idx) {
 			status =
-			    ext4fs_devread(bgd[bg_idx].block_id *
+			    ext4fs_devread((lbaint_t)bgd[bg_idx].block_id *
 					   fs->sect_perblk, 0, fs->blksz,
 					   journal_buffer);
 			if (status == 0)
@@ -186,8 +186,8 @@ static void delete_double_indirect_block(struct ext2_inode *inode)
 		}
 		DIB_start_addr = (unsigned int *)di_buffer;
 		blknr = inode->b.blocks.double_indir_block;
-		status = ext4fs_devread(blknr * fs->sect_perblk, 0, fs->blksz,
-					(char *)di_buffer);
+		status = ext4fs_devread((lbaint_t)blknr * fs->sect_perblk, 0,
+					fs->blksz, (char *)di_buffer);
 		for (i = 0; i < fs->blksz / sizeof(int); i++) {
 			if (*di_buffer == 0)
 				break;
@@ -208,7 +208,8 @@ static void delete_double_indirect_block(struct ext2_inode *inode)
 			fs->sb->free_blocks++;
 			/* journal backup */
 			if (prev_bg_bmap_idx != bg_idx) {
-				status = ext4fs_devread(bgd[bg_idx].block_id
+				status = ext4fs_devread((lbaint_t)
+							bgd[bg_idx].block_id
 							* fs->sect_perblk, 0,
 							fs->blksz,
 							journal_buffer);
@@ -238,7 +239,7 @@ static void delete_double_indirect_block(struct ext2_inode *inode)
 		/* journal backup */
 		if (prev_bg_bmap_idx != bg_idx) {
 			memset(journal_buffer, '\0', fs->blksz);
-			status = ext4fs_devread(bgd[bg_idx].block_id *
+			status = ext4fs_devread((lbaint_t)bgd[bg_idx].block_id *
 						fs->sect_perblk, 0, fs->blksz,
 						journal_buffer);
 			if (status == 0)
@@ -287,8 +288,8 @@ static void delete_triple_indirect_block(struct ext2_inode *inode)
 		}
 		tib_start_addr = (unsigned int *)tigp_buffer;
 		blknr = inode->b.blocks.triple_indir_block;
-		status = ext4fs_devread(blknr * fs->sect_perblk, 0, fs->blksz,
-					(char *)tigp_buffer);
+		status = ext4fs_devread((lbaint_t)blknr * fs->sect_perblk, 0,
+					fs->blksz, (char *)tigp_buffer);
 		for (i = 0; i < fs->blksz / sizeof(int); i++) {
 			if (*tigp_buffer == 0)
 				break;
@@ -298,7 +299,7 @@ static void delete_triple_indirect_block(struct ext2_inode *inode)
 			if (!tip_buffer)
 				goto fail;
 			tipb_start_addr = (unsigned int *)tip_buffer;
-			status = ext4fs_devread((*tigp_buffer) *
+			status = ext4fs_devread((lbaint_t)(*tigp_buffer) *
 						fs->sect_perblk, 0, fs->blksz,
 						(char *)tip_buffer);
 			for (j = 0; j < fs->blksz / sizeof(int); j++) {
@@ -325,6 +326,7 @@ static void delete_triple_indirect_block(struct ext2_inode *inode)
 				if (prev_bg_bmap_idx != bg_idx) {
 					status =
 					    ext4fs_devread(
+							(lbaint_t)
 							bgd[bg_idx].block_id *
 							fs->sect_perblk, 0,
 							fs->blksz,
@@ -365,7 +367,8 @@ static void delete_triple_indirect_block(struct ext2_inode *inode)
 			if (prev_bg_bmap_idx != bg_idx) {
 				memset(journal_buffer, '\0', fs->blksz);
 				status =
-				    ext4fs_devread(bgd[bg_idx].block_id *
+				    ext4fs_devread((lbaint_t)
+						   bgd[bg_idx].block_id *
 						   fs->sect_perblk, 0,
 						   fs->blksz, journal_buffer);
 				if (status == 0)
@@ -394,7 +397,7 @@ static void delete_triple_indirect_block(struct ext2_inode *inode)
 		/* journal backup */
 		if (prev_bg_bmap_idx != bg_idx) {
 			memset(journal_buffer, '\0', fs->blksz);
-			status = ext4fs_devread(bgd[bg_idx].block_id *
+			status = ext4fs_devread((lbaint_t)bgd[bg_idx].block_id *
 						fs->sect_perblk, 0, fs->blksz,
 						journal_buffer);
 			if (status == 0)
@@ -480,7 +483,8 @@ static int ext4fs_delete_file(int inodeno)
 			/* journal backup */
 			if (prev_bg_bmap_idx != bg_idx) {
 				status =
-				    ext4fs_devread(bgd[bg_idx].block_id *
+				    ext4fs_devread((lbaint_t)
+						   bgd[bg_idx].block_id *
 						   fs->sect_perblk, 0,
 						   fs->blksz, journal_buffer);
 				if (status == 0)
@@ -524,7 +528,8 @@ static int ext4fs_delete_file(int inodeno)
 			/* journal backup */
 			if (prev_bg_bmap_idx != bg_idx) {
 				memset(journal_buffer, '\0', fs->blksz);
-				status = ext4fs_devread(bgd[bg_idx].block_id
+				status = ext4fs_devread((lbaint_t)
+							bgd[bg_idx].block_id
 							* fs->sect_perblk,
 							0, fs->blksz,
 							journal_buffer);
@@ -555,7 +560,7 @@ static int ext4fs_delete_file(int inodeno)
 	if (!read_buffer)
 		goto fail;
 	start_block_address = read_buffer;
-	status = ext4fs_devread(blkno * fs->sect_perblk,
+	status = ext4fs_devread((lbaint_t)blkno * fs->sect_perblk,
 				0, fs->blksz, read_buffer);
 	if (status == 0)
 		goto fail;
@@ -578,7 +583,7 @@ static int ext4fs_delete_file(int inodeno)
 	fs->sb->free_inodes++;
 	/* journal backup */
 	memset(journal_buffer, '\0', fs->blksz);
-	status = ext4fs_devread(bgd[ibmap_idx].inode_id *
+	status = ext4fs_devread((lbaint_t)bgd[ibmap_idx].inode_id *
 				fs->sect_perblk, 0, fs->blksz, journal_buffer);
 	if (status == 0)
 		goto fail;
@@ -653,7 +658,8 @@ int ext4fs_init(void)
 
 	for (i = 0; i < fs->no_blkgrp; i++) {
 		status =
-		    ext4fs_devread(fs->bgd[i].block_id * fs->sect_perblk, 0,
+		    ext4fs_devread((lbaint_t)fs->bgd[i].block_id *
+				   fs->sect_perblk, 0,
 				   fs->blksz, (char *)fs->blk_bmaps[i]);
 		if (status == 0)
 			goto fail;
@@ -670,7 +676,8 @@ int ext4fs_init(void)
 	}
 
 	for (i = 0; i < fs->no_blkgrp; i++) {
-		status = ext4fs_devread(fs->bgd[i].inode_id * fs->sect_perblk,
+		status = ext4fs_devread((lbaint_t)fs->bgd[i].inode_id *
+					fs->sect_perblk,
 					0, fs->blksz,
 					(char *)fs->inode_bmaps[i]);
 		if (status == 0)
@@ -710,7 +717,7 @@ void ext4fs_deinit(void)
 				  &inode_journal);
 		blknr = read_allocated_block(&inode_journal,
 					EXT2_JOURNAL_SUPERBLOCK);
-		ext4fs_devread(blknr * fs->sect_perblk, 0, fs->blksz,
+		ext4fs_devread((lbaint_t)blknr * fs->sect_perblk, 0, fs->blksz,
 			       temp_buff);
 		jsb = (struct journal_superblock_t *)temp_buff;
 		jsb->s_start = cpu_to_be32(0);
@@ -934,7 +941,8 @@ int ext4fs_write(const char *fname, unsigned char *buffer,
 			(inodeno % __le32_to_cpu(sblock->inodes_per_group)) /
 			inodes_per_block;
 	blkoff = (inodeno % inodes_per_block) * fs->inodesz;
-	ext4fs_devread(itable_blkno * fs->sect_perblk, 0, fs->blksz, temp_ptr);
+	ext4fs_devread((lbaint_t)itable_blkno * fs->sect_perblk, 0, fs->blksz,
+		       temp_ptr);
 	if (ext4fs_log_journal(temp_ptr, itable_blkno))
 		goto fail;
 
@@ -954,7 +962,7 @@ int ext4fs_write(const char *fname, unsigned char *buffer,
 	blkoff = (parent_inodeno % inodes_per_block) * fs->inodesz;
 	if (parent_itable_blkno != itable_blkno) {
 		memset(temp_ptr, '\0', fs->blksz);
-		ext4fs_devread(parent_itable_blkno * fs->sect_perblk,
+		ext4fs_devread((lbaint_t)parent_itable_blkno * fs->sect_perblk,
 			       0, fs->blksz, temp_ptr);
 		if (ext4fs_log_journal(temp_ptr, parent_itable_blkno))
 			goto fail;
diff --git a/fs/ext4/ext4fs.c b/fs/ext4/ext4fs.c
index 1954afb..20ff10f 100644
--- a/fs/ext4/ext4fs.c
+++ b/fs/ext4/ext4fs.c
@@ -62,16 +62,16 @@ int ext4fs_read_file(struct ext2fs_node *node, int pos,
 {
 	struct ext_filesystem *fs = get_fs();
 	int i;
-	int blockcnt;
+	lbaint_t blockcnt;
 	int log2blksz = fs->dev_desc->log2blksz;
 	int log2_fs_blocksize = LOG2_BLOCK_SIZE(node->data) - log2blksz;
 	int blocksize = (1 << (log2_fs_blocksize + log2blksz));
 	unsigned int filesize = __le32_to_cpu(node->inode.size);
-	int previous_block_number = -1;
-	int delayed_start = 0;
-	int delayed_extent = 0;
-	int delayed_skipfirst = 0;
-	int delayed_next = 0;
+	lbaint_t previous_block_number = -1;
+	lbaint_t delayed_start = 0;
+	lbaint_t delayed_extent = 0;
+	lbaint_t delayed_skipfirst = 0;
+	lbaint_t delayed_next = 0;
 	char *delayed_buf = NULL;
 	short status;
 
@@ -82,7 +82,7 @@ int ext4fs_read_file(struct ext2fs_node *node, int pos,
 	blockcnt = ((len + pos) + blocksize - 1) / blocksize;
 
 	for (i = pos / blocksize; i < blockcnt; i++) {
-		int blknr;
+		lbaint_t blknr;
 		int blockoff = pos % blocksize;
 		int blockend = blocksize;
 		int skipfirst = 0;
diff --git a/include/ext4fs.h b/include/ext4fs.h
index 379f7eb..2429380 100644
--- a/include/ext4fs.h
+++ b/include/ext4fs.h
@@ -135,7 +135,7 @@ int ext4fs_mount(unsigned part_length);
 void ext4fs_close(void);
 int ext4fs_ls(const char *dirname);
 void ext4fs_free_node(struct ext2fs_node *node, struct ext2fs_node *currroot);
-int ext4fs_devread(int sector, int byte_offset, int byte_len, char *buf);
+int ext4fs_devread(lbaint_t sector, int byte_offset, int byte_len, char *buf);
 void ext4fs_set_blk_dev(block_dev_desc_t *rbdd, disk_partition_t *info);
 long int read_allocated_block(struct ext2_inode *inode, int fileblock);
 int ext4fs_probe(block_dev_desc_t *fs_dev_desc,
diff --git a/include/ext_common.h b/include/ext_common.h
index 78a7808..694e49f 100644
--- a/include/ext_common.h
+++ b/include/ext_common.h
@@ -180,7 +180,7 @@ struct ext2_data {
 	struct ext2fs_node diropen;
 };
 
-extern unsigned long part_offset;
+extern lbaint_t part_offset;
 
 int do_ext2ls(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
 int do_ext2load(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
diff --git a/include/ide.h b/include/ide.h
index afea85c..d312a29 100644
--- a/include/ide.h
+++ b/include/ide.h
@@ -44,9 +44,11 @@ extern ulong ide_bus_offset[];
 #ifdef CONFIG_SYS_64BIT_LBA
 typedef uint64_t lbaint_t;
 #define LBAF "%llx"
+#define LBAFU "%llu"
 #else
 typedef ulong lbaint_t;
 #define LBAF "%lx"
+#define LBAFU "%lu"
 #endif
 
 /*
diff --git a/include/part.h b/include/part.h
index f7c7cc5..8d5ea5d 100644
--- a/include/part.h
+++ b/include/part.h
@@ -97,8 +97,8 @@ typedef struct block_dev_desc {
 #define DEV_TYPE_OPDISK		0x07	/* optical disk */
 
 typedef struct disk_partition {
-	ulong	start;		/* # of first block in partition	*/
-	ulong	size;		/* number of blocks in partition	*/
+	lbaint_t	start;	/* # of first block in partition	*/
+	lbaint_t	size;	/* number of blocks in partition	*/
 	ulong	blksz;		/* block size in bytes			*/
 	uchar	name[32];	/* partition name			*/
 	uchar	type[32];	/* string type description		*/
-- 
1.8.1.2

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [U-Boot] Fix block device accesses beyond 2TiB
  2013-06-14 11:07       ` [U-Boot] [PATCH] Fix block device accesses beyond 2TiB Sascha Silbe
  2013-06-17 20:26         ` Marek Vasut
@ 2013-06-26 20:25         ` Tom Rini
  1 sibling, 0 replies; 24+ messages in thread
From: Tom Rini @ 2013-06-26 20:25 UTC (permalink / raw)
  To: u-boot

On Fri, Jun 14, 2013 at 01:07:25PM +0200, Sascha Silbe wrote:

> With CONFIG_SYS_64BIT_LBA, lbaint_t gets defined as a 64-bit type,
> which is required to represent block numbers for storage devices that
> exceed 2TiB (the block size usually is 512B), e.g. recent hard drives.
> 
> For some obscure reason, the current U-Boot code uses lbaint_t for the
> number of blocks to read (a rather optimistic estimation of how RAM
> sizes will evolve), but not for the starting address. Trying to access
> blocks beyond the 2TiB boundary will simply wrap around and read a
> block within the 0..2TiB range.
> 
> We now use lbaint_t for block start addresses, too. This required
> changes to all block drivers as the signature of block_read(),
> block_write() and block_erase() in block_dev_desc_t changed.
> 
> Signed-off-by: Sascha Silbe <t-uboot@infra-silbe.de>

Applied to u-boot/master, thanks!

-- 
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20130626/d8f276e1/attachment.pgp>

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [U-Boot] [PATCH v2] Fix ext2/ext4 filesystem accesses beyond 2TiB
  2013-06-26 16:11                             ` [U-Boot] [PATCH v2] " Frédéric Leroy
@ 2013-07-11 10:41                               ` Albert ARIBAUD
  2013-07-16 14:37                               ` [U-Boot] [U-Boot, " Tom Rini
  1 sibling, 0 replies; 24+ messages in thread
From: Albert ARIBAUD @ 2013-07-11 10:41 UTC (permalink / raw)
  To: u-boot

Hi Tom,

On Wed, 26 Jun 2013 18:11:25 +0200, Fr?d?ric Leroy <fredo@starox.org>
wrote:

> With CONFIG_SYS_64BIT_LBA, lbaint_t gets defined as a 64-bit type,
> which is required to represent block numbers for storage devices that
> exceed 2TiB (the block size usually is 512B), e.g. recent hard drives
> 
> We now use lbaint_t for partition offset to reflect the lbaint_t change,
> and access partitions beyond or crossing the 2.1TiB limit.
> This required changes to signature of ext4fs_devread(), and type of all
> variables relatives to block sector.
> 
> ext2/ext4 fs uses logical block represented by a 32 bit value. Logical
> block is a multiple of device block sector. To avoid overflow problem
> when calling ext4fs_devread(), we need to cast the sector parameter.
> 
> Signed-off-by: Fr?d?ric Leroy <fredo@starox.org>
> ---
> 
> Changes in v2 :
> 	- Fix warning in disk/part_efi.c by Sascha Silbe
> 	- Fix lines over 80 characters
> 	- Move LBAFu to LBAFU to avoid camel case
> 
>  common/cmd_disk.c      |  3 ++-
>  disk/part_efi.c        |  6 +++---
>  disk/part_iso.c        |  4 ++--
>  fs/ext4/dev.c          |  9 +++++----
>  fs/ext4/ext4_common.c  | 48 +++++++++++++++++++++++++++---------------------
>  fs/ext4/ext4_journal.c | 19 ++++++++++++-------
>  fs/ext4/ext4_write.c   | 50 +++++++++++++++++++++++++++++---------------------
>  fs/ext4/ext4fs.c       | 14 +++++++-------
>  include/ext4fs.h       |  2 +-
>  include/ext_common.h   |  2 +-
>  include/ide.h          |  2 ++
>  include/part.h         |  4 ++--
>  12 files changed, 93 insertions(+), 70 deletions(-)
> 
> diff --git a/common/cmd_disk.c b/common/cmd_disk.c
> index ee4e215..8c4d0bd 100644
> --- a/common/cmd_disk.c
> +++ b/common/cmd_disk.c
> @@ -67,7 +67,8 @@ int common_diskboot(cmd_tbl_t *cmdtp, const char *intf, int argc,
>  	       "Name: %.32s  Type: %.32s\n", intf, dev, part, info.name,
>  	       info.type);
>  
> -	debug("First Block: %ld,  # of blocks: %ld, Block Size: %ld\n",
> +	debug("First Block: " LBAFU ",  # of blocks: " LBAFU
> +	      ", Block Size: %ld\n",
>  	      info.start, info.size, info.blksz);
>  
>  	if (dev_desc->block_read(dev, info.start, 1, (ulong *) addr) != 1) {
> diff --git a/disk/part_efi.c b/disk/part_efi.c
> index fb5e9f0..732bdb5 100644
> --- a/disk/part_efi.c
> +++ b/disk/part_efi.c
> @@ -200,8 +200,8 @@ int get_partition_info_efi(block_dev_desc_t * dev_desc, int part,
>  	uuid_string(gpt_pte[part - 1].unique_partition_guid.b, info->uuid);
>  #endif
>  
> -	debug("%s: start 0x%lX, size 0x%lX, name %s", __func__,
> -		info->start, info->size, info->name);
> +	debug("%s: start 0x" LBAF ", size 0x" LBAF ", name %s", __func__,
> +	      info->start, info->size, info->name);
>  
>  	/* Remember to free pte */
>  	free(gpt_pte);
> @@ -431,7 +431,7 @@ int gpt_fill_pte(gpt_header *gpt_h, gpt_entry *gpt_e,
>  			gpt_e[i].partition_name[k] =
>  				(efi_char16_t)(partitions[i].name[k]);
>  
> -		debug("%s: name: %s offset[%d]: 0x%x size[%d]: 0x%lx\n",
> +		debug("%s: name: %s offset[%d]: 0x%x size[%d]: 0x" LBAF "\n",
>  		      __func__, partitions[i].name, i,
>  		      offset, i, partitions[i].size);
>  	}
> diff --git a/disk/part_iso.c b/disk/part_iso.c
> index cc323b0..a050c44 100644
> --- a/disk/part_iso.c
> +++ b/disk/part_iso.c
> @@ -249,8 +249,8 @@ void print_part_iso(block_dev_desc_t * dev_desc)
>  	printf("Part   Start     Sect x Size Type\n");
>  	i=0;
>  	do {
> -		printf (" %2d %8ld %8ld %6ld %.32s\n",
> -			i, info.start, info.size, info.blksz, info.type);
> +		printf(" %2d " LBAFU " " LBAFU " %6ld %.32s\n",
> +		       i, info.start, info.size, info.blksz, info.type);
>  		i++;
>  	} while (get_partition_info_iso_verb(dev_desc,i,&info,0)!=-1);
>  }
> diff --git a/fs/ext4/dev.c b/fs/ext4/dev.c
> index 81b7633..2cd182c 100644
> --- a/fs/ext4/dev.c
> +++ b/fs/ext4/dev.c
> @@ -42,7 +42,7 @@
>  #include <ext_common.h>
>  #include "ext4_common.h"
>  
> -unsigned long part_offset;
> +lbaint_t part_offset;
>  
>  static block_dev_desc_t *ext4fs_block_dev_desc;
>  static disk_partition_t *part_info;
> @@ -58,7 +58,7 @@ void ext4fs_set_blk_dev(block_dev_desc_t *rbdd, disk_partition_t *info)
>  		get_fs()->dev_desc->log2blksz;
>  }
>  
> -int ext4fs_devread(int sector, int byte_offset, int byte_len, char *buf)
> +int ext4fs_devread(lbaint_t sector, int byte_offset, int byte_len, char *buf)
>  {
>  	unsigned block_len;
>  	int log2blksz = ext4fs_block_dev_desc->log2blksz;
> @@ -74,7 +74,8 @@ int ext4fs_devread(int sector, int byte_offset, int byte_len, char *buf)
>  	if ((sector < 0) ||
>  	    ((sector + ((byte_offset + byte_len - 1) >> log2blksz))
>  	     >= part_info->size)) {
> -		printf("%s read outside partition %d\n", __func__, sector);
> +		printf("%s read outside partition " LBAFU "\n", __func__,
> +		       sector);
>  		return 0;
>  	}
>  
> @@ -82,7 +83,7 @@ int ext4fs_devread(int sector, int byte_offset, int byte_len, char *buf)
>  	sector += byte_offset >> log2blksz;
>  	byte_offset &= ext4fs_block_dev_desc->blksz - 1;
>  
> -	debug(" <%d, %d, %d>\n", sector, byte_offset, byte_len);
> +	debug(" <" LBAFU ", %d, %d>\n", sector, byte_offset, byte_len);
>  
>  	if (byte_offset != 0) {
>  		/* read first part which isn't aligned with start of sector */
> diff --git a/fs/ext4/ext4_common.c b/fs/ext4/ext4_common.c
> index 58880b4..2776293 100644
> --- a/fs/ext4/ext4_common.c
> +++ b/fs/ext4/ext4_common.c
> @@ -84,7 +84,7 @@ void put_ext4(uint64_t off, void *buf, uint32_t size)
>  
>  	if ((startblock + (size >> log2blksz)) >
>  	    (part_offset + fs->total_sect)) {
> -		printf("part_offset is %lu\n", part_offset);
> +		printf("part_offset is " LBAFU "\n", part_offset);
>  		printf("total_sector is %llu\n", fs->total_sect);
>  		printf("error: overflow occurs\n");
>  		return;
> @@ -405,7 +405,7 @@ restart:
>  		previous_blknr = root_blknr;
>  	}
>  
> -	status = ext4fs_devread(first_block_no_of_root
> +	status = ext4fs_devread((lbaint_t)first_block_no_of_root
>  				* fs->sect_perblk,
>  				0, fs->blksz, root_first_block_buffer);
>  	if (status == 0)
> @@ -545,7 +545,7 @@ static int search_dir(struct ext2_inode *parent_inode, char *dirname)
>  		if (!block_buffer)
>  			goto fail;
>  
> -		status = ext4fs_devread(blknr * fs->sect_perblk,
> +		status = ext4fs_devread((lbaint_t)blknr * fs->sect_perblk,
>  					0, fs->blksz, (char *)block_buffer);
>  		if (status == 0)
>  			goto fail;
> @@ -783,7 +783,7 @@ static int check_filename(char *filename, unsigned int blknr)
>  	if (!root_first_block_buffer)
>  		return -ENOMEM;
>  	root_first_block_addr = root_first_block_buffer;
> -	status = ext4fs_devread(first_block_no_of_root *
> +	status = ext4fs_devread((lbaint_t)first_block_no_of_root *
>  				fs->sect_perblk, 0,
>  				fs->blksz, root_first_block_buffer);
>  	if (status == 0)
> @@ -895,7 +895,8 @@ long int ext4fs_get_new_blk_no(void)
>  				fs->first_pass_bbmap++;
>  				bgd[i].free_blocks--;
>  				fs->sb->free_blocks--;
> -				status = ext4fs_devread(bgd[i].block_id *
> +				status = ext4fs_devread((lbaint_t)
> +							bgd[i].block_id *
>  							fs->sect_perblk, 0,
>  							fs->blksz,
>  							journal_buffer);
> @@ -957,7 +958,7 @@ restart:
>  		/* journal backup */
>  		if (prev_bg_bitmap_index != bg_idx) {
>  			memset(journal_buffer, '\0', fs->blksz);
> -			status = ext4fs_devread(bgd[bg_idx].block_id
> +			status = ext4fs_devread((lbaint_t)bgd[bg_idx].block_id
>  						* fs->sect_perblk,
>  						0, fs->blksz, journal_buffer);
>  			if (status == 0)
> @@ -1026,7 +1027,8 @@ int ext4fs_get_new_inode_no(void)
>  				bgd[i].free_inodes--;
>  				bgd[i].bg_itable_unused--;
>  				fs->sb->free_inodes--;
> -				status = ext4fs_devread(bgd[i].inode_id *
> +				status = ext4fs_devread((lbaint_t)
> +							bgd[i].inode_id *
>  							fs->sect_perblk, 0,
>  							fs->blksz,
>  							journal_buffer);
> @@ -1067,7 +1069,8 @@ restart:
>  		/* journal backup */
>  		if (prev_inode_bitmap_index != ibmap_idx) {
>  			memset(journal_buffer, '\0', fs->blksz);
> -			status = ext4fs_devread(bgd[ibmap_idx].inode_id
> +			status = ext4fs_devread((lbaint_t)
> +						bgd[ibmap_idx].inode_id
>  						* fs->sect_perblk,
>  						0, fs->blksz, journal_buffer);
>  			if (status == 0)
> @@ -1129,7 +1132,7 @@ static void alloc_single_indirect_block(struct ext2_inode *file_inode,
>  		(*no_blks_reqd)++;
>  		debug("SIPB %ld: %u\n", si_blockno, *total_remaining_blocks);
>  
> -		status = ext4fs_devread(si_blockno * fs->sect_perblk,
> +		status = ext4fs_devread((lbaint_t)si_blockno * fs->sect_perblk,
>  					0, fs->blksz, (char *)si_buffer);
>  		memset(si_buffer, '\0', fs->blksz);
>  		if (status == 0)
> @@ -1193,7 +1196,7 @@ static void alloc_double_indirect_block(struct ext2_inode *file_inode,
>  		debug("DIPB %ld: %u\n", di_blockno_parent,
>  		      *total_remaining_blocks);
>  
> -		status = ext4fs_devread(di_blockno_parent *
> +		status = ext4fs_devread((lbaint_t)di_blockno_parent *
>  					fs->sect_perblk, 0,
>  					fs->blksz, (char *)di_parent_buffer);
>  
> @@ -1224,7 +1227,7 @@ static void alloc_double_indirect_block(struct ext2_inode *file_inode,
>  			debug("DICB %ld: %u\n", di_blockno_child,
>  			      *total_remaining_blocks);
>  
> -			status = ext4fs_devread(di_blockno_child *
> +			status = ext4fs_devread((lbaint_t)di_blockno_child *
>  						fs->sect_perblk, 0,
>  						fs->blksz,
>  						(char *)di_child_buff);
> @@ -1447,7 +1450,8 @@ static struct ext4_extent_header *ext4fs_get_extent_block
>  		block = le32_to_cpu(index[i].ei_leaf_hi);
>  		block = (block << 32) + le32_to_cpu(index[i].ei_leaf_lo);
>  
> -		if (ext4fs_devread(block << log2_blksz, 0, fs->blksz, buf))
> +		if (ext4fs_devread((lbaint_t)block << log2_blksz, 0, fs->blksz,
> +				   buf))
>  			ext_block = (struct ext4_extent_header *)buf;
>  		else
>  			return 0;
> @@ -1470,7 +1474,8 @@ static int ext4fs_blockgroup
>  	debug("ext4fs read %d group descriptor (blkno %ld blkoff %u)\n",
>  	      group, blkno, blkoff);
>  
> -	return ext4fs_devread(blkno << (LOG2_BLOCK_SIZE(data) - log2blksz),
> +	return ext4fs_devread((lbaint_t)blkno <<
> +			      (LOG2_BLOCK_SIZE(data) - log2blksz),
>  			      blkoff, sizeof(struct ext2_block_group),
>  			      (char *)blkgrp);
>  }
> @@ -1497,8 +1502,8 @@ int ext4fs_read_inode(struct ext2_data *data, int ino, struct ext2_inode *inode)
>  	    (ino % __le32_to_cpu(sblock->inodes_per_group)) / inodes_per_block;
>  	blkoff = (ino % inodes_per_block) * fs->inodesz;
>  	/* Read the inode. */
> -	status = ext4fs_devread(blkno << (LOG2_BLOCK_SIZE(data) - log2blksz),
> -				blkoff,
> +	status = ext4fs_devread((lbaint_t)blkno << (LOG2_BLOCK_SIZE(data) -
> +				log2blksz), blkoff,
>  				sizeof(struct ext2_inode), (char *)inode);
>  	if (status == 0)
>  		return 0;
> @@ -1597,7 +1602,7 @@ long int read_allocated_block(struct ext2_inode *inode, int fileblock)
>  		if ((__le32_to_cpu(inode->b.blocks.indir_block) <<
>  		     log2_blksz) != ext4fs_indir1_blkno) {
>  			status =
> -			    ext4fs_devread(__le32_to_cpu
> +			    ext4fs_devread((lbaint_t)__le32_to_cpu
>  					   (inode->b.blocks.
>  					    indir_block) << log2_blksz, 0,
>  					   blksz, (char *)ext4fs_indir1_block);
> @@ -1646,7 +1651,7 @@ long int read_allocated_block(struct ext2_inode *inode, int fileblock)
>  		if ((__le32_to_cpu(inode->b.blocks.double_indir_block) <<
>  		     log2_blksz) != ext4fs_indir1_blkno) {
>  			status =
> -			    ext4fs_devread(__le32_to_cpu
> +			    ext4fs_devread((lbaint_t)__le32_to_cpu
>  					   (inode->b.blocks.
>  					    double_indir_block) << log2_blksz,
>  					   0, blksz,
> @@ -1686,7 +1691,7 @@ long int read_allocated_block(struct ext2_inode *inode, int fileblock)
>  		}
>  		if ((__le32_to_cpu(ext4fs_indir1_block[rblock / perblock]) <<
>  		     log2_blksz) != ext4fs_indir2_blkno) {
> -			status = ext4fs_devread(__le32_to_cpu
> +			status = ext4fs_devread((lbaint_t)__le32_to_cpu
>  						(ext4fs_indir1_block
>  						 [rblock /
>  						  perblock]) << log2_blksz, 0,
> @@ -1738,7 +1743,8 @@ long int read_allocated_block(struct ext2_inode *inode, int fileblock)
>  		if ((__le32_to_cpu(inode->b.blocks.triple_indir_block) <<
>  		     log2_blksz) != ext4fs_indir1_blkno) {
>  			status = ext4fs_devread
> -			    (__le32_to_cpu(inode->b.blocks.triple_indir_block)
> +			    ((lbaint_t)
> +			     __le32_to_cpu(inode->b.blocks.triple_indir_block)
>  			     << log2_blksz, 0, blksz,
>  			     (char *)ext4fs_indir1_block);
>  			if (status == 0) {
> @@ -1778,7 +1784,7 @@ long int read_allocated_block(struct ext2_inode *inode, int fileblock)
>  						       perblock_parent]) <<
>  		     log2_blksz)
>  		    != ext4fs_indir2_blkno) {
> -			status = ext4fs_devread(__le32_to_cpu
> +			status = ext4fs_devread((lbaint_t)__le32_to_cpu
>  						(ext4fs_indir1_block
>  						 [rblock /
>  						  perblock_parent]) <<
> @@ -1823,7 +1829,7 @@ long int read_allocated_block(struct ext2_inode *inode, int fileblock)
>  						       perblock_child]) <<
>  		     log2_blksz) != ext4fs_indir3_blkno) {
>  			status =
> -			    ext4fs_devread(__le32_to_cpu
> +			    ext4fs_devread((lbaint_t)__le32_to_cpu
>  					   (ext4fs_indir2_block
>  					    [(rblock / perblock_child)
>  					     % (blksz / 4)]) << log2_blksz, 0,
> diff --git a/fs/ext4/ext4_journal.c b/fs/ext4/ext4_journal.c
> index 81aa5fc..a540367 100644
> --- a/fs/ext4/ext4_journal.c
> +++ b/fs/ext4/ext4_journal.c
> @@ -360,7 +360,8 @@ void recover_transaction(int prev_desc_logical_no)
>  			  (struct ext2_inode *)&inode_journal);
>  	blknr = read_allocated_block((struct ext2_inode *)
>  				     &inode_journal, i);
> -	ext4fs_devread(blknr * fs->sect_perblk, 0, fs->blksz, temp_buff);
> +	ext4fs_devread((lbaint_t)blknr * fs->sect_perblk, 0, fs->blksz,
> +		       temp_buff);
>  	p_jdb = (char *)temp_buff;
>  	jdb = (struct journal_header_t *) temp_buff;
>  	ofs = sizeof(struct journal_header_t);
> @@ -384,7 +385,7 @@ void recover_transaction(int prev_desc_logical_no)
>  				continue;
>  		}
>  		blknr = read_allocated_block(&inode_journal, i);
> -		ext4fs_devread(blknr * fs->sect_perblk, 0,
> +		ext4fs_devread((lbaint_t)blknr * fs->sect_perblk, 0,
>  			       fs->blksz, metadata_buff);
>  		put_ext4((uint64_t)(be32_to_cpu(tag->block) * fs->blksz),
>  			 metadata_buff, (uint32_t) fs->blksz);
> @@ -431,7 +432,8 @@ int ext4fs_check_journal_state(int recovery_flag)
>  
>  	ext4fs_read_inode(ext4fs_root, EXT2_JOURNAL_INO, &inode_journal);
>  	blknr = read_allocated_block(&inode_journal, EXT2_JOURNAL_SUPERBLOCK);
> -	ext4fs_devread(blknr * fs->sect_perblk, 0, fs->blksz, temp_buff);
> +	ext4fs_devread((lbaint_t)blknr * fs->sect_perblk, 0, fs->blksz,
> +		       temp_buff);
>  	jsb = (struct journal_superblock_t *) temp_buff;
>  
>  	if (fs->sb->feature_incompat & EXT3_FEATURE_INCOMPAT_RECOVER) {
> @@ -455,7 +457,7 @@ int ext4fs_check_journal_state(int recovery_flag)
>  	while (1) {
>  		blknr = read_allocated_block(&inode_journal, i);
>  		memset(temp_buff1, '\0', fs->blksz);
> -		ext4fs_devread(blknr * fs->sect_perblk,
> +		ext4fs_devread((lbaint_t)blknr * fs->sect_perblk,
>  			       0, fs->blksz, temp_buff1);
>  		jdb = (struct journal_header_t *) temp_buff1;
>  
> @@ -574,7 +576,8 @@ static void update_descriptor_block(long int blknr)
>  	ext4fs_read_inode(ext4fs_root, EXT2_JOURNAL_INO, &inode_journal);
>  	jsb_blknr = read_allocated_block(&inode_journal,
>  					 EXT2_JOURNAL_SUPERBLOCK);
> -	ext4fs_devread(jsb_blknr * fs->sect_perblk, 0, fs->blksz, temp_buff);
> +	ext4fs_devread((lbaint_t)jsb_blknr * fs->sect_perblk, 0, fs->blksz,
> +		       temp_buff);
>  	jsb = (struct journal_superblock_t *) temp_buff;
>  
>  	jdb.h_blocktype = cpu_to_be32(EXT3_JOURNAL_DESCRIPTOR_BLOCK);
> @@ -621,10 +624,12 @@ static void update_commit_block(long int blknr)
>  	if (!temp_buff)
>  		return;
>  
> -	ext4fs_read_inode(ext4fs_root, EXT2_JOURNAL_INO, &inode_journal);
> +	ext4fs_read_inode(ext4fs_root, EXT2_JOURNAL_INO,
> +			  &inode_journal);
>  	jsb_blknr = read_allocated_block(&inode_journal,
>  					 EXT2_JOURNAL_SUPERBLOCK);
> -	ext4fs_devread(jsb_blknr * fs->sect_perblk, 0, fs->blksz, temp_buff);
> +	ext4fs_devread((lbaint_t)jsb_blknr * fs->sect_perblk, 0, fs->blksz,
> +		       temp_buff);
>  	jsb = (struct journal_superblock_t *) temp_buff;
>  
>  	jdb.h_blocktype = cpu_to_be32(EXT3_JOURNAL_COMMIT_BLOCK);
> diff --git a/fs/ext4/ext4_write.c b/fs/ext4/ext4_write.c
> index 0c1f62b..501b95a 100644
> --- a/fs/ext4/ext4_write.c
> +++ b/fs/ext4/ext4_write.c
> @@ -88,8 +88,8 @@ int ext4fs_get_bgdtable(void)
>  	if (!fs->gdtable)
>  		return -ENOMEM;
>  	/* read the group descriptor table */
> -	status = ext4fs_devread(fs->gdtable_blkno * fs->sect_perblk, 0,
> -				fs->blksz * fs->no_blk_pergdt, fs->gdtable);
> +	status = ext4fs_devread((lbaint_t)fs->gdtable_blkno * fs->sect_perblk,
> +				0, fs->blksz * fs->no_blk_pergdt, fs->gdtable);
>  	if (status == 0)
>  		goto fail;
>  
> @@ -142,7 +142,7 @@ static void delete_single_indirect_block(struct ext2_inode *inode)
>  		/* journal backup */
>  		if (prev_bg_bmap_idx != bg_idx) {
>  			status =
> -			    ext4fs_devread(bgd[bg_idx].block_id *
> +			    ext4fs_devread((lbaint_t)bgd[bg_idx].block_id *
>  					   fs->sect_perblk, 0, fs->blksz,
>  					   journal_buffer);
>  			if (status == 0)
> @@ -186,8 +186,8 @@ static void delete_double_indirect_block(struct ext2_inode *inode)
>  		}
>  		DIB_start_addr = (unsigned int *)di_buffer;
>  		blknr = inode->b.blocks.double_indir_block;
> -		status = ext4fs_devread(blknr * fs->sect_perblk, 0, fs->blksz,
> -					(char *)di_buffer);
> +		status = ext4fs_devread((lbaint_t)blknr * fs->sect_perblk, 0,
> +					fs->blksz, (char *)di_buffer);
>  		for (i = 0; i < fs->blksz / sizeof(int); i++) {
>  			if (*di_buffer == 0)
>  				break;
> @@ -208,7 +208,8 @@ static void delete_double_indirect_block(struct ext2_inode *inode)
>  			fs->sb->free_blocks++;
>  			/* journal backup */
>  			if (prev_bg_bmap_idx != bg_idx) {
> -				status = ext4fs_devread(bgd[bg_idx].block_id
> +				status = ext4fs_devread((lbaint_t)
> +							bgd[bg_idx].block_id
>  							* fs->sect_perblk, 0,
>  							fs->blksz,
>  							journal_buffer);
> @@ -238,7 +239,7 @@ static void delete_double_indirect_block(struct ext2_inode *inode)
>  		/* journal backup */
>  		if (prev_bg_bmap_idx != bg_idx) {
>  			memset(journal_buffer, '\0', fs->blksz);
> -			status = ext4fs_devread(bgd[bg_idx].block_id *
> +			status = ext4fs_devread((lbaint_t)bgd[bg_idx].block_id *
>  						fs->sect_perblk, 0, fs->blksz,
>  						journal_buffer);
>  			if (status == 0)
> @@ -287,8 +288,8 @@ static void delete_triple_indirect_block(struct ext2_inode *inode)
>  		}
>  		tib_start_addr = (unsigned int *)tigp_buffer;
>  		blknr = inode->b.blocks.triple_indir_block;
> -		status = ext4fs_devread(blknr * fs->sect_perblk, 0, fs->blksz,
> -					(char *)tigp_buffer);
> +		status = ext4fs_devread((lbaint_t)blknr * fs->sect_perblk, 0,
> +					fs->blksz, (char *)tigp_buffer);
>  		for (i = 0; i < fs->blksz / sizeof(int); i++) {
>  			if (*tigp_buffer == 0)
>  				break;
> @@ -298,7 +299,7 @@ static void delete_triple_indirect_block(struct ext2_inode *inode)
>  			if (!tip_buffer)
>  				goto fail;
>  			tipb_start_addr = (unsigned int *)tip_buffer;
> -			status = ext4fs_devread((*tigp_buffer) *
> +			status = ext4fs_devread((lbaint_t)(*tigp_buffer) *
>  						fs->sect_perblk, 0, fs->blksz,
>  						(char *)tip_buffer);
>  			for (j = 0; j < fs->blksz / sizeof(int); j++) {
> @@ -325,6 +326,7 @@ static void delete_triple_indirect_block(struct ext2_inode *inode)
>  				if (prev_bg_bmap_idx != bg_idx) {
>  					status =
>  					    ext4fs_devread(
> +							(lbaint_t)
>  							bgd[bg_idx].block_id *
>  							fs->sect_perblk, 0,
>  							fs->blksz,
> @@ -365,7 +367,8 @@ static void delete_triple_indirect_block(struct ext2_inode *inode)
>  			if (prev_bg_bmap_idx != bg_idx) {
>  				memset(journal_buffer, '\0', fs->blksz);
>  				status =
> -				    ext4fs_devread(bgd[bg_idx].block_id *
> +				    ext4fs_devread((lbaint_t)
> +						   bgd[bg_idx].block_id *
>  						   fs->sect_perblk, 0,
>  						   fs->blksz, journal_buffer);
>  				if (status == 0)
> @@ -394,7 +397,7 @@ static void delete_triple_indirect_block(struct ext2_inode *inode)
>  		/* journal backup */
>  		if (prev_bg_bmap_idx != bg_idx) {
>  			memset(journal_buffer, '\0', fs->blksz);
> -			status = ext4fs_devread(bgd[bg_idx].block_id *
> +			status = ext4fs_devread((lbaint_t)bgd[bg_idx].block_id *
>  						fs->sect_perblk, 0, fs->blksz,
>  						journal_buffer);
>  			if (status == 0)
> @@ -480,7 +483,8 @@ static int ext4fs_delete_file(int inodeno)
>  			/* journal backup */
>  			if (prev_bg_bmap_idx != bg_idx) {
>  				status =
> -				    ext4fs_devread(bgd[bg_idx].block_id *
> +				    ext4fs_devread((lbaint_t)
> +						   bgd[bg_idx].block_id *
>  						   fs->sect_perblk, 0,
>  						   fs->blksz, journal_buffer);
>  				if (status == 0)
> @@ -524,7 +528,8 @@ static int ext4fs_delete_file(int inodeno)
>  			/* journal backup */
>  			if (prev_bg_bmap_idx != bg_idx) {
>  				memset(journal_buffer, '\0', fs->blksz);
> -				status = ext4fs_devread(bgd[bg_idx].block_id
> +				status = ext4fs_devread((lbaint_t)
> +							bgd[bg_idx].block_id
>  							* fs->sect_perblk,
>  							0, fs->blksz,
>  							journal_buffer);
> @@ -555,7 +560,7 @@ static int ext4fs_delete_file(int inodeno)
>  	if (!read_buffer)
>  		goto fail;
>  	start_block_address = read_buffer;
> -	status = ext4fs_devread(blkno * fs->sect_perblk,
> +	status = ext4fs_devread((lbaint_t)blkno * fs->sect_perblk,
>  				0, fs->blksz, read_buffer);
>  	if (status == 0)
>  		goto fail;
> @@ -578,7 +583,7 @@ static int ext4fs_delete_file(int inodeno)
>  	fs->sb->free_inodes++;
>  	/* journal backup */
>  	memset(journal_buffer, '\0', fs->blksz);
> -	status = ext4fs_devread(bgd[ibmap_idx].inode_id *
> +	status = ext4fs_devread((lbaint_t)bgd[ibmap_idx].inode_id *
>  				fs->sect_perblk, 0, fs->blksz, journal_buffer);
>  	if (status == 0)
>  		goto fail;
> @@ -653,7 +658,8 @@ int ext4fs_init(void)
>  
>  	for (i = 0; i < fs->no_blkgrp; i++) {
>  		status =
> -		    ext4fs_devread(fs->bgd[i].block_id * fs->sect_perblk, 0,
> +		    ext4fs_devread((lbaint_t)fs->bgd[i].block_id *
> +				   fs->sect_perblk, 0,
>  				   fs->blksz, (char *)fs->blk_bmaps[i]);
>  		if (status == 0)
>  			goto fail;
> @@ -670,7 +676,8 @@ int ext4fs_init(void)
>  	}
>  
>  	for (i = 0; i < fs->no_blkgrp; i++) {
> -		status = ext4fs_devread(fs->bgd[i].inode_id * fs->sect_perblk,
> +		status = ext4fs_devread((lbaint_t)fs->bgd[i].inode_id *
> +					fs->sect_perblk,
>  					0, fs->blksz,
>  					(char *)fs->inode_bmaps[i]);
>  		if (status == 0)
> @@ -710,7 +717,7 @@ void ext4fs_deinit(void)
>  				  &inode_journal);
>  		blknr = read_allocated_block(&inode_journal,
>  					EXT2_JOURNAL_SUPERBLOCK);
> -		ext4fs_devread(blknr * fs->sect_perblk, 0, fs->blksz,
> +		ext4fs_devread((lbaint_t)blknr * fs->sect_perblk, 0, fs->blksz,
>  			       temp_buff);
>  		jsb = (struct journal_superblock_t *)temp_buff;
>  		jsb->s_start = cpu_to_be32(0);
> @@ -934,7 +941,8 @@ int ext4fs_write(const char *fname, unsigned char *buffer,
>  			(inodeno % __le32_to_cpu(sblock->inodes_per_group)) /
>  			inodes_per_block;
>  	blkoff = (inodeno % inodes_per_block) * fs->inodesz;
> -	ext4fs_devread(itable_blkno * fs->sect_perblk, 0, fs->blksz, temp_ptr);
> +	ext4fs_devread((lbaint_t)itable_blkno * fs->sect_perblk, 0, fs->blksz,
> +		       temp_ptr);
>  	if (ext4fs_log_journal(temp_ptr, itable_blkno))
>  		goto fail;
>  
> @@ -954,7 +962,7 @@ int ext4fs_write(const char *fname, unsigned char *buffer,
>  	blkoff = (parent_inodeno % inodes_per_block) * fs->inodesz;
>  	if (parent_itable_blkno != itable_blkno) {
>  		memset(temp_ptr, '\0', fs->blksz);
> -		ext4fs_devread(parent_itable_blkno * fs->sect_perblk,
> +		ext4fs_devread((lbaint_t)parent_itable_blkno * fs->sect_perblk,
>  			       0, fs->blksz, temp_ptr);
>  		if (ext4fs_log_journal(temp_ptr, parent_itable_blkno))
>  			goto fail;
> diff --git a/fs/ext4/ext4fs.c b/fs/ext4/ext4fs.c
> index 1954afb..20ff10f 100644
> --- a/fs/ext4/ext4fs.c
> +++ b/fs/ext4/ext4fs.c
> @@ -62,16 +62,16 @@ int ext4fs_read_file(struct ext2fs_node *node, int pos,
>  {
>  	struct ext_filesystem *fs = get_fs();
>  	int i;
> -	int blockcnt;
> +	lbaint_t blockcnt;
>  	int log2blksz = fs->dev_desc->log2blksz;
>  	int log2_fs_blocksize = LOG2_BLOCK_SIZE(node->data) - log2blksz;
>  	int blocksize = (1 << (log2_fs_blocksize + log2blksz));
>  	unsigned int filesize = __le32_to_cpu(node->inode.size);
> -	int previous_block_number = -1;
> -	int delayed_start = 0;
> -	int delayed_extent = 0;
> -	int delayed_skipfirst = 0;
> -	int delayed_next = 0;
> +	lbaint_t previous_block_number = -1;
> +	lbaint_t delayed_start = 0;
> +	lbaint_t delayed_extent = 0;
> +	lbaint_t delayed_skipfirst = 0;
> +	lbaint_t delayed_next = 0;
>  	char *delayed_buf = NULL;
>  	short status;
>  
> @@ -82,7 +82,7 @@ int ext4fs_read_file(struct ext2fs_node *node, int pos,
>  	blockcnt = ((len + pos) + blocksize - 1) / blocksize;
>  
>  	for (i = pos / blocksize; i < blockcnt; i++) {
> -		int blknr;
> +		lbaint_t blknr;
>  		int blockoff = pos % blocksize;
>  		int blockend = blocksize;
>  		int skipfirst = 0;
> diff --git a/include/ext4fs.h b/include/ext4fs.h
> index 379f7eb..2429380 100644
> --- a/include/ext4fs.h
> +++ b/include/ext4fs.h
> @@ -135,7 +135,7 @@ int ext4fs_mount(unsigned part_length);
>  void ext4fs_close(void);
>  int ext4fs_ls(const char *dirname);
>  void ext4fs_free_node(struct ext2fs_node *node, struct ext2fs_node *currroot);
> -int ext4fs_devread(int sector, int byte_offset, int byte_len, char *buf);
> +int ext4fs_devread(lbaint_t sector, int byte_offset, int byte_len, char *buf);
>  void ext4fs_set_blk_dev(block_dev_desc_t *rbdd, disk_partition_t *info);
>  long int read_allocated_block(struct ext2_inode *inode, int fileblock);
>  int ext4fs_probe(block_dev_desc_t *fs_dev_desc,
> diff --git a/include/ext_common.h b/include/ext_common.h
> index 78a7808..694e49f 100644
> --- a/include/ext_common.h
> +++ b/include/ext_common.h
> @@ -180,7 +180,7 @@ struct ext2_data {
>  	struct ext2fs_node diropen;
>  };
>  
> -extern unsigned long part_offset;
> +extern lbaint_t part_offset;
>  
>  int do_ext2ls(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
>  int do_ext2load(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
> diff --git a/include/ide.h b/include/ide.h
> index afea85c..d312a29 100644
> --- a/include/ide.h
> +++ b/include/ide.h
> @@ -44,9 +44,11 @@ extern ulong ide_bus_offset[];
>  #ifdef CONFIG_SYS_64BIT_LBA
>  typedef uint64_t lbaint_t;
>  #define LBAF "%llx"
> +#define LBAFU "%llu"
>  #else
>  typedef ulong lbaint_t;
>  #define LBAF "%lx"
> +#define LBAFU "%lu"
>  #endif
>  
>  /*
> diff --git a/include/part.h b/include/part.h
> index f7c7cc5..8d5ea5d 100644
> --- a/include/part.h
> +++ b/include/part.h
> @@ -97,8 +97,8 @@ typedef struct block_dev_desc {
>  #define DEV_TYPE_OPDISK		0x07	/* optical disk */
>  
>  typedef struct disk_partition {
> -	ulong	start;		/* # of first block in partition	*/
> -	ulong	size;		/* number of blocks in partition	*/
> +	lbaint_t	start;	/* # of first block in partition	*/
> +	lbaint_t	size;	/* number of blocks in partition	*/
>  	ulong	blksz;		/* block size in bytes			*/
>  	uchar	name[32];	/* partition name			*/
>  	uchar	type[32];	/* string type description		*/

Shouldn't this bugfix go in 2013.07?

Amicalement,
-- 
Albert.

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [U-Boot] [U-Boot, v2] Fix ext2/ext4 filesystem accesses beyond 2TiB
  2013-06-26 16:11                             ` [U-Boot] [PATCH v2] " Frédéric Leroy
  2013-07-11 10:41                               ` Albert ARIBAUD
@ 2013-07-16 14:37                               ` Tom Rini
  1 sibling, 0 replies; 24+ messages in thread
From: Tom Rini @ 2013-07-16 14:37 UTC (permalink / raw)
  To: u-boot

On Wed, Jun 26, 2013 at 06:11:25PM +0200, Frederic Leroy wrote:

> With CONFIG_SYS_64BIT_LBA, lbaint_t gets defined as a 64-bit type,
> which is required to represent block numbers for storage devices that
> exceed 2TiB (the block size usually is 512B), e.g. recent hard drives
> 
> We now use lbaint_t for partition offset to reflect the lbaint_t change,
> and access partitions beyond or crossing the 2.1TiB limit.
> This required changes to signature of ext4fs_devread(), and type of all
> variables relatives to block sector.
> 
> ext2/ext4 fs uses logical block represented by a 32 bit value. Logical
> block is a multiple of device block sector. To avoid overflow problem
> when calling ext4fs_devread(), we need to cast the sector parameter.
> 
> Signed-off-by: Fr??d??ric Leroy <fredo@starox.org>

Applied to u-boot/master, thanks!

-- 
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20130716/70f4bde3/attachment.pgp>

^ permalink raw reply	[flat|nested] 24+ messages in thread

end of thread, other threads:[~2013-07-16 14:37 UTC | newest]

Thread overview: 24+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-06-10 13:30 [U-Boot] [PATCH] LaCie kirkwood boards: allow disk > 2TB Frederic Leroy
2013-06-10 13:44 ` Simon Guinot
2013-06-10 14:20   ` Frédéric Leroy
2013-06-10 14:29     ` Simon Guinot
2013-06-10 14:48       ` Albert ARIBAUD
2013-06-13 11:33 ` Albert ARIBAUD
2013-06-13 13:03   ` Frédéric Leroy
2013-06-13 13:21     ` Albert ARIBAUD
2013-06-13 13:36       ` Frédéric Leroy
2013-06-13 20:32     ` Sascha Silbe
2013-06-14 11:07       ` [U-Boot] [PATCH] Fix block device accesses beyond 2TiB Sascha Silbe
2013-06-17 20:26         ` Marek Vasut
2013-06-22 10:07           ` Albert ARIBAUD
     [not found]             ` <51C598A6.8040406@starox.org>
2013-06-22 15:31               ` Albert ARIBAUD
2013-06-24  9:46                 ` Frédéric Leroy
2013-06-24 21:13                   ` Sascha Silbe
2013-06-24 21:26                     ` [U-Boot] [PATCH] Fix ext2/ext4 filesystem " Frederic Leroy
2013-06-24 22:26                       ` Sascha Silbe
2013-06-25  6:10                         ` Frederic Leroy
2013-06-25 20:42                           ` Sascha Silbe
2013-06-26 16:11                             ` [U-Boot] [PATCH v2] " Frédéric Leroy
2013-07-11 10:41                               ` Albert ARIBAUD
2013-07-16 14:37                               ` [U-Boot] [U-Boot, " Tom Rini
2013-06-26 20:25         ` [U-Boot] Fix block device " Tom Rini

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.