Patchwork [U-Boot] Fix ext2/ext4 filesystem accesses beyond 2TiB

login
register
mail settings
Submitter Frederic Leroy
Date June 24, 2013, 9:26 p.m.
Message ID <1372109200-24715-1-git-send-email-fredo@starox.org>
Download mbox | patch
Permalink /patch/253977/
State Superseded
Delegated to: Tom Rini
Headers show

Comments

Frederic Leroy - June 24, 2013, 9:26 p.m.
From: Frédéric Leroy <fredo@starox.org>

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

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

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

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

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

 common/cmd_disk.c      |  2 +-
 disk/part_efi.c        |  4 ++--
 fs/ext4/dev.c          |  8 ++++----
 fs/ext4/ext4_common.c  | 40 ++++++++++++++++++++--------------------
 fs/ext4/ext4_journal.c | 12 ++++++------
 fs/ext4/ext4_write.c   | 38 +++++++++++++++++++-------------------
 fs/ext4/ext4fs.c       | 14 +++++++-------
 include/ext4fs.h       |  2 +-
 include/ext_common.h   |  2 +-
 include/ide.h          |  2 ++
 include/part.h         |  4 ++--
 11 files changed, 65 insertions(+), 63 deletions(-)
Sascha Silbe - June 24, 2013, 10:26 p.m.
Frederic Leroy <fredo@starox.org> writes:

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

Thanks for the patch!

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

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


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

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

Sascha

Patch

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