2006-10-18 15:12:37

by Jean-Pierre Dion

[permalink] [raw]
Subject: Re: + ext4_allow_larger_descriptor_size.patch added to -mm tree

Thanks Jean-No?l,

I am just cc'ing the list ;-)


jean-pierre


Jean-Noel Cordenner wrote:

> hi,
>
> I've tested it using 64bits adressing, and it works.
>
> regards,
>
> Jean noel
>
>
>>
>> The patch titled
>>
>> ext4: allow larger descriptor size
>>
>> has been added to the -mm tree. Its filename is
>>
>> ext4_allow_larger_descriptor_size.patch
>>
>> See http://www.zip.com.au/~akpm/linux/patches/stuff/added-to-mm.txt
>> to find
>> out what to do about this
>>
>> ------------------------------------------------------
>> Subject: ext4: allow larger descriptor size
>> From: Alexandre Ratchov <[email protected]>
>>
>> make block group descriptor larger.
>>
>> Signed-off-by: Alexandre Ratchov <[email protected]>
>> Signed-off-by: Dave Kleikamp <[email protected]>
>> Signed-off-by: Andrew Morton <[email protected]>
>> ---
>>
>> fs/ext4/balloc.c | 6 ++++--
>> fs/ext4/inode.c | 8 +++++---
>> fs/ext4/super.c | 18 +++++++++++++++---
>> include/linux/ext4_fs.h | 9 ++++++---
>> include/linux/ext4_fs_sb.h | 1 +
>> 5 files changed, 31 insertions(+), 11 deletions(-)
>>
>> diff -puN fs/ext4/balloc.c~ext4_allow_larger_descriptor_size
>> fs/ext4/balloc.c
>> --- a/fs/ext4/balloc.c~ext4_allow_larger_descriptor_size
>> +++ a/fs/ext4/balloc.c
>> @@ -74,10 +74,12 @@ struct ext4_group_desc * ext4_get_group_
>> return NULL;
>> }
>>
>> - desc = (struct ext4_group_desc *)
>> sbi->s_group_desc[group_desc]->b_data;
>> + desc = (struct ext4_group_desc *)(
>> + (__u8 *)sbi->s_group_desc[group_desc]->b_data +
>> + offset * EXT4_DESC_SIZE(sb));
>> if (bh)
>> *bh = sbi->s_group_desc[group_desc];
>> - return desc + offset;
>> + return desc;
>> }
>>
>> /**
>> diff -puN fs/ext4/inode.c~ext4_allow_larger_descriptor_size
>> fs/ext4/inode.c
>> --- a/fs/ext4/inode.c~ext4_allow_larger_descriptor_size
>> +++ a/fs/ext4/inode.c
>> @@ -2432,14 +2432,16 @@ static ext4_fsblk_t ext4_get_inode_block
>> return 0;
>> }
>>
>> - gdp = (struct ext4_group_desc *)bh->b_data;
>> + gdp = (struct ext4_group_desc *)((__u8 *)bh->b_data +
>> + desc * EXT4_DESC_SIZE(sb));
>> /*
>> * Figure out the offset within the block group inode table
>> */
>> offset = ((ino - 1) % EXT4_INODES_PER_GROUP(sb)) *
>> EXT4_INODE_SIZE(sb);
>> - block = ext4_inode_table(gdp + desc) +
>> - (offset >> EXT4_BLOCK_SIZE_BITS(sb));
>> + block = ext4_inode_table(gdp) + (offset >>
>> EXT4_BLOCK_SIZE_BITS(sb));
>> +
>> +
>>
>> iloc->block_group = block_group;
>> iloc->offset = offset & (EXT4_BLOCK_SIZE(sb) - 1);
>> diff -puN fs/ext4/super.c~ext4_allow_larger_descriptor_size
>> fs/ext4/super.c
>> --- a/fs/ext4/super.c~ext4_allow_larger_descriptor_size
>> +++ a/fs/ext4/super.c
>> @@ -1268,7 +1268,8 @@ static int ext4_check_descriptors (struc
>> return 0;
>> }
>> first_block += EXT4_BLOCKS_PER_GROUP(sb);
>> - gdp++;
>> + gdp = (struct ext4_group_desc *)
>> + ((__u8 *)gdp + EXT4_DESC_SIZE(sb));
>> }
>>
>> ext4_free_blocks_count_set(sbi->s_es, ext4_count_free_blocks(sb));
>> @@ -1619,7 +1620,18 @@ static int ext4_fill_super (struct super
>> sbi->s_frag_size, blocksize);
>> goto failed_mount;
>> }
>> - sbi->s_frags_per_block = 1;
>> + 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 ||
>> + 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",
>> + sbi->s_desc_size);
>> + goto failed_mount;
>> + }
>> + } else
>> + sbi->s_desc_size = EXT4_MIN_DESC_SIZE;
>> sbi->s_blocks_per_group = le32_to_cpu(es->s_blocks_per_group);
>> sbi->s_frags_per_group = le32_to_cpu(es->s_frags_per_group);
>> sbi->s_inodes_per_group = le32_to_cpu(es->s_inodes_per_group);
>> @@ -1630,7 +1642,7 @@ static int ext4_fill_super (struct super
>> goto cantfind_ext4;
>> sbi->s_itb_per_group = sbi->s_inodes_per_group /
>> sbi->s_inodes_per_block;
>> - sbi->s_desc_per_block = blocksize / sizeof(struct ext4_group_desc);
>> + sbi->s_desc_per_block = blocksize / EXT4_DESC_SIZE(sb);
>> sbi->s_sbh = bh;
>> sbi->s_mount_state = le16_to_cpu(es->s_state);
>> sbi->s_addr_per_block_bits = log2(EXT4_ADDR_PER_BLOCK(sb));
>> diff -puN include/linux/ext4_fs.h~ext4_allow_larger_descriptor_size
>> include/linux/ext4_fs.h
>> --- a/include/linux/ext4_fs.h~ext4_allow_larger_descriptor_size
>> +++ a/include/linux/ext4_fs.h
>> @@ -142,6 +142,9 @@ struct ext4_group_desc
>> /*
>> * Macro-instructions used to manage group descriptors
>> */
>> +#define EXT4_MIN_DESC_SIZE 32
>> +#define EXT4_MAX_DESC_SIZE EXT4_MIN_BLOCK_SIZE
>> +#define EXT4_DESC_SIZE(s) (EXT4_SB(s)->s_desc_size)
>> #ifdef __KERNEL__
>> # define EXT4_BLOCKS_PER_GROUP(s) (EXT4_SB(s)->s_blocks_per_group)
>> # define EXT4_DESC_PER_BLOCK(s) (EXT4_SB(s)->s_desc_per_block)
>> @@ -149,7 +152,7 @@ struct ext4_group_desc
>> # define EXT4_DESC_PER_BLOCK_BITS(s)
>> (EXT4_SB(s)->s_desc_per_block_bits)
>> #else
>> # define EXT4_BLOCKS_PER_GROUP(s) ((s)->s_blocks_per_group)
>> -# define EXT4_DESC_PER_BLOCK(s) (EXT4_BLOCK_SIZE(s) / sizeof
>> (struct ext4_group_desc))
>> +# define EXT4_DESC_PER_BLOCK(s) (EXT4_BLOCK_SIZE(s) /
>> EXT4_DESC_SIZE(s))
>> # define EXT4_INODES_PER_GROUP(s) ((s)->s_inodes_per_group)
>> #endif
>>
>> @@ -474,7 +477,7 @@ struct ext4_super_block {
>> * things it doesn't understand...
>> */
>> __le32 s_first_ino; /* First non-reserved inode */
>> - __le16 s_inode_size; /* size of inode structure */
>> + __le16 s_inode_size; /* size of inode structure */
>> __le16 s_block_group_nr; /* block group # of this
>> superblock */
>> __le32 s_feature_compat; /* compatible feature set */
>> /*60*/ __le32 s_feature_incompat; /* incompatible feature
>> set */
>> @@ -500,7 +503,7 @@ struct ext4_super_block {
>> __le32 s_hash_seed[4]; /* HTREE hash seed */
>> __u8 s_def_hash_version; /* Default hash version to use */
>> __u8 s_reserved_char_pad;
>> - __u16 s_reserved_word_pad;
>> + __le16 s_desc_size; /* size of group descriptor */
>> /*100*/ __le32 s_default_mount_opts;
>> __le32 s_first_meta_bg; /* First metablock block group */
>> __le32 s_mkfs_time; /* When the filesystem was created */
>> diff -puN
>> include/linux/ext4_fs_sb.h~ext4_allow_larger_descriptor_size
>> include/linux/ext4_fs_sb.h
>> --- a/include/linux/ext4_fs_sb.h~ext4_allow_larger_descriptor_size
>> +++ a/include/linux/ext4_fs_sb.h
>> @@ -29,6 +29,7 @@
>> */
>> struct ext4_sb_info {
>> unsigned long s_frag_size; /* Size of a fragment in bytes */
>> + unsigned long s_desc_size; /* Size of a group descriptor in
>> bytes */
>> unsigned long s_frags_per_block;/* Number of fragments per block */
>> unsigned long s_inodes_per_block;/* Number of inodes per block */
>> unsigned long s_frags_per_group;/* Number of fragments in a
>> group */
>> _
>>
>> Patches currently in -mm which might be from
>> [email protected] are
>>
>> 64bit-metadata.patch
>> ext4_allow_larger_descriptor_size.patch
>> ext4_move_block_number_hi_bits.patch
>>
>> ----- End forwarded message -----
>> ----- Forwarded message from [email protected] -----
>>
>> From: [email protected]
>> Date: Thu, 05 Oct 2006 17:36:51 -0700
>> To: [email protected]
>> Cc: [email protected], [email protected]
>> Subject: + ext4_move_block_number_hi_bits.patch added to -mm tree
>>
>>
>> The patch titled
>>
>> ext4: move block number hi bits
>>
>> has been added to the -mm tree. Its filename is
>>
>> ext4_move_block_number_hi_bits.patch
>>
>> See http://www.zip.com.au/~akpm/linux/patches/stuff/added-to-mm.txt
>> to find
>> out what to do about this
>>
>> ------------------------------------------------------
>> Subject: ext4: move block number hi bits
>> From: Alexandre Ratchov <[email protected]>
>>
>> move '_hi' bits of block numbers in the larger part of the
>> block group descriptor structure
>>
>> Signed-off-by: Alexandre Ratchov <[email protected]>
>> Signed-off-by: Dave Kleikamp <[email protected]>
>> Signed-off-by: Andrew Morton <[email protected]>
>> ---
>>
>> fs/ext4/balloc.c | 20 ++++++++--------
>> fs/ext4/ialloc.c | 4 +--
>> fs/ext4/inode.c | 7 ++---
>> fs/ext4/resize.c | 6 ++--
>> fs/ext4/super.c | 46 +++++++++++++++++++++++---------------
>> include/linux/ext4_fs.h | 27 ++++++++++++++--------
>> 6 files changed, 64 insertions(+), 46 deletions(-)
>>
>> diff -puN fs/ext4/balloc.c~ext4_move_block_number_hi_bits
>> fs/ext4/balloc.c
>> --- a/fs/ext4/balloc.c~ext4_move_block_number_hi_bits
>> +++ a/fs/ext4/balloc.c
>> @@ -101,13 +101,13 @@ read_block_bitmap(struct super_block *sb
>> 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 @@ do_more:
>> 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 @@ allocated:
>>
>> 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 -puN fs/ext4/ialloc.c~ext4_move_block_number_hi_bits
>> fs/ext4/ialloc.c
>> --- a/fs/ext4/ialloc.c~ext4_move_block_number_hi_bits
>> +++ a/fs/ext4/ialloc.c
>> @@ -60,12 +60,12 @@ read_inode_bitmap(struct super_block * s
>> 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 -puN fs/ext4/inode.c~ext4_move_block_number_hi_bits fs/ext4/inode.c
>> --- a/fs/ext4/inode.c~ext4_move_block_number_hi_bits
>> +++ a/fs/ext4/inode.c
>> @@ -2439,9 +2439,8 @@ static ext4_fsblk_t ext4_get_inode_block
>> */
>> 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 i
>> 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 -puN fs/ext4/resize.c~ext4_move_block_number_hi_bits
>> fs/ext4/resize.c
>> --- a/fs/ext4/resize.c~ext4_move_block_number_hi_bits
>> +++ a/fs/ext4/resize.c
>> @@ -834,9 +834,9 @@ int ext4_group_add(struct super_block *s
>> /* 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 -puN fs/ext4/super.c~ext4_move_block_number_hi_bits fs/ext4/super.c
>> --- a/fs/ext4/super.c~ext4_move_block_number_hi_bits
>> +++ a/fs/ext4/super.c
>> @@ -63,40 +63,52 @@ static void ext4_write_super (struct sup
>> 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 (struc
>> 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 (struc
>> 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 (struc
>> 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
>> }
>> 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 -puN include/linux/ext4_fs.h~ext4_move_block_number_hi_bits
>> include/linux/ext4_fs.h
>> --- a/include/linux/ext4_fs.h~ext4_move_block_number_hi_bits
>> +++ a/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_blo
>> 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)
>> {
>> _
>>
>> Patches currently in -mm which might be from
>> [email protected] are
>>
>> 64bit-metadata.patch
>> ext4_allow_larger_descriptor_size.patch
>> ext4_move_block_number_hi_bits.patch
>>
>> ----- End forwarded message -----
>> ----- Forwarded message from [email protected] -----
>>
>> From: [email protected]
>> Date: Thu, 05 Oct 2006 17:36:41 -0700
>> To: [email protected]
>> Cc: [email protected], [email protected],
>> [email protected]
>> Subject: + 64bit-metadata.patch added to -mm tree
>>
>>
>> The patch titled
>>
>> ext4: 64bit metadata
>>
>> has been added to the -mm tree. Its filename is
>>
>> 64bit-metadata.patch
>>
>> See http://www.zip.com.au/~akpm/linux/patches/stuff/added-to-mm.txt
>> to find
>> out what to do about this
>>
>> ------------------------------------------------------
>> Subject: ext4: 64bit metadata
>> From: Laurent Vivier <[email protected]>
>>
>> In-kernel super block changes to support >32 bit free blocks numbers.
>>
>> Signed-off-by: Laurent Vivier <[email protected]>
>> Signed-off-by: Dave Kleikamp <[email protected]>
>> Signed-off-by: Alexandre Ratchov <[email protected]>
>> Signed-off-by: Andrew Morton <[email protected]>
>> ---
>>
>> fs/ext4/balloc.c | 50 +++++++++----------
>> fs/ext4/ialloc.c | 8 +--
>> fs/ext4/inode.c | 6 +-
>> fs/ext4/resize.c | 52 +++++++++++---------
>> fs/ext4/super.c | 96 ++++++++++++++++++++++++++------------
>> include/linux/ext4_fs.h | 86 ++++++++++++++++++++++++++++------
>> 6 files changed, 201 insertions(+), 97 deletions(-)
>>
>> diff -puN fs/ext4/balloc.c~64bit-metadata fs/ext4/balloc.c
>> --- a/fs/ext4/balloc.c~64bit-metadata
>> +++ a/fs/ext4/balloc.c
>> @@ -99,12 +99,13 @@ read_block_bitmap(struct super_block *sb
>> desc = ext4_get_group_desc (sb, block_group, NULL);
>> if (!desc)
>> goto error_out;
>> - bh = sb_bread(sb, le32_to_cpu(desc->bg_block_bitmap));
>> + bh = sb_bread(sb, ext4_block_bitmap(desc));
>> if (!bh)
>> ext4_error (sb, "read_block_bitmap",
>> "Cannot read block bitmap - "
>> - "block_group = %d, block_bitmap = %u",
>> - block_group, le32_to_cpu(desc->bg_block_bitmap));
>> + "block_group = %d, block_bitmap = "E3FSBLK,
>> + block_group,
>> + ext4_block_bitmap(desc));
>> error_out:
>> return bh;
>> }
>> @@ -432,14 +433,14 @@ void ext4_free_blocks_sb(handle_t *handl
>> es = sbi->s_es;
>> if (block < le32_to_cpu(es->s_first_data_block) ||
>> block + count < block ||
>> - block + count > le32_to_cpu(es->s_blocks_count)) {
>> + block + count > ext4_blocks_count(es)) {
>> ext4_error (sb, "ext4_free_blocks",
>> "Freeing blocks not in datazone - "
>> "block = "E3FSBLK", count = %lu", block, count);
>> goto error_return;
>> }
>>
>> - ext4_debug ("freeing block(s) %lu-%lu\n", block, block + count -
>> 1);
>> + ext4_debug ("freeing block(s) %llu-%llu\n", block, block + count
>> - 1);
>>
>> do_more:
>> overflow = 0;
>> @@ -460,12 +461,11 @@ do_more:
>> if (!desc)
>> goto error_return;
>>
>> - if (in_range (le32_to_cpu(desc->bg_block_bitmap), block, count) ||
>> - in_range (le32_to_cpu(desc->bg_inode_bitmap), block, count) ||
>> - in_range (block, le32_to_cpu(desc->bg_inode_table),
>> - sbi->s_itb_per_group) ||
>> - in_range (block + count - 1, le32_to_cpu(desc->bg_inode_table),
>> - sbi->s_itb_per_group))
>> + 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),
>> + sbi->s_itb_per_group))
>> ext4_error (sb, "ext4_free_blocks",
>> "Freeing blocks in system zones - "
>> "Block = "E3FSBLK", count = %lu",
>> @@ -552,8 +552,8 @@ do_more:
>> bit + i, bitmap_bh->b_data)) {
>> jbd_unlock_bh_state(bitmap_bh);
>> ext4_error(sb, __FUNCTION__,
>> - "bit already cleared for block "E3FSBLK,
>> - block + i);
>> + "bit already cleared for block "E3FSBLK,
>> + (ext4_fsblk_t)(block + i));
>> jbd_lock_bh_state(bitmap_bh);
>> BUFFER_TRACE(bitmap_bh, "bit already cleared");
>> } else {
>> @@ -1351,7 +1351,7 @@ static int ext4_has_free_blocks(struct e
>> ext4_fsblk_t free_blocks, root_blocks;
>>
>> free_blocks =
>> percpu_counter_read_positive(&sbi->s_freeblocks_counter);
>> - root_blocks = le32_to_cpu(sbi->s_es->s_r_blocks_count);
>> + root_blocks = ext4_r_blocks_count(sbi->s_es);
>> if (free_blocks < root_blocks + 1 && !capable(CAP_SYS_RESOURCE) &&
>> sbi->s_resuid != current->fsuid &&
>> (sbi->s_resgid == 0 || !in_group_p (sbi->s_resgid))) {
>> @@ -1462,7 +1462,7 @@ ext4_fsblk_t ext4_new_blocks(handle_t *h
>> * First, test whether the goal block is free.
>> */
>> if (goal < le32_to_cpu(es->s_first_data_block) ||
>> - goal >= le32_to_cpu(es->s_blocks_count))
>> + goal >= ext4_blocks_count(es))
>> goal = le32_to_cpu(es->s_first_data_block);
>> ext4_get_group_no_and_offset(sb, goal, &group_no, &grp_target_blk);
>> goal_group = group_no;
>> @@ -1561,12 +1561,12 @@ allocated:
>>
>> ret_block = grp_alloc_blk + ext4_group_first_block_no(sb,
>> group_no);
>>
>> - if (in_range(le32_to_cpu(gdp->bg_block_bitmap), ret_block, num) ||
>> - in_range(le32_to_cpu(gdp->bg_inode_bitmap), ret_block, num) ||
>> - in_range(ret_block, le32_to_cpu(gdp->bg_inode_table),
>> - EXT4_SB(sb)->s_itb_per_group) ||
>> - in_range(ret_block + num - 1, le32_to_cpu(gdp->bg_inode_table),
>> - EXT4_SB(sb)->s_itb_per_group))
>> + 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),
>> + EXT4_SB(sb)->s_itb_per_group) ||
>> + in_range(ret_block + num - 1, ext4_inode_table(gdp),
>> + EXT4_SB(sb)->s_itb_per_group))
>> ext4_error(sb, "ext4_new_block",
>> "Allocating block in system zone - "
>> "blocks from "E3FSBLK", length %lu",
>> @@ -1604,11 +1604,11 @@ allocated:
>> jbd_unlock_bh_state(bitmap_bh);
>> #endif
>>
>> - if (ret_block + num - 1 >= le32_to_cpu(es->s_blocks_count)) {
>> + if (ret_block + num - 1 >= ext4_blocks_count(es)) {
>> ext4_error(sb, "ext4_new_block",
>> - "block("E3FSBLK") >= blocks count(%d) - "
>> + "block("E3FSBLK") >= blocks count("E3FSBLK") - "
>> "block_group = %lu, es == %p ", ret_block,
>> - le32_to_cpu(es->s_blocks_count), group_no, es);
>> + ext4_blocks_count(es), group_no, es);
>> goto out;
>> }
>>
>> @@ -1707,7 +1707,7 @@ ext4_fsblk_t ext4_count_free_blocks(stru
>> brelse(bitmap_bh);
>> printk("ext4_count_free_blocks: stored = "E3FSBLK
>> ", computed = "E3FSBLK", "E3FSBLK"\n",
>> - le32_to_cpu(es->s_free_blocks_count),
>> + EXT4_FREE_BLOCKS_COUNT(es),
>> desc_count, bitmap_count);
>> return bitmap_count;
>> #else
>> diff -puN fs/ext4/ialloc.c~64bit-metadata fs/ext4/ialloc.c
>> --- a/fs/ext4/ialloc.c~64bit-metadata
>> +++ a/fs/ext4/ialloc.c
>> @@ -60,12 +60,12 @@ read_inode_bitmap(struct super_block * s
>> if (!desc)
>> goto error_out;
>>
>> - bh = sb_bread(sb, le32_to_cpu(desc->bg_inode_bitmap));
>> + bh = sb_bread(sb, ext4_inode_bitmap(desc));
>> if (!bh)
>> ext4_error(sb, "read_inode_bitmap",
>> "Cannot read inode bitmap - "
>> - "block_group = %lu, inode_bitmap = %u",
>> - block_group, le32_to_cpu(desc->bg_inode_bitmap));
>> + "block_group = %lu, inode_bitmap = %llu",
>> + block_group, ext4_inode_bitmap(desc));
>> error_out:
>> return bh;
>> }
>> @@ -304,7 +304,7 @@ static int find_group_orlov(struct super
>> goto fallback;
>> }
>>
>> - blocks_per_dir = le32_to_cpu(es->s_blocks_count) - freeb;
>> + blocks_per_dir = ext4_blocks_count(es) - freeb;
>> sector_div(blocks_per_dir, ndirs);
>>
>> max_dirs = ndirs / ngroups + inodes_per_group / 16;
>> diff -puN fs/ext4/inode.c~64bit-metadata fs/ext4/inode.c
>> --- a/fs/ext4/inode.c~64bit-metadata
>> +++ a/fs/ext4/inode.c
>> @@ -2438,8 +2438,8 @@ static ext4_fsblk_t ext4_get_inode_block
>> */
>> offset = ((ino - 1) % EXT4_INODES_PER_GROUP(sb)) *
>> EXT4_INODE_SIZE(sb);
>> - block = le32_to_cpu(gdp[desc].bg_inode_table) +
>> - (offset >> EXT4_BLOCK_SIZE_BITS(sb));
>> + block = ext4_inode_table(gdp + desc) +
>> + (offset >> EXT4_BLOCK_SIZE_BITS(sb));
>>
>> iloc->block_group = block_group;
>> iloc->offset = offset & (EXT4_BLOCK_SIZE(sb) - 1);
>> @@ -2506,7 +2506,7 @@ static int __ext4_get_inode_loc(struct i
>> goto make_io;
>>
>> bitmap_bh = sb_getblk(inode->i_sb,
>> - le32_to_cpu(desc->bg_inode_bitmap));
>> + ext4_inode_bitmap(desc));
>> if (!bitmap_bh)
>> goto make_io;
>>
>> diff -puN fs/ext4/resize.c~64bit-metadata fs/ext4/resize.c
>> --- a/fs/ext4/resize.c~64bit-metadata
>> +++ a/fs/ext4/resize.c
>> @@ -27,7 +27,7 @@ static int verify_group_input(struct sup
>> {
>> struct ext4_sb_info *sbi = EXT4_SB(sb);
>> struct ext4_super_block *es = sbi->s_es;
>> - ext4_fsblk_t start = le32_to_cpu(es->s_blocks_count);
>> + ext4_fsblk_t start = ext4_blocks_count(es);
>> ext4_fsblk_t end = start + input->blocks_count;
>> unsigned group = input->group;
>> ext4_fsblk_t itend = input->inode_table + sbi->s_itb_per_group;
>> @@ -68,43 +68,43 @@ static int verify_group_input(struct sup
>> end - 1);
>> else if (outside(input->block_bitmap, start, end))
>> ext4_warning(sb, __FUNCTION__,
>> - "Block bitmap not in group (block %u)",
>> + "Block bitmap not in group (block %llu)",
>> input->block_bitmap);
>> else if (outside(input->inode_bitmap, start, end))
>> ext4_warning(sb, __FUNCTION__,
>> - "Inode bitmap not in group (block %u)",
>> + "Inode bitmap not in group (block %llu)",
>> input->inode_bitmap);
>> else if (outside(input->inode_table, start, end) ||
>> outside(itend - 1, start, end))
>> ext4_warning(sb, __FUNCTION__,
>> - "Inode table not in group (blocks %u-"E3FSBLK")",
>> + "Inode table not in group (blocks %llu-%llu)",
>> input->inode_table, itend - 1);
>> else if (input->inode_bitmap == input->block_bitmap)
>> ext4_warning(sb, __FUNCTION__,
>> - "Block bitmap same as inode bitmap (%u)",
>> + "Block bitmap same as inode bitmap (%llu)",
>> input->block_bitmap);
>> else if (inside(input->block_bitmap, input->inode_table, itend))
>> ext4_warning(sb, __FUNCTION__,
>> - "Block bitmap (%u) in inode table (%u-"E3FSBLK")",
>> + "Block bitmap (%llu) in inode table (%llu-%llu)",
>> input->block_bitmap, input->inode_table, itend-1);
>> else if (inside(input->inode_bitmap, input->inode_table, itend))
>> ext4_warning(sb, __FUNCTION__,
>> - "Inode bitmap (%u) in inode table (%u-"E3FSBLK")",
>> + "Inode bitmap (%llu) in inode table (%llu-%llu)",
>> input->inode_bitmap, input->inode_table, itend-1);
>> else if (inside(input->block_bitmap, start, metaend))
>> ext4_warning(sb, __FUNCTION__,
>> - "Block bitmap (%u) in GDT table"
>> + "Block bitmap (%llu) in GDT table"
>> " ("E3FSBLK"-"E3FSBLK")",
>> input->block_bitmap, start, metaend - 1);
>> else if (inside(input->inode_bitmap, start, metaend))
>> ext4_warning(sb, __FUNCTION__,
>> - "Inode bitmap (%u) in GDT table"
>> + "Inode bitmap (%llu) in GDT table"
>> " ("E3FSBLK"-"E3FSBLK")",
>> input->inode_bitmap, start, metaend - 1);
>> else if (inside(input->inode_table, start, metaend) ||
>> inside(itend - 1, start, metaend))
>> ext4_warning(sb, __FUNCTION__,
>> - "Inode table (%u-"E3FSBLK") overlaps"
>> + "Inode table ("E3FSBLK"-"E3FSBLK") overlaps"
>> "GDT table ("E3FSBLK"-"E3FSBLK")",
>> input->inode_table, itend - 1, start, metaend - 1);
>> else
>> @@ -286,6 +286,7 @@ exit_journal:
>> return err;
>> }
>>
>> +
>> /*
>> * Iterate through the groups which hold BACKUP superblock/GDT
>> copies in an
>> * ext4 filesystem. The counters should be initialized to 1, 5, and
>> 7 before
>> @@ -340,12 +341,15 @@ static int verify_reserved_gdb(struct su
>> int gdbackups = 0;
>>
>> while ((grp = ext4_list_backups(sb, &three, &five, &seven)) <
>> end) {
>> - if (le32_to_cpu(*p++) != grp * EXT4_BLOCKS_PER_GROUP(sb) +
>> blk){
>> + if (le32_to_cpu(*p++) !=
>> + grp * EXT4_BLOCKS_PER_GROUP(sb) + blk){
>> ext4_warning(sb, __FUNCTION__,
>> "reserved GDT "E3FSBLK
>> " missing grp %d ("E3FSBLK")",
>> blk, grp,
>> - grp * EXT4_BLOCKS_PER_GROUP(sb) + blk);
>> + grp *
>> + (ext4_fsblk_t)EXT4_BLOCKS_PER_GROUP(sb) +
>> + blk);
>> return -EINVAL;
>> }
>> if (++gdbackups > EXT4_ADDR_PER_BLOCK(sb))
>> @@ -731,8 +735,8 @@ int ext4_group_add(struct super_block *s
>> return -EPERM;
>> }
>>
>> - if (le32_to_cpu(es->s_blocks_count) + input->blocks_count <
>> - le32_to_cpu(es->s_blocks_count)) {
>> + if (ext4_blocks_count(es) + input->blocks_count <
>> + ext4_blocks_count(es)) {
>> ext4_warning(sb, __FUNCTION__, "blocks_count overflow\n");
>> return -EINVAL;
>> }
>> @@ -830,9 +834,9 @@ int ext4_group_add(struct super_block *s
>> /* Update group descriptor block for new group */
>> gdp = (struct ext4_group_desc *)primary->b_data + gdb_off;
>>
>> - gdp->bg_block_bitmap = cpu_to_le32(input->block_bitmap);
>> - gdp->bg_inode_bitmap = cpu_to_le32(input->inode_bitmap);
>> - gdp->bg_inode_table = cpu_to_le32(input->inode_table);
>> + 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 */
>> 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));
>>
>> @@ -846,7 +850,7 @@ int ext4_group_add(struct super_block *s
>> * blocks/inodes before the group is live won't actually let us
>> * allocate the new space yet.
>> */
>> - es->s_blocks_count = cpu_to_le32(le32_to_cpu(es->s_blocks_count) +
>> + ext4_blocks_count_set(es, ext4_blocks_count(es) +
>> input->blocks_count);
>> es->s_inodes_count = cpu_to_le32(le32_to_cpu(es->s_inodes_count) +
>> EXT4_INODES_PER_GROUP(sb));
>> @@ -882,7 +886,7 @@ int ext4_group_add(struct super_block *s
>>
>> /* Update the reserved block counts only once the new group is
>> * active. */
>> - es->s_r_blocks_count =
>> cpu_to_le32(le32_to_cpu(es->s_r_blocks_count) +
>> + ext4_r_blocks_count_set(es, ext4_r_blocks_count(es) +
>> input->reserved_blocks);
>>
>> /* Update the free space counts */
>> @@ -933,7 +937,7 @@ int ext4_group_extend(struct super_block
>> /* We don't need to worry about locking wrt other resizers just
>> * yet: we're going to revalidate es->s_blocks_count after
>> * taking lock_super() below. */
>> - o_blocks_count = le32_to_cpu(es->s_blocks_count);
>> + o_blocks_count = ext4_blocks_count(es);
>> o_groups_count = EXT4_SB(sb)->s_groups_count;
>>
>> if (test_opt(sb, DEBUG))
>> @@ -1004,7 +1008,7 @@ int ext4_group_extend(struct super_block
>> }
>>
>> lock_super(sb);
>> - if (o_blocks_count != le32_to_cpu(es->s_blocks_count)) {
>> + if (o_blocks_count != ext4_blocks_count(es)) {
>> ext4_warning(sb, __FUNCTION__,
>> "multiple resizers run on filesystem!");
>> unlock_super(sb);
>> @@ -1020,7 +1024,7 @@ int ext4_group_extend(struct super_block
>> ext4_journal_stop(handle);
>> goto exit_put;
>> }
>> - es->s_blocks_count = cpu_to_le32(o_blocks_count + add);
>> + ext4_blocks_count_set(es, o_blocks_count + add);
>> ext4_journal_dirty_metadata(handle, EXT4_SB(sb)->s_sbh);
>> sb->s_dirt = 1;
>> unlock_super(sb);
>> @@ -1032,8 +1036,8 @@ int ext4_group_extend(struct super_block
>> if ((err = ext4_journal_stop(handle)))
>> goto exit_put;
>> if (test_opt(sb, DEBUG))
>> - printk(KERN_DEBUG "EXT4-fs: extended group to %u blocks\n",
>> - le32_to_cpu(es->s_blocks_count));
>> + printk(KERN_DEBUG "EXT4-fs: extended group to %llu blocks\n",
>> + ext4_blocks_count(es));
>> update_backups(sb, EXT4_SB(sb)->s_sbh->b_blocknr, (char *)es,
>> sizeof(struct ext4_super_block));
>> exit_put:
>> diff -puN fs/ext4/super.c~64bit-metadata fs/ext4/super.c
>> --- a/fs/ext4/super.c~64bit-metadata
>> +++ a/fs/ext4/super.c
>> @@ -62,6 +62,43 @@ static void ext4_unlockfs(struct super_b
>> 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)
>> +{
>> + return le32_to_cpu(bg->bg_block_bitmap) |
>> + ((ext4_fsblk_t)le16_to_cpu(bg->bg_block_bitmap_hi) << 32);
>> +}
>> +
>> +ext4_fsblk_t ext4_inode_bitmap(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_fsblk_t ext4_inode_table(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);
>> +}
>> +
>> +void ext4_block_bitmap_set(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);
>> +}
>> +
>> +void ext4_inode_bitmap_set(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);
>> +}
>> +
>> +void ext4_inode_table_set(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);
>> +}
>> +
>> /*
>> * Wrappers for jbd2_journal_start/end.
>> *
>> @@ -1182,6 +1219,9 @@ static int ext4_check_descriptors (struc
>> struct ext4_sb_info *sbi = EXT4_SB(sb);
>> ext4_fsblk_t first_block =
>> le32_to_cpu(sbi->s_es->s_first_data_block);
>> ext4_fsblk_t last_block;
>> + ext4_fsblk_t block_bitmap;
>> + ext4_fsblk_t inode_bitmap;
>> + ext4_fsblk_t inode_table;
>> struct ext4_group_desc * gdp = NULL;
>> int desc_block = 0;
>> int i;
>> @@ -1191,7 +1231,7 @@ static int ext4_check_descriptors (struc
>> for (i = 0; i < sbi->s_groups_count; i++)
>> {
>> if (i == sbi->s_groups_count - 1)
>> - last_block = le32_to_cpu(sbi->s_es->s_blocks_count) - 1;
>> + last_block = ext4_blocks_count(sbi->s_es) - 1;
>> else
>> last_block = first_block +
>> (EXT4_BLOCKS_PER_GROUP(sb) - 1);
>> @@ -1199,42 +1239,39 @@ static int ext4_check_descriptors (struc
>> if ((i % EXT4_DESC_PER_BLOCK(sb)) == 0)
>> gdp = (struct ext4_group_desc *)
>> sbi->s_group_desc[desc_block++]->b_data;
>> - if (le32_to_cpu(gdp->bg_block_bitmap) < first_block ||
>> - le32_to_cpu(gdp->bg_block_bitmap) > last_block)
>> + block_bitmap = ext4_block_bitmap(gdp);
>> + if (block_bitmap < first_block || block_bitmap > last_block)
>> {
>> ext4_error (sb, "ext4_check_descriptors",
>> "Block bitmap for group %d"
>> - " not in group (block %lu)!",
>> - i, (unsigned long)
>> - le32_to_cpu(gdp->bg_block_bitmap));
>> + " not in group (block "E3FSBLK")!",
>> + i, block_bitmap);
>> return 0;
>> }
>> - if (le32_to_cpu(gdp->bg_inode_bitmap) < first_block ||
>> - le32_to_cpu(gdp->bg_inode_bitmap) > last_block)
>> + inode_bitmap = ext4_inode_bitmap(gdp);
>> + if (inode_bitmap < first_block || inode_bitmap > last_block)
>> {
>> ext4_error (sb, "ext4_check_descriptors",
>> "Inode bitmap for group %d"
>> - " not in group (block %lu)!",
>> - i, (unsigned long)
>> - le32_to_cpu(gdp->bg_inode_bitmap));
>> + " not in group (block "E3FSBLK")!",
>> + i, inode_bitmap);
>> return 0;
>> }
>> - if (le32_to_cpu(gdp->bg_inode_table) < first_block ||
>> - le32_to_cpu(gdp->bg_inode_table) + sbi->s_itb_per_group >
>> - last_block)
>> + inode_table = ext4_inode_table(gdp);
>> + if (inode_table < first_block ||
>> + inode_table + sbi->s_itb_per_group > last_block)
>> {
>> ext4_error (sb, "ext4_check_descriptors",
>> "Inode table for group %d"
>> - " not in group (block %lu)!",
>> - i, (unsigned long)
>> - le32_to_cpu(gdp->bg_inode_table));
>> + " not in group (block "E3FSBLK")!",
>> + i, inode_table);
>> return 0;
>> }
>> first_block += EXT4_BLOCKS_PER_GROUP(sb);
>> gdp++;
>> }
>>
>> -
>> sbi->s_es->s_free_blocks_count=cpu_to_le32(ext4_count_free_blocks(sb));
>> + ext4_free_blocks_count_set(sbi->s_es, ext4_count_free_blocks(sb));
>>
>> sbi->s_es->s_free_inodes_count=cpu_to_le32(ext4_count_free_inodes(sb));
>> return 1;
>> }
>> @@ -1411,6 +1448,7 @@ static int ext4_fill_super (struct super
>> int i;
>> int needs_recovery;
>> __le32 features;
>> + __u64 blocks_count;
>>
>> sbi = kzalloc(sizeof(*sbi), GFP_KERNEL);
>> if (!sbi)
>> @@ -1620,7 +1658,7 @@ static int ext4_fill_super (struct super
>> goto failed_mount;
>> }
>>
>> - if (le32_to_cpu(es->s_blocks_count) >
>> + if (ext4_blocks_count(es) >
>> (sector_t)(~0ULL) >> (sb->s_blocksize_bits - 9)) {
>> printk(KERN_ERR "EXT4-fs: filesystem on %s:"
>> " too large to mount safely\n", sb->s_id);
>> @@ -1632,9 +1670,11 @@ static int ext4_fill_super (struct super
>>
>> if (EXT4_BLOCKS_PER_GROUP(sb) == 0)
>> goto cantfind_ext4;
>> - sbi->s_groups_count = ((le32_to_cpu(es->s_blocks_count) -
>> - le32_to_cpu(es->s_first_data_block) - 1)
>> - / EXT4_BLOCKS_PER_GROUP(sb)) + 1;
>> + blocks_count = (ext4_blocks_count(es) -
>> + le32_to_cpu(es->s_first_data_block) +
>> + EXT4_BLOCKS_PER_GROUP(sb) - 1);
>> + do_div(blocks_count, EXT4_BLOCKS_PER_GROUP(sb));
>> + sbi->s_groups_count = blocks_count;
>> db_count = (sbi->s_groups_count + EXT4_DESC_PER_BLOCK(sb) - 1) /
>> EXT4_DESC_PER_BLOCK(sb);
>> sbi->s_group_desc = kmalloc(db_count * sizeof (struct
>> buffer_head *),
>> @@ -1949,7 +1989,7 @@ static journal_t *ext4_get_dev_journal(s
>> goto out_bdev;
>> }
>>
>> - len = le32_to_cpu(es->s_blocks_count);
>> + len = ext4_blocks_count(es);
>> start = sb_block + 1;
>> brelse(bh); /* we're done with the superblock */
>>
>> @@ -2119,7 +2159,7 @@ static void ext4_commit_super (struct su
>> if (!sbh)
>> return;
>> es->s_wtime = cpu_to_le32(get_seconds());
>> - es->s_free_blocks_count = cpu_to_le32(ext4_count_free_blocks(sb));
>> + ext4_free_blocks_count_set(es, ext4_count_free_blocks(sb));
>> es->s_free_inodes_count = cpu_to_le32(ext4_count_free_inodes(sb));
>> BUFFER_TRACE(sbh, "marking dirty");
>> mark_buffer_dirty(sbh);
>> @@ -2312,7 +2352,7 @@ static int ext4_remount (struct super_bl
>> ext4_init_journal_params(sb, sbi->s_journal);
>>
>> if ((*flags & MS_RDONLY) != (sb->s_flags & MS_RDONLY) ||
>> - n_blocks_count > le32_to_cpu(es->s_blocks_count)) {
>> + n_blocks_count > ext4_blocks_count(es)) {
>> if (sbi->s_mount_opt & EXT4_MOUNT_ABORT) {
>> err = -EROFS;
>> goto restore_opts;
>> @@ -2431,10 +2471,10 @@ static int ext4_statfs (struct dentry *
>> buf->f_type = EXT4_SUPER_MAGIC;
>> buf->f_bsize = sb->s_blocksize;
>> - buf->f_blocks = le32_to_cpu(es->s_blocks_count) - overhead;
>> + buf->f_blocks = ext4_blocks_count(es) - overhead;
>> buf->f_bfree = percpu_counter_sum(&sbi->s_freeblocks_counter);
>> - buf->f_bavail = buf->f_bfree - le32_to_cpu(es->s_r_blocks_count);
>> - if (buf->f_bfree < le32_to_cpu(es->s_r_blocks_count))
>> + buf->f_bavail = buf->f_bfree - ext4_r_blocks_count(es);
>> + if (buf->f_bfree < ext4_r_blocks_count(es))
>> buf->f_bavail = 0;
>> buf->f_files = le32_to_cpu(es->s_inodes_count);
>> buf->f_ffree = percpu_counter_sum(&sbi->s_freeinodes_counter);
>> diff -puN include/linux/ext4_fs.h~64bit-metadata include/linux/ext4_fs.h
>> --- a/include/linux/ext4_fs.h~64bit-metadata
>> +++ a/include/linux/ext4_fs.h
>> @@ -128,10 +128,17 @@ struct ext4_group_desc
>> __le16 bg_free_blocks_count; /* Free blocks count */
>> __le16 bg_free_inodes_count; /* Free inodes count */
>> __le16 bg_used_dirs_count; /* Directories count */
>> - __u16 bg_pad;
>> - __le32 bg_reserved[3];
>> + __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];
>> };
>>
>> +#ifdef __KERNEL__
>> +#include <linux/ext4_fs_i.h>
>> +#include <linux/ext4_fs_sb.h>
>> +#endif
>> /*
>> * Macro-instructions used to manage group descriptors
>> */
>> @@ -194,9 +201,9 @@ struct ext4_group_desc
>> /* Used to pass group descriptor data when online resize is done */
>> struct ext4_new_group_input {
>> __u32 group; /* Group number for this data */
>> - __u32 block_bitmap; /* Absolute block number of block bitmap */
>> - __u32 inode_bitmap; /* Absolute block number of inode bitmap */
>> - __u32 inode_table; /* Absolute block number of inode table
>> start */
>> + __u64 block_bitmap; /* Absolute block number of block bitmap */
>> + __u64 inode_bitmap; /* Absolute block number of inode bitmap */
>> + __u64 inode_table; /* Absolute block number of inode table
>> start */
>> __u32 blocks_count; /* Total number of blocks in this group */
>> __u16 reserved_blocks; /* Number of reserved blocks in this
>> group */
>> __u16 unused;
>> @@ -205,9 +212,9 @@ struct ext4_new_group_input {
>> /* The struct ext4_new_group_input in kernel space, with
>> free_blocks_count */
>> struct ext4_new_group_data {
>> __u32 group;
>> - __u32 block_bitmap;
>> - __u32 inode_bitmap;
>> - __u32 inode_table;
>> + __u64 block_bitmap;
>> + __u64 inode_bitmap;
>> + __u64 inode_table;
>> __u32 blocks_count;
>> __u16 reserved_blocks;
>> __u16 unused;
>> @@ -494,14 +501,18 @@ struct ext4_super_block {
>> __u8 s_def_hash_version; /* Default hash version to use */
>> __u8 s_reserved_char_pad;
>> __u16 s_reserved_word_pad;
>> - __le32 s_default_mount_opts;
>> +/*100*/ __le32 s_default_mount_opts;
>> __le32 s_first_meta_bg; /* First metablock block group */
>> - __u32 s_reserved[190]; /* Padding to the end of the block */
>> + __le32 s_mkfs_time; /* When the filesystem was created */
>> + __le32 s_jnl_blocks[17]; /* Backup of the journal inode */
>> + /* 64bit support valid if EXT4_FEATURE_COMPAT_64BIT */
>> +/*150*/ __le32 s_blocks_count_hi; /* Blocks count */
>> + __le32 s_r_blocks_count_hi; /* Reserved blocks count */
>> + __le32 s_free_blocks_count_hi; /* Free blocks count */
>> + __u32 s_reserved[169]; /* Padding to the end of the block */
>> };
>>
>> #ifdef __KERNEL__
>> -#include <linux/ext4_fs_i.h>
>> -#include <linux/ext4_fs_sb.h>
>> static inline struct ext4_sb_info * EXT4_SB(struct super_block *sb)
>> {
>> return sb->s_fs_info;
>> @@ -588,12 +599,14 @@ static inline int ext4_valid_inum(struct
>> #define EXT4_FEATURE_INCOMPAT_JOURNAL_DEV 0x0008 /* Journal
>> device */
>> #define EXT4_FEATURE_INCOMPAT_META_BG 0x0010
>> #define EXT4_FEATURE_INCOMPAT_EXTENTS 0x0040 /* extents
>> support */
>> +#define EXT4_FEATURE_INCOMPAT_64BIT 0x0080
>>
>> #define EXT4_FEATURE_COMPAT_SUPP EXT2_FEATURE_COMPAT_EXT_ATTR
>> #define EXT4_FEATURE_INCOMPAT_SUPP
>> (EXT4_FEATURE_INCOMPAT_FILETYPE| \
>> EXT4_FEATURE_INCOMPAT_RECOVER| \
>> EXT4_FEATURE_INCOMPAT_META_BG| \
>> - EXT4_FEATURE_INCOMPAT_EXTENTS)
>> + EXT4_FEATURE_INCOMPAT_EXTENTS| \
>> + EXT4_FEATURE_INCOMPAT_64BIT)
>> #define EXT4_FEATURE_RO_COMPAT_SUPP
>> (EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER| \
>> EXT4_FEATURE_RO_COMPAT_LARGE_FILE| \
>> EXT4_FEATURE_RO_COMPAT_BTREE_DIR)
>> @@ -888,6 +901,53 @@ extern void ext4_abort (struct super_blo
>> 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);
>> +
>> +static inline ext4_fsblk_t ext4_blocks_count(struct ext4_super_block
>> *es)
>> +{
>> + return ((ext4_fsblk_t)le32_to_cpu(es->s_blocks_count_hi) << 32) |
>> + le32_to_cpu(es->s_blocks_count);
>> +}
>> +
>> +static inline ext4_fsblk_t ext4_r_blocks_count(struct
>> ext4_super_block *es)
>> +{
>> + return ((ext4_fsblk_t)le32_to_cpu(es->s_r_blocks_count_hi) << 32) |
>> + le32_to_cpu(es->s_r_blocks_count);
>> +}
>> +
>> +static inline ext4_fsblk_t ext4_free_blocks_count(struct
>> ext4_super_block *es)
>> +{
>> + return ((ext4_fsblk_t)le32_to_cpu(es->s_free_blocks_count_hi) <<
>> 32) |
>> + le32_to_cpu(es->s_free_blocks_count);
>> +}
>> +
>> +static inline void ext4_blocks_count_set(struct ext4_super_block *es,
>> + ext4_fsblk_t blk)
>> +{
>> + es->s_blocks_count = cpu_to_le32((u32)blk);
>> + es->s_blocks_count_hi = cpu_to_le32(blk >> 32);
>> +}
>> +
>> +static inline void ext4_free_blocks_count_set(struct
>> ext4_super_block *es,
>> + ext4_fsblk_t blk)
>> +{
>> + es->s_free_blocks_count = cpu_to_le32((u32)blk);
>> + es->s_free_blocks_count_hi = cpu_to_le32(blk >> 32);
>> +}
>> +
>> +static inline void ext4_r_blocks_count_set(struct ext4_super_block *es,
>> + ext4_fsblk_t blk)
>> +{
>> + es->s_r_blocks_count = cpu_to_le32((u32)blk);
>> + es->s_r_blocks_count_hi = cpu_to_le32(blk >> 32);
>> +}
>> +
>> +
>>
>> #define ext4_std_error(sb, errno) \
>> do { \
>> _
>>
>> Patches currently in -mm which might be from [email protected] are
>>
>> 64bit-metadata.patch
>>
>> ----- End forwarded message -----
>>
>