diff --git a/debugfs/ChangeLog b/debugfs/ChangeLog index a9fb8a4d..0425d227 100644 --- a/debugfs/ChangeLog +++ b/debugfs/ChangeLog @@ -1,3 +1,8 @@ +2006-05-08 Theodore Tso + + * debugfs.c (do_show_super_stats): Print out the block group flags + if they are set. + 2006-04-27 Theodore Ts'o * htree.c (do_htree_dump, do_dx_hash), ls.c (do_list_dir): Add diff --git a/debugfs/debugfs.c b/debugfs/debugfs.c index 12ef00c2..25d52d75 100644 --- a/debugfs/debugfs.c +++ b/debugfs/debugfs.c @@ -266,13 +266,26 @@ static void print_features(struct ext2_super_block * s, FILE *f) fputs("\n", f); } +static void print_bg_opts(struct ext2_group_desc *gdp, int mask, + const char *str, int *first, FILE *f) +{ + if (gdp->bg_flags & mask) { + if (*first) { + fputs(" [", f); + *first = 0; + } else + fputs(", ", f); + fputs(str, f); + } +} + void do_show_super_stats(int argc, char *argv[]) { dgrp_t i; FILE *out; struct ext2_group_desc *gdp; int c, header_only = 0; - int numdirs = 0; + int numdirs = 0, first; reset_getopt(); while ((c = getopt (argc, argv, "h")) != EOF) { @@ -302,7 +315,7 @@ void do_show_super_stats(int argc, char *argv[]) } gdp = ¤t_fs->group_desc[0]; - for (i = 0; i < current_fs->group_desc_count; i++, gdp++) + for (i = 0; i < current_fs->group_desc_count; i++, gdp++) { fprintf(out, " Group %2d: block bitmap at %u, " "inode bitmap at %u, " "inode table at %u\n" @@ -318,6 +331,14 @@ void do_show_super_stats(int argc, char *argv[]) gdp->bg_used_dirs_count, gdp->bg_used_dirs_count != 1 ? "directories" : "directory"); + first = 1; + print_bg_opts(gdp, EXT2_BG_INODE_UNINIT, "Inode not init", + &first, out); + print_bg_opts(gdp, EXT2_BG_BLOCK_UNINIT, "Block not init", + &first, out); + if (!first) + fputs("]\n", out); + } close_pager(out); return; print_usage: diff --git a/e2fsck/ChangeLog b/e2fsck/ChangeLog index 3b408fab..545dafcc 100644 --- a/e2fsck/ChangeLog +++ b/e2fsck/ChangeLog @@ -1,3 +1,11 @@ +2006-05-08 Theodore Tso + + * pass5.c (check_block_bitmaps, check_inode_bitmaps): Add support + for the lazy_bg feature; if the block group does not have + an initialized block or inode bitmaps/table, emulate what + the allocation bitmap would look like if no blocks or + inodes have been allocated. + 2006-03-27 Theodore Ts'o * e2fsck.8.in: Add badblocks(8) to the See Also section. diff --git a/e2fsck/pass5.c b/e2fsck/pass5.c index e708fa41..eb3ebf02 100644 --- a/e2fsck/pass5.c +++ b/e2fsck/pass5.c @@ -111,7 +111,7 @@ static void print_bitmap_problem(e2fsck_t ctx, int problem, static void check_block_bitmaps(e2fsck_t ctx) { ext2_filsys fs = ctx->fs; - blk_t i; + blk_t i, super; int *free_array; int group = 0; unsigned int blocks = 0; @@ -121,6 +121,8 @@ static void check_block_bitmaps(e2fsck_t ctx) struct problem_context pctx; int problem, save_problem, fixit, had_problem; errcode_t retval; + int lazy_bg = 0; + int skip_group = 0; clear_problem_context(&pctx); free_array = (int *) e2fsck_allocate_memory(ctx, @@ -156,19 +158,45 @@ static void check_block_bitmaps(e2fsck_t ctx) return; } + if (EXT2_HAS_COMPAT_FEATURE(fs->super, + EXT2_FEATURE_COMPAT_LAZY_BG)) + lazy_bg++; + redo_counts: had_problem = 0; save_problem = 0; pctx.blk = pctx.blk2 = NO_BLK; + if (lazy_bg && (fs->group_desc[group].bg_flags & + EXT2_BG_BLOCK_UNINIT)) + skip_group++; + super = fs->super->s_first_data_block; for (i = fs->super->s_first_data_block; i < fs->super->s_blocks_count; i++) { actual = ext2fs_fast_test_block_bitmap(ctx->block_found_map, i); - bitmap = ext2fs_fast_test_block_bitmap(fs->block_map, i); + + if (skip_group) { + if ((i >= super) && + (i <= super + fs->desc_blocks) && + ext2fs_bg_has_super(fs, group)) + bitmap = 1; + else if (i == fs->group_desc[group].bg_block_bitmap) + bitmap = 1; + else if (i == fs->group_desc[group].bg_inode_bitmap) + bitmap = 1; + else if (i >= fs->group_desc[group].bg_inode_table && + (i < fs->group_desc[group].bg_inode_table + + fs->inode_blocks_per_group)) + bitmap = 1; + else + bitmap = 0; + actual = (actual != 0); + } else + bitmap = ext2fs_fast_test_block_bitmap(fs->block_map, i); if (actual == bitmap) goto do_counts; - + if (!actual && bitmap) { /* * Block not used, but marked in use in the bitmap. @@ -197,7 +225,7 @@ redo_counts: had_problem++; do_counts: - if (!bitmap) { + if (!bitmap && !skip_group) { group_free++; free_blocks++; } @@ -208,10 +236,17 @@ redo_counts: group ++; blocks = 0; group_free = 0; + skip_group = 0; + super += fs->super->s_blocks_per_group; if (ctx->progress) if ((ctx->progress)(ctx, 5, group, fs->group_desc_count*2)) return; + if (lazy_bg && + (i != fs->super->s_blocks_count-1) && + (fs->group_desc[group].bg_flags & + EXT2_BG_BLOCK_UNINIT)) + skip_group++; } } if (pctx.blk != NO_BLK) @@ -286,6 +321,8 @@ static void check_inode_bitmaps(e2fsck_t ctx) errcode_t retval; struct problem_context pctx; int problem, save_problem, fixit, had_problem; + int lazy_bg = 0; + int skip_group = 0; clear_problem_context(&pctx); free_array = (int *) e2fsck_allocate_memory(ctx, @@ -321,14 +358,24 @@ static void check_inode_bitmaps(e2fsck_t ctx) return; } + if (EXT2_HAS_COMPAT_FEATURE(fs->super, + EXT2_FEATURE_COMPAT_LAZY_BG)) + lazy_bg++; + redo_counts: had_problem = 0; save_problem = 0; pctx.ino = pctx.ino2 = 0; + if (lazy_bg && (fs->group_desc[group].bg_flags & + EXT2_BG_INODE_UNINIT)) + skip_group++; + for (i = 1; i <= fs->super->s_inodes_count; i++) { actual = ext2fs_fast_test_inode_bitmap(ctx->inode_used_map, i); - bitmap = ext2fs_fast_test_inode_bitmap(fs->inode_map, i); - + if (skip_group) + bitmap = 0; + else + bitmap = ext2fs_fast_test_inode_bitmap(fs->inode_map, i); if (actual == bitmap) goto do_counts; @@ -360,12 +407,12 @@ redo_counts: had_problem++; do_counts: - if (!bitmap) { - group_free++; - free_inodes++; - } else { + if (bitmap) { if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, i)) dirs_count++; + } else if (!skip_group) { + group_free++; + free_inodes++; } inodes++; if ((inodes == fs->super->s_inodes_per_group) || @@ -374,6 +421,7 @@ do_counts: dir_array[group] = dirs_count; group ++; inodes = 0; + skip_group = 0; group_free = 0; dirs_count = 0; if (ctx->progress) @@ -381,6 +429,11 @@ do_counts: group + fs->group_desc_count, fs->group_desc_count*2)) return; + if (lazy_bg && + (i != fs->super->s_inodes_count) && + (fs->group_desc[group].bg_flags & + EXT2_BG_INODE_UNINIT)) + skip_group++; } } if (pctx.ino) diff --git a/lib/e2p/ChangeLog b/lib/e2p/ChangeLog index 358e108c..641e7d8d 100644 --- a/lib/e2p/ChangeLog +++ b/lib/e2p/ChangeLog @@ -1,3 +1,7 @@ +2006-05-08 Theodore Tso + + * feature.c: Add support for EXT2_FEATURE_COMPAT_LAZY_BG feature. + 2006-04-18 Theodore Ts'o * uuid.c (e2p_is_null_uuid): Fix really stupid bug which could diff --git a/lib/e2p/feature.c b/lib/e2p/feature.c index 50f1ef3d..e8f6729d 100644 --- a/lib/e2p/feature.c +++ b/lib/e2p/feature.c @@ -35,6 +35,8 @@ static struct feature feature_list[] = { "dir_index" }, { E2P_FEATURE_COMPAT, EXT2_FEATURE_COMPAT_RESIZE_INODE, "resize_inode" }, + { E2P_FEATURE_COMPAT, EXT2_FEATURE_COMPAT_LAZY_BG, + "lazy_bg" }, { E2P_FEATURE_RO_INCOMPAT, EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER, "sparse_super" }, { E2P_FEATURE_RO_INCOMPAT, EXT2_FEATURE_RO_COMPAT_LARGE_FILE, diff --git a/lib/ext2fs/ChangeLog b/lib/ext2fs/ChangeLog index 7da3fe2e..512ef3f7 100644 --- a/lib/ext2fs/ChangeLog +++ b/lib/ext2fs/ChangeLog @@ -1,3 +1,29 @@ +2006-05-08 Theodore Tso + + * rw_bitmaps.c (write_bitmaps, read_bitmaps): Added support for + lazy blockgroups. If a block group has flags indicating + that its block or inode data structures have not been + initialized, skip reading or writing that portion of the + bitmap. + + * inode.c (ext2fs_open_inode_scan, ext2fs_read_inode_full): When + scanning a filesystem with lazy blockgroups, skip + uninitialized portions of the inode table when iterating + over the block group. + + * swapfs.c (ext2fs_swap_group_desc): Byte swap the bg_flags field. + + * ext2fs.h: Define the a new internal flag, EXT2_SF_DO_LAZY, so + that the inode interator knows compat_lazy_bg feature is + enabled. Declare that this version of e2fsprogs supports + the EXT2_FEATURE_COMPAY_LAZY_BG feature. + + * ext2_fs.h (struct ext2_group_desc): Use the bg_pad field for + bg_flags, and define the flags EXT2_BG_INODE_UNINIT and + EXT2_BG_BLOCK_UNINIT. These flags are only honored if + EXT2_FEATURE_COMPAT_LAZY_BG feature is enabled (also + added). + 2006-04-23 Theodore Ts'o * rw_bitmaps.c (write_bitmaps, ext2fs_write_inode_bitmap, diff --git a/lib/ext2fs/ext2_fs.h b/lib/ext2fs/ext2_fs.h index e427addf..1cfbc358 100644 --- a/lib/ext2fs/ext2_fs.h +++ b/lib/ext2fs/ext2_fs.h @@ -143,10 +143,13 @@ struct ext2_group_desc __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; + __u16 bg_flags; __u32 bg_reserved[3]; }; +#define EXT2_BG_INODE_UNINIT 0x0001 /* Inode table/bitmap not initialized */ +#define EXT2_BG_BLOCK_UNINIT 0x0002 /* Block bitmap not initialized */ + /* * Data structures used by the directory indexing feature * @@ -568,6 +571,7 @@ struct ext2_super_block { #define EXT2_FEATURE_COMPAT_EXT_ATTR 0x0008 #define EXT2_FEATURE_COMPAT_RESIZE_INODE 0x0010 #define EXT2_FEATURE_COMPAT_DIR_INDEX 0x0020 +#define EXT2_FEATURE_COMPAT_LAZY_BG 0x0040 #define EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER 0x0001 #define EXT2_FEATURE_RO_COMPAT_LARGE_FILE 0x0002 diff --git a/lib/ext2fs/ext2fs.h b/lib/ext2fs/ext2fs.h index c3d04289..8618fe26 100644 --- a/lib/ext2fs/ext2fs.h +++ b/lib/ext2fs/ext2fs.h @@ -341,6 +341,7 @@ typedef struct ext2_struct_inode_scan *ext2_inode_scan; #define EXT2_SF_BAD_INODE_BLK 0x0002 #define EXT2_SF_BAD_EXTRA_BYTES 0x0004 #define EXT2_SF_SKIP_MISSING_ITABLE 0x0008 +#define EXT2_SF_DO_LAZY 0x0010 /* * ext2fs_check_if_mounted flags @@ -437,6 +438,7 @@ typedef struct ext2_icount *ext2_icount_t; EXT3_FEATURE_COMPAT_HAS_JOURNAL|\ EXT2_FEATURE_COMPAT_RESIZE_INODE|\ EXT2_FEATURE_COMPAT_DIR_INDEX|\ + EXT2_FEATURE_COMPAT_LAZY_BG|\ EXT2_FEATURE_COMPAT_EXT_ATTR) /* This #ifdef is temporary until compression is fully supported */ diff --git a/lib/ext2fs/inode.c b/lib/ext2fs/inode.c index 222568eb..8d528b44 100644 --- a/lib/ext2fs/inode.c +++ b/lib/ext2fs/inode.c @@ -164,6 +164,9 @@ errcode_t ext2fs_open_inode_scan(ext2_filsys fs, int buffer_blocks, } if (scan->fs->badblocks && scan->fs->badblocks->num) scan->scan_flags |= EXT2_SF_CHK_BADBLOCKS; + if (EXT2_HAS_COMPAT_FEATURE(fs->super, + EXT2_FEATURE_COMPAT_LAZY_BG)) + scan->scan_flags |= EXT2_SF_DO_LAZY; *ret_scan = scan; return 0; } @@ -407,9 +410,13 @@ errcode_t ext2fs_get_next_inode_full(ext2_inode_scan scan, ext2_ino_t *ino, return retval; } /* - * This is done outside the above if statement so that the - * check can be done for block group #0. + * These checks are done outside the above if statement so + * they can be done for block group #0. */ + if ((scan->scan_flags & EXT2_SF_DO_LAZY) && + (scan->fs->group_desc[scan->current_group].bg_flags & + EXT2_BG_INODE_UNINIT)) + goto force_new_group; if (scan->current_block == 0) { if (scan->scan_flags & EXT2_SF_SKIP_MISSING_ITABLE) { goto force_new_group; diff --git a/lib/ext2fs/rw_bitmaps.c b/lib/ext2fs/rw_bitmaps.c index 7ab0a4db..cb470b8e 100644 --- a/lib/ext2fs/rw_bitmaps.c +++ b/lib/ext2fs/rw_bitmaps.c @@ -60,12 +60,16 @@ static errcode_t write_bitmaps(ext2_filsys fs, int do_inode, int do_block) errcode_t retval; char *block_bitmap, *inode_bitmap; char *block_buf, *inode_buf; + int lazy_flag = 0; blk_t blk; EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS); if (!(fs->flags & EXT2_FLAG_RW)) return EXT2_ET_RO_FILSYS; + if (EXT2_HAS_COMPAT_FEATURE(fs->super, + EXT2_FEATURE_COMPAT_LAZY_BG)) + lazy_flag = 1; inode_nbytes = block_nbytes = 0; block_bitmap = inode_bitmap = 0; if (do_block) { @@ -89,6 +93,10 @@ static errcode_t write_bitmaps(ext2_filsys fs, int do_inode, int do_block) for (i = 0; i < fs->group_desc_count; i++) { if (!block_bitmap || !do_block) goto skip_block_bitmap; + + if (lazy_flag && fs->group_desc[i].bg_flags & + EXT2_BG_BLOCK_UNINIT) + goto skip_this_block_bitmap; memcpy(block_buf, block_bitmap, block_nbytes); if (i == fs->group_desc_count - 1) { @@ -113,12 +121,17 @@ static errcode_t write_bitmaps(ext2_filsys fs, int do_inode, int do_block) if (retval) return EXT2_ET_BLOCK_BITMAP_WRITE; } + skip_this_block_bitmap: block_bitmap += block_nbytes; skip_block_bitmap: if (!inode_bitmap || !do_inode) continue; + if (lazy_flag && fs->group_desc[i].bg_flags & + EXT2_BG_INODE_UNINIT) + goto skip_this_inode_bitmap; + memcpy(inode_buf, inode_bitmap, inode_nbytes); blk = fs->group_desc[i].bg_inode_bitmap; if (blk) { @@ -133,6 +146,7 @@ static errcode_t write_bitmaps(ext2_filsys fs, int do_inode, int do_block) if (retval) return EXT2_ET_INODE_BITMAP_WRITE; } + skip_this_inode_bitmap: inode_bitmap += inode_nbytes; } @@ -155,12 +169,17 @@ static errcode_t read_bitmaps(ext2_filsys fs, int do_inode, int do_block) 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 lazy_flag = 0; blk_t blk; EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS); fs->write_bitmaps = ext2fs_write_bitmaps; + if (EXT2_HAS_COMPAT_FEATURE(fs->super, + EXT2_FEATURE_COMPAT_LAZY_BG)) + lazy_flag = 1; + retval = ext2fs_get_mem(strlen(fs->device_name) + 80, &buf); if (retval) return retval; @@ -209,6 +228,9 @@ static errcode_t read_bitmaps(ext2_filsys fs, int do_inode, int do_block) for (i = 0; i < fs->group_desc_count; i++) { if (block_bitmap) { blk = fs->group_desc[i].bg_block_bitmap; + if (lazy_flag && fs->group_desc[i].bg_flags & + EXT2_BG_BLOCK_UNINIT) + blk = 0; if (blk) { retval = io_channel_read_blk(fs->io, blk, -block_nbytes, block_bitmap); @@ -222,11 +244,14 @@ static errcode_t read_bitmaps(ext2_filsys fs, int do_inode, int do_block) ext2fs_swap_bitmap(fs, block_bitmap, block_nbytes); #endif } else - memset(block_bitmap, 0, block_nbytes); + memset(block_bitmap, 0xff, block_nbytes); block_bitmap += block_nbytes; } if (inode_bitmap) { blk = fs->group_desc[i].bg_inode_bitmap; + if (lazy_flag && fs->group_desc[i].bg_flags & + EXT2_BG_INODE_UNINIT) + blk = 0; if (blk) { retval = io_channel_read_blk(fs->io, blk, -inode_nbytes, inode_bitmap); @@ -240,7 +265,7 @@ static errcode_t read_bitmaps(ext2_filsys fs, int do_inode, int do_block) ext2fs_swap_bitmap(fs, inode_bitmap, inode_nbytes); #endif } else - memset(inode_bitmap, 0, inode_nbytes); + memset(inode_bitmap, 0xff, inode_nbytes); inode_bitmap += inode_nbytes; } } diff --git a/lib/ext2fs/swapfs.c b/lib/ext2fs/swapfs.c index 90817012..a4c66980 100644 --- a/lib/ext2fs/swapfs.c +++ b/lib/ext2fs/swapfs.c @@ -78,6 +78,7 @@ void ext2fs_swap_group_desc(struct ext2_group_desc *gdp) gdp->bg_free_blocks_count = ext2fs_swab16(gdp->bg_free_blocks_count); gdp->bg_free_inodes_count = ext2fs_swab16(gdp->bg_free_inodes_count); gdp->bg_used_dirs_count = ext2fs_swab16(gdp->bg_used_dirs_count); + gdp->bg_flags = ext2fs_swab16(gdp->bg_flags); } void ext2fs_swap_ext_attr(char *to, char *from, int bufsize, int has_header) diff --git a/misc/ChangeLog b/misc/ChangeLog index 605928a9..0cb03895 100644 --- a/misc/ChangeLog +++ b/misc/ChangeLog @@ -1,3 +1,14 @@ +2006-05-08 Theodore Tso + + * mke2fs.c (write_inode_tables, setup_lazy_bg, main): Add support + for the COMPAT_LAZY_BG feature. This is currently + intended for debugging purposes only, as a way to create + very large filesystems stored on sparse files for testing + purposes. + + * dumpe2fs.c (list_desc): Print out the block group flags if they + are set. + 2006-04-22 Theodore Ts'o * filefrag.c: Make filefrag 32-bit clean, so that it works on diff --git a/misc/dumpe2fs.c b/misc/dumpe2fs.c index 2e42cb3d..58c9869b 100644 --- a/misc/dumpe2fs.c +++ b/misc/dumpe2fs.c @@ -96,6 +96,36 @@ static void print_free (unsigned long group, char * bitmap, } } +static void print_bg_opt(int bg_flags, int mask, + const char *str, int *first) +{ + if (bg_flags & mask) { + if (*first) { + fputs(" [", stdout); + *first = 0; + } else + fputs(", ", stdout); + fputs(str, stdout); + } +} +static void print_bg_opts(ext2_filsys fs, dgrp_t i) +{ + int first = 1, bg_flags; + + if (fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_LAZY_BG) + bg_flags = fs->group_desc[i].bg_flags; + else + bg_flags = 0; + + print_bg_opt(bg_flags, EXT2_BG_INODE_UNINIT, "Inode not init", + &first); + print_bg_opt(bg_flags, EXT2_BG_BLOCK_UNINIT, "Block not init", + &first); + if (!first) + fputc(']', stdout); + fputc('\n', stdout); +} + static void list_desc (ext2_filsys fs) { unsigned long i; @@ -130,7 +160,8 @@ static void list_desc (ext2_filsys fs) next_blk = fs->super->s_blocks_count; printf (_("Group %lu: (Blocks "), i); print_range(group_blk, next_blk - 1); - fputs(")\n", stdout); + fputs(")", stdout); + print_bg_opts(fs, i); has_super = ((i==0) || super_blk); if (has_super) { printf (_(" %s superblock at "), diff --git a/misc/mke2fs.c b/misc/mke2fs.c index 6fd55400..9f23ea5d 100644 --- a/misc/mke2fs.c +++ b/misc/mke2fs.c @@ -403,6 +403,7 @@ static void write_inode_tables(ext2_filsys fs) dgrp_t i; int num; struct progress_struct progress; + int lazy_flag = 0; if (quiet) memset(&progress, 0, sizeof(progress)); @@ -410,18 +411,25 @@ static void write_inode_tables(ext2_filsys fs) progress_init(&progress, _("Writing inode tables: "), fs->group_desc_count); + if (EXT2_HAS_COMPAT_FEATURE(fs->super, + EXT2_FEATURE_COMPAT_LAZY_BG)) + lazy_flag = 1; + for (i = 0; i < fs->group_desc_count; i++) { progress_update(&progress, i); blk = fs->group_desc[i].bg_inode_table; num = fs->inode_blocks_per_group; - retval = zero_blocks(fs, blk, num, 0, &blk, &num); - if (retval) { - fprintf(stderr, _("\nCould not write %d blocks " - "in inode table starting at %u: %s\n"), - num, blk, error_message(retval)); - exit(1); + if (!(lazy_flag && + (fs->group_desc[i].bg_flags & EXT2_BG_INODE_UNINIT))) { + retval = zero_blocks(fs, blk, num, 0, &blk, &num); + if (retval) { + fprintf(stderr, _("\nCould not write %d " + "blocks in inode table starting at %u: %s\n"), + num, blk, error_message(retval)); + exit(1); + } } if (sync_kludge) { if (sync_kludge == 1) @@ -434,6 +442,37 @@ static void write_inode_tables(ext2_filsys fs) progress_close(&progress); } +static void setup_lazy_bg(ext2_filsys fs) +{ + dgrp_t i; + int blks; + struct ext2_super_block *sb = fs->super; + struct ext2_group_desc *bg = fs->group_desc; + + if (EXT2_HAS_COMPAT_FEATURE(fs->super, + EXT2_FEATURE_COMPAT_LAZY_BG)) { + for (i = 0; i < fs->group_desc_count; i++, bg++) { + if ((i == 0) || + (i == fs->group_desc_count-1)) + continue; + if (bg->bg_free_inodes_count == + sb->s_inodes_per_group) { + bg->bg_free_inodes_count = 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) { + bg->bg_free_blocks_count = 0; + bg->bg_flags |= EXT2_BG_BLOCK_UNINIT; + sb->s_free_blocks_count -= blks; + } + } + } +} + + static void create_root_dir(ext2_filsys fs) { errcode_t retval; @@ -814,7 +853,8 @@ static void parse_extended_opts(struct ext2_super_block *param, static __u32 ok_features[3] = { EXT3_FEATURE_COMPAT_HAS_JOURNAL | EXT2_FEATURE_COMPAT_RESIZE_INODE | - EXT2_FEATURE_COMPAT_DIR_INDEX, /* Compat */ + EXT2_FEATURE_COMPAT_DIR_INDEX | + EXT2_FEATURE_COMPAT_LAZY_BG, /* Compat */ EXT2_FEATURE_INCOMPAT_FILETYPE| /* Incompat */ EXT3_FEATURE_INCOMPAT_JOURNAL_DEV| EXT2_FEATURE_INCOMPAT_META_BG, @@ -1557,6 +1597,7 @@ int main (int argc, char *argv[]) _("while zeroing block %u at end of filesystem"), ret_blk); } + setup_lazy_bg(fs); write_inode_tables(fs); create_root_dir(fs); create_lost_and_found(fs);