Subject: afs/fs/cachefs recycling.c,1.19,1.20 journal.c,1.31,1.32 index.c,1.17,1.18 dump-journal.c,1.9,1.10 cachefs-layout.h,1.23,1.24 cachefs-int.h,1.32,1.33 aops.c,1.29,1.30

From: [email-masked]
Date: Wed, 28 May 2003 11:32:57 +0100

Update of /home/cvs/afs/fs/cachefs
In directory phoenix.infradead.org:/tmp/cvs-serv28592/fs/cachefs

Modified Files:
	recycling.c journal.c index.c dump-journal.c cachefs-layout.h 
	cachefs-int.h aops.c 
Log Message:
start adding journal replaying back in

Index: recycling.c
===================================================================
RCS file: /home/cvs/afs/fs/cachefs/recycling.c,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -r1.19 -r1.20
--- recycling.c	23 May 2003 14:07:31 -0000	1.19
+++ recycling.c	28 May 2003 10:32:54 -0000	1.20
@@ -942,3 +942,53 @@
 	kleave(" [error %d]",ret);
 
 } /* end cachefs_recycle_unallocate_data_block() */
+
+/*****************************************************************************/
+/*
+ * 
+ */
+int cachefs_replay_ujnl_recyc_empty_node(struct cachefs_super *super,
+					 struct cachefs_ondisc_update_journal *jentry)
+{
+	return -ENOANO;
+} /* end cachefs_replay_ujnl_recyc_empty_node() */
+
+/*****************************************************************************/
+/*
+ * 
+ */
+int cachefs_replay_ujnl_recyc_begin_new(struct cachefs_super *super,
+					struct cachefs_ondisc_update_journal *jentry)
+{
+	return -ENOANO;
+} /* end cachefs_replay_ujnl_recyc_begin_new() */
+
+/*****************************************************************************/
+/*
+ * 
+ */
+int cachefs_replay_ujnl_recyc_transfer(struct cachefs_super *super,
+				       struct cachefs_ondisc_update_journal *jentry)
+{
+	return -ENOANO;
+} /* end cachefs_replay_ujnl_recyc_transfer() */
+
+/*****************************************************************************/
+/*
+ * 
+ */
+int cachefs_replay_ujnl_recyc_scavenge(struct cachefs_super *super,
+				       struct cachefs_ondisc_update_journal *jentry)
+{
+	return -ENOANO;
+} /* end cachefs_replay_ujnl_recyc_scavenge() */
+
+/*****************************************************************************/
+/*
+ * 
+ */
+int cachefs_replay_ujnl_recyc_makeready(struct cachefs_super *super,
+					struct cachefs_ondisc_update_journal *jentry)
+{
+	return -ENOANO;
+} /* end cachefs_replay_ujnl_recyc_makeready() */

Index: journal.c
===================================================================
RCS file: /home/cvs/afs/fs/cachefs/journal.c,v
retrieving revision 1.31
retrieving revision 1.32
diff -u -r1.31 -r1.32
--- journal.c	23 May 2003 12:59:21 -0000	1.31
+++ journal.c	28 May 2003 10:32:54 -0000	1.32
@@ -17,6 +17,15 @@
 #include <linux/bio.h>
 #include "cachefs-int.h"
 
+struct cachefs_replay_find_batch_desc {
+	read_descriptor_t	desc;
+	unsigned short		batch_first;	/* sector holding first entry in batch */
+	unsigned short		batch_end;	/* batch mark sector for ujnl_batch */
+	unsigned short		batch_ack;	/* batch ACK sector for ujnl_batch */
+	unsigned short		batch_count;	/* number of marks in batch */
+	unsigned		ack_hi;		/* highest batch with ACK number */
+};
+
 const char *cachefs_ondisc_ujnl_marks[] = {
 	"Null     ",
 	"Batch    ",
@@ -50,8 +59,8 @@
 static void cachefs_trans_batch_process_written_blocks(struct cachefs_super *super, int wait);
 
 static void cachefs_trans_batch_write_marker(struct cachefs_super *super,
-						   unsigned short jstop,
-						   struct cachefs_ondisc_update_journal *ajentry);
+					     unsigned short jstop,
+					     struct cachefs_ondisc_update_journal *ajentry);
 
 static void cachefs_trans_batch_write_ack(struct cachefs_super *super,
 					  unsigned short jstop,
@@ -67,6 +76,31 @@
 	}											\
 } while(0)
 
