[RFC][E2FSPROGS][PATCH 8/8]
Alexandre Ratchov <[email protected]>
| Newsgroups | gmane.comp.file-systems.ext2.devel |
|---|---|
| Message-ID | <[email protected]> |
Introduce management of larger block groups. The patch allows
bitmaps of each block group to be spread over several blocks and
also allows groups to be larger than (8 * blocksize) blocks.
Index: e2fsprogs/lib/e2p/feature.c
===================================================================
--- e2fsprogs.orig/lib/e2p/feature.c 2006-05-24 15:25:36.000000000 +0200
+++ e2fsprogs/lib/e2p/feature.c 2006-05-24 15:26:05.000000000 +0200
@@ -41,6 +41,8 @@
"sparse_super" },
{ E2P_FEATURE_RO_INCOMPAT, EXT2_FEATURE_RO_COMPAT_LARGE_FILE,
"large_file" },
+ { E2P_FEATURE_RO_INCOMPAT, EXT2_FEATURE_RO_COMPAT_BIG_BG,
+ "big_bg" },
{ E2P_FEATURE_RO_INCOMPAT, EXT2_FEATURE_RO_COMPAT_64BIT,
"64bit" },
{ E2P_FEATURE_INCOMPAT, EXT2_FEATURE_INCOMPAT_COMPRESSION,
Index: e2fsprogs/e2fsck/pass5.c
===================================================================
--- e2fsprogs.orig/e2fsck/pass5.c 2006-05-24 15:25:36.000000000 +0200
+++ e2fsprogs/e2fsck/pass5.c 2006-05-24 15:26:05.000000000 +0200
@@ -278,15 +278,20 @@
ext2fs_unmark_valid(fs);
for (i = 0; i < fs->group_desc_count; i++) {
- if (free_array[i] != fs->group_desc[i].bg_free_blocks_count) {
+ __u32 free_blocks;
+
+ free_blocks = fs->group_desc[i].bg_free_blocks_count;
+ free_blocks += (__u32)fs->group_desc[i].bg_free_blocks_count_hi << 16;
+
+ if (free_array[i] != free_blocks) {
pctx.group = i;
- pctx.blk = fs->group_desc[i].bg_free_blocks_count;
+ pctx.blk = free_blocks;
pctx.blk2 = free_array[i];
if (fix_problem(ctx, PR_5_FREE_BLOCK_COUNT_GROUP,
&pctx)) {
- fs->group_desc[i].bg_free_blocks_count =
- free_array[i];
+ fs->group_desc[i].bg_free_blocks_count = free_blocks;
+ fs->group_desc[i].bg_free_blocks_count_hi = free_blocks >> 16;
ext2fs_mark_super_dirty(fs);
} else
ext2fs_unmark_valid(fs);
@@ -468,27 +473,36 @@
ext2fs_unmark_valid(fs);
for (i = 0; i < fs->group_desc_count; i++) {
- if (free_array[i] != fs->group_desc[i].bg_free_inodes_count) {
+ __u32 free_inodes, used_dirs;
+ free_inodes = fs->group_desc[i].bg_free_inodes_count;
+ used_dirs = fs->group_desc[i].bg_used_dirs_count;
+ free_inodes += (__u32)fs->group_desc[i].bg_free_inodes_count_hi << 16;
+ used_dirs += (__u32)fs->group_desc[i].bg_used_dirs_count_hi << 16;
+ if (free_array[i] != free_inodes) {
pctx.group = i;
- pctx.ino = fs->group_desc[i].bg_free_inodes_count;
+ pctx.ino = free_inodes;
pctx.ino2 = free_array[i];
if (fix_problem(ctx, PR_5_FREE_INODE_COUNT_GROUP,
&pctx)) {
fs->group_desc[i].bg_free_inodes_count =
free_array[i];
+ fs->group_desc[i].bg_free_inodes_count_hi =
+ free_array[i] >> 16;
ext2fs_mark_super_dirty(fs);
} else
ext2fs_unmark_valid(fs);
}
- if (dir_array[i] != fs->group_desc[i].bg_used_dirs_count) {
+ if (dir_array[i] != used_dirs) {
pctx.group = i;
- pctx.ino = fs->group_desc[i].bg_used_dirs_count;
+ pctx.ino = used_dirs;
pctx.ino2 = dir_array[i];
if (fix_problem(ctx, PR_5_FREE_DIR_COUNT_GROUP,
&pctx)) {
fs->group_desc[i].bg_used_dirs_count =
dir_array[i];
+ fs->group_desc[i].bg_used_dirs_count_hi =
+ dir_array[i] >> 16;
ext2fs_mark_super_dirty(fs);
} else
ext2fs_unmark_valid(fs);
Index: e2fsprogs/lib/ext2fs/alloc_stats.c
===================================================================
--- e2fsprogs.orig/lib/ext2fs/alloc_stats.c 2006-05-24 15:25:36.000000000 +0200
+++ e2fsprogs/lib/ext2fs/alloc_stats.c 2006-05-24 15:26:05.000000000 +0200
@@ -19,14 +19,24 @@
int inuse, int isdir)
{
int group = ext2fs_group_of_ino(fs, ino);
+ __u32 free_inodes, used_dirs;
if (inuse > 0)
ext2fs_mark_inode_bitmap(fs->inode_map, ino);
else
ext2fs_unmark_inode_bitmap(fs->inode_map, ino);
- fs->group_desc[group].bg_free_inodes_count -= inuse;
- if (isdir)
- fs->group_desc[group].bg_used_dirs_count += inuse;
+ free_inodes = fs->group_desc[group].bg_free_inodes_count;
+ free_inodes += (__u32)fs->group_desc[group].bg_free_inodes_count_hi << 16;
+ free_inodes -= inuse;
+ fs->group_desc[group].bg_free_inodes_count = free_inodes;
+ fs->group_desc[group].bg_free_inodes_count_hi = free_inodes >> 16;
+ if (isdir) {
+ used_dirs = fs->group_desc[group].bg_used_dirs_count;
+ used_dirs += (__u32)fs->group_desc[group].bg_used_dirs_count_hi << 16;
+ used_dirs += inuse;
+ fs->group_desc[group].bg_used_dirs_count = used_dirs;
+ fs->group_desc[group].bg_used_dirs_count_hi = used_dirs >> 16;
+ }
fs->super->s_free_inodes_count -= inuse;
ext2fs_mark_super_dirty(fs);
ext2fs_mark_ib_dirty(fs);
@@ -39,13 +49,21 @@
void ext2fs_block_alloc_stats(ext2_filsys fs, blk_t blk, int inuse)
{
+ __u32 free_blocks;
+
int group = ext2fs_group_of_blk(fs, blk);
if (inuse > 0)
ext2fs_mark_block_bitmap(fs->block_map, blk);
else
ext2fs_unmark_block_bitmap(fs->block_map, blk);
- fs->group_desc[group].bg_free_blocks_count -= inuse;
+ free_blocks = fs->group_desc[group].bg_free_blocks_count;
+ free_blocks += (__u32)fs->group_desc[group].bg_free_blocks_count_hi << 16;
+
+ free_blocks -= inuse;
+ fs->group_desc[group].bg_free_blocks_count = free_blocks;
+ fs->group_desc[group].bg_free_blocks_count_hi = free_blocks >> 16;
+
EXT2_FREE_BLOCKS_COUNT_SET(fs->super, EXT2_FREE_BLOCKS_COUNT(fs->super) - inuse);
ext2fs_mark_super_dirty(fs);
ext2fs_mark_bb_dirty(fs);
Index: e2fsprogs/lib/ext2fs/ext2fs.h
===================================================================
--- e2fsprogs.orig/lib/ext2fs/ext2fs.h 2006-05-24 15:25:39.000000000 +0200
+++ e2fsprogs/lib/ext2fs/ext2fs.h 2006-05-24 15:26:05.000000000 +0200
@@ -467,6 +467,7 @@
#endif
#define EXT2_LIB_FEATURE_RO_COMPAT_SUPP (EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER|\
EXT2_FEATURE_RO_COMPAT_LARGE_FILE|\
+ EXT2_FEATURE_RO_COMPAT_BIG_BG|\
EXT2_FEATURE_RO_COMPAT_64BIT)
/*
* function prototypes
Index: e2fsprogs/lib/ext2fs/swapfs.c
===================================================================
--- e2fsprogs.orig/lib/ext2fs/swapfs.c 2006-05-24 15:25:36.000000000 +0200
+++ e2fsprogs/lib/ext2fs/swapfs.c 2006-05-24 15:26:05.000000000 +0200
@@ -79,7 +79,9 @@
gdp->bg_inode_bitmap = ext2fs_swab32(gdp->bg_inode_bitmap);
gdp->bg_inode_table = ext2fs_swab32(gdp->bg_inode_table);
gdp->bg_free_blocks_count = ext2fs_swab16(gdp->bg_free_blocks_count);
+ gdp->bg_free_blocks_count_hi = ext2fs_swab16(gdp->bg_free_blocks_count_hi);
gdp->bg_free_inodes_count = ext2fs_swab16(gdp->bg_free_inodes_count);
+ gdp->bg_free_inodes_count_hi = ext2fs_swab16(gdp->bg_free_inodes_count_hi);
gdp->bg_used_dirs_count = ext2fs_swab16(gdp->bg_used_dirs_count);
gdp->bg_flags = ext2fs_swab16(gdp->bg_flags);
}
Index: e2fsprogs/debugfs/debugfs.c
===================================================================
--- e2fsprogs.orig/debugfs/debugfs.c 2006-05-24 15:25:36.000000000 +0200
+++ e2fsprogs/debugfs/debugfs.c 2006-05-24 15:26:05.000000000 +0200
@@ -286,6 +286,7 @@
struct ext2_group_desc *gdp;
int c, header_only = 0;
int numdirs = 0, first;
+ __u32 free_blocks, free_inodes, used_dirs;
reset_getopt();
while ((c = getopt (argc, argv, "h")) != EOF) {
@@ -305,8 +306,12 @@
out = open_pager();
list_super2(current_fs->super, out);
- for (i=0; i < current_fs->group_desc_count; i++)
- numdirs += current_fs->group_desc[i].bg_used_dirs_count;
+ for (i=0; i < current_fs->group_desc_count; i++) {
+ used_dirs = current_fs->group_desc[i].bg_used_dirs_count;
+ if (current_fs->super->s_feature_ro_compat & EXT2_FEATURE_RO_COMPAT_BIG_BG)
+ used_dirs += (__u32)current_fs->group_desc[i].bg_used_dirs_count_hi << 16;
+ numdirs += used_dirs;
+ }
fprintf(out, "Directories: %d\n", numdirs);
if (header_only) {
@@ -317,6 +322,17 @@
gdp = ¤t_fs->group_desc[0];
for (i = 0; i < current_fs->group_desc_count; i++, gdp++) {
blk_t group_base = EXT2_GROUP_BASE(current_fs->super, i);
+ free_blocks = gdp->bg_free_blocks_count;
+ free_inodes = gdp->bg_free_inodes_count;
+ used_dirs = gdp->bg_used_dirs_count;
+
+ if (current_fs->super->s_feature_ro_compat &
+ EXT2_FEATURE_RO_COMPAT_BIG_BG) {
+ free_blocks += (__u32)gdp->bg_free_blocks_count_hi << 16;
+ free_inodes += (__u32)gdp->bg_free_inodes_count_hi << 16;
+ used_dirs += (__u32)gdp->bg_used_dirs_count_hi << 16;
+ }
+
fprintf(out, " Group %2d: block bitmap at %llu, "
"inode bitmap at %llu, "
"inode table at %llu\n"
@@ -326,13 +342,9 @@
i, EXT2_BLOCK_BITMAP(gdp, group_base),
EXT2_INODE_BITMAP(gdp, group_base),
EXT2_INODE_TABLE(gdp, group_base),
- gdp->bg_free_blocks_count,
- gdp->bg_free_blocks_count != 1 ? "blocks" : "block",
- gdp->bg_free_inodes_count,
- gdp->bg_free_inodes_count != 1 ? "inodes" : "inode",
- gdp->bg_used_dirs_count,
- gdp->bg_used_dirs_count != 1 ? "directories"
- : "directory");
+ free_blocks, free_blocks != 1 ? "blocks" : "block",
+ free_inodes, free_inodes != 1 ? "inodes" : "inode",
+ used_dirs, used_dirs != 1 ? "directories" : "directory");
first = 1;
print_bg_opts(gdp, EXT2_BG_INODE_UNINIT, "Inode not init",
&first, out);
Index: e2fsprogs/misc/dumpe2fs.c
===================================================================
--- e2fsprogs.orig/misc/dumpe2fs.c 2006-05-24 15:25:36.000000000 +0200
+++ e2fsprogs/misc/dumpe2fs.c 2006-05-24 15:26:05.000000000 +0200
@@ -135,6 +135,7 @@
char *block_bitmap=NULL, *inode_bitmap=NULL;
int inode_blocks_per_group, old_desc_blocks, reserved_gdt;
int has_super;
+ int free_blocks, free_inodes, used_dirs;
if (fs->block_map)
block_bitmap = fs->block_map->bitmap;
@@ -203,11 +204,15 @@
diff = EXT2_INODE_TABLE(&fs->group_desc[i], group_blk) - group_blk;
if (diff > 0)
printf(" (+%ld)", diff);
+ free_blocks = fs->group_desc[i].bg_free_blocks_count;
+ free_blocks += (__u32)fs->group_desc[i].bg_free_blocks_count_hi << 16;
+ free_inodes = fs->group_desc[i].bg_free_inodes_count;
+ free_inodes += (__u32)fs->group_desc[i].bg_free_inodes_count_hi << 16;
+ used_dirs = fs->group_desc[i].bg_used_dirs_count;
+ used_dirs += (__u32)fs->group_desc[i].bg_used_dirs_count_hi << 16;
printf (_("\n %d free blocks, %d free inodes, "
"%d directories\n"),
- fs->group_desc[i].bg_free_blocks_count,
- fs->group_desc[i].bg_free_inodes_count,
- fs->group_desc[i].bg_used_dirs_count);
+ free_blocks, free_inodes, used_dirs);
if (block_bitmap) {
fputs(_(" Free blocks: "), stdout);
print_free (i, block_bitmap,
Index: e2fsprogs/resize/resize2fs.c
===================================================================
--- e2fsprogs.orig/resize/resize2fs.c 2006-05-24 15:25:36.000000000 +0200
+++ e2fsprogs/resize/resize2fs.c 2006-05-24 15:26:05.000000000 +0200
@@ -187,6 +187,7 @@
unsigned long i, j, old_desc_blocks, max_group;
unsigned int meta_bg, meta_bg_size;
int has_super;
+ int free_blocks;
EXT2_BLOCKS_COUNT_SET(fs->super, new_size);
@@ -333,8 +334,12 @@
} else
numblocks = fs->super->s_blocks_per_group;
i = old_fs->group_desc_count - 1;
- fs->group_desc[i].bg_free_blocks_count += (numblocks-old_numblocks);
-
+ free_blocks = fs->group_desc[i].bg_free_blocks_count;
+ free_blocks += (__u32)fs->group_desc[i].bg_free_blocks_count_hi << 16;
+ free_blocks += (numblocks-old_numblocks);
+ fs->group_desc[i].bg_free_blocks_count = free_blocks;
+ fs->group_desc[i].bg_free_blocks_count_hi = free_blocks >> 16;
+
/*
* If the number of block groups is staying the same, we're
* done and can exit now. (If the number block groups is
@@ -407,9 +412,13 @@
fs->super->s_free_inodes_count +=
fs->super->s_inodes_per_group;
fs->group_desc[i].bg_free_blocks_count = numblocks;
+ fs->group_desc[i].bg_free_blocks_count_hi = numblocks >> 16;
fs->group_desc[i].bg_free_inodes_count =
fs->super->s_inodes_per_group;
+ fs->group_desc[i].bg_free_inodes_count_hi =
+ fs->super->s_inodes_per_group >> 16;
fs->group_desc[i].bg_used_dirs_count = 0;
+ fs->group_desc[i].bg_used_dirs_count_hi = 0;
retval = ext2fs_allocate_group_table(fs, i, 0);
if (retval) goto errout;
@@ -434,6 +443,7 @@
blk_t group_block;
unsigned long i;
unsigned long max_group;
+ int free_blocks;
fs = rfs->new_fs;
ext2fs_mark_super_dirty(fs);
@@ -566,14 +576,18 @@
/*
* Mark block used for the block bitmap
*/
- ext2fs_mark_block_bitmap(bmap,
- EXT2_BLOCK_BITMAP(&fs->group_desc[i], block));
+ for (j = 0, b = EXT2_BLOCK_BITMAP(&fs->group_desc[i], block);
+ j < EXT2_BLOCK_BITMAP_PER_GROUP(fs->super);
+ j++, b++)
+ ext2fs_mark_block_bitmap(bmap, b);
/*
* Mark block used for the inode bitmap
*/
- ext2fs_mark_block_bitmap(bmap,
- EXT2_INODE_BITMAP(&fs->group_desc[i], block));
+ for (j = 0, b = EXT2_INODE_BITMAP(&fs->group_desc[i], block);
+ j < EXT2_INODE_BITMAP_PER_GROUP(fs->super);
+ j++, b++)
+ ext2fs_mark_block_bitmap(bmap, b);
block += fs->super->s_blocks_per_group;
}
return 0;
@@ -1221,8 +1235,14 @@
if (retval) goto errout;
group = (new_inode-1) / EXT2_INODES_PER_GROUP(rfs->new_fs->super);
- if (LINUX_S_ISDIR(inode.i_mode))
- rfs->new_fs->group_desc[group].bg_used_dirs_count++;
+ if (LINUX_S_ISDIR(inode.i_mode)) {
+ __u32 used_dirs;
+ used_dirs = rfs->new_fs->group_desc[group].bg_used_dirs_count;
+ used_dirs += (__u32)rfs->new_fs->group_desc[group].bg_used_dirs_count_hi << 16;
+ used_dirs++;
+ rfs->new_fs->group_desc[group].bg_used_dirs_count = used_dirs;
+ rfs->new_fs->group_desc[group].bg_used_dirs_count_hi = used_dirs >> 16;
+ }
#ifdef RESIZE2FS_DEBUG
if (rfs->flags & RESIZE_DEBUG_INODEMAP)
@@ -1580,6 +1600,8 @@
(blk == EXT2_BLOCKS_COUNT(fs->super)-1)) {
fs->group_desc[group++].bg_free_blocks_count =
group_free;
+ fs->group_desc[group++].bg_free_blocks_count_hi =
+ group_free >> 16;
count = 0;
group_free = 0;
}
@@ -1603,6 +1625,8 @@
(ino == fs->super->s_inodes_count)) {
fs->group_desc[group++].bg_free_inodes_count =
group_free;
+ fs->group_desc[group++].bg_free_inodes_count_hi =
+ group_free >> 16;
count = 0;
group_free = 0;
}
Index: e2fsprogs/misc/mke2fs.c
===================================================================
--- e2fsprogs.orig/misc/mke2fs.c 2006-05-24 15:25:39.000000000 +0200
+++ e2fsprogs/misc/mke2fs.c 2006-05-24 15:26:05.000000000 +0200
@@ -219,6 +219,7 @@
blk_t group_block;
int group;
int group_bad;
+ int free_blocks;
if (!bb_list)
return;
@@ -260,7 +261,11 @@
group_block);
group_bad++;
group = ext2fs_group_of_blk(fs, group_block+j);
- fs->group_desc[group].bg_free_blocks_count++;
+ free_blocks = fs->group_desc[group].bg_free_blocks_count;
+ free_blocks += (__u32)fs->group_desc[group].bg_free_blocks_count_hi << 16;
+ free_blocks++;
+ fs->group_desc[group].bg_free_blocks_count = free_blocks;
+ fs->group_desc[group].bg_free_blocks_count_hi = free_blocks >> 16;
EXT2_FREE_BLOCKS_COUNT_SET(fs->super, EXT2_FREE_BLOCKS_COUNT(fs->super) + 1);
}
}
@@ -455,15 +460,17 @@
if ((i == 0) ||
(i == fs->group_desc_count-1))
continue;
- if (bg->bg_free_inodes_count ==
+ if ((bg->bg_free_inodes_count + (bg->bg_free_inodes_count_hi<<16)) ==
sb->s_inodes_per_group) {
bg->bg_free_inodes_count = 0;
+ bg->bg_free_inodes_count_hi = 0;
bg->bg_flags |= EXT2_BG_INODE_UNINIT;
sb->s_free_inodes_count -=
sb->s_inodes_per_group;
}
blks = ext2fs_super_and_bgd_loc(fs, i, 0, 0, 0, 0);
- if (bg->bg_free_blocks_count == blks) {
+ if ((bg->bg_free_blocks_count + (bg->bg_free_blocks_count<< 16)) ==
+ blks) {
bg->bg_free_blocks_count = 0;
bg->bg_flags |= EXT2_BG_BLOCK_UNINIT;
EXT2_FREE_BLOCKS_COUNT_SET(sb,
@@ -543,9 +550,14 @@
static void create_bad_block_inode(ext2_filsys fs, badblocks_list bb_list)
{
errcode_t retval;
+ __u32 free_inodes;
ext2fs_mark_inode_bitmap(fs->inode_map, EXT2_BAD_INO);
- fs->group_desc[0].bg_free_inodes_count--;
+ free_inodes = fs->group_desc[0].bg_free_inodes_count;
+ free_inodes += (__u32)fs->group_desc[0].bg_free_inodes_count_hi << 16;
+ free_inodes--;
+ fs->group_desc[0].bg_free_inodes_count = free_inodes;
+ fs->group_desc[0].bg_free_inodes_count_hi = free_inodes >> 16;
fs->super->s_free_inodes_count--;
retval = ext2fs_update_bb_inode(fs, bb_list);
if (retval) {
@@ -560,11 +572,16 @@
{
ext2_ino_t i;
int group;
+ __u32 free_inodes;
for (i = EXT2_ROOT_INO + 1; i < EXT2_FIRST_INODE(fs->super); i++) {
ext2fs_mark_inode_bitmap(fs->inode_map, i);
group = ext2fs_group_of_ino(fs, i);
- fs->group_desc[group].bg_free_inodes_count--;
+ free_inodes = fs->group_desc[group].bg_free_inodes_count;
+ free_inodes += (__u32)fs->group_desc[group].bg_free_inodes_count_hi << 16;
+ free_inodes--;
+ fs->group_desc[group].bg_free_inodes_count = free_inodes;
+ fs->group_desc[group].bg_free_inodes_count_hi = free_inodes >> 16;
fs->super->s_free_inodes_count--;
}
ext2fs_mark_ib_dirty(fs);
@@ -1401,12 +1418,14 @@
}
if (fs_param.s_blocks_per_group) {
- if (fs_param.s_blocks_per_group < 256 ||
- fs_param.s_blocks_per_group > 8 * (unsigned) blocksize) {
+ if (fs_param.s_blocks_per_group < 256) {
com_err(program_name, 0,
_("blocks per group count out of range"));
exit(1);
}
+ if (fs_param.s_blocks_per_group > 8 * (unsigned) blocksize) {
+ fs_param.s_feature_ro_compat |= EXT2_FEATURE_RO_COMPAT_BIG_BG;
+ }
}
if ((blocksize > 4096) &&
Index: e2fsprogs/lib/ext2fs/openfs.c
===================================================================
--- e2fsprogs.orig/lib/ext2fs/openfs.c 2006-05-24 15:25:36.000000000 +0200
+++ e2fsprogs/lib/ext2fs/openfs.c 2006-05-24 15:26:05.000000000 +0200
@@ -252,7 +252,8 @@
*/
blocks_per_group = EXT2_BLOCKS_PER_GROUP(fs->super);
if (blocks_per_group == 0 ||
- blocks_per_group > EXT2_MAX_BLOCKS_PER_GROUP(fs->super) ||
+ (!(fs->super->s_feature_ro_compat & EXT2_FEATURE_RO_COMPAT_BIG_BG)) &&
+ (blocks_per_group > EXT2_MAX_BLOCKS_PER_GROUP(fs->super)) ||
fs->inode_blocks_per_group > EXT2_MAX_INODES_PER_GROUP(fs->super)) {
retval = EXT2_ET_CORRUPT_SUPERBLOCK;
goto cleanup;
Index: e2fsprogs/lib/ext2fs/closefs.c
===================================================================
--- e2fsprogs.orig/lib/ext2fs/closefs.c 2006-05-24 15:25:36.000000000 +0200
+++ e2fsprogs/lib/ext2fs/closefs.c 2006-05-24 15:26:05.000000000 +0200
@@ -100,7 +100,9 @@
}
}
- numblocks -= 2 + fs->inode_blocks_per_group;
+ numblocks -= EXT2_BLOCK_BITMAP_PER_GROUP(fs->super) +
+ EXT2_INODE_BITMAP_PER_GROUP(fs->super) +
+ fs->inode_blocks_per_group;
if (ret_super_blk)
*ret_super_blk = super_blk;
Index: e2fsprogs/e2fsck/journal.c
===================================================================
--- e2fsprogs.orig/e2fsck/journal.c 2006-05-24 15:25:36.000000000 +0200
+++ e2fsprogs/e2fsck/journal.c 2006-05-24 15:26:05.000000000 +0200
@@ -851,6 +851,7 @@
errcode_t retval;
const char * const * cpp;
int group, mount_flags;
+ __u32 free_inodes;
clear_problem_context(&pctx);
@@ -947,7 +948,11 @@
group = ext2fs_group_of_ino(fs, ino);
ext2fs_unmark_inode_bitmap(fs->inode_map, ino);
ext2fs_mark_ib_dirty(fs);
- fs->group_desc[group].bg_free_inodes_count++;
+ free_inodes = fs->group_desc[group].bg_free_inodes_count;
+ free_inodes += (__u32)fs->group_desc[group].bg_free_inodes_count_hi << 16;
+ free_inodes++;
+ fs->group_desc[group].bg_free_inodes_count = free_inodes;
+ fs->group_desc[group].bg_free_inodes_count_hi = free_inodes >> 16;
fs->super->s_free_inodes_count++;
return;
Index: e2fsprogs/lib/ext2fs/ext2_fs.h
===================================================================
--- e2fsprogs.orig/lib/ext2fs/ext2_fs.h 2006-05-24 15:25:36.000000000 +0200
+++ e2fsprogs/lib/ext2fs/ext2_fs.h 2006-05-24 15:29:43.000000000 +0200
@@ -143,8 +143,10 @@
__u16 bg_free_blocks_count; /* Free blocks count */
__u16 bg_free_inodes_count; /* Free inodes count */
__u16 bg_used_dirs_count; /* Directories count */
- __u16 bg_pad;
- __u32 bg_reserved1;
+ __u8 bg_used_dirs_count_hi; /* Directories count */
+ __u8 bg_pad;
+ __u16 bg_free_blocks_count_hi; /* Free blocks count */
+ __u16 bg_free_inodes_count_hi; /* Free inodes count */
__u16 bg_flags;
__u16 bg_reserved2[3];
};
@@ -235,6 +237,14 @@
#define EXT2_DESC_PER_BLOCK_BITS(s) (EXT2_SB(s)->s_desc_per_block_bits)
#else
#define EXT2_DESC_PER_BLOCK(s) (EXT2_BLOCK_SIZE(s) / sizeof (struct ext2_group_desc))
+/* several block bitmaps per group */
+#define EXT2_BLOCK_BITMAP_NBYTES(s) ((EXT2_BLOCKS_PER_GROUP(s) + 7) / 8)
+#define EXT2_BLOCK_BITMAP_PER_GROUP(s) ((EXT2_BLOCK_BITMAP_NBYTES(s) + (EXT2_BLOCK_SIZE(s) - 1)) / EXT2_BLOCK_SIZE(s))
+#define EXT2_BLOCK_BITMAP_SIZE(s) (EXT2_BLOCK_BITMAP_PER_GROUP(s) * EXT2_BLOCK_SIZE(s))
+/* several inode bitmaps per group */
+#define EXT2_INODE_BITMAP_NBYTES(s) ((EXT2_INODES_PER_GROUP(s) + 7) / 8)
+#define EXT2_INODE_BITMAP_PER_GROUP(s) ((EXT2_INODE_BITMAP_NBYTES(s) + (EXT2_BLOCK_SIZE(s) - 1)) / EXT2_BLOCK_SIZE(s))
+#define EXT2_INODE_BITMAP_SIZE(s) (EXT2_INODE_BITMAP_PER_GROUP(s) * EXT2_BLOCK_SIZE(s))
#endif
/*
@@ -635,6 +645,7 @@
#define EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER 0x0001
#define EXT2_FEATURE_RO_COMPAT_LARGE_FILE 0x0002
/* #define EXT2_FEATURE_RO_COMPAT_BTREE_DIR 0x0004 not used */
+#define EXT2_FEATURE_RO_COMPAT_BIG_BG 0x0008
#define EXT2_FEATURE_RO_COMPAT_64BIT 0x0010
#define EXT2_FEATURE_INCOMPAT_COMPRESSION 0x0001
@@ -650,6 +661,7 @@
#define EXT2_FEATURE_RO_COMPAT_SUPP (EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER| \
EXT2_FEATURE_RO_COMPAT_LARGE_FILE| \
EXT2_FEATURE_RO_COMPAT_BTREE_DIR| \
+ EXT2_FEATURE_RO_COMPAT_BIG_BG| \
EXT2_FEATURE_RO_COMPAT_64BIT)
/*
Index: e2fsprogs/e2fsck/pass1.c
===================================================================
--- e2fsprogs.orig/e2fsck/pass1.c 2006-05-24 15:25:39.000000000 +0200
+++ e2fsprogs/e2fsck/pass1.c 2006-05-24 15:26:05.000000000 +0200
@@ -2035,33 +2035,40 @@
* Mark block used for the block bitmap
*/
if (EXT2_IS_USED_BLOCK_BITMAP(&fs->group_desc[i])) {
- if (ext2fs_test_block_bitmap(ctx->block_found_map,
- EXT2_BLOCK_BITMAP(&fs->group_desc[i], block))) {
- pctx.blk = EXT2_BLOCK_BITMAP(&fs->group_desc[i], block);
- if (fix_problem(ctx, PR_1_BB_CONFLICT, &pctx)) {
- ctx->invalid_block_bitmap_flag[i]++;
- ctx->invalid_bitmaps++;
+ for (j = 0, b = EXT2_BLOCK_BITMAP(&fs->group_desc[i], block);
+ j < EXT2_BLOCK_BITMAP_PER_GROUP(fs->super);
+ j++, b++) {
+ if (ext2fs_test_block_bitmap(ctx->block_found_map,
+ b)) {
+ pctx.blk = b;
+ if (fix_problem(ctx, PR_1_BB_CONFLICT, &pctx)) {
+ ctx->invalid_block_bitmap_flag[i]++;
+ ctx->invalid_bitmaps++;
+ }
+ } else {
+ ext2fs_mark_block_bitmap(ctx->block_found_map,
+ b);
}
- } else {
- ext2fs_mark_block_bitmap(ctx->block_found_map,
- EXT2_BLOCK_BITMAP(&fs->group_desc[i], block));
- }
-
+ }
}
/*
* Mark block used for the inode bitmap
*/
if (EXT2_IS_USED_INODE_BITMAP(&fs->group_desc[i])) {
- if (ext2fs_test_block_bitmap(ctx->block_found_map,
- EXT2_INODE_BITMAP(&fs->group_desc[i], block))) {
- pctx.blk = EXT2_INODE_BITMAP(&fs->group_desc[i], block);
- if (fix_problem(ctx, PR_1_IB_CONFLICT, &pctx)) {
- ctx->invalid_inode_bitmap_flag[i]++;
- ctx->invalid_bitmaps++;
- }
- } else {
- ext2fs_mark_block_bitmap(ctx->block_found_map,
- EXT2_INODE_BITMAP(&fs->group_desc[i], block));
+ for (j = 0, b = EXT2_INODE_BITMAP(&fs->group_desc[i], block);
+ j < EXT2_INODE_BITMAP_PER_GROUP(fs->super);
+ j++, b++) {
+ if (ext2fs_test_block_bitmap(ctx->block_found_map,
+ b)) {
+ pctx.blk = b;
+ if (fix_problem(ctx, PR_1_IB_CONFLICT, &pctx)) {
+ ctx->invalid_inode_bitmap_flag[i]++;
+ ctx->invalid_bitmaps++;
+ }
+ } else {
+ ext2fs_mark_block_bitmap(ctx->block_found_map,
+ b);
+ }
}
}
block += fs->super->s_blocks_per_group;
Index: e2fsprogs/e2fsck/super.c
===================================================================
--- e2fsprogs.orig/e2fsck/super.c 2006-05-24 15:25:36.000000000 +0200
+++ e2fsprogs/e2fsck/super.c 2006-05-24 15:26:05.000000000 +0200
@@ -451,6 +451,8 @@
blk_t should_be;
struct problem_context pctx;
__u32 free_blocks = 0, free_inodes = 0;
+ __u32 group_free_blocks, group_free_inodes, used_dirs;
+ int big_bg;
inodes_per_block = EXT2_INODES_PER_BLOCK(fs->super);
ipg_max = inodes_per_block * (blocks_per_group - 4);
@@ -472,6 +474,9 @@
/*
* Verify the super block constants...
*/
+
+ big_bg = (fs->super->s_feature_ro_compat & EXT2_FEATURE_RO_COMPAT_BIG_BG) ? 0 : MAX_CHECK;
+
check_super_value(ctx, "inodes_count", sb->s_inodes_count,
MIN_CHECK, 1, 0);
check_super_value(ctx, "blocks_count", EXT2_BLOCKS_COUNT(sb),
@@ -484,12 +489,12 @@
check_super_value(ctx, "log_frag_size", sb->s_log_frag_size,
MIN_CHECK | MAX_CHECK, 0, sb->s_log_block_size);
check_super_value(ctx, "frags_per_group", sb->s_frags_per_group,
- MIN_CHECK | MAX_CHECK, sb->s_blocks_per_group,
+ MIN_CHECK | big_bg, sb->s_blocks_per_group,
bpg_max);
check_super_value(ctx, "blocks_per_group", sb->s_blocks_per_group,
- MIN_CHECK | MAX_CHECK, 8, bpg_max);
+ MIN_CHECK | big_bg, 8, bpg_max);
check_super_value(ctx, "inodes_per_group", sb->s_inodes_per_group,
- MIN_CHECK | MAX_CHECK, inodes_per_block, ipg_max);
+ MIN_CHECK | big_bg, inodes_per_block, ipg_max);
check_super_value(ctx, "r_blocks_count", EXT2_R_BLOCKS_COUNT(sb),
MAX_CHECK, 0, EXT2_BLOCKS_COUNT(sb) / 2);
check_super_value(ctx, "reserved_gdt_blocks",
@@ -604,14 +609,22 @@
ctx->invalid_inode_table_flag[i]++;
ctx->invalid_bitmaps++;
}
- free_blocks += gd->bg_free_blocks_count;
- free_inodes += gd->bg_free_inodes_count;
+ group_free_blocks = gd->bg_free_blocks_count;
+ group_free_blocks += (__u32)gd->bg_free_blocks_count_hi << 16;
+ group_free_inodes = gd->bg_free_inodes_count;
+ group_free_inodes += (__u32)gd->bg_free_inodes_count_hi << 16;
+ used_dirs = gd->bg_used_dirs_count;
+ used_dirs += (__u32)gd->bg_used_dirs_count_hi << 16;
+
+
+ free_blocks += group_free_blocks;
+ free_inodes += group_free_inodes;
first_block += sb->s_blocks_per_group;
last_block += sb->s_blocks_per_group;
- if ((gd->bg_free_blocks_count > sb->s_blocks_per_group) ||
- (gd->bg_free_inodes_count > sb->s_inodes_per_group) ||
- (gd->bg_used_dirs_count > sb->s_inodes_per_group))
+ if ((group_free_blocks > sb->s_blocks_per_group) ||
+ (group_free_inodes > sb->s_inodes_per_group) ||
+ (used_dirs > sb->s_inodes_per_group))
ext2fs_unmark_valid(fs);
}
Index: e2fsprogs/lib/ext2fs/alloc_tables.c
===================================================================
--- e2fsprogs.orig/lib/ext2fs/alloc_tables.c 2006-05-24 15:25:36.000000000 +0200
+++ e2fsprogs/lib/ext2fs/alloc_tables.c 2006-05-24 15:26:05.000000000 +0200
@@ -61,25 +61,35 @@
if (!EXT2_IS_USED_BLOCK_BITMAP(&fs->group_desc[group])) {
retval = ext2fs_get_free_blocks(fs, start_blk, last_blk,
- 1, bmap, &new_blk);
+ EXT2_BLOCK_BITMAP_PER_GROUP(fs->super),
+ bmap, &new_blk);
if (retval == EXT2_ET_BLOCK_ALLOC_FAIL)
retval = ext2fs_get_free_blocks(fs, group_blk,
- last_blk, 1, bmap, &new_blk);
+ last_blk, EXT2_BLOCK_BITMAP_PER_GROUP(fs->super),
+ bmap, &new_blk);
if (retval)
return retval;
- ext2fs_mark_block_bitmap(bmap, new_blk);
+ for (j=0, blk = new_blk;
+ j < EXT2_BLOCK_BITMAP_PER_GROUP(fs->super);
+ j++, blk++)
+ ext2fs_mark_block_bitmap(bmap, blk);
EXT2_BLOCK_BITMAP_SET(&fs->group_desc[group], group_blk, new_blk);
}
if (!EXT2_IS_USED_INODE_BITMAP(&fs->group_desc[group])) {
retval = ext2fs_get_free_blocks(fs, start_blk, last_blk,
- 1, bmap, &new_blk);
+ EXT2_INODE_BITMAP_PER_GROUP(fs->super),
+ bmap, &new_blk);
if (retval == EXT2_ET_BLOCK_ALLOC_FAIL)
retval = ext2fs_get_free_blocks(fs, group_blk,
- last_blk, 1, bmap, &new_blk);
+ last_blk, EXT2_INODE_BITMAP_PER_GROUP(fs->super),
+ bmap, &new_blk);
if (retval)
return retval;
- ext2fs_mark_block_bitmap(bmap, new_blk);
+ for (j=0, blk = new_blk;
+ j < EXT2_INODE_BITMAP_PER_GROUP(fs->super);
+ j++, blk++)
+ ext2fs_mark_block_bitmap(bmap, blk);
EXT2_INODE_BITMAP_SET(&fs->group_desc[group], group_blk, new_blk);
}
Index: e2fsprogs/lib/ext2fs/dblist.c
===================================================================
--- e2fsprogs.orig/lib/ext2fs/dblist.c 2006-05-24 15:22:49.000000000 +0200
+++ e2fsprogs/lib/ext2fs/dblist.c 2006-05-24 15:26:05.000000000 +0200
@@ -31,16 +31,19 @@
{
dgrp_t i;
ext2_ino_t num_dirs, max_dirs;
+ __u32 used_dirs;
EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
num_dirs = 0;
max_dirs = fs->super->s_inodes_per_group;
for (i = 0; i < fs->group_desc_count; i++) {
- if (fs->group_desc[i].bg_used_dirs_count > max_dirs)
+ used_dirs = fs->group_desc[i].bg_used_dirs_count;
+ used_dirs += (__u32)fs->group_desc[i].bg_used_dirs_count_hi << 16;
+ if (used_dirs > max_dirs)
num_dirs += max_dirs / 8;
else
- num_dirs += fs->group_desc[i].bg_used_dirs_count;
+ num_dirs += used_dirs;
}
if (num_dirs > fs->super->s_inodes_count)
num_dirs = fs->super->s_inodes_count;
Index: e2fsprogs/misc/e2image.c
===================================================================
--- e2fsprogs.orig/misc/e2image.c 2006-05-24 15:25:36.000000000 +0200
+++ e2fsprogs/misc/e2image.c 2006-05-24 15:26:05.000000000 +0200
@@ -277,16 +277,20 @@
* Mark block used for the block bitmap
*/
if (EXT2_IS_USED_BLOCK_BITMAP(&fs->group_desc[i])) {
- ext2fs_mark_block_bitmap(meta_block_map,
- EXT2_BLOCK_BITMAP(&fs->group_desc[i], block));
+ for (j = 0, b = EXT2_BLOCK_BITMAP(&fs->group_desc[i], block);
+ j < EXT2_BLOCK_BITMAP_PER_GROUP(fs->super);
+ j++, b++)
+ ext2fs_mark_block_bitmap(meta_block_map, b);
}
/*
* Mark block used for the inode bitmap
*/
if (EXT2_IS_USED_INODE_BITMAP(&fs->group_desc[i])) {
- ext2fs_mark_block_bitmap(meta_block_map,
- EXT2_INODE_BITMAP(&fs->group_desc[i], block));
+ for (j = 0, b = EXT2_INODE_BITMAP(&fs->group_desc[i], block);
+ j < EXT2_INODE_BITMAP_PER_GROUP(fs->super);
+ j++, b++)
+ ext2fs_mark_block_bitmap(meta_block_map, b);
}
block += fs->super->s_blocks_per_group;
}
Index: e2fsprogs/lib/ext2fs/initialize.c
===================================================================
--- e2fsprogs.orig/lib/ext2fs/initialize.c 2006-05-24 15:25:36.000000000 +0200
+++ e2fsprogs/lib/ext2fs/initialize.c 2006-05-24 15:26:05.000000000 +0200
@@ -240,20 +240,22 @@
*/
ipg = ((blk_t)super->s_inodes_count + (blk_t)fs->group_desc_count - 1) /
fs->group_desc_count;
- if (ipg > fs->blocksize * 8) {
- if (super->s_blocks_per_group >= 256) {
- /* Try again with slightly different parameters */
- super->s_blocks_per_group -= 8;
- EXT2_BLOCKS_COUNT_SET(super, EXT2_BLOCKS_COUNT(param));
- super->s_frags_per_group = super->s_blocks_per_group *
- frags_per_block;
- goto retry;
- } else
- return EXT2_ET_TOO_MANY_INODES;
- }
+ if ( !(super->s_feature_ro_compat & EXT2_FEATURE_RO_COMPAT_BIG_BG) ) {
+ if (ipg > fs->blocksize * 8) {
+ if (super->s_blocks_per_group >= 256) {
+ /* Try again with slightly different parameters */
+ super->s_blocks_per_group -= 8;
+ EXT2_BLOCKS_COUNT_SET(super, EXT2_BLOCKS_COUNT(param));
+ super->s_frags_per_group = super->s_blocks_per_group *
+ frags_per_block;
+ goto retry;
+ } else
+ return EXT2_ET_TOO_MANY_INODES;
+ }
- if (ipg > (unsigned) EXT2_MAX_INODES_PER_GROUP(super))
- ipg = EXT2_MAX_INODES_PER_GROUP(super);
+ if (ipg > (unsigned) EXT2_MAX_INODES_PER_GROUP(super))
+ ipg = EXT2_MAX_INODES_PER_GROUP(super);
+ }
super->s_inodes_per_group = ipg;
if (super->s_inodes_count > ipg * fs->group_desc_count)
@@ -375,9 +377,13 @@
EXT2_FREE_BLOCKS_COUNT_SET(super, EXT2_FREE_BLOCKS_COUNT(super) + numblocks);
fs->group_desc[i].bg_free_blocks_count = numblocks;
+ fs->group_desc[i].bg_free_blocks_count_hi = numblocks >> 16;
fs->group_desc[i].bg_free_inodes_count =
fs->super->s_inodes_per_group;
+ fs->group_desc[i].bg_free_inodes_count_hi =
+ fs->super->s_inodes_per_group >> 16;
fs->group_desc[i].bg_used_dirs_count = 0;
+ fs->group_desc[i].bg_used_dirs_count_hi = 0;
group_block += super->s_blocks_per_group;
}
Index: e2fsprogs/misc/tune2fs.c
===================================================================
--- e2fsprogs.orig/misc/tune2fs.c 2006-05-24 15:25:36.000000000 +0200
+++ e2fsprogs/misc/tune2fs.c 2006-05-24 15:26:05.000000000 +0200
@@ -213,7 +213,18 @@
block = *blocknr;
ext2fs_unmark_block_bitmap(fs->block_map,block);
group = ext2fs_group_of_blk(fs, block);
- fs->group_desc[group].bg_free_blocks_count++;
+ if (fs->super->s_feature_ro_compat & EXT2_FEATURE_RO_COMPAT_BIG_BG) {
+ __u32 val;
+
+ val = fs->group_desc[group].bg_free_blocks_count +
+ ((__u32)fs->group_desc[group].bg_free_blocks_count_hi << 16);
+ val++;
+ fs->group_desc[group].bg_free_blocks_count = val;
+ fs->group_desc[group].bg_free_blocks_count_hi = val >> 16;
+ }
+ else
+ fs->group_desc[group].bg_free_blocks_count++;
+
EXT2_FREE_BLOCKS_COUNT_SET(fs->super, EXT2_FREE_BLOCKS_COUNT(fs->super) + 1);
return 0;
}
Index: e2fsprogs/lib/ext2fs/rw_bitmaps.c
===================================================================
--- e2fsprogs.orig/lib/ext2fs/rw_bitmaps.c 2006-05-24 15:25:36.000000000 +0200
+++ e2fsprogs/lib/ext2fs/rw_bitmaps.c 2006-05-24 15:26:05.000000000 +0200
@@ -74,20 +74,22 @@
block_bitmap = inode_bitmap = 0;
if (do_block) {
block_bitmap = fs->block_map->bitmap;
- block_nbytes = EXT2_BLOCKS_PER_GROUP(fs->super) / 8;
- retval = ext2fs_get_mem(fs->blocksize, &block_buf);
+ block_nbytes = EXT2_BLOCK_BITMAP_NBYTES(fs->super);
+ retval = ext2fs_get_mem(EXT2_BLOCK_BITMAP_SIZE(fs->super),
+ &block_buf);
if (retval)
return retval;
- memset(block_buf, 0xff, fs->blocksize);
+ memset(block_buf, 0xff, EXT2_BLOCK_BITMAP_SIZE(fs->super));
}
if (do_inode) {
inode_bitmap = fs->inode_map->bitmap;
inode_nbytes = (size_t)
- ((EXT2_INODES_PER_GROUP(fs->super)+7) / 8);
- retval = ext2fs_get_mem(fs->blocksize, &inode_buf);
+ EXT2_INODE_BITMAP_NBYTES(fs->super);
+ retval = ext2fs_get_mem(EXT2_INODE_BITMAP_SIZE(fs->super),
+ &inode_buf);
if (retval)
return retval;
- memset(inode_buf, 0xff, fs->blocksize);
+ memset(inode_buf, 0xff, EXT2_INODE_BITMAP_SIZE(fs->super));
}
for (i = 0; i < fs->group_desc_count; i++) {
@@ -106,7 +108,9 @@
- fs->super->s_first_data_block)
% EXT2_BLOCKS_PER_GROUP(fs->super));
if (nbits)
- for (j = nbits; j < fs->blocksize * 8; j++)
+ for (j = nbits;
+ j < EXT2_BLOCK_BITMAP_SIZE(fs->super) * 8;
+ j++)
ext2fs_set_bit(j, block_buf);
}
if (EXT2_IS_USED_BLOCK_BITMAP(&fs->group_desc[i])) {
@@ -117,7 +121,8 @@
ext2fs_swap_bitmap(fs, block_buf,
block_nbytes);
#endif
- retval = io_channel_write_blk(fs->io, blk, 1,
+ retval = io_channel_write_blk(fs->io, blk,
+ EXT2_BLOCK_BITMAP_PER_GROUP(fs->super),
block_buf);
if (retval)
return EXT2_ET_BLOCK_BITMAP_WRITE;
@@ -142,7 +147,8 @@
ext2fs_swap_bitmap(fs, inode_buf,
inode_nbytes);
#endif
- retval = io_channel_write_blk(fs->io, blk, 1,
+ retval = io_channel_write_blk(fs->io, blk,
+ EXT2_INODE_BITMAP_PER_GROUP(fs->super),
inode_buf);
if (retval)
return EXT2_ET_INODE_BITMAP_WRITE;
@@ -168,8 +174,8 @@
char *block_bitmap = 0, *inode_bitmap = 0;
char *buf;
errcode_t retval;
- int block_nbytes = (int) EXT2_BLOCKS_PER_GROUP(fs->super) / 8;
- int inode_nbytes = (int) EXT2_INODES_PER_GROUP(fs->super) / 8;
+ int block_nbytes = (int) EXT2_BLOCK_BITMAP_NBYTES(fs->super);
+ int inode_nbytes = (int) EXT2_INODE_BITMAP_NBYTES(fs->super);
int lazy_flag = 0;
blk_t blk;
-------------------------------------------------------
All the advantages of Linux Managed Hosting--Without the Cost and Risk!
Fully trained technicians. The highest number of Red Hat certifications in
the hosting industry. Fanatical Support. Click to learn more
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=107521&bid=248729&dat=121642