From f1a1761d678a5ac539419f62676ce4c1bbd0767e Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Sun, 23 Dec 2001 22:27:52 -0500 Subject: [PATCH] Enhnaced the get backup superblock function so that it does the right thing if the filesystem superblock is unavailable; it will search for the superblock by iterating over possible blocksizes. --- TODO | 11 -------- e2fsck/ChangeLog | 14 ++++++++++ e2fsck/e2fsck.h | 4 ++- e2fsck/message.c | 2 +- e2fsck/unix.c | 10 +++---- e2fsck/util.c | 69 +++++++++++++++++++++++++++++++++++++++++++++--- 6 files changed, 88 insertions(+), 22 deletions(-) diff --git a/TODO b/TODO index c8440a310..8ce869e64 100644 --- a/TODO +++ b/TODO @@ -40,11 +40,6 @@ Add chmod command to debugfs. ------------------------------------------ -fix up get_backup_sb, so that it doesn't choose something bogus if -fs->super->.... is ridiculous - ----------------------------------- - Maybe a bug in debugfs v.1.14: if a file has more than one hardlink, only the first filename is shown when using command @@ -200,12 +195,6 @@ TODO list. check_if_mounted() should check to see if the file is in /proc/swaps, to avoid mkfs's or checking a active swap partition. ----------------------------------------------------------------- - -Add a check in configure.in on Linux systems making sure that -/usr/include/linux and /usr/include/asm exist. Otherwise you can have -some very obscure errors! - ----------------------------------------------------------------- Debugfs's link command should set the file type information diff --git a/e2fsck/ChangeLog b/e2fsck/ChangeLog index 9c0bc450d..9748f6503 100644 --- a/e2fsck/ChangeLog +++ b/e2fsck/ChangeLog @@ -1,5 +1,19 @@ 2001-12-23 Theodore Tso + * util.c (get_backup_sb): This function now searches for the + backup superblock by iterating over possible blocksizes + instead of defaulting a guess of 8193 if the superblock + isn't available. + + * message.c (expand_percent_expression), unix.c (main): Pass in + new parameters to get_backup_sb. Also, in unix.c, use the + blocksize paramter in the e2fsck context structure instead + of using a static variable, since get_backup_sb wants to + be able to set the blocksize paramter. + + * e2fsck.h: Update function prototype for get_backup_sb; also add + the blocksize parameter to the e2fsck context structure. + * Makefile.in, jfs_user.h: Move linux/jbd.h to ext2fs/kernel-jbd.h, to avoid using the system header file version of hbd.h when using diet glibc (since it diff --git a/e2fsck/e2fsck.h b/e2fsck/e2fsck.h index 2cadfca97..d3eeedf79 100644 --- a/e2fsck/e2fsck.h +++ b/e2fsck/e2fsck.h @@ -148,6 +148,7 @@ struct e2fsck_struct { int options; blk_t use_superblock; /* sb requested by user */ blk_t superblock; /* sb used to open fs */ + int blocksize; /* blocksize */ blk_t num_blocks; /* Total number of blocks */ #ifdef HAVE_SETJMP_H @@ -363,7 +364,8 @@ extern void e2fsck_write_inode(e2fsck_t ctx, unsigned long ino, #ifdef MTRACE extern void mtrace_print(char *mesg); #endif -extern blk_t get_backup_sb(ext2_filsys fs); +extern blk_t get_backup_sb(e2fsck_t ctx, ext2_filsys fs, + const char *name, io_manager manager); extern int ext2_file_type(unsigned int mode); /* unix.c */ diff --git a/e2fsck/message.c b/e2fsck/message.c index 3428e30e5..991bbee84 100644 --- a/e2fsck/message.c +++ b/e2fsck/message.c @@ -396,7 +396,7 @@ static _INLINE_ void expand_percent_expression(ext2_filsys fs, char ch, print_pathname(fs, ctx->dir, ctx->ino); break; case 'S': - printf("%d", get_backup_sb(fs)); + printf("%d", get_backup_sb(NULL, fs, NULL, NULL)); break; case 's': printf("%s", ctx->str ? ctx->str : "NULL"); diff --git a/e2fsck/unix.c b/e2fsck/unix.c index e811df679..43a235f35 100644 --- a/e2fsck/unix.c +++ b/e2fsck/unix.c @@ -42,7 +42,6 @@ extern int optind; #include "../version.h" /* Command line options */ -static int blocksize = 0; static int swapfs = 0; static int normalize_swapfs = 0; static int cflag = 0; /* check disk */ @@ -523,7 +522,7 @@ static errcode_t PRS(int argc, char *argv[], e2fsck_t *ret_ctx) ctx->flags |= E2F_FLAG_SB_SPECIFIED; break; case 'B': - blocksize = atoi(optarg); + ctx->blocksize = atoi(optarg); break; case 'I': ctx->inode_buffer_blocks = atoi(optarg); @@ -731,9 +730,10 @@ restart: if ((ctx->options & E2F_OPT_READONLY) == 0) flags |= EXT2_FLAG_RW; - if (ctx->superblock && blocksize) { + if (ctx->superblock && ctx->blocksize) { retval = ext2fs_open(ctx->filesystem_name, flags, - ctx->superblock, blocksize, io_ptr, &fs); + ctx->superblock, ctx->blocksize, + io_ptr, &fs); } else if (ctx->superblock) { for (i=0; possible_block_sizes[i]; i++) { retval = ext2fs_open(ctx->filesystem_name, flags, @@ -754,7 +754,7 @@ restart: printf(_("%s trying backup blocks...\n"), retval ? _("Couldn't find ext2 superblock,") : _("Group descriptors look bad...")); - ctx->superblock = get_backup_sb(fs); + get_backup_sb(ctx, fs, ctx->filesystem_name, io_ptr); if (fs) ext2fs_close(fs); goto restart; diff --git a/e2fsck/util.c b/e2fsck/util.c index 13fd9261a..e3a840cf9 100644 --- a/e2fsck/util.c +++ b/e2fsck/util.c @@ -318,11 +318,72 @@ void mtrace_print(char *mesg) } #endif -blk_t get_backup_sb(ext2_filsys fs) +blk_t get_backup_sb(e2fsck_t ctx, ext2_filsys fs, const char *name, + io_manager manager) { - if (!fs || !fs->super) - return 8193; - return fs->super->s_blocks_per_group + fs->super->s_first_data_block; + struct ext2_super_block *sb; + io_channel io = NULL; + void *buf; + int blocksize; + blk_t superblock, ret_sb = 8193; + + if (fs && fs->super) { + ret_sb = (fs->super->s_blocks_per_group + + fs->super->s_first_data_block); + if (ctx) { + ctx->superblock = ret_sb; + ctx->blocksize = fs->blocksize; + } + return ret_sb; + } + + if (ctx) { + if (ctx->blocksize) { + ret_sb = ctx->blocksize * 8; + if (ctx->blocksize == 1024) + ret_sb++; + ctx->superblock = ret_sb; + return ret_sb; + } + ctx->superblock = ret_sb; + ctx->blocksize = 1024; + } + + if (!name || !manager) + goto cleanup; + + if (manager->open(name, 0, &io) != 0) + goto cleanup; + + if (ext2fs_get_mem(SUPERBLOCK_SIZE, &buf)) + goto cleanup; + sb = (struct ext2_super_block *) buf; + + for (blocksize=1024; blocksize <= 8192 ; blocksize = blocksize*2) { + superblock = blocksize*8; + if (blocksize == 1024) + superblock++; + io_channel_set_blksize(io, blocksize); + if (io_channel_read_blk(io, superblock, + -SUPERBLOCK_SIZE, buf)) + continue; +#ifdef EXT2FS_ENABLE_SWAPFS + if (sb->s_magic == ext2fs_swab16(EXT2_SUPER_MAGIC)) + ext2fs_swap_super(sb); +#endif + if (sb->s_magic == EXT2_SUPER_MAGIC) { + ret_sb = ctx->superblock = superblock; + ctx->blocksize = blocksize; + break; + } + } + +cleanup: + if (io) + io_channel_close(io); + if (buf) + ext2fs_free_mem(&buf); + return (ret_sb); } /* -- 2.47.3