diff options
| author | Frederic Leroy <fredo@starox.org> | 2013-06-26 18:11:25 +0200 | 
|---|---|---|
| committer | Tom Rini <trini@ti.com> | 2013-07-15 17:06:13 -0400 | 
| commit | 04735e9c5578dd4f3584be5454b9779e8e5c2af9 (patch) | |
| tree | 5641d35f98ffda64ff900a8356639eeb88f320a5 /fs/ext4/ext4_write.c | |
| parent | 0eb33ad253026d5a773854dd42b2a56937678aa9 (diff) | |
| download | olio-uboot-2014.01-04735e9c5578dd4f3584be5454b9779e8e5c2af9.tar.xz olio-uboot-2014.01-04735e9c5578dd4f3584be5454b9779e8e5c2af9.zip | |
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>
Diffstat (limited to 'fs/ext4/ext4_write.c')
| -rw-r--r-- | fs/ext4/ext4_write.c | 50 | 
1 files changed, 29 insertions, 21 deletions
| diff --git a/fs/ext4/ext4_write.c b/fs/ext4/ext4_write.c index 0c1f62b60..501b95ab7 100644 --- a/fs/ext4/ext4_write.c +++ b/fs/ext4/ext4_write.c @@ -88,8 +88,8 @@ int ext4fs_get_bgdtable(void)  	if (!fs->gdtable)  		return -ENOMEM;  	/* read the group descriptor table */ -	status = ext4fs_devread(fs->gdtable_blkno * fs->sect_perblk, 0, -				fs->blksz * fs->no_blk_pergdt, fs->gdtable); +	status = ext4fs_devread((lbaint_t)fs->gdtable_blkno * fs->sect_perblk, +				0, fs->blksz * fs->no_blk_pergdt, fs->gdtable);  	if (status == 0)  		goto fail; @@ -142,7 +142,7 @@ static void delete_single_indirect_block(struct ext2_inode *inode)  		/* journal backup */  		if (prev_bg_bmap_idx != bg_idx) {  			status = -			    ext4fs_devread(bgd[bg_idx].block_id * +			    ext4fs_devread((lbaint_t)bgd[bg_idx].block_id *  					   fs->sect_perblk, 0, fs->blksz,  					   journal_buffer);  			if (status == 0) @@ -186,8 +186,8 @@ static void delete_double_indirect_block(struct ext2_inode *inode)  		}  		DIB_start_addr = (unsigned int *)di_buffer;  		blknr = inode->b.blocks.double_indir_block; -		status = ext4fs_devread(blknr * fs->sect_perblk, 0, fs->blksz, -					(char *)di_buffer); +		status = ext4fs_devread((lbaint_t)blknr * fs->sect_perblk, 0, +					fs->blksz, (char *)di_buffer);  		for (i = 0; i < fs->blksz / sizeof(int); i++) {  			if (*di_buffer == 0)  				break; @@ -208,7 +208,8 @@ static void delete_double_indirect_block(struct ext2_inode *inode)  			fs->sb->free_blocks++;  			/* journal backup */  			if (prev_bg_bmap_idx != bg_idx) { -				status = ext4fs_devread(bgd[bg_idx].block_id +				status = ext4fs_devread((lbaint_t) +							bgd[bg_idx].block_id  							* fs->sect_perblk, 0,  							fs->blksz,  							journal_buffer); @@ -238,7 +239,7 @@ static void delete_double_indirect_block(struct ext2_inode *inode)  		/* journal backup */  		if (prev_bg_bmap_idx != bg_idx) {  			memset(journal_buffer, '\0', fs->blksz); -			status = ext4fs_devread(bgd[bg_idx].block_id * +			status = ext4fs_devread((lbaint_t)bgd[bg_idx].block_id *  						fs->sect_perblk, 0, fs->blksz,  						journal_buffer);  			if (status == 0) @@ -287,8 +288,8 @@ static void delete_triple_indirect_block(struct ext2_inode *inode)  		}  		tib_start_addr = (unsigned int *)tigp_buffer;  		blknr = inode->b.blocks.triple_indir_block; -		status = ext4fs_devread(blknr * fs->sect_perblk, 0, fs->blksz, -					(char *)tigp_buffer); +		status = ext4fs_devread((lbaint_t)blknr * fs->sect_perblk, 0, +					fs->blksz, (char *)tigp_buffer);  		for (i = 0; i < fs->blksz / sizeof(int); i++) {  			if (*tigp_buffer == 0)  				break; @@ -298,7 +299,7 @@ static void delete_triple_indirect_block(struct ext2_inode *inode)  			if (!tip_buffer)  				goto fail;  			tipb_start_addr = (unsigned int *)tip_buffer; -			status = ext4fs_devread((*tigp_buffer) * +			status = ext4fs_devread((lbaint_t)(*tigp_buffer) *  						fs->sect_perblk, 0, fs->blksz,  						(char *)tip_buffer);  			for (j = 0; j < fs->blksz / sizeof(int); j++) { @@ -325,6 +326,7 @@ static void delete_triple_indirect_block(struct ext2_inode *inode)  				if (prev_bg_bmap_idx != bg_idx) {  					status =  					    ext4fs_devread( +							(lbaint_t)  							bgd[bg_idx].block_id *  							fs->sect_perblk, 0,  							fs->blksz, @@ -365,7 +367,8 @@ static void delete_triple_indirect_block(struct ext2_inode *inode)  			if (prev_bg_bmap_idx != bg_idx) {  				memset(journal_buffer, '\0', fs->blksz);  				status = -				    ext4fs_devread(bgd[bg_idx].block_id * +				    ext4fs_devread((lbaint_t) +						   bgd[bg_idx].block_id *  						   fs->sect_perblk, 0,  						   fs->blksz, journal_buffer);  				if (status == 0) @@ -394,7 +397,7 @@ static void delete_triple_indirect_block(struct ext2_inode *inode)  		/* journal backup */  		if (prev_bg_bmap_idx != bg_idx) {  			memset(journal_buffer, '\0', fs->blksz); -			status = ext4fs_devread(bgd[bg_idx].block_id * +			status = ext4fs_devread((lbaint_t)bgd[bg_idx].block_id *  						fs->sect_perblk, 0, fs->blksz,  						journal_buffer);  			if (status == 0) @@ -480,7 +483,8 @@ static int ext4fs_delete_file(int inodeno)  			/* journal backup */  			if (prev_bg_bmap_idx != bg_idx) {  				status = -				    ext4fs_devread(bgd[bg_idx].block_id * +				    ext4fs_devread((lbaint_t) +						   bgd[bg_idx].block_id *  						   fs->sect_perblk, 0,  						   fs->blksz, journal_buffer);  				if (status == 0) @@ -524,7 +528,8 @@ static int ext4fs_delete_file(int inodeno)  			/* journal backup */  			if (prev_bg_bmap_idx != bg_idx) {  				memset(journal_buffer, '\0', fs->blksz); -				status = ext4fs_devread(bgd[bg_idx].block_id +				status = ext4fs_devread((lbaint_t) +							bgd[bg_idx].block_id  							* fs->sect_perblk,  							0, fs->blksz,  							journal_buffer); @@ -555,7 +560,7 @@ static int ext4fs_delete_file(int inodeno)  	if (!read_buffer)  		goto fail;  	start_block_address = read_buffer; -	status = ext4fs_devread(blkno * fs->sect_perblk, +	status = ext4fs_devread((lbaint_t)blkno * fs->sect_perblk,  				0, fs->blksz, read_buffer);  	if (status == 0)  		goto fail; @@ -578,7 +583,7 @@ static int ext4fs_delete_file(int inodeno)  	fs->sb->free_inodes++;  	/* journal backup */  	memset(journal_buffer, '\0', fs->blksz); -	status = ext4fs_devread(bgd[ibmap_idx].inode_id * +	status = ext4fs_devread((lbaint_t)bgd[ibmap_idx].inode_id *  				fs->sect_perblk, 0, fs->blksz, journal_buffer);  	if (status == 0)  		goto fail; @@ -653,7 +658,8 @@ int ext4fs_init(void)  	for (i = 0; i < fs->no_blkgrp; i++) {  		status = -		    ext4fs_devread(fs->bgd[i].block_id * fs->sect_perblk, 0, +		    ext4fs_devread((lbaint_t)fs->bgd[i].block_id * +				   fs->sect_perblk, 0,  				   fs->blksz, (char *)fs->blk_bmaps[i]);  		if (status == 0)  			goto fail; @@ -670,7 +676,8 @@ int ext4fs_init(void)  	}  	for (i = 0; i < fs->no_blkgrp; i++) { -		status = ext4fs_devread(fs->bgd[i].inode_id * fs->sect_perblk, +		status = ext4fs_devread((lbaint_t)fs->bgd[i].inode_id * +					fs->sect_perblk,  					0, fs->blksz,  					(char *)fs->inode_bmaps[i]);  		if (status == 0) @@ -710,7 +717,7 @@ void ext4fs_deinit(void)  				  &inode_journal);  		blknr = read_allocated_block(&inode_journal,  					EXT2_JOURNAL_SUPERBLOCK); -		ext4fs_devread(blknr * fs->sect_perblk, 0, fs->blksz, +		ext4fs_devread((lbaint_t)blknr * fs->sect_perblk, 0, fs->blksz,  			       temp_buff);  		jsb = (struct journal_superblock_t *)temp_buff;  		jsb->s_start = cpu_to_be32(0); @@ -934,7 +941,8 @@ int ext4fs_write(const char *fname, unsigned char *buffer,  			(inodeno % __le32_to_cpu(sblock->inodes_per_group)) /  			inodes_per_block;  	blkoff = (inodeno % inodes_per_block) * fs->inodesz; -	ext4fs_devread(itable_blkno * fs->sect_perblk, 0, fs->blksz, temp_ptr); +	ext4fs_devread((lbaint_t)itable_blkno * fs->sect_perblk, 0, fs->blksz, +		       temp_ptr);  	if (ext4fs_log_journal(temp_ptr, itable_blkno))  		goto fail; @@ -954,7 +962,7 @@ int ext4fs_write(const char *fname, unsigned char *buffer,  	blkoff = (parent_inodeno % inodes_per_block) * fs->inodesz;  	if (parent_itable_blkno != itable_blkno) {  		memset(temp_ptr, '\0', fs->blksz); -		ext4fs_devread(parent_itable_blkno * fs->sect_perblk, +		ext4fs_devread((lbaint_t)parent_itable_blkno * fs->sect_perblk,  			       0, fs->blksz, temp_ptr);  		if (ext4fs_log_journal(temp_ptr, parent_itable_blkno))  			goto fail; |