Whamcloud - gitweb
libext2fs: Teach *_initialize and *_allocate_group to be 64-bit safe
authorTheodore Ts'o <tytso@mit.edu>
Sun, 13 Jun 2010 13:00:00 +0000 (09:00 -0400)
committerTheodore Ts'o <tytso@mit.edu>
Sun, 13 Jun 2010 13:00:00 +0000 (09:00 -0400)
This is needed to enable 64-bit mke2fs to work correctly.

Signed-off-by: Jose R. Santos <jrs@us.ibm.com>
Signed-off-by: Valerie Aurora Henson <vaurora@redhat.com>
Signed-off-by: Nick Dokos <nicholas.dokos@hp.com>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
lib/ext2fs/alloc_tables.c
lib/ext2fs/initialize.c

index 56d2678..1c4532b 100644 (file)
  * block number with a correct offset were the bitmaps and inode
  * tables can be allocated continously and in order.
  */
-static blk_t flexbg_offset(ext2_filsys fs, dgrp_t group, blk64_t start_blk,
-                          ext2fs_block_bitmap bmap, int offset, int size,
-                          int elem_size)
+static blk64_t flexbg_offset(ext2_filsys fs, dgrp_t group, blk64_t start_blk,
+                            ext2fs_block_bitmap bmap, int offset, int size,
+                            int elem_size)
 {
        int             flexbg, flexbg_size;
-       blk_t           last_blk, first_free = 0;
+       blk64_t         last_blk, first_free = 0;
        dgrp_t          last_grp;
 
        flexbg_size = 1 << fs->super->s_log_groups_per_flex;
@@ -68,11 +68,11 @@ static blk_t flexbg_offset(ext2_filsys fs, dgrp_t group, blk64_t start_blk,
        last_blk = ext2fs_group_last_block2(fs, last_grp);
 
        /* Find the first available block */
-       if (ext2fs_get_free_blocks(fs, start_blk, last_blk, 1, bmap,
+       if (ext2fs_get_free_blocks2(fs, start_blk, last_blk, 1, bmap,
                                   &first_free))
                return first_free;
 
-       if (ext2fs_get_free_blocks(fs, first_free + offset, last_blk, size,
+       if (ext2fs_get_free_blocks2(fs, first_free + offset, last_blk, size,
                                   bmap, &first_free))
                return first_free;
 
@@ -83,7 +83,7 @@ errcode_t ext2fs_allocate_group_table(ext2_filsys fs, dgrp_t group,
                                      ext2fs_block_bitmap bmap)
 {
        errcode_t       retval;
-       blk_t           group_blk, start_blk, last_blk, new_blk, blk;
+       blk64_t         group_blk, start_blk, last_blk, new_blk, blk;
        dgrp_t          last_grp = 0;
        int             j, rem_grps = 0, flexbg_size = 0;
 
@@ -107,8 +107,8 @@ errcode_t ext2fs_allocate_group_table(ext2_filsys fs, dgrp_t group,
         * Allocate the block and inode bitmaps, if necessary
         */
        if (fs->stride) {
-               retval = ext2fs_get_free_blocks(fs, group_blk, last_blk,
-                                               1, bmap, &start_blk);
+               retval = ext2fs_get_free_blocks2(fs, group_blk, last_blk,
+                                                1, bmap, &start_blk);
                if (retval)
                        return retval;
                start_blk += fs->inode_blocks_per_group;
@@ -130,10 +130,10 @@ errcode_t ext2fs_allocate_group_table(ext2_filsys fs, dgrp_t group,
        }
 
        if (!ext2fs_block_bitmap_loc(fs, group)) {
-               retval = ext2fs_get_free_blocks(fs, start_blk, last_blk,
-                                               1, bmap, &new_blk);
+               retval = ext2fs_get_free_blocks2(fs, start_blk, last_blk,
+                                                1, bmap, &new_blk);
                if (retval == EXT2_ET_BLOCK_ALLOC_FAIL)
-                       retval = ext2fs_get_free_blocks(fs, group_blk,
+                       retval = ext2fs_get_free_blocks2(fs, group_blk,
                                        last_blk, 1, bmap, &new_blk);
                if (retval)
                        return retval;
@@ -158,11 +158,11 @@ errcode_t ext2fs_allocate_group_table(ext2_filsys fs, dgrp_t group,
        }
 
        if (!ext2fs_inode_bitmap_loc(fs, group)) {
-               retval = ext2fs_get_free_blocks(fs, start_blk, last_blk,
-                                               1, bmap, &new_blk);
+               retval = ext2fs_get_free_blocks2(fs, start_blk, last_blk,
+                                                1, bmap, &new_blk);
                if (retval == EXT2_ET_BLOCK_ALLOC_FAIL)
-                       retval = ext2fs_get_free_blocks(fs, group_blk,
-                                       last_blk, 1, bmap, &new_blk);
+                       retval = ext2fs_get_free_blocks2(fs, group_blk,
+                                        last_blk, 1, bmap, &new_blk);
                if (retval)
                        return retval;
                ext2fs_mark_block_bitmap2(bmap, new_blk);
@@ -194,7 +194,7 @@ errcode_t ext2fs_allocate_group_table(ext2_filsys fs, dgrp_t group,
        }
 
        if (!ext2fs_inode_table_loc(fs, group)) {
-               retval = ext2fs_get_free_blocks(fs, group_blk, last_blk,
+               retval = ext2fs_get_free_blocks2(fs, group_blk, last_blk,
                                                fs->inode_blocks_per_group,
                                                bmap, &new_blk);
                if (retval)
index 2446852..7c38975 100644 (file)
@@ -77,6 +77,10 @@ static unsigned int calc_reserved_gdt_blocks(ext2_filsys fs)
         */
        if (ext2fs_blocks_count(sb) < max_blocks / 1024)
                max_blocks = ext2fs_blocks_count(sb) * 1024;
+       /*
+        * ext2fs_div64_ceil() is unnecessary because max_blocks is
+        * max _GDT_ blocks, which is limited to 32 bits.
+        */
        rsv_groups = ext2fs_div_ceil(max_blocks - sb->s_first_data_block, bpg);
        rsv_gdb = ext2fs_div_ceil(rsv_groups, gdpb) - fs->desc_blocks;
        if (rsv_gdb > EXT2_ADDR_PER_BLOCK(sb))
@@ -226,11 +230,20 @@ retry:
                retval = EXT2_ET_TOOSMALL;
                goto cleanup;
        }
+
+       if (super->s_feature_incompat & EXT4_FEATURE_INCOMPAT_64BIT)
+               super->s_desc_size = EXT2_MIN_DESC_SIZE_64BIT;
+
        fs->desc_blocks = ext2fs_div_ceil(fs->group_desc_count,
                                          EXT2_DESC_PER_BLOCK(super));
 
        i = fs->blocksize >= 4096 ? 1 : 4096 / fs->blocksize;
-       set_field(s_inodes_count, ext2fs_blocks_count(super) / i);
+
+       if (super->s_feature_incompat & EXT4_FEATURE_INCOMPAT_64BIT &&
+           (ext2fs_blocks_count(super) / i) > (1ULL << 32))
+               set_field(s_inodes_count, ~0U);
+       else
+               set_field(s_inodes_count, ext2fs_blocks_count(super) / i);
 
        /*
         * Make sure we have at least EXT2_FIRST_INO + 1 inodes, so