+typedef int (*cachefs_ujnl_replay_func_t)(struct cachefs_super *super,
+					  struct cachefs_ondisc_update_journal *jentry);
+
+static const cachefs_ujnl_replay_func_t cachefs_ujnl_replay_tbl[CACHEFS_ONDISC_UJNL__LAST] = {
+	[CACHEFS_ONDISC_UJNL_RECYC_EMPTY_NODE]	= cachefs_replay_ujnl_recyc_empty_node,
+	[CACHEFS_ONDISC_UJNL_RECYC_BEGIN_NEW]	= cachefs_replay_ujnl_recyc_begin_new,
+	[CACHEFS_ONDISC_UJNL_RECYC_TRANSFER]	= cachefs_replay_ujnl_recyc_transfer,
+	[CACHEFS_ONDISC_UJNL_RECYC_SCAVENGE]	= cachefs_replay_ujnl_recyc_scavenge,
+	[CACHEFS_ONDISC_UJNL_RECYC_MAKEREADY]	= cachefs_replay_ujnl_recyc_makeready,
+	[CACHEFS_ONDISC_UJNL_INODE_ALLOCING]	= cachefs_replay_ujnl_inode_allocing,
+	[CACHEFS_ONDISC_UJNL_INODE_UPDATING]	= cachefs_replay_ujnl_inode_updating,
+	[CACHEFS_ONDISC_UJNL_INODE_DELETING]	= cachefs_replay_ujnl_inode_deleting,
+	[CACHEFS_ONDISC_UJNL_INODE_MARK_RECLAIM]= cachefs_replay_ujnl_inode_mark_reclaim,
+	[CACHEFS_ONDISC_UJNL_INODE_RECLAIMING]	= cachefs_replay_ujnl_inode_reclaiming,
+	[CACHEFS_ONDISC_UJNL_DATA_ALLOCING]	= cachefs_replay_ujnl_data_allocing,
+	[CACHEFS_ONDISC_UJNL_DATA_WRITTEN]	= cachefs_replay_ujnl_data_written,
+	[CACHEFS_ONDISC_UJNL_DATA_UNALLOCING]	= cachefs_replay_ujnl_data_unallocing,
+	[CACHEFS_ONDISC_UJNL_INDIRECT_ALLOCING]	= cachefs_replay_ujnl_indirect_allocing,
+	[CACHEFS_ONDISC_UJNL_INDIRECT_FREEING]	= cachefs_replay_ujnl_indirect_freeing,
+	[CACHEFS_ONDISC_UJNL_INDEX_EXTENDING]	= cachefs_replay_ujnl_index_extending,
+	[CACHEFS_ONDISC_UJNL_INDEX_ALLOCING]	= cachefs_replay_ujnl_index_allocing,
+	[CACHEFS_ONDISC_UJNL_INDEX_MODIFYING]	= cachefs_replay_ujnl_index_modifying,
+	[CACHEFS_ONDISC_UJNL_INDEX_FREEING]	= cachefs_replay_ujnl_index_freeing,
+};
+
 /*****************************************************************************/
 /*
  * batch write timer callback
@@ -835,8 +869,8 @@
  * write a BATCH marker to the journal to indicate where the end of the batch is
  */
 static void cachefs_trans_batch_write_marker(struct cachefs_super *super,
-						   unsigned short jstop,
-						   struct cachefs_ondisc_update_journal *ajentry)
+					     unsigned short jstop,
+					     struct cachefs_ondisc_update_journal *ajentry)
 {
 	struct cachefs_ondisc_update_journal *jentry;
 	struct cachefs_block *jblock;
@@ -1208,7 +1242,7 @@
 void cachefs_trans_sync(struct cachefs_super *super, int wait)
 {
 	int16_t next_batch;
-	
+
 	DECLARE_WAITQUEUE(myself,current);
 
 	kenter("{batch=%hd}",super->ujnl_batch);
@@ -1244,7 +1278,7 @@
 		while (next_batch - super->ujnl_batch > 0) {
 			schedule();
 			set_current_state(TASK_UNINTERRUPTIBLE);
-		}		
+		}
 
 		remove_wait_queue(&super->batch_sync_wq,&myself);
 		set_current_state(TASK_RUNNING);
@@ -1259,59 +1293,131 @@
 
 /*****************************************************************************/
 /*
- * journal replay actor for determining the ACK window
- * - work out the bounds of the serial number window of the ACK'd and un-ACK'd parts of the journal
+ * journal replay actor for determining bounds of the latest batch of journal
+ * entries
+ * - each batch is a cyclically adjacent collection of entries with the same
+ *   batch number, hopefully ending in a BATCH mark and an ACK mark
  */
-static int cachefs_ujnl_replay_ackwin_actor(read_descriptor_t *desc, struct page *page,
-					    unsigned long offset, unsigned long size)
+static int cachefs_ujnl_find_batch_actor(read_descriptor_t *_desc,
+					 struct page *page,
+					 unsigned long offset,
+					 unsigned long size)
 {
-	BUG();
-#if 0
+	struct cachefs_replay_find_batch_desc *desc;
 	struct cachefs_ondisc_update_journal *jentry;
-	struct cachefs_super *super = (struct cachefs_super *) desc->buf;
+	struct cachefs_super *super = (struct cachefs_super *) _desc->buf;
 	unsigned short slot;
-	char *data;
+	u_int8_t *data;
+	int tmp;
 
-	_enter("{%x},{%lu},%lu,%lu",desc->count,page->index,offset,size);
+	desc = container_of(_desc,struct cachefs_replay_find_batch_desc,desc);
 
+	_enter("{%x},{%lu},%lu,%lu",desc->desc.count,page->index,offset,size);
 
 	BUG_ON(size!=PAGE_SIZE);
 	BUG_ON(offset!=0);
 
-	data = (char *) kmap(page);
+	data = (u_int8_t *) kmap(page);
 
-	/* just paste the values of the very first slot in directly */
 	slot = (page->index - super->layout->bix_ujournal) * super->layout->ujnl_recperblk;
 
 	while (offset<size) {
-		jentry = (struct cachefs_ondisc_update_journal *) (data+offset);
+		jentry = (struct cachefs_ondisc_update_journal *) (data + offset);
 
-		if (slot==0) {
-			_debug("UJNL[%04x] mk=%s s=%d a=%d",
+		if (slot == 0) {
+			/* just paste the values of the very first slot in directly */
+			_debug("UJNL[%04x] mk=%s s=%hu.%hu",
 			       slot,
 			       cachefs_ondisc_ujnl_marks[jentry->mark],
-			       jentry->serial,
-			       jentry->ack);
+			       (unsigned) jentry->batch,
+			       jentry->serial);
+
+			super->ujnl_batch	= jentry->batch;
+			super->ujnl_serial	= jentry->serial;
+			super->ujnl_head	= slot;
+			desc->batch_first	= ~0;
+			desc->batch_end		= ~0;
+			desc->batch_ack		= ~0;
+			desc->batch_count	= 1;
+
+			if (jentry->serial == 0) {
+				desc->batch_first = slot;
+				super->ujnl_tail = slot;
+			}
 
-			super->ujnl_mk_serial	= jentry->serial + 1;
-			super->ujnl_ack_disc	= jentry->ack + 1;
 		}
-		else if (jentry->mark==CACHEFS_ONDISC_UJNL_NULL) {
+		else if (jentry->mark == CACHEFS_ONDISC_UJNL_NULL) {
 			/* do nothing */
 		}
 		else {
-			_debug("UJNL[%04x] mk=%s s=%d a=%d { s=%d a=%d }",
+			_debug("UJNL[%04x] mk=%s s=%d a=%d { b=%d s=%u }",
 			       slot,
 			       cachefs_ondisc_ujnl_marks[jentry->mark],
 			       jentry->serial,
 			       jentry->ack,
-			       super->ujnl_mk_serial,
-			       super->ujnl_ack_disc);
+			       super->ujnl_batch,
+			       super->ujnl_serial);
 
-			if (super->ujnl_mk_serial - (jentry->serial + 1) < 0)
-				super->ujnl_mk_serial = jentry->serial + 1;
-			if (super->ujnl_ack_disc - (jentry->ack + 1) < 0)
-				super->ujnl_ack_disc = jentry->ack + 1;
+			tmp = jentry->batch - super->ujnl_batch;
+			if (tmp > 0) {
+				super->ujnl_batch	= jentry->batch;
+				super->ujnl_serial	= jentry->serial;
+				desc->batch_first	= ~0;
+				desc->batch_end		= ~0;
+				desc->batch_ack		= ~0;
+				desc->batch_count	= 1;
+				super->ujnl_head	= slot;
+
+				if (jentry->serial == 0) {
+					desc->batch_first = slot;
+					super->ujnl_tail = slot;
+				}
+			}
+			else if (tmp == 0) {
+				desc->batch_count++;
+
+				if (super->ujnl_serial < jentry->serial) {
+					super->ujnl_serial = jentry->serial;
+					super->ujnl_head = slot;
+				}
+
+				if (jentry->serial == 0)
+					desc->batch_first = slot;
+			}
+		}
+
+		switch (jentry->mark) {
+		case CACHEFS_ONDISC_UJNL_BATCH:
+			if (super->ujnl_serial == jentry->serial)
+				desc->batch_end = slot;
+			break;
+
+		case CACHEFS_ONDISC_UJNL_ACK:
+			if (super->ujnl_serial == jentry->serial)
+				desc->batch_ack	= slot;
+
+			if (jentry->batch - desc->ack_hi < 0) {
+				super->alloc_leaf	= jentry->alloc_leaf;
+				super->alloc_cur	= jentry->alloc_cur;
+				super->recycle_cur	= jentry->recycle_cur;
+				super->rcm_block	= jentry->rcm_block;
+				super->rcm_ptrnext	= jentry->rcm_ptrnext;
+				super->rcm_ptrstop	= jentry->rcm_ptrstop;
+				super->rcm_indirect	= jentry->rcm_indirect;
+				super->rcm_ino		= jentry->rcm_ino;
+
+				desc->ack_hi = jentry->batch;
+
+				kdebug("UJNL[%u] ACK %u { a=%u[%u] r=%u R=%u:%u:%u[%u-%u]",
+				       slot,desc->ack_hi,
+				       super->alloc_leaf,super->alloc_cur,super->recycle_cur,
+				       super->rcm_ino,super->rcm_indirect,super->rcm_block,
+				       super->rcm_ptrnext,super->rcm_ptrstop);
+			}
+			break;
+
+		default:
+			break;
 		}
 
 		offset += super->layout->ujnl_rsize;
@@ -1319,67 +1425,67 @@
 	}
 
 	kunmap(page);
-#endif
 
-	desc->count	-= size;
-	desc->written	+= size;
+	desc->desc.count	-= size;
+	desc->desc.written	+= size;
 	return size;
-} /* end cachefs_ujnl_replay_ackwin_actor() */
+} /* end cachefs_ujnl_find_batch_actor() */
 
 /*****************************************************************************/
 /*
- * journal replay actor for determining the slot window
- * - also load other parameters from the highest ACK'd mark
+ * replay entries from the update journal
  */
-static int cachefs_ujnl_replay_slotwin_actor(read_descriptor_t *desc, struct page *page,
-					     unsigned long offset, unsigned long size)
+static int cachefs_ujnl_replay_actor(read_descriptor_t *desc,
+				     struct page *page,
+				     unsigned long offset,
+				     unsigned long size)
 {
-	BUG();
-#if 0
 	struct cachefs_ondisc_update_journal *jentry;
 	struct cachefs_super *super = (struct cachefs_super *) desc->buf;
-	unsigned short slot;
-	char *data;
-
-	_enter("{%x},{%lu},%lu,%lu",desc->count,page->index,offset,size);
+	unsigned long stop;
+	u_int8_t *data;
 
-	BUG_ON(size!=PAGE_SIZE);
-	BUG_ON(offset!=0);
-
-	data = (char *) kmap(page);
+	kenter("{%x},{%lu},%lu,%lu",desc->count,page->index,offset,size);
 
-	/* just paste the values of the very first slot in directly */
-	slot = (page->index - super->layout->bix_ujournal) * super->layout->ujnl_recperblk;
+	BUG_ON(offset % super->layout->ujnl_rsize);
+	BUG_ON(size % super->layout->ujnl_rsize);
 
-	while (offset<size) {
-		jentry = (struct cachefs_ondisc_update_journal *) (data+offset);
+	stop = offset + size;
 
-		if (jentry->mark!=CACHEFS_ONDISC_UJNL_NULL) {
-			if (jentry->serial + 1 == super->ujnl_mk_serial)
-				super->ujnl_head = (slot+1) & (CACHEFS_ONDISC_UJNL_NUMENTS-1);
+	data = (u_int8_t *) kmap(page);
 
-			if (jentry->ack + 1 == super->ujnl_ack_disc) {
-				super->ujnl_tail = (slot+1) & (CACHEFS_ONDISC_UJNL_NUMENTS-1);
+	while (offset<stop) {
+		jentry = (struct cachefs_ondisc_update_journal *) (data + offset);
+		if ((unsigned)jentry->mark >= (unsigned)CACHEFS_ONDISC_UJNL__LAST) {
+			kunmap(page);
+			printk("CacheFS: unimplemented u-jnl mark (%x) found\n",jentry->mark);
+			return -EIO;
+		}
 
-				super->alloc_leaf	= jentry->alloc_leaf;
-				super->alloc_cur	= jentry->alloc_cur;
-				super->recycle_cur	= jentry->recycle_cur;
-				super->rcyblock		= jentry->rcyblock;
-				super->rcynext		= jentry->rcynext;
-				super->rcystop		= jentry->rcystop;
-			}
+		if (cachefs_ujnl_replay_tbl[jentry->mark]) {
+			desc->error = (*cachefs_ujnl_replay_tbl[jentry->mark])(super,jentry);
+			if (desc->error < 0)
+				break;
 		}
 
+		super->alloc_leaf	= jentry->alloc_leaf;
+		super->alloc_cur	= jentry->alloc_cur;
+		super->recycle_cur	= jentry->recycle_cur;
+		super->rcm_block	= jentry->rcm_block;
+		super->rcm_ptrnext	= jentry->rcm_ptrnext;
+		super->rcm_ptrstop	= jentry->rcm_ptrstop;
+		super->rcm_indirect	= jentry->rcm_indirect;
+		super->rcm_ino		= jentry->rcm_ino;
+
 		offset += super->layout->ujnl_rsize;
-		slot++;
 	}
 
 	kunmap(page);
-#endif
+
 	desc->count	-= size;
 	desc->written	+= size;
 	return size;
-} /* end cachefs_ujnl_replay_slotwin_actor() */
+} /* end cachefs_ujnl_replay_actor() */
 
 /*****************************************************************************/
 /*
@@ -1388,56 +1494,143 @@
  */
 int cachefs_ujnl_replay(struct cachefs_super *super)
 {
+	struct cachefs_replay_find_batch_desc find_batch;
+	struct cachefs_ondisc_update_journal *ajentry;
 	struct cachefs_ondisc_free_node *node;
 	struct file_ra_state ra;
 	read_descriptor_t desc;
 	loff_t ppos;
 	int loop;
 
-	_enter("");
+	kenter("");
 
 	file_ra_state_init(&ra,super->imisc->i_mapping);
 
-	/* first of all scan to determine the ACK window */
-	memset(&desc,0,sizeof(desc));
-	desc.count = super->layout->bix_wbjournal - super->layout->bix_ujournal;
-	desc.count *= super->layout->bsize;
-	desc.buf = (char*) super;
+	/* first of all scan to determine the bounds of the latest batch of
+	 * u-journal entries */
+	memset(&find_batch,0,sizeof(find_batch));
+	find_batch.desc.count = super->layout->bix_vjournal - super->layout->bix_ujournal;
+	find_batch.desc.count *= super->layout->bsize;
+	find_batch.desc.buf   = (char*) super;
 
 	ppos = super->layout->bix_ujournal;
 	ppos *= super->layout->bsize;
 
-	do_generic_mapping_read(super->imisc->i_mapping,&ra,NULL,&ppos,&desc,
-				cachefs_ujnl_replay_ackwin_actor);
-	if (desc.error<0) {
-		printk("CacheFS: failed to replay ujournal: %d\n",desc.error);
-		return desc.error;
+	do_generic_mapping_read(super->imisc->i_mapping,&ra,NULL,&ppos,&find_batch.desc,
+				cachefs_ujnl_find_batch_actor);
+	if (find_batch.desc.error<0) {
+		printk("CacheFS: failed to replay ujournal: %d\n",find_batch.desc.error);
+		return find_batch.desc.error;
 	}
 
-	_debug("UJNL: next batch=%d",super->ujnl_batch);
+	kdebug("UJNL: last batch=%d { s=%u f=%u b=%u a=%u }",
+	       super->ujnl_batch,super->ujnl_serial,
+	       find_batch.batch_first,find_batch.batch_end,find_batch.batch_ack);
+
+	if (find_batch.batch_end != ~0u && find_batch.batch_ack != ~0u)
+		goto reload_tracking;
+
+	if (find_batch.batch_first == ~0u) {
+		printk("CacheFS: corrupted journal: ujnl batch has no start entry\n");
+		return -EIO;
+	}
+
+	if (find_batch.batch_ack != ~0u) {
+		printk("CacheFS: corrupted journal: ujnl batch has ACK but no end marker\n");
+		return -EIO;
+	}
+
+	if (find_batch.batch_count != super->ujnl_serial) {
+		/* hmmm... some marks are missing from the batch */
+		printk("CacheFS: corrupted journal: ujnl batch has missing marks\n");
+		return -EIO;
+	}
+
+	/* need to replay journal - note it may need to be done in two chunks
+	 * if the batch wraps over the end of the journal space */
+	if (super->ujnl_head < super->ujnl_tail) {
+		memset(&desc,0,sizeof(desc));
+		desc.count = CACHEFS_ONDISC_UJNL_NUMENTS - super->ujnl_tail;
+		desc.count *= super->layout->ujnl_rsize;
+		desc.buf   = (char*) super;
+
+		ppos = super->layout->bix_ujournal;
+		ppos *= super->layout->bsize;
+		ppos += super->ujnl_tail * super->layout->ujnl_rsize;
+
+		do_generic_mapping_read(super->imisc->i_mapping,&ra,NULL,&ppos,&desc,
+					cachefs_ujnl_replay_actor);
+		if (desc.error<0) {
+			printk("CacheFS: failed to replay ujournal: %d\n",desc.error);
+			return desc.error;
+		}
 
-	/* scan to determine the slot allocation window */
-	super->ujnl_head = super->ujnl_tail = 0xffff;
+		super->ujnl_tail = 0;
+	}
 
 	memset(&desc,0,sizeof(desc));
-	desc.count = super->layout->bix_wbjournal - super->layout->bix_ujournal;
-	desc.count *= super->layout->bsize;
-	desc.buf = (char*) super;
+	desc.count = super->ujnl_head - super->ujnl_tail;
+	desc.count *= super->layout->ujnl_rsize;
+	desc.buf   = (char*) super;
 
 	ppos = super->layout->bix_ujournal;
 	ppos *= super->layout->bsize;
+	ppos += super->ujnl_tail * super->layout->ujnl_rsize;
 
 	do_generic_mapping_read(super->imisc->i_mapping,&ra,NULL,&ppos,&desc,
-				cachefs_ujnl_replay_slotwin_actor);
+				cachefs_ujnl_replay_actor);
 	if (desc.error<0) {
 		printk("CacheFS: failed to replay ujournal: %d\n",desc.error);
 		return desc.error;
 	}
 
-	_debug("UJNL slot window: next head=%hu tail=%hu",super->ujnl_head,super->ujnl_tail);
-	_debug("UJNL Alloc stacks: A=%u[%u] R=%u",
+	/* write all blocks that are marked for writeback */
+	cachefs_trans_batch_write_data(super);
+	cachefs_trans_batch_process_written_blocks(super,2);
+
+	/* seal the replayed batch with BATCH and ACK markers */
+	ajentry = kmalloc(super->layout->ujnl_rsize,GFP_KERNEL);
+	if (!ajentry)
+		return -ENOMEM;
+
+	memset(ajentry,0,sizeof(*ajentry));
+
+	ajentry->batch		= super->ujnl_batch;
+	ajentry->serial		= super->ujnl_serial;
+	ajentry->alloc_leaf	= super->alloc_leaf;
+	ajentry->alloc_cur	= super->alloc_cur;
+	ajentry->recycle_cur	= super->recycle_cur;
+	ajentry->rcm_ino	= super->rcm_ino;
+	ajentry->rcm_indirect	= super->rcm_indirect;
+	ajentry->rcm_block	= super->rcm_block;
+	ajentry->rcm_ptrnext	= super->rcm_ptrnext;
+	ajentry->rcm_ptrstop	= super->rcm_ptrstop;
+
+	if (find_batch.batch_end == ~0u) {
+		cachefs_trans_batch_write_marker(super,super->ujnl_head,ajentry);
+		super->ujnl_head = (super->ujnl_head+1) & (CACHEFS_ONDISC_UJNL_NUMENTS-1);
+		ajentry->serial++;
+	}
+
+	find_batch.batch_ack = super->ujnl_head;
+	cachefs_trans_batch_write_ack(super,super->ujnl_head,ajentry);
+
+	kfree(ajentry);
+
+ reload_tracking:
+	kdebug("reload_tracking");
+	super->ujnl_batch++;
+	super->ujnl_serial	= 0;
+	super->ujnl_head	= find_batch.batch_ack + 1;
+	super->ujnl_head	&= CACHEFS_ONDISC_UJNL_NUMENTS - 1;
+	super->ujnl_tail	= super->ujnl_head;
+
+	kdebug("UJNL slot window: next head=%hu tail=%hu",super->ujnl_head,super->ujnl_tail);
+	kdebug("UJNL Alloc stacks: A=%u[%u] R=%u",
 	       super->alloc_cur,super->alloc_leaf,super->recycle_cur);
-	_debug("UJNL Recycling: block=%u:%u-%u",super->rcyblock,super->rcynext,super->rcystop);
+	kdebug("UJNL Recycling: %u:%u:%u:%u-%u",
+	       super->rcm_ino,super->rcm_indirect,super->rcm_block,
+	       super->rcm_ptrnext,super->rcm_ptrstop);
 
 	/* reload the front nodes for the allocation and recycling stacks */
 	if (super->alloc_cur) {

Index: index.c
===================================================================
RCS file: /home/cvs/afs/fs/cachefs/index.c,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -r1.17 -r1.18
--- index.c	23 May 2003 12:59:21 -0000	1.17
+++ index.c	28 May 2003 10:32:54 -0000	1.18
@@ -560,3 +560,99 @@
 	return ret;
 
 } /* end cachefs_index_zap() */
+
+/*****************************************************************************/
+/*
+ * replay the creation of a new data inode
+ * - since we don't know what index data was associated with it, all we can do
+ *   is mark it for reclamation
+ */
+int cachefs_replay_ujnl_inode_allocing(struct cachefs_super *super,
+				       struct cachefs_ondisc_update_journal *jentry)
+{
+	return -ENOANO;
+} /* end cachefs_replay_ujnl_inode_allocing() */
+
+/*****************************************************************************/
+/*
+ * replay the updating of the information stored in an inode
+ * - since we don't know what changes were to be made, we can't actually do
+ *   anything, so we trust that the inode version number will suffice to cause
+ *   an update upon accessing if need be
+ */
+int cachefs_replay_ujnl_inode_updating(struct cachefs_super *super,
+				       struct cachefs_ondisc_update_journal *jentry)
+{
+	return 0;
+} /* end cachefs_replay_ujnl_inode_updating() */
+
+/*****************************************************************************/
+/*
+ * not yet supported
+ */
+int cachefs_replay_ujnl_inode_deleting(struct cachefs_super *super,
+				       struct cachefs_ondisc_update_journal *jentry)
+{
+	printk("CacheFS: u-jnl mark UJNL_INODE_DELETING not yet supported\n"
+	return -EIO;
+} /* end cachefs_replay_ujnl_inode_deleting() */
+
+/*****************************************************************************/
+/*
+ * replay an inode being marked for reclamation
+ */
+int cachefs_replay_ujnl_inode_mark_reclaim(struct cachefs_super *super,
+					   struct cachefs_ondisc_update_journal *jentry)
+{
+	return -ENOANO;
+} /* end cachefs_replay_ujnl_inode_mark_reclaim() */
+
+/*****************************************************************************/
+/*
+ * 
+ */
+int cachefs_replay_ujnl_inode_reclaiming(struct cachefs_super *super,
+					 struct cachefs_ondisc_update_journal *jentry)
+{
+	return -ENOANO;
+} /* end cachefs_replay_ujnl_inode_reclaiming() */
+
+/*****************************************************************************/
+/*
+ * 
+ */
+int cachefs_replay_ujnl_index_extending(struct cachefs_super *super,
+					struct cachefs_ondisc_update_journal *jentry)
+{
+	return -ENOANO;
+} /* end cachefs_replay_ujnl_index_extending() */
+
+/*****************************************************************************/
+/*
+ * 
+ */
+int cachefs_replay_ujnl_index_allocing(struct cachefs_super *super,
+				       struct cachefs_ondisc_update_journal *jentry)
+{
+	return -ENOANO;
+} /* end cachefs_replay_ujnl_index_allocing() */
+
+/*****************************************************************************/
+/*
+ * 
+ */
+int cachefs_replay_ujnl_index_modifying(struct cachefs_super *super,
+					struct cachefs_ondisc_update_journal *jentry)
+{
+	return -ENOANO;
+} /* end cachefs_replay_ujnl_index_modifying() */
+
+/*****************************************************************************/
+/*
+ * 
+ */
+int cachefs_replay_ujnl_index_freeing(struct cachefs_super *super,
+				      struct cachefs_ondisc_update_journal *jentry)
+{
+	return -ENOANO;
+} /* end cachefs_replay_ujnl_index_freeing() */

Index: dump-journal.c
===================================================================
RCS file: /home/cvs/afs/fs/cachefs/dump-journal.c,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -r1.9 -r1.10
--- dump-journal.c	23 May 2003 12:59:22 -0000	1.9
+++ dump-journal.c	28 May 2003 10:32:54 -0000	1.10
@@ -174,7 +174,7 @@
 		       "%4hu" GREY"-"NORMAL "%-4hu"
 		       "\n",
 		       loop&7 ? NORMAL : GREEN,
-		       loop+jsof,
+		       loop,
 		       jentry->batch,		jentry->serial,
 		       cachefs_ondisc_ujnl_marks[jentry->mark],jentry->auxmark,
 		       jentry->ino,		jentry->pgnum,

Index: cachefs-layout.h
===================================================================
RCS file: /home/cvs/afs/fs/cachefs/cachefs-layout.h,v
retrieving revision 1.23
retrieving revision 1.24
diff -u -r1.23 -r1.24
--- cachefs-layout.h	23 May 2003 14:07:31 -0000	1.23
+++ cachefs-layout.h	28 May 2003 10:32:54 -0000	1.24
@@ -359,6 +359,8 @@
 
 	/* index entry being freed */
 	CACHEFS_ONDISC_UJNL_INDEX_FREEING,
+
+	CACHEFS_ONDISC_UJNL__LAST
 } __attribute__((packed));
 
 struct cachefs_ondisc_update_journal

Index: cachefs-int.h
===================================================================
RCS file: /home/cvs/afs/fs/cachefs/cachefs-int.h,v
retrieving revision 1.32
retrieving revision 1.33
diff -u -r1.32 -r1.33
--- cachefs-int.h	23 May 2003 14:07:31 -0000	1.32
+++ cachefs-int.h	28 May 2003 10:32:54 -0000	1.33
@@ -200,6 +200,17 @@
 extern void cachefs_recycle_reclaim(struct cachefs_super *super);
 extern void cachefs_recycle_unallocate_data_block(struct cachefs_super *super);
 
+extern int cachefs_replay_ujnl_recyc_empty_node(struct cachefs_super *super,
+						struct cachefs_ondisc_update_journal *jentry);
+extern int cachefs_replay_ujnl_recyc_begin_new(struct cachefs_super *super,
+					       struct cachefs_ondisc_update_journal *jentry);
+extern int cachefs_replay_ujnl_recyc_transfer(struct cachefs_super *super,
+					      struct cachefs_ondisc_update_journal *jentry);
+extern int cachefs_replay_ujnl_recyc_scavenge(struct cachefs_super *super,
+					      struct cachefs_ondisc_update_journal *jentry);
+extern int cachefs_replay_ujnl_recyc_makeready(struct cachefs_super *super,
+					       struct cachefs_ondisc_update_journal *jentry);
+
 /*****************************************************************************/
 /*
  * data file or index object cookie
@@ -297,6 +308,36 @@
 			     unsigned *_newino);
 
 extern int cachefs_index_zap(struct cachefs_super *super);
+
+extern int cachefs_replay_ujnl_inode_allocing(struct cachefs_super *super,
+					      struct cachefs_ondisc_update_journal *jentry);
+extern int cachefs_replay_ujnl_inode_updating(struct cachefs_super *super,
+					      struct cachefs_ondisc_update_journal *jentry);
+extern int cachefs_replay_ujnl_inode_deleting(struct cachefs_super *super,
+					      struct cachefs_ondisc_update_journal *jentry);
+extern int cachefs_replay_ujnl_inode_mark_reclaim(struct cachefs_super *super,
+						  struct cachefs_ondisc_update_journal *jentry);
+extern int cachefs_replay_ujnl_inode_reclaiming(struct cachefs_super *super,
+						struct cachefs_ondisc_update_journal *jentry);
+extern int cachefs_replay_ujnl_index_extending(struct cachefs_super *super,
+					       struct cachefs_ondisc_update_journal *jentry);
+extern int cachefs_replay_ujnl_index_allocing(struct cachefs_super *super,
+					      struct cachefs_ondisc_update_journal *jentry);
+extern int cachefs_replay_ujnl_index_modifying(struct cachefs_super *super,
+					       struct cachefs_ondisc_update_journal *jentry);
+extern int cachefs_replay_ujnl_index_freeing(struct cachefs_super *super,
+					     struct cachefs_ondisc_update_journal *jentry);
+
+extern int cachefs_replay_ujnl_data_allocing(struct cachefs_super *super,
+					     struct cachefs_ondisc_update_journal *jentry);
+extern int cachefs_replay_ujnl_data_written(struct cachefs_super *super,
+					    struct cachefs_ondisc_update_journal *jentry);
+extern int cachefs_replay_ujnl_data_unallocing(struct cachefs_super *super,
+					       struct cachefs_ondisc_update_journal *jentry);
+extern int cachefs_replay_ujnl_indirect_allocing(struct cachefs_super *super,
+						 struct cachefs_ondisc_update_journal *jentry);
+extern int cachefs_replay_ujnl_indirect_freeing(struct cachefs_super *super,
+						struct cachefs_ondisc_update_journal *jentry);
 
 /*****************************************************************************/
 /*

Index: aops.c
===================================================================
RCS file: /home/cvs/afs/fs/cachefs/aops.c,v
retrieving revision 1.29
retrieving revision 1.30
diff -u -r1.29 -r1.30
--- aops.c	23 May 2003 12:59:22 -0000	1.29
+++ aops.c	28 May 2003 10:32:54 -0000	1.30
@@ -1428,3 +1428,53 @@
 	return ret;
 
 } /* end cachefs_file_readpage() */
+
+/*****************************************************************************/
+/*
+ * replay data block allocation and v-journal set
+ */
+int cachefs_replay_ujnl_data_allocing(struct cachefs_super *super,
+				      struct cachefs_ondisc_update_journal *jentry)
+{
+	return -ENOANO;
+} /* end cachefs_replay_ujnl_data_allocing() */
+
+/*****************************************************************************/
+/*
+ * replay data write and v-journal clear
+ */
+int cachefs_replay_ujnl_data_written(struct cachefs_super *super,
+				     struct cachefs_ondisc_update_journal *jentry)
+{
+	return -ENOANO;
+} /* end cachefs_replay_ujnl_data_written() */
+
+/*****************************************************************************/
+/*
+ * replay data block unallocation and v-journal clear
+ */
+int cachefs_replay_ujnl_data_unallocing(struct cachefs_super *super,
+					struct cachefs_ondisc_update_journal *jentry)
+{
+	return -ENOANO;
+} /* end cachefs_replay_ujnl_data_unallocing() */
+
+/*****************************************************************************/
+/*
+ * replay indirection block allocation
+ */
+int cachefs_replay_ujnl_indirect_allocing(struct cachefs_super *super,
+					  struct cachefs_ondisc_update_journal *jentry)
+{
+	return -ENOANO;
+} /* end cachefs_replay_ujnl_indirect_allocing() */
+
+/*****************************************************************************/
+/*
+ * replay indirection block freeing
+ */
+int cachefs_replay_ujnl_indirect_freeing(struct cachefs_super *super,
+					 struct cachefs_ondisc_update_journal *jentry)
+{
+	return -ENOANO;
+} /* end cachefs_replay_ujnl_indirect_freeing() */