OSDN Git Service

Enhnaced the get backup superblock function so that it does
authorTheodore Ts'o <tytso@mit.edu>
Mon, 24 Dec 2001 03:27:52 +0000 (22:27 -0500)
committerTheodore Ts'o <tytso@mit.edu>
Mon, 24 Dec 2001 03:27:52 +0000 (22:27 -0500)
the right thing if the filesystem superblock is unavailable;
it will search for the superblock by iterating over possible
blocksizes.

TODO
e2fsck/ChangeLog
e2fsck/e2fsck.h
e2fsck/message.c
e2fsck/unix.c
e2fsck/util.c

diff --git a/TODO b/TODO
index c8440a3..8ce869e 100644 (file)
--- 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
index 9c0bc45..9748f65 100644 (file)
@@ -1,5 +1,19 @@
 2001-12-23  Theodore Tso  <tytso@valinux.com>
 
+       * 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
index 2cadfca..d3eeedf 100644 (file)
@@ -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 */
index 3428e30..991bbee 100644 (file)
@@ -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");
index e811df6..43a235f 100644 (file)
@@ -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;
index 13fd926..e3a840c 100644 (file)
@@ -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);
 }
 
 /*