diff options
author | Egbert Eich <eich@suse.com> | 2013-05-01 01:13:19 +0000 |
---|---|---|
committer | Tom Rini <trini@ti.com> | 2013-05-10 08:16:33 -0400 |
commit | 50ce4c07df1c98aabf4630b35152ed95a87242f7 (patch) | |
tree | c7e506ab5bcb2839a697cb0a89faa3244077cf69 /fs/ext4/dev.c | |
parent | b1e6c4c3d4a2b394096766d959aaa9b51a38099b (diff) |
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>
Diffstat (limited to 'fs/ext4/dev.c')
-rw-r--r-- | fs/ext4/dev.c | 62 |
1 files changed, 40 insertions, 22 deletions
diff --git a/fs/ext4/dev.c b/fs/ext4/dev.c index 464a67d531..3e993cc220 100644 --- a/fs/ext4/dev.c +++ b/fs/ext4/dev.c @@ -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); +} |