#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"
_("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"
"%llu/%llu blocks\n"),
ctx->device_name, inodes_used, inodes,
frag_percent_total / 10, frag_percent_total % 10,
- blocks_used, blocks);
+ (unsigned long long) blocks_used,
+ (unsigned long long) blocks);
return;
}
profile_get_boolean(ctx->profile, "options", "report_features", 0, 0,
log_out(ctx, P_("%12llu block used (%2.2f%%, out of %llu)\n",
"%12llu blocks used (%2.2f%%, out of %llu)\n",
blocks_used),
- blocks_used, 100.0 * blocks_used / blocks, blocks);
+ (unsigned long long) blocks_used, 100.0 * blocks_used / blocks,
+ (unsigned long long) blocks);
log_out(ctx, P_("%12u bad block\n", "%12u bad blocks\n",
ctx->fs_badblocks_count), ctx->fs_badblocks_count);
log_out(ctx, P_("%12u large file\n", "%12u large files\n",
}
f = fopen("/proc/apm", "r");
if (f) {
- if (fscanf(f, "%s %s %s %x", tmp, tmp, tmp, &acflag) != 4)
+ if (fscanf(f, "%79s %79s %79s %x", tmp, tmp, tmp, &acflag) != 4)
acflag = 1;
fclose(f);
return (acflag != 1);
f = fopen(fname, "r");
if (!f)
continue;
- if (fscanf(f, "%s %s", tmp2, tmp) != 2)
+ if (fscanf(f, "%79s %79s", tmp2, tmp) != 2)
tmp[0] = 0;
fclose(f);
if (strncmp(tmp, "off-line", 8) == 0) {
ctx->device_name,
fs->super->s_inodes_count - fs->super->s_free_inodes_count,
fs->super->s_inodes_count,
- ext2fs_blocks_count(fs->super) -
+ (unsigned long long) ext2fs_blocks_count(fs->super) -
ext2fs_free_blocks_count(fs->super),
- ext2fs_blocks_count(fs->super));
+ (unsigned long long) ext2fs_blocks_count(fs->super));
next_check = 100000;
if (fs->super->s_max_mnt_count > 0) {
next_check = fs->super->s_max_mnt_count - fs->super->s_mnt_count;
ctx->options |= E2F_OPT_UNSHARE_BLOCKS;
ctx->options |= E2F_OPT_FORCE;
continue;
+ } else if (strcmp(token, "check_encoding") == 0) {
+ ctx->options |= E2F_OPT_CHECK_ENCODING;
+ continue;
#ifdef CONFIG_DEVELOPER_FEATURES
} else if (strcmp(token, "clear_all_uninit_bits") == 0) {
ctx->options |= E2F_OPT_CLEAR_UNINIT;
fputs("\tbmap2extent\n", stderr);
fputs("\tunshare_blocks\n", stderr);
fputs("\tfixes_only\n", stderr);
+ fputs("\tcheck_encoding\n", stderr);
fputc('\n', stderr);
exit(1);
}
#ifdef CONFIG_JBD_DEBUG
char *jbd_debug;
#endif
- unsigned long long phys_mem_kb;
+ unsigned long long phys_mem_kb, blk;
retval = e2fsck_allocate_context(&ctx);
if (retval)
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;
/* What we do by default, anyway! */
break;
case 'b':
- res = sscanf(optarg, "%llu", &ctx->use_superblock);
+ res = sscanf(optarg, "%llu", &blk);
+ ctx->use_superblock = blk;
if (res != 1)
goto sscanf_err;
ctx->flags |= E2F_FLAG_SB_SPECIFIED;
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'"),
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]);
errcode_t retval;
*ret_fs = NULL;
- if (ctx->superblock && ctx->blocksize) {
- retval = ext2fs_open2(ctx->filesystem_name, ctx->io_options,
- flags, ctx->superblock, ctx->blocksize,
- io_ptr, ret_fs);
- } else if (ctx->superblock) {
- int blocksize;
- for (blocksize = EXT2_MIN_BLOCK_SIZE;
- blocksize <= EXT2_MAX_BLOCK_SIZE; blocksize *= 2) {
- if (*ret_fs) {
- ext2fs_free(*ret_fs);
- *ret_fs = NULL;
+
+ if (ctx->superblock) {
+ unsigned long blocksize = ctx->blocksize;
+
+ if (!blocksize) {
+ for (blocksize = EXT2_MIN_BLOCK_SIZE;
+ blocksize <= EXT2_MAX_BLOCK_SIZE; blocksize *= 2) {
+
+ retval = ext2fs_open2(ctx->filesystem_name,
+ ctx->io_options, flags,
+ ctx->superblock, blocksize,
+ unix_io_manager, ret_fs);
+ if (*ret_fs) {
+ ext2fs_free(*ret_fs);
+ *ret_fs = NULL;
+ }
+ if (!retval)
+ break;
}
- retval = ext2fs_open2(ctx->filesystem_name,
- ctx->io_options, flags,
- ctx->superblock, blocksize,
- io_ptr, ret_fs);
- if (!retval)
- break;
+ if (retval)
+ return retval;
}
+
+ retval = ext2fs_open2(ctx->filesystem_name, ctx->io_options,
+ flags, ctx->superblock, blocksize,
+ io_ptr, ret_fs);
} else
retval = ext2fs_open2(ctx->filesystem_name, ctx->io_options,
flags, 0, 0, io_ptr, ret_fs);
__u32 features[3];
char *cp;
enum quota_type qtype;
+ struct ext2fs_journal_params jparams;
clear_problem_context(&pctx);
sigcatcher_setup();
fputs("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n",
ctx->problem_logf);
fprintf(ctx->problem_logf, "<problem_log time=\"%lu\">\n",
- ctx->now);
+ (unsigned long) ctx->now);
fprintf(ctx->problem_logf, "<invocation prog=\"%s\"",
argv[0]);
for (i = 1; i < argc; i++)
}
ctx->superblock = ctx->use_superblock;
- flags = EXT2_FLAG_SKIP_MMP;
+ flags = EXT2_FLAG_SKIP_MMP | EXT2_FLAG_THREADS;
restart:
#ifdef CONFIG_TESTIO_DEBUG
if (getenv("TEST_IO_FLAGS") || getenv("TEST_IO_BLOCK")) {
* so that we are able to recover from more errors
* (e.g. some tool messing up some value in the sb).
*/
- if ((retval == EXT2_ET_CORRUPT_SUPERBLOCK) &&
+ if (((retval == EXT2_ET_CORRUPT_SUPERBLOCK) ||
+ (retval == EXT2_ET_BAD_DESC_SIZE)) &&
!(flags & EXT2_FLAG_IGNORE_SB_ERRORS)) {
if (fs)
ext2fs_close_free(&fs);
* or informational messages to the user.
*/
if (ctx->device_name == 0 && sb->s_volume_name[0])
- ctx->device_name = string_copy(ctx, sb->s_volume_name,
+ ctx->device_name = string_copy(ctx, (char *) sb->s_volume_name,
sizeof(sb->s_volume_name));
if (ctx->device_name == 0)
/*
* Save the journal size in megabytes.
* Try and use the journal size from the backup else let e2fsck
- * find the default journal size.
+ * find the default journal size. If fast commit feature is enabled,
+ * it is not clear how many of the journal blocks were fast commit
+ * blocks. So, ignore the size of journal found in backup.
+ *
+ * TODO: Add a new backup type that captures fast commit info as
+ * well.
*/
- if (sb->s_jnl_backup_type == EXT3_JNL_BACKUP_BLOCKS)
+ if (sb->s_jnl_backup_type == EXT3_JNL_BACKUP_BLOCKS &&
+ !ext2fs_has_feature_fast_commit(sb))
journal_size = (sb->s_jnl_blocks[15] << (32 - 20)) |
(sb->s_jnl_blocks[16] >> 20);
else
if (!ctx->invalid_bitmaps &&
(ctx->flags & E2F_FLAG_JOURNAL_INODE)) {
if (fix_problem(ctx, PR_6_RECREATE_JOURNAL, &pctx)) {
- if (journal_size < 1024)
- journal_size = ext2fs_default_journal_size(ext2fs_blocks_count(fs->super));
- if (journal_size < 0) {
- ext2fs_clear_feature_journal(fs->super);
- fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;
- log_out(ctx, "%s: Couldn't determine "
- "journal size\n", ctx->program_name);
- goto no_journal;
+ if (journal_size < 1024) {
+ ext2fs_get_journal_params(&jparams, fs);
+ } else {
+ jparams.num_journal_blocks = journal_size;
+ jparams.num_fc_blocks = 0;
}
log_out(ctx, _("Creating journal (%d blocks): "),
- journal_size);
+ jparams.num_journal_blocks);
fflush(stdout);
- retval = ext2fs_add_journal_inode(fs,
- journal_size, 0);
+ retval = ext2fs_add_journal_inode3(fs, &jparams, ~0ULL, 0);
if (retval) {
log_out(ctx, "%s: while trying to create "
"journal\n", error_message(retval));
_("\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++) {
goto restart;
}
+cleanup:
#ifdef MTRACE
mtrace_print("Cleanup");
#endif