⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 e2fsck.c

📁 busybox最新版的源码:学习和应用的好东东,多的不说了,大家看后再说吧
💻 C
📖 第 1 页 / 共 5 页
字号:
			/*			 * Need a full fsck if we are releasing a			 * journal stored on a reserved inode.			 */			force_fsck = recover ||				(sb->s_journal_inum < EXT2_FIRST_INODE(sb));			/* Clear all of the journal fields */			sb->s_journal_inum = 0;			sb->s_journal_dev = 0;			memset(sb->s_journal_uuid, 0,			       sizeof(sb->s_journal_uuid));			e2fsck_clear_recover(ctx, force_fsck);		} else if (!(ctx->options & E2F_OPT_READONLY)) {			sb->s_feature_compat |= EXT3_FEATURE_COMPAT_HAS_JOURNAL;			ext2fs_mark_super_dirty(ctx->fs);		}	}	if (sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL &&	    !(sb->s_feature_incompat & EXT3_FEATURE_INCOMPAT_RECOVER) &&	    journal->j_superblock->s_start != 0) {		/* Print status information */		fix_problem(ctx, PR_0_JOURNAL_RECOVERY_CLEAR, &pctx);		if (ctx->superblock)			problem = PR_0_JOURNAL_RUN_DEFAULT;		else			problem = PR_0_JOURNAL_RUN;		if (fix_problem(ctx, problem, &pctx)) {			ctx->options |= E2F_OPT_FORCE;			sb->s_feature_incompat |=				EXT3_FEATURE_INCOMPAT_RECOVER;			ext2fs_mark_super_dirty(ctx->fs);		} else if (fix_problem(ctx,				       PR_0_JOURNAL_RESET_JOURNAL, &pctx)) {			reset = 1;			sb->s_state &= ~EXT2_VALID_FS;			ext2fs_mark_super_dirty(ctx->fs);		}		/*		 * If the user answers no to the above question, we		 * ignore the fact that journal apparently has data;		 * accidentally replaying over valid data would be far		 * worse than skipping a questionable recovery.		 *		 * XXX should we abort with a fatal error here?  What		 * will the ext3 kernel code do if a filesystem with		 * !NEEDS_RECOVERY but with a non-zero		 * journal->j_superblock->s_start is mounted?		 */	}	e2fsck_journal_release(ctx, journal, reset, 0);	return retval;}static errcode_t recover_ext3_journal(e2fsck_t ctx){	journal_t *journal;	int retval;	journal_init_revoke_caches();	retval = e2fsck_get_journal(ctx, &journal);	if (retval)		return retval;	retval = e2fsck_journal_load(journal);	if (retval)		goto errout;	retval = journal_init_revoke(journal, 1024);	if (retval)		goto errout;	retval = -journal_recover(journal);	if (retval)		goto errout;	if (journal->j_superblock->s_errno) {		ctx->fs->super->s_state |= EXT2_ERROR_FS;		ext2fs_mark_super_dirty(ctx->fs);		journal->j_superblock->s_errno = 0;		mark_buffer_dirty(journal->j_sb_buffer);	}errout:	journal_destroy_revoke(journal);	journal_destroy_revoke_caches();	e2fsck_journal_release(ctx, journal, 1, 0);	return retval;}static int e2fsck_run_ext3_journal(e2fsck_t ctx){	io_manager io_ptr = ctx->fs->io->manager;	int blocksize = ctx->fs->blocksize;	errcode_t       retval, recover_retval;	printf(_("%s: recovering journal\n"), ctx->device_name);	if (ctx->options & E2F_OPT_READONLY) {		printf(_("%s: won't do journal recovery while read-only\n"),		       ctx->device_name);		return EXT2_ET_FILE_RO;	}	if (ctx->fs->flags & EXT2_FLAG_DIRTY)		ext2fs_flush(ctx->fs);  /* Force out any modifications */	recover_retval = recover_ext3_journal(ctx);	/*	 * Reload the filesystem context to get up-to-date data from disk	 * because journal recovery will change the filesystem under us.	 */	ext2fs_close(ctx->fs);	retval = ext2fs_open(ctx->filesystem_name, EXT2_FLAG_RW,			     ctx->superblock, blocksize, io_ptr,			     &ctx->fs);	if (retval) {		bb_error_msg(_("while trying to re-open %s"),			ctx->device_name);		bb_error_msg_and_die(0);	}	ctx->fs->priv_data = ctx;	/* Set the superblock flags */	e2fsck_clear_recover(ctx, recover_retval);	return recover_retval;}/* * This function will move the journal inode from a visible file in * the filesystem directory hierarchy to the reserved inode if necessary. */static const char *const journal_names[] = {	".journal", "journal", ".journal.dat", "journal.dat", 0 };static void e2fsck_move_ext3_journal(e2fsck_t ctx){	struct ext2_super_block *sb = ctx->fs->super;	struct problem_context  pctx;	struct ext2_inode       inode;	ext2_filsys             fs = ctx->fs;	ext2_ino_t              ino;	errcode_t               retval;	const char *const *    cpp;	int                     group, mount_flags;	clear_problem_context(&pctx);	/*	 * If the filesystem is opened read-only, or there is no	 * journal, then do nothing.	 */	if ((ctx->options & E2F_OPT_READONLY) ||	    (sb->s_journal_inum == 0) ||	    !(sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL))		return;	/*	 * Read in the journal inode	 */	if (ext2fs_read_inode(fs, sb->s_journal_inum, &inode) != 0)		return;	/*	 * If it's necessary to backup the journal inode, do so.	 */	if ((sb->s_jnl_backup_type == 0) ||	    ((sb->s_jnl_backup_type == EXT3_JNL_BACKUP_BLOCKS) &&	     memcmp(inode.i_block, sb->s_jnl_blocks, EXT2_N_BLOCKS*4))) {		if (fix_problem(ctx, PR_0_BACKUP_JNL, &pctx)) {			memcpy(sb->s_jnl_blocks, inode.i_block,			       EXT2_N_BLOCKS*4);			sb->s_jnl_blocks[16] = inode.i_size;			sb->s_jnl_backup_type = EXT3_JNL_BACKUP_BLOCKS;			ext2fs_mark_super_dirty(fs);			fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;		}	}	/*	 * If the journal is already the hidden inode, then do nothing	 */	if (sb->s_journal_inum == EXT2_JOURNAL_INO)		return;	/*	 * The journal inode had better have only one link and not be readable.	 */	if (inode.i_links_count != 1)		return;	/*	 * If the filesystem is mounted, or we can't tell whether	 * or not it's mounted, do nothing.	 */	retval = ext2fs_check_if_mounted(ctx->filesystem_name, &mount_flags);	if (retval || (mount_flags & EXT2_MF_MOUNTED))		return;	/*	 * If we can't find the name of the journal inode, then do	 * nothing.	 */	for (cpp = journal_names; *cpp; cpp++) {		retval = ext2fs_lookup(fs, EXT2_ROOT_INO, *cpp,				       strlen(*cpp), 0, &ino);		if ((retval == 0) && (ino == sb->s_journal_inum))			break;	}	if (*cpp == 0)		return;	/* We need the inode bitmap to be loaded */	retval = ext2fs_read_bitmaps(fs);	if (retval)		return;	pctx.str = *cpp;	if (!fix_problem(ctx, PR_0_MOVE_JOURNAL, &pctx))		return;	/*	 * OK, we've done all the checks, let's actually move the	 * journal inode.  Errors at this point mean we need to force	 * an ext2 filesystem check.	 */	if ((retval = ext2fs_unlink(fs, EXT2_ROOT_INO, *cpp, ino, 0)) != 0)		goto err_out;	if ((retval = ext2fs_write_inode(fs, EXT2_JOURNAL_INO, &inode)) != 0)		goto err_out;	sb->s_journal_inum = EXT2_JOURNAL_INO;	ext2fs_mark_super_dirty(fs);	fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;	inode.i_links_count = 0;	inode.i_dtime = time(0);	if ((retval = ext2fs_write_inode(fs, ino, &inode)) != 0)		goto err_out;	group = ext2fs_group_of_ino(fs, ino);	ext2fs_unmark_inode_bitmap(fs->inode_map, ino);	ext2fs_mark_ib_dirty(fs);	fs->group_desc[group].bg_free_inodes_count++;	fs->super->s_free_inodes_count++;	return;err_out:	pctx.errcode = retval;	fix_problem(ctx, PR_0_ERR_MOVE_JOURNAL, &pctx);	fs->super->s_state &= ~EXT2_VALID_FS;	ext2fs_mark_super_dirty(fs);}/* * message.c --- print e2fsck messages (with compression) * * print_e2fsck_message() prints a message to the user, using * compression techniques and expansions of abbreviations. * * The following % expansions are supported: * *      %b      <blk>                   block number *      %B      <blkcount>              integer *      %c      <blk2>                  block number *      %Di     <dirent>->ino           inode number *      %Dn     <dirent>->name          string *      %Dr     <dirent>->rec_len *      %Dl     <dirent>->name_len *      %Dt     <dirent>->filetype *      %d      <dir>                   inode number *      %g      <group>                 integer *      %i      <ino>                   inode number *      %Is     <inode> -> i_size *      %IS     <inode> -> i_extra_isize *      %Ib     <inode> -> i_blocks *      %Il     <inode> -> i_links_count *      %Im     <inode> -> i_mode *      %IM     <inode> -> i_mtime *      %IF     <inode> -> i_faddr *      %If     <inode> -> i_file_acl *      %Id     <inode> -> i_dir_acl *      %Iu     <inode> -> i_uid *      %Ig     <inode> -> i_gid *      %j      <ino2>                  inode number *      %m      <com_err error message> *      %N      <num> *      %p      ext2fs_get_pathname of directory <ino> *      %P      ext2fs_get_pathname of <dirent>->ino with <ino2> as *                      the containing directory.  (If dirent is NULL *                      then return the pathname of directory <ino2>) *      %q      ext2fs_get_pathname of directory <dir> *      %Q      ext2fs_get_pathname of directory <ino> with <dir> as *                      the containing directory. *      %s      <str>                   miscellaneous string *      %S      backup superblock *      %X      <num> hexadecimal format * * The following '@' expansions are supported: * *      @a      extended attribute *      @A      error allocating *      @b      block *      @B      bitmap *      @c      compress *      @C      conflicts with some other fs block *      @D      deleted *      @d      directory *      @e      entry *      @E      Entry '%Dn' in %p (%i) *      @f      filesystem *      @F      for @i %i (%Q) is *      @g      group *      @h      HTREE directory inode *      @i      inode *      @I      illegal *      @j      journal *      @l      lost+found *      @L      is a link *      @m      multiply-claimed *      @n      invalid *      @o      orphaned *      @p      problem in *      @r      root inode *      @s      should be *      @S      superblock *      @u      unattached *      @v      device *      @z      zero-length *//* * This structure defines the abbreviations used by the text strings * below.  The first character in the string is the index letter.  An * abbreviation of the form '@<i>' is expanded by looking up the index * letter <i> in the table below. */static const char *const abbrevs[] = {	N_("aextended attribute"),	N_("Aerror allocating"),	N_("bblock"),	N_("Bbitmap"),	N_("ccompress"),	N_("Cconflicts with some other fs @b"),	N_("iinode"),	N_("Iillegal"),	N_("jjournal"),	N_("Ddeleted"),	N_("ddirectory"),	N_("eentry"),	N_("E@e '%Dn' in %p (%i)"),	N_("ffilesystem"),	N_("Ffor @i %i (%Q) is"),	N_("ggroup"),	N_("hHTREE @d @i"),	N_("llost+found"),	N_("Lis a link"),    N_("mmultiply-claimed"),    N_("ninvalid"),	N_("oorphaned"),	N_("pproblem in"),	N_("rroot @i"),	N_("sshould be"),	N_("Ssuper@b"),	N_("uunattached"),	N_("vdevice"),	N_("zzero-length"),	"@@",	0	};/* * Give more user friendly names to the "special" inodes. */#define num_special_inodes      11static const char *const special_inode_name[] ={	N_("<The NULL inode>"),                 /* 0 */	N_("<The bad blocks inode>"),           /* 1 */	"/",                                    /* 2 */	N_("<The ACL index inode>"),            /* 3 */	N_("<The ACL data inode>"),             /* 4 */	N_("<The boot loader inode>"),          /* 5 */	N_("<The undelete directory inode>"),   /* 6 */	N_("<The group descriptor inode>"),     /* 7 */	N_("<The journal inode>"),              /* 8 */	N_("<Reserved inode 9>"),               /* 9 */	N_("<Reserved inode 10>"),              /* 10 */};/* * This function does "safe" printing.  It will convert non-printable * ASCII characters using '^' and M- notation. */static void safe_print(const char *cp, int len){	unsigned char   ch;	if (len < 0)		len = strlen(cp);	while (len--) {		ch = *cp++;		if (ch > 128) {			fputs("M-", stdout);			ch -= 128;		}		if ((ch < 32) || (ch == 0x7f)) {			fputc('^', stdout);			ch ^= 0x40; /* ^@, ^A, ^B; ^? for DEL */		}		fputc(ch, stdout);	}}/* * This function prints a pathname, using the ext2fs_get_pathname * function */static void print_pathname(ext2_filsys fs, ext2_ino_t dir, ext2_ino_t ino){	errcode_t       retval;	char            *path;	if (!dir && (ino < num_special_inodes)) {		fputs(_(special_inode_name[ino]), stdout);		return;	}	retval = ext2fs_get_pathname(fs, dir, ino, &path);	if (retval)		fputs("???", stdout);	else {		safe_print(path, -1);		ext2fs_free_mem(&path);	}}static void print_e2fsck_message(e2fsck_t ctx, const char *msg,			  struct problem_context *pctx, int first);/* * This function handles the '@' expansion.  We allow recursive * expansion; an @ expression can contain further '@' and '%' * expressions. */static void expand_at_expression(e2fsck_t ctx, char ch,					  struct problem_context *pctx,					  int *first){	const char *const *cpp;	const char *str;	/* Search for the abbreviation */	for (cpp = abbrevs; *cpp; cpp++) {		if (ch == *cpp[0])			break;	}	if (*cpp) {		str = _(*cpp) + 1;		if (*first && islower(*str)) {			*first = 0;			fputc(toupper(*str++), stdout);		}		print_e2fsck_message(ctx, str, pctx, *first);	} else		printf("@%c", ch);}/* * This function expands '%IX' expressions */static void expand_inode_expression(char ch,					     struct problem_context *ctx){	struct ext2_inode       *inode;	struct ext2_inode_large *large_inode;	char *                  time_str;	time_t                  t;	int                     do_gmt = -1;	if (!ctx || !ctx->inode)		goto no_inode;	inode = ctx->inode;	large_inode = (struct ext2_inode_large *) inode;	switch (ch) {	case 's':		if (LINUX_S_ISDIR(inode->i_mode))			printf("%u", inode->i_size);		else {			printf("%"PRIu64, (inode->i_size |					((uint64_t) inode->i_size_high << 32)));		}		break;	case 'S':		printf("%u", large_inode->i_extra_isize);		break;	case 'b':		printf("%u", inode->i_blocks);		break;	case 'l':		printf("%d", inode->i_links_count);		break;	case 'm':		pr

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -