ChangeLog, journal.c:
  journal.c: Make sure all functions which return an error code use the
  	errcode_t return type, and not "int"
  	(e2fsck_journal_release): Add new parameter, "drop", which is used
  	when we just want to deallocate the journal without trying to write
  	out any changes.
  	(mark_buffer_clean): New function e2fsck_check_ext3_journal): If we
  	fail loading the journal, make sure we free all memory associated with
  	it.
  	(recover_ext3_journal): If we fail to load the journal or initialize
  	the revoke data structures, make sure we free all memory associated
  	with the journal.

diff --git a/e2fsck/ChangeLog b/e2fsck/ChangeLog
index 4d128a2..43a4daa 100644
--- a/e2fsck/ChangeLog
+++ b/e2fsck/ChangeLog
@@ -1,5 +1,17 @@
 2001-01-12  Theodore Ts'o  <tytso@valinux.com>
 
+	* journal.c: Make sure all functions which return an error code
+		use the errcode_t return type, and not "int"
+		(e2fsck_journal_release): Add new parameter, "drop",
+		which is used when we just want to deallocate the journal
+		without trying to write out any changes.
+		(mark_buffer_clean): New function
+		(e2fsck_check_ext3_journal): If we fail loading the
+		journal, make sure we free all memory associated with it.
+		(recover_ext3_journal): If we fail to load the journal or
+		initialize the revoke data structures, make sure we free all
+		memory associated with the journal.
+
 	* message.c (special_inode_name): Add more special inode names
 		(From Andreas Dilger)
 
diff --git a/e2fsck/journal.c b/e2fsck/journal.c
index 8b49e9c..5a83c06 100644
--- a/e2fsck/journal.c
+++ b/e2fsck/journal.c
@@ -116,6 +116,11 @@
 	bh->b_dirty = dummy | 1; /* use dummy to avoid unused variable */
 }
 
+static void mark_buffer_clean(struct buffer_head * bh)
+{
+	bh->b_dirty = 0;
+}
+
 void brelse(struct buffer_head *bh)
 {
 	if (bh->b_dirty)
@@ -147,10 +152,10 @@
 	ext2fs_mark_super_dirty(ctx->fs);
 }
 
-static int e2fsck_journal_init_inode(e2fsck_t ctx,
-				     struct ext2_super_block *s,
-				     ext2_ino_t journal_inum,
-				     journal_t **journal)
+static errcode_t e2fsck_journal_init_inode(e2fsck_t ctx,
+					   struct ext2_super_block *s,
+					   ext2_ino_t journal_inum,
+					   journal_t **journal)
 {
 	struct inode *inode;
 	struct buffer_head *bh;
@@ -206,7 +211,7 @@
 	return retval;
 }
 
-static int e2fsck_get_journal(e2fsck_t ctx, journal_t **journal)
+static errcode_t e2fsck_get_journal(e2fsck_t ctx, journal_t **journal)
 {
 	char uuid_str[40];
 	struct problem_context pctx;
@@ -259,8 +264,8 @@
 	return e2fsck_journal_init_inode(ctx, sb, sb->s_journal_inum, journal);
 }
 
-static int e2fsck_journal_fix_bad_inode(e2fsck_t ctx,
-					struct problem_context *pctx)
+static errcode_t e2fsck_journal_fix_bad_inode(e2fsck_t ctx,
+					      struct problem_context *pctx)
 {
 	struct ext2_super_block *sb = ctx->fs->super;
 	int recover = ctx->fs->super->s_feature_incompat &
@@ -291,8 +296,8 @@
 	return 0;
 }
 
-static int e2fsck_journal_fix_unsupported_super(e2fsck_t ctx,
-						struct problem_context *pctx)
+static errcode_t e2fsck_journal_fix_unsupported_super(e2fsck_t ctx,
+					      struct problem_context *pctx)
 {
 	struct ext2_super_block *sb = ctx->fs->super;
 
@@ -312,7 +317,7 @@
 	return 0;
 }
 
