Whamcloud - gitweb
Merge branch 'maint' into next
[tools/e2fsprogs.git] / e2fsck / unix.c
index 3708a4d..e5b672a 100644 (file)
@@ -52,6 +52,7 @@ extern int optind;
 #include "e2p/e2p.h"
 #include "uuid/uuid.h"
 #include "support/plausible.h"
+#include "support/devname.h"
 #include "e2fsck.h"
 #include "problem.h"
 #include "jfs_user.h"
@@ -78,7 +79,7 @@ static void usage(e2fsck_t ctx)
                _("Usage: %s [-panyrcdfktvDFV] [-b superblock] [-B blocksize]\n"
                "\t\t[-l|-L bad_blocks_file] [-C fd] [-j external_journal]\n"
                "\t\t[-E extended-options] [-z undo_file] device\n"),
-               ctx->program_name);
+               ctx->program_name ? ctx->program_name : "e2fsck");
 
        fprintf(stderr, "%s", _("\nEmergency help:\n"
                " -p                   Automatic repair (no questions)\n"
@@ -849,7 +850,7 @@ static errcode_t PRS(int argc, char *argv[], e2fsck_t *ret_ctx)
        if (argc && *argv)
                ctx->program_name = *argv;
        else
-               ctx->program_name = "e2fsck";
+               usage(NULL);
 
        phys_mem_kb = get_memory_size() / 1024;
        ctx->readahead_kb = ~0ULL;
@@ -939,8 +940,8 @@ static errcode_t PRS(int argc, char *argv[], e2fsck_t *ret_ctx)
                                goto sscanf_err;
                        break;
                case 'j':
-                       ctx->journal_name = blkid_get_devname(ctx->blkid,
-                                                             optarg, NULL);
+                       ctx->journal_name = get_devname(ctx->blkid,
+                                                       optarg, NULL);
                        if (!ctx->journal_name) {
                                com_err(ctx->program_name, 0,
                                        _("Unable to resolve '%s'"),
@@ -1019,7 +1020,7 @@ static errcode_t PRS(int argc, char *argv[], e2fsck_t *ret_ctx)
        ctx->io_options = strchr(argv[optind], '?');
        if (ctx->io_options)
                *ctx->io_options++ = 0;
-       ctx->filesystem_name = blkid_get_devname(ctx->blkid, argv[optind], 0);
+       ctx->filesystem_name = get_devname(ctx->blkid, argv[optind], 0);
        if (!ctx->filesystem_name) {
                com_err(ctx->program_name, 0, _("Unable to resolve '%s'"),
                        argv[optind]);
@@ -1953,15 +1954,82 @@ print_unsupp_features:
                                _("\n*** journal has been regenerated ***\n"));
                }
        }
-no_journal:
 
+no_journal:
        if (run_result & E2F_FLAG_ABORT) {
                fatal_error(ctx, _("aborted"));
        } else if (run_result & E2F_FLAG_CANCEL) {
                log_out(ctx, _("%s: e2fsck canceled.\n"), ctx->device_name ?
                        ctx->device_name : ctx->filesystem_name);
                exit_value |= FSCK_CANCELED;
-       } else if (ctx->qctx && !ctx->invalid_bitmaps) {
+               goto cleanup;
+       }
+
+       if (ext2fs_has_feature_orphan_file(fs->super)) {
+               int ret;
+
+               /* No point in orphan file without a journal... */
+               if (!ext2fs_has_feature_journal(fs->super) &&
+                   fix_problem(ctx, PR_6_ORPHAN_FILE_WITHOUT_JOURNAL, &pctx)) {
+                       retval = ext2fs_truncate_orphan_file(fs);
+                       if (retval) {
+                               /* Huh, failed to delete file */
+                               fix_problem(ctx, PR_6_ORPHAN_FILE_TRUNC_FAILED,
+                                           &pctx);
+                               goto check_quotas;
+                       }
+                       ext2fs_clear_feature_orphan_file(fs->super);
+                       ext2fs_mark_super_dirty(fs);
+                       goto check_quotas;
+               }
+               ret = check_init_orphan_file(ctx);
+               if (ret == 2 ||
+                   (ret == 0 && ext2fs_has_feature_orphan_present(fs->super) &&
+                    fix_problem(ctx, PR_6_ORPHAN_PRESENT_CLEAN_FILE, &pctx))) {
+                       ext2fs_clear_feature_orphan_present(fs->super);
+                       ext2fs_mark_super_dirty(fs);
+               } else if (ret == 1 &&
+                   fix_problem(ctx, PR_6_ORPHAN_FILE_CORRUPTED, &pctx)) {
+                       int orphan_file_blocks;
+
+                       if (ctx->invalid_bitmaps) {
+                               fix_problem(ctx,
+                                           PR_6_ORPHAN_FILE_BITMAP_INVALID,
+                                           &pctx);
+                               goto check_quotas;
+                       }
+
+                       retval = ext2fs_truncate_orphan_file(fs);
+                       if (retval) {
+                               /* Huh, failed to truncate file */
+                               fix_problem(ctx, PR_6_ORPHAN_FILE_TRUNC_FAILED,
+                                           &pctx);
+                               goto check_quotas;
+                       }
+
+                       orphan_file_blocks =
+                               ext2fs_default_orphan_file_blocks(fs);
+                       log_out(ctx, _("Creating orphan file (%d blocks): "),
+                               orphan_file_blocks);
+                       fflush(stdout);
+                       retval = ext2fs_create_orphan_file(fs,
+                                                          orphan_file_blocks);
+                       if (retval) {
+                               log_out(ctx, "%s: while trying to create "
+                                       "orphan file\n", error_message(retval));
+                               fix_problem(ctx, PR_6_ORPHAN_FILE_CREATE_FAILED,
+                                           &pctx);
+                               goto check_quotas;
+                       }
+                       log_out(ctx, "%s", _(" Done.\n"));
+               }
+       } else if (ext2fs_has_feature_orphan_present(fs->super) &&
+                  fix_problem(ctx, PR_6_ORPHAN_PRESENT_NO_FILE, &pctx)) {
+                       ext2fs_clear_feature_orphan_present(fs->super);
+                       ext2fs_mark_super_dirty(fs);
+       }
+check_quotas:
+       if (ctx->qctx && !ctx->invalid_bitmaps) {
                int needs_writeout;
 
                for (qtype = 0; qtype < MAXQUOTAS; qtype++) {
@@ -1996,6 +2064,7 @@ no_journal:
                goto restart;
        }
 
+cleanup:
 #ifdef MTRACE
        mtrace_print("Cleanup");
 #endif