Skip to contentSkip to conversation

LaCie kirkwood boards: allow disk > 2TB

PATCH New Frederic Leroy 6 participants 24 messages Jun 10, 2013 – Jul 16, 2013 1 message not in the archive

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

PATCH 1/1 LaCie kirkwood boards: allow disk > 2TB

From: Fr?d?ric Leroy <[email protected]>

For big disk support, we need LBA addressing on 64 bits

---
 include/configs/lacie_kw.h | 1 +
 1 file changed, 1 insertion(+)
include/configs/lacie_kw.h +1 -0
index 09b5798..847afcd 100644
@@ -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)
Signature · 1 line
1.8.1.2
#1 lore raw

PATCH 1/1 LaCie kirkwood boards: allow disk > 2TB

Quoted 12 lines · Frederic Leroy

From: Fr?d?ric Leroy <[email protected]>

For big disk support, we need LBA addressing on 64 bits

---
 include/configs/lacie_kw.h | 1 +
 1 file changed, 1 insertion(+)
include/configs/lacie_kw.h +0 -0
index 09b5798..847afcd 100644

include/configs/lacie_kw.h line 114

Quoted 4 lines
include/configs/lacie_kw.h +1 -0
@@ -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

Quoted 5 lines
include/configs/lacie_kw.h +0 -0
 #if defined(CONFIG_D2NET_V2)
 #define CONFIG_SYS_PROMPT		"d2v2> "
 #elif defined(CONFIG_NET2BIG_V2)
Signature · 1 line
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>

#2 lore raw

PATCH 1/1 LaCie kirkwood boards: allow disk > 2TB

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

Le 10/06/2013 15:44, Simon Guinot a ?crit :

Quoted 20 lines · Frederic Leroy
Quoted 12 lines

From: Fr?d?ric Leroy <[email protected]>

For big disk support, we need LBA addressing on 64 bits

---
 include/configs/lacie_kw.h | 1 +
 1 file changed, 1 insertion(+)
include/configs/lacie_kw.h +0 -0
index 09b5798..847afcd 100644

include/configs/lacie_kw.h line 114

Quoted 4 lines
include/configs/lacie_kw.h +1 -0
@@ -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,

Quoted 3 lines

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-----

#3 lore raw

PATCH 1/1 LaCie kirkwood boards: allow disk > 2TB

Quoted 25 lines · Fr?d?ric Leroy

Le 10/06/2013 15:44, Simon Guinot a ?crit :

Quoted 20 lines · Frederic Leroy
Quoted 12 lines

From: Fr?d?ric Leroy <[email protected]>

For big disk support, we need LBA addressing on 64 bits

---
 include/configs/lacie_kw.h | 1 +
 1 file changed, 1 insertion(+)
include/configs/lacie_kw.h +0 -0
index 09b5798..847afcd 100644

include/configs/lacie_kw.h line 114

Quoted 4 lines
include/configs/lacie_kw.h +1 -0
@@ -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,

Quoted 3 lines

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 ?

Quoted 8 lines

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.

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>

#4 lore raw

PATCH 1/1 LaCie kirkwood boards: allow disk > 2TB

Hi Simon,

Quoted 33 lines · Simon Guinot
Quoted 32 lines · Fr?d?ric Leroy

Le 10/06/2013 15:44, Simon Guinot a ?crit :

Quoted 20 lines · Frederic Leroy
Quoted 12 lines

From: Fr?d?ric Leroy <[email protected]>

For big disk support, we need LBA addressing on 64 bits

---
 include/configs/lacie_kw.h | 1 +
 1 file changed, 1 insertion(+)
include/configs/lacie_kw.h +0 -0
index 09b5798..847afcd 100644

include/configs/lacie_kw.h line 114

Quoted 4 lines
include/configs/lacie_kw.h +1 -0
@@ -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,

Quoted 3 lines

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.

Quoted 6 lines
Quoted 1 line

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

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.

Quoted 3 lines

Regards,

Simon

Amicalement,

Signature · 1 line
Albert.
#5 lore raw

PATCH 1/1 LaCie kirkwood boards: allow disk > 2TB

In reply to Frederic Leroy

Hi Frederic,

Quoted 12 lines · Frederic Leroy

From: Fr?d?ric Leroy <[email protected]>

For big disk support, we need LBA addressing on 64 bits

---
 include/configs/lacie_kw.h | 1 +
 1 file changed, 1 insertion(+)
include/configs/lacie_kw.h +0 -0
index 09b5798..847afcd 100644

include/configs/lacie_kw.h line 117

Quoted 7 lines
include/configs/lacie_kw.h +1 -0
@@ -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,

Signature · 1 line
Albert.
#6 lore raw

PATCH 1/1 LaCie kirkwood boards: allow disk > 2TB

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

Quoted 7 lines

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,

Signature · 1 line
Fr?d?ric
#7 lore raw

PATCH 1/1 LaCie kirkwood boards: allow disk > 2TB

Hi Fr?d?ric,

Quoted 10 lines · Fr?d?ric Leroy

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