-static int e2fsck_journal_load(journal_t *journal)
+static errcode_t e2fsck_journal_load(journal_t *journal)
 {
 	e2fsck_t ctx = journal->j_dev;
 	journal_superblock_t *jsb;
@@ -395,7 +400,7 @@
 }
 
 static void e2fsck_journal_reset_super(e2fsck_t ctx, journal_superblock_t *jsb,
-				journal_t *journal)
+				       journal_t *journal)
 {
 	char *p;
 	
@@ -426,8 +431,9 @@
 	ll_rw_block(WRITE, 1, &journal->j_sb_buffer);
 }
 
-static int e2fsck_journal_fix_corrupt_super(e2fsck_t ctx, journal_t *journal,
-					    struct problem_context *pctx)
+static errcode_t e2fsck_journal_fix_corrupt_super(e2fsck_t ctx,
+						  journal_t *journal,
+						  struct problem_context *pctx)
 {
 	struct ext2_super_block *sb = ctx->fs->super;
 	int recover = ctx->fs->super->s_feature_incompat &
@@ -450,11 +456,14 @@
 	return 0;
 }
 
-static void e2fsck_journal_release(e2fsck_t ctx, journal_t *journal, int reset)
+static void e2fsck_journal_release(e2fsck_t ctx, journal_t *journal,
+				   int reset, int drop)
 {
 	journal_superblock_t *jsb;
 
-	if (!(ctx->options & E2F_OPT_READONLY)) {
+	if (drop)
+		mark_buffer_clean(journal->j_sb_buffer);
+	else if (!(ctx->options & E2F_OPT_READONLY)) {
 		jsb = journal->j_superblock;
 		jsb->s_sequence = htonl(journal->j_transaction_sequence);
 		if (reset)
@@ -464,7 +473,7 @@
 	brelse(journal->j_sb_buffer);
 
 	if (journal->j_inode)
-		free(journal->j_inode);
+		ext2fs_free_mem((void **)&journal->j_inode);
 	ext2fs_free_mem((void **)&journal);
 }
 
@@ -504,8 +513,9 @@
 	retval = e2fsck_journal_load(journal);
 	if (retval) {
 		if (retval == EXT2_ET_CORRUPT_SUPERBLOCK)
-			return e2fsck_journal_fix_corrupt_super(ctx, journal,
-								&pctx);
+			retval = e2fsck_journal_fix_corrupt_super(ctx, journal,
+								  &pctx);
+		e2fsck_journal_release(ctx, journal, 0, 1);
 		return retval;
 	}
 
@@ -561,11 +571,11 @@
 		 */
 	}
 
-	e2fsck_journal_release(ctx, journal, reset);
+	e2fsck_journal_release(ctx, journal, reset, 0);
 	return retval;
 }
 
-static int recover_ext3_journal(e2fsck_t ctx)
+static errcode_t recover_ext3_journal(e2fsck_t ctx)
 {
 	journal_t *journal;
 	int retval;
@@ -576,14 +586,15 @@
 
 	retval = e2fsck_journal_load(journal);
 	if (retval)
-		return retval;
+		goto errout;
 
 	retval = journal_init_revoke(journal, 1024);
 	if (retval)
-		return retval;
+		goto errout;
 	
 	retval = -journal_recover(journal);
-	e2fsck_journal_release(ctx, journal, 1);
+errout:
+	e2fsck_journal_release(ctx, journal, 1, 0);
 	return retval;
 }
 
@@ -596,7 +607,7 @@
  * which is a cheap way to force the kernel to run the journal and
  * handle the recovery for us.
  */
-static int recover_ext3_journal_via_mount(e2fsck_t ctx)
+static errcode_t recover_ext3_journal_via_mount(e2fsck_t ctx)
 {
 	ext2_filsys fs = ctx->fs;
 	char	*dirlist[] = {"/mnt","/lost+found","/tmp","/root","/boot",0};