* 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 */
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
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)
{
}
mark_buffer_dirty(nbh, 1);
+ mark_buffer_uptodate(nbh, 1);
++info->nr_replays;
/* ll_rw_block(WRITE, 1, &nbh); */
brelse(obh);
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)
(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;
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;
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++) {
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);
}
/*