diff --git a/e2fsck/ChangeLog b/e2fsck/ChangeLog index b5b9efa0..79a9bcdd 100644 --- a/e2fsck/ChangeLog +++ b/e2fsck/ChangeLog @@ -1,3 +1,9 @@ +2003-09-03 Theodore Ts'o + + * pass1.c (mark_table_blocks): Use the new function + ext2fs_reserve_super_and_bgd to calculate the blocks to be + reserved. + 2003-08-24 Theodore Ts'o * util.c (get_backup_sb): Check to make sure the context is passed diff --git a/e2fsck/pass1.c b/e2fsck/pass1.c index a585cfff..992d91d5 100644 --- a/e2fsck/pass1.c +++ b/e2fsck/pass1.c @@ -1783,52 +1783,17 @@ static void mark_table_blocks(e2fsck_t ctx) { ext2_filsys fs = ctx->fs; blk_t block, b; - int i, j, has_super, meta_bg, meta_bg_size, old_desc_blocks; + int i, j; struct problem_context pctx; clear_problem_context(&pctx); block = fs->super->s_first_data_block; - if (fs->super->s_feature_incompat & EXT2_FEATURE_INCOMPAT_META_BG) - old_desc_blocks = fs->super->s_first_meta_bg; - else - old_desc_blocks = fs->desc_blocks; for (i = 0; i < fs->group_desc_count; i++) { pctx.group = i; - has_super = ext2fs_bg_has_super(fs, i); - if (has_super) - /* - * Mark this group's copy of the superblock - */ - ext2fs_mark_block_bitmap(ctx->block_found_map, block); - - meta_bg_size = (fs->blocksize / - sizeof (struct ext2_group_desc)); - meta_bg = i / meta_bg_size; - if (!(fs->super->s_feature_incompat & - EXT2_FEATURE_INCOMPAT_META_BG) || - (meta_bg < fs->super->s_first_meta_bg)) { - if (has_super) { - /* - * Mark this group's copy of the descriptors - */ - for (j = 0; j < old_desc_blocks; j++) { - ext2fs_mark_block_bitmap(ctx->block_found_map, - block + j + 1); - } - } - } else { - if (has_super) - has_super = 1; - if (((i % meta_bg_size) == 0) || - ((i % meta_bg_size) == 1) || - ((i % meta_bg_size) == (meta_bg_size-1))) - ext2fs_mark_block_bitmap(ctx->block_found_map, - block + has_super); - } - - + ext2fs_reserve_super_and_bgd(fs, i, ctx->block_found_map); + /* * Mark the blocks used for the inode table */ diff --git a/lib/ext2fs/ChangeLog b/lib/ext2fs/ChangeLog index 52b29446..377f5941 100644 --- a/lib/ext2fs/ChangeLog +++ b/lib/ext2fs/ChangeLog @@ -1,3 +1,19 @@ +2003-09-03 Theodore Ts'o + + * closefs.c (ext2fs_super_and_bgd_loc): New function which + centralizes the calculation of the superblock and block + group descriptors. + (ext2fs_flush): Use ext2fs_super_and_bgd_lock to figure + out where to write the superblock and block group + descriptors. + + * alloc_sb.c (ext2fs_reserve_super_and_bgd): New function which + reserves space in the block bitmap using + ext2fs_super_and_bgd_loc. + + * initialize.c (ext2fs_initialize): Use + ext2fs_reserve_super_and_bgd to initialize the block bitmap. + 2003-08-20 Theodore Ts'o * inode_io.c (ext2fs_inode_io_intern2), ext2fs.h: Add new function diff --git a/lib/ext2fs/Makefile.in b/lib/ext2fs/Makefile.in index cc56d663..773791b2 100644 --- a/lib/ext2fs/Makefile.in +++ b/lib/ext2fs/Makefile.in @@ -17,6 +17,7 @@ INSTALL = @INSTALL@ OBJS= $(DEBUGFS_LIB_OBJS) $(RESIZE_LIB_OBJS) $(E2IMAGE_LIB_OBJS) \ ext2_err.o \ alloc.o \ + alloc_sb.o \ alloc_stats.o \ alloc_tables.o \ badblocks.o \ @@ -65,6 +66,7 @@ OBJS= $(DEBUGFS_LIB_OBJS) $(RESIZE_LIB_OBJS) $(E2IMAGE_LIB_OBJS) \ SRCS= ext2_err.c \ $(srcdir)/alloc.c \ + $(srcdir)/alloc_sb.c \ $(srcdir)/alloc_stats.c \ $(srcdir)/alloc_tables.c \ $(srcdir)/badblocks.c \ diff --git a/lib/ext2fs/alloc_sb.c b/lib/ext2fs/alloc_sb.c new file mode 100644 index 00000000..e4733c99 --- /dev/null +++ b/lib/ext2fs/alloc_sb.c @@ -0,0 +1,56 @@ +/* + * alloc_sb.c --- Allocate the superblock and block group descriptors for a + * newly initialized filesystem. Used by mke2fs when initializing a filesystem + * + * Copyright (C) 1994, 1995, 1996, 2003 Theodore Ts'o. + * + * %Begin-Header% + * This file may be redistributed under the terms of the GNU Public + * License. + * %End-Header% + */ + +#include +#include +#if HAVE_UNISTD_H +#include +#endif +#include +#include +#if HAVE_SYS_STAT_H +#include +#endif +#if HAVE_SYS_TYPES_H +#include +#endif + +#include "ext2_fs.h" +#include "ext2fs.h" + +int ext2fs_reserve_super_and_bgd(ext2_filsys fs, + dgrp_t group, + ext2fs_block_bitmap bmap) +{ + blk_t super_blk, old_desc_blk, new_desc_blk; + int j, old_desc_blocks, num_blocks; + + num_blocks = ext2fs_super_and_bgd_loc(fs, group, &super_blk, + &old_desc_blk, &new_desc_blk, 0); + + if (fs->super->s_feature_incompat & EXT2_FEATURE_INCOMPAT_META_BG) + old_desc_blocks = fs->super->s_first_meta_bg; + else + old_desc_blocks = fs->desc_blocks; + + if (super_blk || (group == 0)) + ext2fs_mark_block_bitmap(bmap, super_blk); + + if (old_desc_blk) { + for (j=0; j < old_desc_blocks; j++) + ext2fs_mark_block_bitmap(bmap, old_desc_blk + j); + } + if (new_desc_blk) + ext2fs_mark_block_bitmap(bmap, new_desc_blk); + + return num_blocks; +} diff --git a/lib/ext2fs/closefs.c b/lib/ext2fs/closefs.c index 74acbeab..56be2923 100644 --- a/lib/ext2fs/closefs.c +++ b/lib/ext2fs/closefs.c @@ -45,6 +45,74 @@ int ext2fs_bg_has_super(ext2_filsys fs, int group_block) return 0; } +int ext2fs_super_and_bgd_loc(ext2_filsys fs, + dgrp_t group, + blk_t *ret_super_blk, + blk_t *ret_old_desc_blk, + blk_t *ret_new_desc_blk, + int *ret_meta_bg) +{ + blk_t group_block, super_blk = 0, old_desc_blk = 0, new_desc_blk = 0; + int numblocks, j, has_super, meta_bg_size, meta_bg; + int old_desc_blocks; + + group_block = fs->super->s_first_data_block + + (group * fs->super->s_blocks_per_group); + + if (fs->super->s_feature_incompat & EXT2_FEATURE_INCOMPAT_META_BG) + old_desc_blocks = fs->super->s_first_meta_bg; + else + old_desc_blocks = fs->desc_blocks; + + if (group == fs->group_desc_count-1) { + numblocks = (fs->super->s_blocks_count - + fs->super->s_first_data_block) % + fs->super->s_blocks_per_group; + if (!numblocks) + numblocks = fs->super->s_blocks_per_group; + } else + numblocks = fs->super->s_blocks_per_group; + + has_super = ext2fs_bg_has_super(fs, group); + + if (has_super) { + super_blk = group_block; + numblocks--; + } + meta_bg_size = (fs->blocksize / sizeof (struct ext2_group_desc)); + meta_bg = group / meta_bg_size; + + if (!(fs->super->s_feature_incompat & EXT2_FEATURE_INCOMPAT_META_BG) || + (meta_bg < fs->super->s_first_meta_bg)) { + if (has_super) { + old_desc_blk = group_block + 1; + numblocks -= old_desc_blocks; + } + } else { + if (((group % meta_bg_size) == 0) || + ((group % meta_bg_size) == 1) || + ((group % meta_bg_size) == (meta_bg_size-1))) { + if (has_super) + has_super = 1; + new_desc_blk = group_block + has_super; + numblocks--; + } + } + + numblocks -= 2 + fs->inode_blocks_per_group; + + if (ret_super_blk) + *ret_super_blk = super_blk; + if (ret_old_desc_blk) + *ret_old_desc_blk = old_desc_blk; + if (ret_new_desc_blk) + *ret_new_desc_blk = new_desc_blk; + if (ret_meta_bg) + *ret_meta_bg = meta_bg; + return (numblocks); +} + + /* * This function forces out the primary superblock. We need to only * write out those fields which we have changed, since if the @@ -113,53 +181,6 @@ void ext2fs_update_dynamic_rev(ext2_filsys fs) /* other fields should be left alone */ } -/* - * This writes out the block group descriptors the original, - * old-fashioned way. - */ -static errcode_t write_bgdesc(ext2_filsys fs, dgrp_t group, blk_t group_block, - struct ext2_group_desc *group_shadow) -{ - errcode_t retval; - char *group_ptr = (char *) group_shadow; - int j, old_desc_blocks, mod; - int has_super = ext2fs_bg_has_super(fs, group); - dgrp_t meta_bg_size, meta_bg; - - meta_bg_size = (fs->blocksize / sizeof (struct ext2_group_desc)); - meta_bg = group / meta_bg_size; - if (fs->super->s_feature_incompat & EXT2_FEATURE_INCOMPAT_META_BG) - old_desc_blocks = fs->super->s_first_meta_bg; - else - old_desc_blocks = fs->desc_blocks; - if (!(fs->super->s_feature_incompat & EXT2_FEATURE_INCOMPAT_META_BG) || - (meta_bg < fs->super->s_first_meta_bg)) { - if (!has_super || - ((fs->flags & EXT2_FLAG_MASTER_SB_ONLY) && (group != 0))) - return 0; - for (j=0; j < old_desc_blocks; j++) { - retval = io_channel_write_blk(fs->io, - group_block+1+j, 1, - group_ptr); - if (retval) - return retval; - group_ptr += fs->blocksize; - } - } else { - if (has_super) - group_block++; - mod = group % meta_bg_size; - if ((mod == 0) || (mod == 1) || (mod == (meta_bg_size-1))) { - if (mod && (fs->flags & EXT2_FLAG_MASTER_SB_ONLY)) - return 0; - return io_channel_write_blk(fs->io, group_block, - 1, group_ptr + (meta_bg*fs->blocksize)); - } - } - return 0; -} - - static errcode_t write_backup_super(ext2_filsys fs, dgrp_t group, blk_t group_block, struct ext2_super_block *super_shadow) @@ -189,6 +210,8 @@ errcode_t ext2fs_flush(ext2_filsys fs) struct ext2_super_block *super_shadow = 0; struct ext2_group_desc *group_shadow = 0; struct ext2_group_desc *s, *t; + char *group_ptr; + int old_desc_blocks; EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS); @@ -266,20 +289,40 @@ errcode_t ext2fs_flush(ext2_filsys fs) * superblocks and group descriptors. */ group_block = fs->super->s_first_data_block; + group_ptr = (char *) group_shadow; + if (fs->super->s_feature_incompat & EXT2_FEATURE_INCOMPAT_META_BG) + old_desc_blocks = fs->super->s_first_meta_bg; + else + old_desc_blocks = fs->desc_blocks; + for (i = 0; i < fs->group_desc_count; i++) { - if (!(fs->flags & EXT2_FLAG_MASTER_SB_ONLY) && - i && ext2fs_bg_has_super(fs, i)) { - retval = write_backup_super(fs, i, group_block, + blk_t super_blk, old_desc_blk, new_desc_blk; + int meta_bg; + + ext2fs_super_and_bgd_loc(fs, i, &super_blk, &old_desc_blk, + &new_desc_blk, &meta_bg); + + if (!(fs->flags & EXT2_FLAG_MASTER_SB_ONLY) &&i && super_blk) { + retval = write_backup_super(fs, i, super_blk, super_shadow); if (retval) goto errout; } - if (!(fs->flags & EXT2_FLAG_SUPER_ONLY)) { - if ((retval = write_bgdesc(fs, i, group_block, - group_shadow))) + if (fs->flags & EXT2_FLAG_SUPER_ONLY) + continue; + if ((old_desc_blk) && + (!(fs->flags & EXT2_FLAG_MASTER_SB_ONLY) || (i == 0))) { + retval = io_channel_write_blk(fs->io, + old_desc_blk, old_desc_blocks, group_ptr); + if (retval) + goto errout; + } + if (new_desc_blk) { + retval = io_channel_write_blk(fs->io, new_desc_blk, + 1, group_ptr + (meta_bg*fs->blocksize)); + if (retval) goto errout; } - group_block += EXT2_BLOCKS_PER_GROUP(fs->super); } fs->super->s_block_group_nr = 0; diff --git a/lib/ext2fs/ext2fs.h b/lib/ext2fs/ext2fs.h index 77b2de7d..d0bd2807 100644 --- a/lib/ext2fs/ext2fs.h +++ b/lib/ext2fs/ext2fs.h @@ -463,6 +463,11 @@ extern errcode_t ext2fs_get_free_blocks(ext2_filsys fs, blk_t start, extern errcode_t ext2fs_alloc_block(ext2_filsys fs, blk_t goal, char *block_buf, blk_t *ret); +/* alloc_sb.c */ +extern int ext2fs_reserve_super_and_bgd(ext2_filsys fs, + dgrp_t group, + ext2fs_block_bitmap bmap); + /* alloc_stats.c */ void ext2fs_inode_alloc_stats(ext2_filsys fs, ext2_ino_t ino, int inuse); void ext2fs_inode_alloc_stats2(ext2_filsys fs, ext2_ino_t ino, @@ -588,6 +593,12 @@ extern errcode_t ext2fs_check_desc(ext2_filsys fs); extern errcode_t ext2fs_close(ext2_filsys fs); extern errcode_t ext2fs_flush(ext2_filsys fs); extern int ext2fs_bg_has_super(ext2_filsys fs, int group_block); +extern int ext2fs_super_and_bgd_loc(ext2_filsys fs, + dgrp_t group, + blk_t *ret_super_blk, + blk_t *ret_old_desc_blk, + blk_t *ret_new_desc_blk, + int *ret_meta_bg); extern void ext2fs_update_dynamic_rev(ext2_filsys fs); /* cmp_bitmaps.c */ diff --git a/lib/ext2fs/initialize.c b/lib/ext2fs/initialize.c index 843afff0..d1cb7506 100644 --- a/lib/ext2fs/initialize.c +++ b/lib/ext2fs/initialize.c @@ -73,7 +73,6 @@ errcode_t ext2fs_initialize(const char *name, int flags, int i, j; blk_t numblocks; char *buf; - int meta_bg_size, meta_bg, has_super, old_desc_blocks; if (!param || !param->s_blocks_count) return EXT2_ET_INVALID_ARGUMENT; @@ -310,53 +309,9 @@ retry: */ group_block = super->s_first_data_block; super->s_free_blocks_count = 0; - if (fs->super->s_feature_incompat & EXT2_FEATURE_INCOMPAT_META_BG) - old_desc_blocks = fs->super->s_first_meta_bg; - else - old_desc_blocks = fs->desc_blocks; for (i = 0; i < fs->group_desc_count; i++) { - if (i == fs->group_desc_count-1) { - numblocks = (fs->super->s_blocks_count - - fs->super->s_first_data_block) % - fs->super->s_blocks_per_group; - if (!numblocks) - numblocks = fs->super->s_blocks_per_group; - } else - numblocks = fs->super->s_blocks_per_group; + numblocks = ext2fs_reserve_super_and_bgd(fs, i, fs->block_map); - has_super = ext2fs_bg_has_super(fs, i); - - if (has_super) { - ext2fs_mark_block_bitmap(fs->block_map, group_block); - numblocks--; - } - meta_bg_size = (fs->blocksize / - sizeof (struct ext2_group_desc)); - meta_bg = i / meta_bg_size; - - if (!(fs->super->s_feature_incompat & - EXT2_FEATURE_INCOMPAT_META_BG) || - (meta_bg < fs->super->s_first_meta_bg)) { - if (has_super) { - for (j=0; j < old_desc_blocks; j++) - ext2fs_mark_block_bitmap(fs->block_map, - group_block + j + 1); - numblocks -= old_desc_blocks; - } - } else { - if (has_super) - has_super = 1; - if (((i % meta_bg_size) == 0) || - ((i % meta_bg_size) == 1) || - ((i % meta_bg_size) == (meta_bg_size-1))) { - ext2fs_mark_block_bitmap(fs->block_map, - group_block + has_super); - numblocks--; - } - } - - numblocks -= 2 + fs->inode_blocks_per_group; - super->s_free_blocks_count += numblocks; fs->group_desc[i].bg_free_blocks_count = numblocks; fs->group_desc[i].bg_free_inodes_count = diff --git a/misc/ChangeLog b/misc/ChangeLog index 69734315..98ec8207 100644 --- a/misc/ChangeLog +++ b/misc/ChangeLog @@ -1,3 +1,9 @@ +2003-09-03 Theodore Ts'o + + * dumpe2fs.c (list_desc): Use ext2fs_super_and_bgd_loc to + determine the locations of the superblock and block group + descriptors. + 2003-11-20 Theodore Ts'o * util.c (check_plausibility): Support 2.6 kernel header files, diff --git a/misc/dumpe2fs.c b/misc/dumpe2fs.c index 073238e4..d04fe16b 100644 --- a/misc/dumpe2fs.c +++ b/misc/dumpe2fs.c @@ -86,9 +86,10 @@ static void list_desc (ext2_filsys fs) unsigned long i; long diff; blk_t group_blk, next_blk; + blk_t super_blk, old_desc_blk, new_desc_blk; char *block_bitmap=NULL, *inode_bitmap=NULL; int inode_blocks_per_group, old_desc_blocks; - int meta_bg, meta_bg_size, has_super; + int has_super; if (fs->block_map) block_bitmap = fs->block_map->bitmap; @@ -106,43 +107,32 @@ static void list_desc (ext2_filsys fs) else old_desc_blocks = fs->desc_blocks; for (i = 0; i < fs->group_desc_count; i++) { + ext2fs_super_and_bgd_loc(fs, i, &super_blk, + &old_desc_blk, &new_desc_blk, 0); next_blk = group_blk + fs->super->s_blocks_per_group; if (next_blk > fs->super->s_blocks_count) next_blk = fs->super->s_blocks_count; printf (_("Group %lu: (Blocks "), i); printf(range_format, group_blk, next_blk - 1); fputs(")\n", stdout); - has_super = ext2fs_bg_has_super(fs, i); + has_super = ((i==0) || super_blk); if (has_super) { printf (_(" %s superblock at "), i == 0 ? _("Primary") : _("Backup")); - printf(num_format, group_blk); + printf(num_format, super_blk); } - meta_bg_size = (fs->blocksize / - sizeof (struct ext2_group_desc)); - meta_bg = i / meta_bg_size; - if (!(fs->super->s_feature_incompat & - EXT2_FEATURE_INCOMPAT_META_BG) || - (meta_bg < fs->super->s_first_meta_bg)) { - if (has_super) { - printf(_(", Group descriptors at ")); - printf(range_format, group_blk+1, - group_blk + old_desc_blocks); - fputc('\n', stdout); - } - } else { - if (has_super) - has_super = 1; - if (((i % meta_bg_size) == 0) || - ((i % meta_bg_size) == 1) || - ((i % meta_bg_size) == (meta_bg_size-1))) { - fputc(has_super ? ',' : ' ', stdout); - printf(_(" Group descriptor at ")); - printf(num_format, group_blk + has_super); - fputc('\n', stdout); - } else if (has_super) - fputc('\n', stdout); + if (old_desc_blk) { + printf(_(", Group descriptors at ")); + printf(range_format, old_desc_blk, + old_desc_blk + old_desc_blocks - 1); + } else if (new_desc_blk) { + fputc(has_super ? ',' : ' ', stdout); + printf(_(" Group descriptor at ")); + printf(num_format, new_desc_blk); + has_super++; } + if (has_super) + fputc('\n', stdout); fputs(_(" Block bitmap at "), stdout); printf(num_format, fs->group_desc[i].bg_block_bitmap); diff = fs->group_desc[i].bg_block_bitmap - group_blk;