mirror of
https://xff.cz/git/u-boot/
synced 2025-09-01 16:52:14 +02:00
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. Signed-off-by: Frédéric Leroy <fredo@starox.org>
This commit is contained in:
@@ -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;
|
||||
|
Reference in New Issue
Block a user