LaCie kirkwood boards: allow disk > 2TB
Subsystems (2)
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
@@ -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
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
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>
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
-0include/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 withCONFIG_SYS_64BIT_LBAenabled. 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-----
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
-0include/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 withCONFIG_SYS_64BIT_LBAenabled. 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>
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
-0include/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 withCONFIG_SYS_64BIT_LBAenabled. 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.
Acked-by Simon Guinot <[email protected]>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.
PATCH 1/1 LaCie kirkwood boards: allow disk > 2TB
In reply to Frederic LeroyHi 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
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.
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
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_LBA48is also broken incommon/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.
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_LBA48is also broken incommon/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.
PATCH 1/1 LaCie kirkwood boards: allow disk > 2TB
In reply to Frédéric LeroyQuoted 2 lines · Fr?d?ric Leroy
I will convert every ide block number to 64 bit for disk and partitions. I guess
CONFIG_LBA48is also broken incommon/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>
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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
PATCH 1/1 Fix block device accesses beyond 2TiB
Hello Sascha,
Quoted 19 lines
With
CONFIG_SYS_64BIT_LBA,lbaint_tgets 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_tfor 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_tfor block start addresses, too. This required changes to all block drivers as the signature ofblock_read(),block_write()andblock_erase()inblock_dev_desc_tchanged.Signed-off-by Sascha Silbe <[email protected]>---
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
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_tgets 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_tfor 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_tfor block start addresses, too. This required changes to all block drivers as the signature ofblock_read(),block_write()andblock_erase()inblock_dev_desc_tchanged.Signed-off-by Sascha Silbe <[email protected]>---
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]
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 VasutAnyone 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.
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
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>
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
@@ -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
@@ -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
@@ -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
@@ -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_blockgroupdebug ("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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
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_tgets 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_tfor partition offset to reflect thelbaint_tchange, and access partitions beyond or crossing the 2.1TiB limit. This required changes to signature ofext4fs_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>
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
@@ -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
@@ -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
@@ -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
@@ -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_blockgroupdebug ("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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
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
@@ -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>
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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
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_tgets 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 drivesWe now use
lbaint_tfor partition offset to reflect thelbaint_tchange, and access partitions beyond or crossing the 2.1TiB limit. This required changes to signature ofext4fs_devread(), and type of all variables relatives to block sector.ext2/ext4 fs uses logical block represented by a 32 bit value. Logical block is a multiple of device block sector. To avoid overflow problem when calling
ext4fs_devread(), we need to cast the sector parameter.Signed-off-by Fr?d?ric Leroy <[email protected]>---
Changes in v2 :
- Fix warning indisk/part_efi.cby Sascha Silbe
- Fix lines over 80 characters
- Move LBAFu to LBAFU to avoid camel casecommon/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@@ -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@@ -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@@ -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@@ -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@@ -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_blockgroupdebug ("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@@ -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@@ -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@@ -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@@ -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@@ -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@@ -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
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.
PATCH v2 1/1 Fix ext2/ext4 filesystem accesses beyond 2TiB
In reply to Frédéric LeroyQuoted 9 lines · Frederic Leroy
With
CONFIG_SYS_64BIT_LBA,lbaint_tgets 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 drivesWe now use
lbaint_tfor partition offset to reflect thelbaint_tchange, and access partitions beyond or crossing the 2.1TiB limit. This required changes to signature ofext4fs_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.Signed-off-by Fr??d??ric Leroy <[email protected]>
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>
[U-Boot] Fix block device accesses beyond 2TiB
In reply to Sascha SilbeQuoted 10 lines · Sascha Silbe
With
CONFIG_SYS_64BIT_LBA,lbaint_tgets 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_tfor 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_tfor block start addresses, too. This required changes to all block drivers as the signature ofblock_read(),block_write()andblock_erase()inblock_dev_desc_tchanged.Signed-off-by Sascha Silbe <[email protected]>
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>