Whamcloud - gitweb
Don't write changes to the backup superblocks by default
[tools/e2fsprogs.git] / e2fsck / unix.c
index 7a617cf..72091f8 100644 (file)
@@ -523,7 +523,7 @@ static void parse_extended_opts(e2fsck_t ctx, const char *opts)
                if (p) {
                        *p = 0;
                        next = p+1;
-               } 
+               }
                arg = strchr(token, '=');
                if (arg) {
                        *arg = 0;
@@ -549,6 +549,8 @@ static void parse_extended_opts(e2fsck_t ctx, const char *opts)
                        extended_usage++;
                }
        }
+       free(buf);
+
        if (extended_usage) {
                fputs(("\nExtended options are separated by commas, "
                       "and may take an argument which\n"
@@ -557,7 +559,7 @@ static void parse_extended_opts(e2fsck_t ctx, const char *opts)
                       "\tea_ver=<ea_version (1 or 2)>\n\n"), stderr);
                exit(1);
        }
-}      
+}
 
 static void syntax_err_report(const char *filename, long err, int line_num)
 {
@@ -600,8 +602,8 @@ static errcode_t PRS(int argc, char *argv[], e2fsck_t *ret_ctx)
        }
        memset(bar, '=', sizeof(bar)-1);
        memset(spaces, ' ', sizeof(spaces)-1);
-       initialize_ext2_error_table();
-       initialize_prof_error_table();
+       add_error_table(&et_ext2_error_table);
+       add_error_table(&et_prof_error_table);
        blkid_get_cache(&ctx->blkid, NULL);
        
        if (argc && *argv)
@@ -810,19 +812,22 @@ static errcode_t PRS(int argc, char *argv[], e2fsck_t *ret_ctx)
        /* Update our PATH to include /sbin if we need to run badblocks  */
        if (cflag) {
                char *oldpath = getenv("PATH");
+               char *newpath;
+               int len = sizeof(PATH_SET) + 1;
+
+               if (oldpath)
+                       len += strlen(oldpath);
+
+               newpath = malloc(len);
+               if (!newpath)
+                       fatal_error(ctx, "Couldn't malloc() newpath");
+               strcpy(newpath, PATH_SET);
+
                if (oldpath) {
-                       char *newpath;
-
-                       newpath = (char *) malloc(sizeof (PATH_SET) + 1 +
-                                                 strlen (oldpath));
-                       if (!newpath)
-                               fatal_error(ctx, "Couldn't malloc() newpath");
-                       strcpy (newpath, PATH_SET);
-                       strcat (newpath, ":");
-                       strcat (newpath, oldpath);
-                       putenv (newpath);
-               } else
-                       putenv (PATH_SET);
+                       strcat(newpath, ":");
+                       strcat(newpath, oldpath);
+               }
+               putenv(newpath);
        }
 #ifdef CONFIG_JBD_DEBUG
        if (getenv("E2FSCK_JBD_DEBUG"))
@@ -976,6 +981,54 @@ restart:
                        fix_problem(ctx, PR_0_SB_CORRUPT, &pctx);
                fatal_error(ctx, 0);
        }
+       /*
+        * We only update the master superblock because (a) paranoia;
+        * we don't want to corrupt the backup superblocks, and (b) we
+        * don't need to update the mount count and last checked
+        * fields in the backup superblock (the kernel doesn't update
+        * the backup superblocks anyway).  With newer versions of the
+        * library this flag is set by ext2fs_open2(), but we set this
+        * here just to be sure.  (No, we don't support e2fsck running
+        * with some other libext2fs than the one that it was shipped
+        * with, but just in case....)
+        */
+       fs->flags |= EXT2_FLAG_MASTER_SB_ONLY;
+
+       if (!(ctx->flags & E2F_FLAG_GOT_DEVSIZE)) {
+               __u32 blocksize = EXT2_BLOCK_SIZE(fs->super);
+               int need_restart = 0;
+
+               pctx.errcode = ext2fs_get_device_size(ctx->filesystem_name,
+                                                     blocksize,
+                                                     &ctx->num_blocks);
+               /*
+                * The floppy driver refuses to allow anyone else to
+                * open the device if has been opened with O_EXCL;
+                * this is unlike other block device drivers in Linux.
+                * To handle this, we close the filesystem and then
+                * reopen the filesystem after we get the device size.
+                */
+               if (pctx.errcode == EBUSY) {
+                       ext2fs_close(fs);
+                       need_restart++;
+                       pctx.errcode = 
+                               ext2fs_get_device_size(ctx->filesystem_name, 
+                                                      blocksize,
+                                                      &ctx->num_blocks);
+               }
+               if (pctx.errcode == EXT2_ET_UNIMPLEMENTED)
+                       ctx->num_blocks = 0;
+               else if (pctx.errcode) {
+                       fix_problem(ctx, PR_0_GETSIZE_ERROR, &pctx);
+                       ctx->flags |= E2F_FLAG_ABORT;
+                       fatal_error(ctx, 0);
+                       return;
+               }
+               ctx->flags |= E2F_FLAG_GOT_DEVSIZE;
+               if (need_restart)
+                       goto restart;
+       }
+
        ctx->fs = fs;
        fs->priv_data = ctx;
        fs->now = ctx->now;
@@ -1086,15 +1139,6 @@ restart:
            !(ctx->options & E2F_OPT_READONLY))
                ext2fs_mark_super_dirty(fs);
 
-       /*
-        * We only update the master superblock because (a) paranoia;
-        * we don't want to corrupt the backup superblocks, and (b) we
-        * don't need to update the mount count and last checked
-        * fields in the backup superblock (the kernel doesn't
-        * update the backup superblocks anyway).
-        */
-       fs->flags |= EXT2_FLAG_MASTER_SB_ONLY;
-
        ehandler_init(fs->io);
 
        if (ctx->superblock)
@@ -1221,5 +1265,7 @@ restart:
                print_resource_track(NULL, &ctx->global_rtrack);
 #endif
        e2fsck_free_context(ctx);
+       remove_error_table(&et_ext2_error_table);
+       remove_error_table(&et_prof_error_table);
        return exit_value;
 }