Quoted 7 lines

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.

Quoted 8 lines

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;
Quoted 8 lines
#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?

Quoted 1 line

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.

Quoted 1 line

Sinc?rement,

Amicalement,

Signature · 1 line
Albert.
#8 lore raw

PATCH 1/1 LaCie kirkwood boards: allow disk > 2TB

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

Quoted 11 lines
Quoted 11 lines

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;
Quoted 7 lines
Quoted 5 lines
    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.

#9 lore raw

PATCH 1/1 LaCie kirkwood boards: allow disk > 2TB

In reply to Frédéric Leroy
Quoted 2 lines · Fr?d?ric Leroy

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>

#10 lore raw

PATCH 1/1 Fix block device accesses beyond 2TiB

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.

---
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(-)
common/cmd_ide.c +7 -7
index 78b4aa7..59e95df 100644
@@ -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;
 		}
 
common/usb_storage.c +4 -4
index 457970f..4599d03 100644
@@ -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;
drivers/mmc/mmc.c +9 -8
index 0a2f535..3b01434 100644
@@ -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;
 	}
include/ide.h +3 -2
index afea85c..f691a74 100644
@@ -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);
include/part.h +3 -3
index f7c7cc5..35c1c5b 100644
@@ -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;
Signature · 1 line
1.8.2.1
#11 lore raw

PATCH 1/1 Fix block device accesses beyond 2TiB

Hello Sascha,

Quoted 19 lines

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.

---
Functionality tested on CuBox Pro with a Western Digital WD30EFRX hard disk (3TB). Build tested for all arm boards and sandbox.

Quoted 7 lines

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

#12 lore raw

PATCH 1/1 Fix block device accesses beyond 2TiB

Quoted 29 lines · Marek Vasut

Hello Sascha,

Quoted 19 lines

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.

---
Functionality tested on CuBox Pro with a Western Digital WD30EFRX hard disk (3TB). Build tested for all arm boards and sandbox.

Quoted 7 lines

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.

Quoted 4 lines

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,

Signature · 1 line
Albert.

A message that is not in the archive (sent off-list or not yet received): [email protected]

#14 lore raw

PATCH 1/1 Fix block device accesses beyond 2TiB

Hi Fr?d?ric,

Quoted 22 lines · Fr?d?ric Leroy

Hello Albert, Sascha, Marek

Le 22/06/2013 12:07, Albert ARIBAUD a ?crit :

Quoted 10 lines
Quoted 4 lines

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).

Quoted 2 lines

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. :)

Quoted 1 line

Best regards,

Amicalement,

Signature · 1 line
Albert.
#15 lore raw

PATCH 1/1 Fix block device accesses beyond 2TiB

Le 22/06/2013 17:31, Albert ARIBAUD a ?crit :

Quoted 8 lines

Hi Fr?d?ric,

Quoted 2 lines

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,

Signature · 1 line
Frederic Leroy
#16 lore raw

PATCH 1/1 Fix block device accesses beyond 2TiB

Quoted 7 lines · Fr?d?ric Leroy

Le 22/06/2013 17:31, Albert ARIBAUD a ?crit :

Quoted 6 lines
Quoted 2 lines

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.

[...]

Quoted 6 lines

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>

#17 lore raw

PATCH 1/1 Fix ext2/ext4 filesystem accesses beyond 2TiB

From: Fr?d?ric Leroy <[email protected]>

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(-)
common/cmd_disk.c +1 -1
index ee4e215..809e231 100644
@@ -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) {
disk/part_efi.c +2 -2
index fb5e9f0..5c426fe 100644
@@ -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);
 	}
fs/ext4/dev.c +4 -4
index 81b7633..7296118 100644
@@ -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 */
fs/ext4/ext4_common.c +20 -20
index 58880b4..61b1ca1 100644
@@ -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,
fs/ext4/ext4_journal.c +6 -6
index 81aa5fc..85081df 100644
@@ -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);
fs/ext4/ext4_write.c +19 -19
index 0c1f62b..8dfa1ae 100644
@@ -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;
fs/ext4/ext4fs.c +7 -7
index 1954afb..20ff10f 100644
@@ -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;
include/ext4fs.h +1 -1
index 379f7eb..2429380 100644
@@ -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,
include/ext_common.h +1 -1
index 78a7808..694e49f 100644
@@ -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[]);
include/ide.h +2 -0
index f691a74..24c29f9 100644
@@ -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
 
 /*
include/part.h +2 -2
index 35c1c5b..8388ba8 100644
@@ -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		*/
Signature · 1 line
1.8.1.2
#18 lore raw

PATCH 1/1 Fix ext2/ext4 filesystem accesses beyond 2TiB

Quoted 6 lines · Frederic Leroy

From: Fr?d?ric Leroy <[email protected]>

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

Quoted 8 lines

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.

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>

#19 lore raw

PATCH 1/1 Fix ext2/ext4 filesystem accesses beyond 2TiB

From: Fr?d?ric Leroy <[email protected]>

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.

