fs/ext4: Support device block sizes != 512 bytes

The 512 byte block size was hard coded in the ext4 file systems.
Large harddisks today support bigger block sizes typically 4096
bytes.
This patch removes this limitation.

Signed-off-by: Egbert Eich <eich@suse.com>
This commit is contained in:
Egbert Eich 2013-05-01 01:13:19 +00:00 committed by Tom Rini
parent b1e6c4c3d4
commit 50ce4c07df
8 changed files with 95 additions and 76 deletions

View file

@ -40,6 +40,7 @@
#include <config.h>
#include <ext4fs.h>
#include <ext_common.h>
#include "ext4_common.h"
unsigned long part_offset;
@ -48,37 +49,41 @@ static disk_partition_t *part_info;
void ext4fs_set_blk_dev(block_dev_desc_t *rbdd, disk_partition_t *info)
{
assert(rbdd->blksz == (1 << rbdd->log2blksz));
ext4fs_block_dev_desc = rbdd;
part_info = info;
part_offset = info->start;
get_fs()->total_sect = (info->size * info->blksz) / SECTOR_SIZE;
get_fs()->total_sect = (info->size * info->blksz) >>
get_fs()->dev_desc->log2blksz;
get_fs()->dev_desc = rbdd;
}
int ext4fs_devread(int sector, int byte_offset, int byte_len, char *buf)
{
ALLOC_CACHE_ALIGN_BUFFER(char, sec_buf, SECTOR_SIZE);
unsigned block_len;
int log2blksz = ext4fs_block_dev_desc->log2blksz;
ALLOC_CACHE_ALIGN_BUFFER(char, sec_buf, (ext4fs_block_dev_desc ?
ext4fs_block_dev_desc->blksz :
0));
if (ext4fs_block_dev_desc == NULL) {
printf("** Invalid Block Device Descriptor (NULL)\n");
return 0;
}
/* Check partition boundaries */
if ((sector < 0)
|| ((sector + ((byte_offset + byte_len - 1) >> SECTOR_BITS)) >=
part_info->size)) {
if ((sector < 0) ||
((sector + ((byte_offset + byte_len - 1) >> log2blksz))
>= part_info->size)) {
printf("%s read outside partition %d\n", __func__, sector);
return 0;
}
/* Get the read to the beginning of a partition */
sector += byte_offset >> SECTOR_BITS;
byte_offset &= SECTOR_SIZE - 1;
sector += byte_offset >> log2blksz;
byte_offset &= ext4fs_block_dev_desc->blksz - 1;
debug(" <%d, %d, %d>\n", sector, byte_offset, byte_len);
if (ext4fs_block_dev_desc == NULL) {
printf("** Invalid Block Device Descriptor (NULL)\n");
return 0;
}
if (byte_offset != 0) {
/* read first part which isn't aligned with start of sector */
if (ext4fs_block_dev_desc->
@ -89,9 +94,12 @@ int ext4fs_devread(int sector, int byte_offset, int byte_len, char *buf)
return 0;
}
memcpy(buf, sec_buf + byte_offset,
min(SECTOR_SIZE - byte_offset, byte_len));
buf += min(SECTOR_SIZE - byte_offset, byte_len);
byte_len -= min(SECTOR_SIZE - byte_offset, byte_len);
min(ext4fs_block_dev_desc->blksz
- byte_offset, byte_len));
buf += min(ext4fs_block_dev_desc->blksz
- byte_offset, byte_len);
byte_len -= min(ext4fs_block_dev_desc->blksz
- byte_offset, byte_len);
sector++;
}
@ -99,12 +107,12 @@ int ext4fs_devread(int sector, int byte_offset, int byte_len, char *buf)
return 1;
/* read sector aligned part */
block_len = byte_len & ~(SECTOR_SIZE - 1);
block_len = byte_len & ~(ext4fs_block_dev_desc->blksz - 1);
if (block_len == 0) {
ALLOC_CACHE_ALIGN_BUFFER(u8, p, SECTOR_SIZE);
ALLOC_CACHE_ALIGN_BUFFER(u8, p, ext4fs_block_dev_desc->blksz);
block_len = SECTOR_SIZE;
block_len = ext4fs_block_dev_desc->blksz;
ext4fs_block_dev_desc->block_read(ext4fs_block_dev_desc->dev,
part_info->start + sector,
1, (unsigned long *)p);
@ -114,16 +122,16 @@ int ext4fs_devread(int sector, int byte_offset, int byte_len, char *buf)
if (ext4fs_block_dev_desc->block_read(ext4fs_block_dev_desc->dev,
part_info->start + sector,
block_len / SECTOR_SIZE,
block_len >> log2blksz,
(unsigned long *) buf) !=
block_len / SECTOR_SIZE) {
block_len >> log2blksz) {
printf(" ** %s read error - block\n", __func__);
return 0;
}
block_len = byte_len & ~(SECTOR_SIZE - 1);
block_len = byte_len & ~(ext4fs_block_dev_desc->blksz - 1);
buf += block_len;
byte_len -= block_len;
sector += block_len / SECTOR_SIZE;
sector += block_len / ext4fs_block_dev_desc->blksz;
if (byte_len != 0) {
/* read rest of data which are not in whole sector */
@ -138,3 +146,13 @@ int ext4fs_devread(int sector, int byte_offset, int byte_len, char *buf)
}
return 1;
}
int ext4_read_superblock(char *buffer)
{
struct ext_filesystem *fs = get_fs();
int sect = SUPERBLOCK_START >> fs->dev_desc->log2blksz;
int off = SUPERBLOCK_START % fs->dev_desc->blksz;
return ext4fs_devread(sect, off, SUPERBLOCK_SIZE,
buffer);
}