ChangeLog, recovery.c, revoke.c:
  recovery.c, revoke.c: Synchronize with 0.6b ext3 files.

diff --git a/e2fsck/ChangeLog b/e2fsck/ChangeLog
index 2749884..6b199ec 100644
--- a/e2fsck/ChangeLog
+++ b/e2fsck/ChangeLog
@@ -1,3 +1,7 @@
+2001-03-29  Theodore Tso  <tytso@valinux.com>
+
+	* recovery.c, revoke.c: Synchronize with 0.6b ext3 files.
+
 2001-02-12  Theodore Tso  <tytso@valinux.com>
 
 	* journal.c (e2fsck_run_ext3_journal): Force a flush of the
diff --git a/e2fsck/recovery.c b/e2fsck/recovery.c
index 8ad13b8..5630f13 100644
--- a/e2fsck/recovery.c
+++ b/e2fsck/recovery.c
@@ -65,13 +65,13 @@
  * fixed value.
  */
 
+#define MAXBUF 8
 static int do_readahead(journal_t *journal, unsigned int start)
 {
 	int err;
 	unsigned int max, nbufs, next, blocknr;
 	struct buffer_head *bh;
 	
-#define MAXBUF 8
 	struct buffer_head * bufs[MAXBUF];
 	
 	/* Do up to 128K of readahead */
@@ -226,11 +226,10 @@
 	journal_superblock_t *	sb;
 
 	struct recovery_info	info;
-
-	memset(&info, 0, sizeof(info));
 	
+	memset(&info, 0, sizeof(info));
 	sb = journal->j_superblock;
-
+	
 	/* 
 	 * The journal superblock's s_start field (the current log head)
 	 * is always zero if, and only if, the journal was cleanly
@@ -266,6 +265,47 @@
 	return err;
 }
 
+/*
+ * journal_skip_recovery
+ *
+ * Locate any valid recovery information from the journal and set up the
+ * journal structures in memory to ignore it (presumably because the
+ * caller has evidence that it is out of date).  
+ *
+ * We perform one pass over the journal to allow us to tell the user how
+ * much recovery information is being erased, and to let us initialise
+ * the journal transaction sequence numbers to the next unused ID. 
+ */
+
+int journal_skip_recovery(journal_t *journal)
+{
+	int			err;
+	journal_superblock_t *	sb;
+
+	struct recovery_info	info;
+	
+	memset (&info, 0, sizeof(info));
+	sb = journal->j_superblock;
+	
+	err = do_one_pass(journal, &info, PASS_SCAN);
+
+	if (err) {
+		printk(KERN_ERR "JFS: error %d scanning journal\n", err);
+		++journal->j_transaction_sequence;
+	} else {
+		int dropped = info.end_transaction - ntohl(sb->s_sequence);
+		
+		jfs_debug(0, 
+			  "JFS: ignoring %d transaction%s from the journal.\n",
+			  dropped, (dropped == 1) ? "" : "s");
+		journal->j_transaction_sequence = ++info.end_transaction;
+	}
+
+	journal->j_tail = 0;
+	
+	return err;
+}
+
 static int do_one_pass(journal_t *journal, struct recovery_info *info,
 		       enum passtype pass)
 {
@@ -437,6 +477,7 @@
 					}
 					
 					mark_buffer_dirty(nbh, 1);
+					mark_buffer_uptodate(nbh, 1);
 					++info->nr_replays;
 					/* ll_rw_block(WRITE, 1, &nbh); */
 					brelse(obh);
@@ -530,7 +571,7 @@
 		unsigned long blocknr;
 		int err;
 		
-		blocknr = * ((unsigned int *) bh->b_data+offset);
+		blocknr = * ((unsigned int *) (bh->b_data+offset));
 		offset += 4;
 		err = journal_set_revoke(journal, blocknr, sequence);
 		if (err)
diff --git a/e2fsck/revoke.c b/e2fsck/revoke.c
index e53b69b..5e98f51 100644
--- a/e2fsck/revoke.c
+++ b/e2fsck/revoke.c
@@ -114,8 +114,7 @@
 		(block << (hash_shift - 12))) & (table->hash_size - 1);
 }
 
-static int insert_revoke_hash(journal_t *journal, unsigned long blocknr, 
-			      tid_t seq)
+int insert_revoke_hash(journal_t *journal, unsigned long blocknr, tid_t seq)
 {
 	struct list_head *hash_list;
 	struct jfs_revoke_record_s *record;
@@ -259,8 +258,10 @@
 	int err;
 
 	journal = handle->h_transaction->t_journal;
-	if (!journal_set_features(journal, 0, 0, JFS_FEATURE_INCOMPAT_REVOKE))
+	if (!journal_set_features(journal, 0, 0, JFS_FEATURE_INCOMPAT_REVOKE)){
+		J_ASSERT (!"Cannot set revoke feature!");
 		return -EINVAL;
+	}
 	
 	dev = journal->j_dev;
 	bh = bh_in;
@@ -350,10 +351,11 @@
 	struct jfs_revoke_record_s *record;
 	struct jfs_revoke_table_s *revoke;
 	struct list_head *hash_list;
-	int i, offset;
+	int i, offset, count;
 	
 	descriptor = NULL; 
 	offset = 0;
+	count = 0;
 	revoke = journal->j_revoke;
 	
 	for (i = 0; i < revoke->hash_size; i++) {
@@ -365,12 +367,14 @@
 			write_one_revoke_record(journal, transaction,
 						&descriptor, &offset, 
 						record);
+			count++;
 			list_del(&record->hash);
 			kmem_cache_free(revoke_record_cache, record);
 		}
 	}
 	if (descriptor) 
 		flush_descriptor(journal, descriptor, offset);
+	jfs_debug(1, "Wrote %d revoke records\n", count);
 }
 
 /*