diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c index 3dacb124b8c828535b5c4648aa3624ff9fae18cd..3e85886a6382b734f1a9b20af4aadf96ef1ebd8b 100644 --- a/fs/ext4/balloc.c +++ b/fs/ext4/balloc.c @@ -101,13 +101,13 @@ read_block_bitmap(struct super_block *sb, unsigned int block_group) desc = ext4_get_group_desc (sb, block_group, NULL); if (!desc) goto error_out; - bh = sb_bread(sb, ext4_block_bitmap(desc)); + bh = sb_bread(sb, ext4_block_bitmap(sb, desc)); if (!bh) ext4_error (sb, "read_block_bitmap", "Cannot read block bitmap - " "block_group = %d, block_bitmap = %llu", block_group, - ext4_block_bitmap(desc)); + ext4_block_bitmap(sb, desc)); error_out: return bh; } @@ -463,10 +463,10 @@ void ext4_free_blocks_sb(handle_t *handle, struct super_block *sb, if (!desc) goto error_return; - if (in_range(ext4_block_bitmap(desc), block, count) || - in_range(ext4_inode_bitmap(desc), block, count) || - in_range(block, ext4_inode_table(desc), sbi->s_itb_per_group) || - in_range(block + count - 1, ext4_inode_table(desc), + if (in_range(ext4_block_bitmap(sb, desc), block, count) || + in_range(ext4_inode_bitmap(sb, desc), block, count) || + in_range(block, ext4_inode_table(sb, desc), sbi->s_itb_per_group) || + in_range(block + count - 1, ext4_inode_table(sb, desc), sbi->s_itb_per_group)) ext4_error (sb, "ext4_free_blocks", "Freeing blocks in system zones - " @@ -1563,11 +1563,11 @@ ext4_fsblk_t ext4_new_blocks(handle_t *handle, struct inode *inode, ret_block = grp_alloc_blk + ext4_group_first_block_no(sb, group_no); - if (in_range(ext4_block_bitmap(gdp), ret_block, num) || - in_range(ext4_block_bitmap(gdp), ret_block, num) || - in_range(ret_block, ext4_inode_table(gdp), + if (in_range(ext4_block_bitmap(sb, gdp), ret_block, num) || + in_range(ext4_block_bitmap(sb, gdp), ret_block, num) || + in_range(ret_block, ext4_inode_table(sb, gdp), EXT4_SB(sb)->s_itb_per_group) || - in_range(ret_block + num - 1, ext4_inode_table(gdp), + in_range(ret_block + num - 1, ext4_inode_table(sb, gdp), EXT4_SB(sb)->s_itb_per_group)) ext4_error(sb, "ext4_new_block", "Allocating block in system zone - " diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c index 959b7fa8f5dbccc5b1648cd757b8749d5cc8615e..75608e1e5555a1068b1eaf1b9cc4f64ee5c1a2df 100644 --- a/fs/ext4/ialloc.c +++ b/fs/ext4/ialloc.c @@ -60,12 +60,12 @@ read_inode_bitmap(struct super_block * sb, unsigned long block_group) if (!desc) goto error_out; - bh = sb_bread(sb, ext4_inode_bitmap(desc)); + bh = sb_bread(sb, ext4_inode_bitmap(sb, desc)); if (!bh) ext4_error(sb, "read_inode_bitmap", "Cannot read inode bitmap - " "block_group = %lu, inode_bitmap = %llu", - block_group, ext4_inode_bitmap(desc)); + block_group, ext4_inode_bitmap(sb, desc)); error_out: return bh; } diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index d03e7d85a6385babe192b50780279be0d6b83008..0a60ec5a16dbc4bb92645dfafcd644e895d05161 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -2439,9 +2439,8 @@ static ext4_fsblk_t ext4_get_inode_block(struct super_block *sb, */ offset = ((ino - 1) % EXT4_INODES_PER_GROUP(sb)) * EXT4_INODE_SIZE(sb); - block = ext4_inode_table(gdp) + (offset >> EXT4_BLOCK_SIZE_BITS(sb)); - - + block = ext4_inode_table(sb, gdp) + + (offset >> EXT4_BLOCK_SIZE_BITS(sb)); iloc->block_group = block_group; iloc->offset = offset & (EXT4_BLOCK_SIZE(sb) - 1); @@ -2508,7 +2507,7 @@ static int __ext4_get_inode_loc(struct inode *inode, goto make_io; bitmap_bh = sb_getblk(inode->i_sb, - ext4_inode_bitmap(desc)); + ext4_inode_bitmap(inode->i_sb, desc)); if (!bitmap_bh) goto make_io; diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c index 3e960677c2f285c1ceacf402efa8574b0bfdf2b9..1e9578052cd35b3cba19c87f5ab8f948d057452d 100644 --- a/fs/ext4/resize.c +++ b/fs/ext4/resize.c @@ -834,9 +834,9 @@ int ext4_group_add(struct super_block *sb, struct ext4_new_group_data *input) /* Update group descriptor block for new group */ gdp = (struct ext4_group_desc *)primary->b_data + gdb_off; - ext4_block_bitmap_set(gdp, input->block_bitmap); /* LV FIXME */ - ext4_inode_bitmap_set(gdp, input->inode_bitmap); /* LV FIXME */ - ext4_inode_table_set(gdp, input->inode_table); /* LV FIXME */ + ext4_block_bitmap_set(sb, gdp, input->block_bitmap); /* LV FIXME */ + ext4_inode_bitmap_set(sb, gdp, input->inode_bitmap); /* LV FIXME */ + ext4_inode_table_set(sb, gdp, input->inode_table); /* LV FIXME */ gdp->bg_free_blocks_count = cpu_to_le16(input->free_blocks_count); gdp->bg_free_inodes_count = cpu_to_le16(EXT4_INODES_PER_GROUP(sb)); diff --git a/fs/ext4/super.c b/fs/ext4/super.c index bc8848bff2f112c7e2e143f38fac306369c04484..811011fc5c94e0082f5a5620dc55683edddb3eab 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -63,40 +63,52 @@ static void ext4_write_super (struct super_block * sb); static void ext4_write_super_lockfs(struct super_block *sb); -ext4_fsblk_t ext4_block_bitmap(struct ext4_group_desc *bg) +ext4_fsblk_t ext4_block_bitmap(struct super_block *sb, + struct ext4_group_desc *bg) { return le32_to_cpu(bg->bg_block_bitmap) | - ((ext4_fsblk_t)le16_to_cpu(bg->bg_block_bitmap_hi) << 32); + (EXT4_DESC_SIZE(sb) >= EXT4_MIN_DESC_SIZE_64BIT ? + (ext4_fsblk_t)le32_to_cpu(bg->bg_block_bitmap_hi) << 32 : 0); } -ext4_fsblk_t ext4_inode_bitmap(struct ext4_group_desc *bg) +ext4_fsblk_t ext4_inode_bitmap(struct super_block *sb, + struct ext4_group_desc *bg) { return le32_to_cpu(bg->bg_inode_bitmap) | - ((ext4_fsblk_t)le16_to_cpu(bg->bg_inode_bitmap_hi) << 32); + (EXT4_DESC_SIZE(sb) >= EXT4_MIN_DESC_SIZE_64BIT ? + (ext4_fsblk_t)le32_to_cpu(bg->bg_inode_bitmap_hi) << 32 : 0); } -ext4_fsblk_t ext4_inode_table(struct ext4_group_desc *bg) +ext4_fsblk_t ext4_inode_table(struct super_block *sb, + struct ext4_group_desc *bg) { return le32_to_cpu(bg->bg_inode_table) | - ((ext4_fsblk_t)le16_to_cpu(bg->bg_inode_table_hi) << 32); + (EXT4_DESC_SIZE(sb) >= EXT4_MIN_DESC_SIZE_64BIT ? + (ext4_fsblk_t)le32_to_cpu(bg->bg_inode_table_hi) << 32 : 0); } -void ext4_block_bitmap_set(struct ext4_group_desc *bg, ext4_fsblk_t blk) +void ext4_block_bitmap_set(struct super_block *sb, + struct ext4_group_desc *bg, ext4_fsblk_t blk) { bg->bg_block_bitmap = cpu_to_le32((u32)blk); - bg->bg_block_bitmap_hi = cpu_to_le16(blk >> 32); + if (EXT4_DESC_SIZE(sb) >= EXT4_MIN_DESC_SIZE_64BIT) + bg->bg_block_bitmap_hi = cpu_to_le32(blk >> 32); } -void ext4_inode_bitmap_set(struct ext4_group_desc *bg, ext4_fsblk_t blk) +void ext4_inode_bitmap_set(struct super_block *sb, + struct ext4_group_desc *bg, ext4_fsblk_t blk) { bg->bg_inode_bitmap = cpu_to_le32((u32)blk); - bg->bg_inode_bitmap_hi = cpu_to_le16(blk >> 32); + if (EXT4_DESC_SIZE(sb) >= EXT4_MIN_DESC_SIZE_64BIT) + bg->bg_inode_bitmap_hi = cpu_to_le32(blk >> 32); } -void ext4_inode_table_set(struct ext4_group_desc *bg, ext4_fsblk_t blk) +void ext4_inode_table_set(struct super_block *sb, + struct ext4_group_desc *bg, ext4_fsblk_t blk) { bg->bg_inode_table = cpu_to_le32((u32)blk); - bg->bg_inode_table_hi = cpu_to_le16(blk >> 32); + if (EXT4_DESC_SIZE(sb) >= EXT4_MIN_DESC_SIZE_64BIT) + bg->bg_inode_table_hi = cpu_to_le32(blk >> 32); } /* @@ -1239,7 +1251,7 @@ static int ext4_check_descriptors (struct super_block * sb) if ((i % EXT4_DESC_PER_BLOCK(sb)) == 0) gdp = (struct ext4_group_desc *) sbi->s_group_desc[desc_block++]->b_data; - block_bitmap = ext4_block_bitmap(gdp); + block_bitmap = ext4_block_bitmap(sb, gdp); if (block_bitmap < first_block || block_bitmap > last_block) { ext4_error (sb, "ext4_check_descriptors", @@ -1248,7 +1260,7 @@ static int ext4_check_descriptors (struct super_block * sb) i, block_bitmap); return 0; } - inode_bitmap = ext4_inode_bitmap(gdp); + inode_bitmap = ext4_inode_bitmap(sb, gdp); if (inode_bitmap < first_block || inode_bitmap > last_block) { ext4_error (sb, "ext4_check_descriptors", @@ -1257,7 +1269,7 @@ static int ext4_check_descriptors (struct super_block * sb) i, inode_bitmap); return 0; } - inode_table = ext4_inode_table(gdp); + inode_table = ext4_inode_table(sb, gdp); if (inode_table < first_block || inode_table + sbi->s_itb_per_group > last_block) { @@ -1622,11 +1634,11 @@ static int ext4_fill_super (struct super_block *sb, void *data, int silent) } sbi->s_desc_size = le16_to_cpu(es->s_desc_size); if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_64BIT)) { - if (sbi->s_desc_size < EXT4_MIN_DESC_SIZE || + if (sbi->s_desc_size < EXT4_MIN_DESC_SIZE_64BIT || sbi->s_desc_size > EXT4_MAX_DESC_SIZE || sbi->s_desc_size & (sbi->s_desc_size - 1)) { printk(KERN_ERR - "EXT4-fs: unsupported descriptor size %ld\n", + "EXT4-fs: unsupported descriptor size %lu\n", sbi->s_desc_size); goto failed_mount; } diff --git a/include/linux/ext4_fs.h b/include/linux/ext4_fs.h index a3df2afc004b80250caa0b902e9763c0380bd9cf..296609b9242d55f902a751cc7ce5e0a5c7b31385 100644 --- a/include/linux/ext4_fs.h +++ b/include/linux/ext4_fs.h @@ -129,10 +129,10 @@ struct ext4_group_desc __le16 bg_free_inodes_count; /* Free inodes count */ __le16 bg_used_dirs_count; /* Directories count */ __u16 bg_flags; - __le16 bg_block_bitmap_hi; /* Blocks bitmap block MSB */ - __le16 bg_inode_bitmap_hi; /* Inodes bitmap block MSB */ - __le16 bg_inode_table_hi; /* Inodes table block MSB */ - __u16 bg_reserved[3]; + __u32 bg_reserved[3]; + __le32 bg_block_bitmap_hi; /* Blocks bitmap block MSB */ + __le32 bg_inode_bitmap_hi; /* Inodes bitmap block MSB */ + __le32 bg_inode_table_hi; /* Inodes table block MSB */ }; #ifdef __KERNEL__ @@ -143,6 +143,7 @@ struct ext4_group_desc * Macro-instructions used to manage group descriptors */ #define EXT4_MIN_DESC_SIZE 32 +#define EXT4_MIN_DESC_SIZE_64BIT 64 #define EXT4_MAX_DESC_SIZE EXT4_MIN_BLOCK_SIZE #define EXT4_DESC_SIZE(s) (EXT4_SB(s)->s_desc_size) #ifdef __KERNEL__ @@ -904,12 +905,18 @@ extern void ext4_abort (struct super_block *, const char *, const char *, ...) extern void ext4_warning (struct super_block *, const char *, const char *, ...) __attribute__ ((format (printf, 3, 4))); extern void ext4_update_dynamic_rev (struct super_block *sb); -extern ext4_fsblk_t ext4_block_bitmap(struct ext4_group_desc *bg); -extern ext4_fsblk_t ext4_inode_bitmap(struct ext4_group_desc *bg); -extern ext4_fsblk_t ext4_inode_table(struct ext4_group_desc *bg); -extern void ext4_block_bitmap_set(struct ext4_group_desc *bg, ext4_fsblk_t blk); -extern void ext4_inode_bitmap_set(struct ext4_group_desc *bg, ext4_fsblk_t blk); -extern void ext4_inode_table_set(struct ext4_group_desc *bg, ext4_fsblk_t blk); +extern ext4_fsblk_t ext4_block_bitmap(struct super_block *sb, + struct ext4_group_desc *bg); +extern ext4_fsblk_t ext4_inode_bitmap(struct super_block *sb, + struct ext4_group_desc *bg); +extern ext4_fsblk_t ext4_inode_table(struct super_block *sb, + struct ext4_group_desc *bg); +extern void ext4_block_bitmap_set(struct super_block *sb, + struct ext4_group_desc *bg, ext4_fsblk_t blk); +extern void ext4_inode_bitmap_set(struct super_block *sb, + struct ext4_group_desc *bg, ext4_fsblk_t blk); +extern void ext4_inode_table_set(struct super_block *sb, + struct ext4_group_desc *bg, ext4_fsblk_t blk); static inline ext4_fsblk_t ext4_blocks_count(struct ext4_super_block *es) {