---

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(-)
common/cmd_disk.c +1 -1
index ee4e215..809e231 100644
@@ -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) {
disk/part_efi.c +2 -2
index fb5e9f0..5c426fe 100644
@@ -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);
 	}
fs/ext4/dev.c +4 -4
index 81b7633..7296118 100644
@@ -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 */
fs/ext4/ext4_common.c +20 -20
index 58880b4..61b1ca1 100644
@@ -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,
fs/ext4/ext4_journal.c +6 -6
index 81aa5fc..85081df 100644
@@ -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);
fs/ext4/ext4_write.c +19 -19
index 0c1f62b..8dfa1ae 100644
@@ -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;
fs/ext4/ext4fs.c +7 -7
index 1954afb..20ff10f 100644
@@ -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;
include/ext4fs.h +1 -1
index 379f7eb..2429380 100644
@@ -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,
include/ext_common.h +1 -1
index 78a7808..694e49f 100644
@@ -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[]);
include/ide.h +2 -0
index f691a74..24c29f9 100644
@@ -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
 
 /*
include/part.h +2 -2
index 35c1c5b..8388ba8 100644
@@ -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		*/
Signature · 1 line
1.8.1.2
#20 lore raw

PATCH 1/1 Fix ext2/ext4 filesystem accesses beyond 2TiB

Frederic Leroy <[email protected]> writes:

[...]

Quoted 1 line
 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:

disk/part_iso.c +1 -1
index cc323b0..e15e1b9 100644
@@ -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>

#21 lore raw

PATCH v2 1/1 Fix ext2/ext4 filesystem accesses beyond 2TiB

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.

---

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(-)
common/cmd_disk.c +2 -1
index ee4e215..8c4d0bd 100644
@@ -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) {
disk/part_efi.c +3 -3
index fb5e9f0..732bdb5 100644
@@ -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);
 	}
disk/part_iso.c +2 -2
index cc323b0..a050c44 100644
@@ -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);
 }
fs/ext4/dev.c +5 -4
index 81b7633..2cd182c 100644
@@ -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 */
fs/ext4/ext4_common.c +27 -21

168 lines not on this page · raw message

fs/ext4/ext4_journal.c +12 -7
index 81aa5fc..a540367 100644
@@ -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);
fs/ext4/ext4_write.c +29 -21

164 lines not on this page · raw message

fs/ext4/ext4fs.c +7 -7
index 1954afb..20ff10f 100644
@@ -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;
include/ext4fs.h +1 -1
index 379f7eb..2429380 100644
@@ -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,
include/ext_common.h +1 -1
index 78a7808..694e49f 100644
@@ -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[]);
include/ide.h +2 -0
index afea85c..d312a29 100644
@@ -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
 
 /*
include/part.h +2 -2
index f7c7cc5..8d5ea5d 100644
@@ -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		*/
Signature · 1 line
1.8.1.2
#22 lore raw

PATCH v2 1/1 Fix ext2/ext4 filesystem accesses beyond 2TiB

Hi Tom,

Quoted 658 lines · Fr?d?ric Leroy

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.

---

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(-)
common/cmd_disk.c +2 -1
index ee4e215..8c4d0bd 100644
@@ -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) {
disk/part_efi.c +3 -3
index fb5e9f0..732bdb5 100644
@@ -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);
 	}
disk/part_iso.c +2 -2
index cc323b0..a050c44 100644
@@ -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);
 }
fs/ext4/dev.c +5 -4
index 81b7633..2cd182c 100644
@@ -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 */
fs/ext4/ext4_common.c +27 -21
index 58880b4..2776293 100644
@@ -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,
fs/ext4/ext4_journal.c +12 -7
index 81aa5fc..a540367 100644
@@ -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);
fs/ext4/ext4_write.c +29 -21
index 0c1f62b..501b95a 100644
@@ -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;
fs/ext4/ext4fs.c +7 -7
index 1954afb..20ff10f 100644
@@ -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;
include/ext4fs.h +1 -1
index 379f7eb..2429380 100644
@@ -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,
include/ext_common.h +1 -1
index 78a7808..694e49f 100644
@@ -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[]);
include/ide.h +2 -0
index afea85c..d312a29 100644
@@ -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
 
 /*
include/part.h +0 -0
index f7c7cc5..8d5ea5d 100644

include/part.h typedef struct block_dev_desc { · line 104

Quoted 10 lines
include/part.h +2 -2
@@ -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,

Signature · 1 line
Albert.
#23 lore raw

PATCH v2 1/1 Fix ext2/ext4 filesystem accesses beyond 2TiB

In reply to Frédéric Leroy
Quoted 9 lines · Frederic Leroy

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.

Quoted 5 lines

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.

Applied to u-boot/master, thanks!

Signature · 8 lines
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>
#24 lore raw

[U-Boot] Fix block device accesses beyond 2TiB

In reply to Sascha Silbe
Quoted 10 lines · Sascha Silbe

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.

Quoted 5 lines

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.

Applied to u-boot/master, thanks!

Signature · 8 lines
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>