mirror of https://github.com/vitalif/e2fsprogs
Add support for EXT2_FEATURE_COMPAT_LAZY_BG
This feature is initially intended for testing purposes; it allows an ext2/ext3 developer to create very large filesystems using sparse files where most of the block groups are not initialized and so do not require much disk space. Eventually it could be used as a way of speeding up mke2fs and e2fsck for large filesystem, but that would be best done by adding an RO_COMPAT extension to the filesystem to allow the inode table to be lazily initialized on a per-block basis, instead of being entirely initialized or entirely unused on a per-blockgroup basis. Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>bitmap-optimize
parent
49c6b4e947
commit
f5fa20078b
|
@ -1,3 +1,8 @@
|
|||
2006-05-08 Theodore Tso <tytso@mit.edu>
|
||||
|
||||
* debugfs.c (do_show_super_stats): Print out the block group flags
|
||||
if they are set.
|
||||
|
||||
2006-04-27 Theodore Ts'o <tytso@mit.edu>
|
||||
|
||||
* htree.c (do_htree_dump, do_dx_hash), ls.c (do_list_dir): Add
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -1,3 +1,11 @@
|
|||
2006-05-08 Theodore Tso <tytso@mit.edu>
|
||||
|
||||
* 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 <tytso@mit.edu>
|
||||
|
||||
* e2fsck.8.in: Add badblocks(8) to the See Also section.
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
2006-05-08 Theodore Tso <tytso@mit.edu>
|
||||
|
||||
* feature.c: Add support for EXT2_FEATURE_COMPAT_LAZY_BG feature.
|
||||
|
||||
2006-04-18 Theodore Ts'o <tytso@mit.edu>
|
||||
|
||||
* uuid.c (e2p_is_null_uuid): Fix really stupid bug which could
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -1,3 +1,29 @@
|
|||
2006-05-08 Theodore Tso <tytso@mit.edu>
|
||||
|
||||
* 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 <tytso@mit.edu>
|
||||
|
||||
* rw_bitmaps.c (write_bitmaps, ext2fs_write_inode_bitmap,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -1,3 +1,14 @@
|
|||
2006-05-08 Theodore Tso <tytso@mit.edu>
|
||||
|
||||
* 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 <tytso@mit.edu>
|
||||
|
||||
* filefrag.c: Make filefrag 32-bit clean, so that it works on
|
||||
|
|
|
@ -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 "),
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue