Exemple #1
0
static void ext2fs_journal_release(ext2_filsys fs, journal_t *journal,
				   int reset, int drop)
{
	journal_superblock_t *jsb;

	if (drop)
		mark_buffer_clean(journal->j_sb_buffer);
	else if (fs->flags & EXT2_FLAG_RW) {
		jsb = journal->j_superblock;
		jsb->s_sequence = htonl(journal->j_tail_sequence);
		if (reset)
			jsb->s_start = 0; /* this marks the journal as empty */
		ext2fs_journal_sb_csum_set(journal, jsb);
		mark_buffer_dirty(journal->j_sb_buffer);
	}
	brelse(journal->j_sb_buffer);

	if (fs && fs->journal_io) {
		if (fs->io != fs->journal_io)
			io_channel_close(fs->journal_io);
		fs->journal_io = NULL;
	}

#ifndef USE_INODE_IO
	if (journal->j_inode)
		ext2fs_free_mem(&journal->j_inode);
#endif
	if (journal->j_fs_dev)
		ext2fs_free_mem(&journal->j_fs_dev);
	ext2fs_free_mem(&journal);
}
Exemple #2
0
/*
 * This function makes sure that the superblock fields regarding the
 * journal are consistent.
 */
errcode_t ext2fs_check_ext3_journal(ext2_filsys fs)
{
	struct ext2_super_block *sb = fs->super;
	journal_t *journal;
	int recover = fs->super->s_feature_incompat &
		EXT3_FEATURE_INCOMPAT_RECOVER;
	errcode_t retval;

	/* If we don't have any journal features, don't do anything more */
	if (!(sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL) &&
	    !recover && sb->s_journal_inum == 0 && sb->s_journal_dev == 0 &&
	    uuid_is_null(sb->s_journal_uuid))
		return 0;

	retval = ext2fs_get_journal(fs, &journal);
	if (retval)
		return retval;

	retval = ext2fs_journal_load(journal);
	if (retval)
		goto err;

	/*
	 * We want to make the flags consistent here.  We will not leave with
	 * needs_recovery set but has_journal clear.  We can't get in a loop
	 * with -y, -n, or -p, only if a user isn't making up their mind.
	 */
	if (!(sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL)) {
		retval = EXT2_ET_JOURNAL_FLAGS_WRONG;
		goto err;
	}

	if (sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL &&
	    !(sb->s_feature_incompat & EXT3_FEATURE_INCOMPAT_RECOVER) &&
	    journal->j_superblock->s_start != 0) {
		retval = EXT2_ET_JOURNAL_FLAGS_WRONG;
		goto err;
	}

	/*
	 * If we don't need to do replay the journal, check to see if
	 * the journal's errno is set; if so, we need to mark the file
	 * system as being corrupt and clear the journal's s_errno.
	 */
	if (!(sb->s_feature_incompat & EXT3_FEATURE_INCOMPAT_RECOVER) &&
	    journal->j_superblock->s_errno) {
		fs->super->s_state |= EXT2_ERROR_FS;
		ext2fs_mark_super_dirty(fs);
		journal->j_superblock->s_errno = 0;
		ext2fs_journal_sb_csum_set(journal, journal->j_superblock);
		mark_buffer_dirty(journal->j_sb_buffer);
	}

err:
	ext2fs_journal_release(fs, journal, 0, retval ? 1 : 0);
	return retval;
}