Subject: afs/fs/cachefs vjournal.c,1.1,1.2 super.c,1.28,1.29 recycling.c,1.18,1.19 kcachefsd.c,1.10,1.11 interface.c,1.6,1.7 cachefs-layout.h,1.22,1.23 cachefs-int.h,1.31,1.32

From: [email-masked]
Date: Fri, 23 May 2003 15:07:34 +0100

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

Modified Files:
	vjournal.c super.c recycling.c kcachefsd.c interface.c 
	cachefs-layout.h cachefs-int.h 
Log Message:
now clear v-journal entries for data blocks that have been written

Index: vjournal.c
===================================================================
RCS file: /home/cvs/afs/fs/cachefs/vjournal.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- vjournal.c	23 May 2003 12:59:21 -0000	1.1
+++ vjournal.c	23 May 2003 14:07:31 -0000	1.2
@@ -136,9 +136,22 @@
 /*
  * clear a v-journal entry due to the target block having been written
  */
-void cachefs_vj_write_complete(struct cachefs_vj_entry *vjentry)
+void cachefs_vj_write_complete(struct cachefs_block *block)
 {
-	kenter("");
+	struct cachefs_vj_entry *vjentry = block->vjentry;
+	struct cachefs_super *super;
+
+	kenter("{vs=%u pg={%u}+%u up={%u}+%u",
+	       vjentry->vslot,vjentry->ino,vjentry->pgnum,vjentry->upblock,vjentry->upentry);
+
+	block->vjentry = NULL;
+	super = block->super;
+
+	spin_lock(&super->vjnl_lock);
+	list_move_tail(&vjentry->link,&super->vjnl_writtenq);
+	spin_unlock(&super->vjnl_lock);
+
+	wake_up(&super->dmn_sleepq);
 
 	kleave("");
 } /* end cachefs_vj_write_complete() */
@@ -164,3 +177,62 @@
 
 	kleave("");
 } /* end cachefs_vj_cancel() */
+
+/*****************************************************************************/
+/*
+ * unallocate and recycle a single data storage block that's marked as invalid
+ * in the validity journal
+ */
+void cachefs_vj_note_write_completion(struct cachefs_super *super)
+{
+	struct cachefs_transaction *trans;
+	struct cachefs_vj_entry *vjentry;
+	int ret;
+
+	kenter("");
+
+	BUG_ON(list_empty(&super->vjnl_writtenq));
+
+	/* we can access the next pointer without a lock because we know we're
+	 * the only ones going to change it now */
+	vjentry = list_entry(super->vjnl_writtenq.next,struct cachefs_vj_entry,link);
+
+	ret = -ENOMEM;
+	trans = cachefs_trans_alloc(super,GFP_KERNEL);
+	if (!trans)
+		goto error;
+
+	trans->jentry->mark   	= CACHEFS_ONDISC_UJNL_DATA_WRITTEN;
+	trans->jentry->ino	= vjentry->ino;
+	trans->jentry->auxmark	= vjentry->vslot;
+	trans->jentry->block	= vjentry->bix;
+
+	cachefs_trans_affects_block(trans,vjentry->vblock,vjentry->ventry,
+				    sizeof(struct cachefs_ondisc_validity_journal));
+
+	/* mark the journal and then make modifications */
+	ret = cachefs_trans_mark(trans);
+	if (ret<0)
+		goto error_free;
+
+	cachefs_block_modify(super,vjentry->vblock,&vjentry->vpage);
+	memset(kmap(vjentry->vpage) + vjentry->ventry, 0,
+	       sizeof(struct cachefs_ondisc_validity_journal));
+	kunmap(vjentry->vpage);
+
+	cachefs_trans_commit(trans);
+
+	spin_lock(&super->vjnl_lock);
+	list_del_init(&vjentry->link);
+	spin_unlock(&super->vjnl_lock);
+
+	cachefs_vj_release(super,vjentry);
+	kleave("");
+	return;
+
+ error_free:
+	cachefs_trans_put(trans);
+ error:
+	kleave(" [error %d]",ret);
+
+} /* end cachefs_vj_note_write_completion() */

Index: super.c
===================================================================
RCS file: /home/cvs/afs/fs/cachefs/super.c,v
retrieving revision 1.28
retrieving revision 1.29
diff -u -r1.28 -r1.29
--- super.c	23 May 2003 12:59:21 -0000	1.28
+++ super.c	23 May 2003 14:07:31 -0000	1.29
@@ -314,6 +314,7 @@
 	spin_lock_init(&super->vjnl_lock);
 	init_waitqueue_head(&super->vjnl_alloc_wq);
 	INIT_LIST_HEAD(&super->vjnl_unallocq);
+	INIT_LIST_HEAD(&super->vjnl_writtenq);
 
 	init_MUTEX(&super->alloc_sem);
 	init_waitqueue_head(&super->alloc_wq);
@@ -716,11 +717,14 @@
 
 	cachefs_withdraw_cache(super);
 
-	if (!list_empty(&super->vjnl_unallocq)) {
+	if (!list_empty(&super->vjnl_unallocq) ||
+	    !list_empty(&super->vjnl_writtenq)
+	    ) {
 		set_current_state(TASK_UNINTERRUPTIBLE);
 		add_wait_queue(&super->vjnl_alloc_wq,&myself);
 
-		while (!list_empty(&super->vjnl_unallocq)) {
+		while (!list_empty(&super->vjnl_unallocq) ||
+		       !list_empty(&super->vjnl_writtenq)) {
 			schedule();
 			set_current_state(TASK_UNINTERRUPTIBLE);
 		}

Index: recycling.c
===================================================================
RCS file: /home/cvs/afs/fs/cachefs/recycling.c,v
retrieving revision 1.18
retrieving revision 1.19
diff -u -r1.18 -r1.19
--- recycling.c	23 May 2003 12:59:21 -0000	1.18
+++ recycling.c	23 May 2003 14:07:31 -0000	1.19
@@ -835,10 +835,9 @@
 
 	BUG_ON(list_empty(&super->vjnl_unallocq));
 
-	spin_lock(&super->vjnl_lock);
+	/* we can access the next pointer without a lock because we know we're
+	 * the only ones going to change it now */
 	vjentry = list_entry(super->vjnl_unallocq.next,struct cachefs_vj_entry,link);
-	list_del_init(&vjentry->link);
-	spin_unlock(&super->vjnl_lock);
 
 	ret = -ENOMEM;
 	trans = cachefs_trans_alloc(super,GFP_KERNEL);
@@ -921,6 +920,10 @@
 
 	cachefs_trans_commit(trans);
 
+	spin_lock(&super->vjnl_lock);
+	list_del_init(&vjentry->link);
+	spin_unlock(&super->vjnl_lock);
+
 	cachefs_vj_release(super,vjentry);
 	cachefs_put_page(uppage);
 	cachefs_put_page(rcypage);
@@ -936,9 +939,6 @@
 	cachefs_block_put(rcyblock);
 	cachefs_trans_put(trans);
  error:
-	spin_lock(&super->vjnl_lock);
-	list_add_tail(&vjentry->link,&super->vjnl_unallocq);
-	spin_unlock(&super->vjnl_lock);
 	kleave(" [error %d]",ret);
 
 } /* end cachefs_recycle_unallocate_data_block() */

Index: kcachefsd.c
===================================================================
RCS file: /home/cvs/afs/fs/cachefs/kcachefsd.c,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -r1.10 -r1.11
--- kcachefsd.c	23 May 2003 12:59:21 -0000	1.10
+++ kcachefsd.c	23 May 2003 14:07:31 -0000	1.11
@@ -78,7 +78,8 @@
 			    super->layout->bix_unready < super->layout->bix_end ||
 			    test_bit(CACHEFS_SUPER_BATCH_TIMER,&super->flags) ||
 			    test_bit(CACHEFS_SUPER_DO_RECLAIM,&super->flags) ||
-			    !list_empty(&super->vjnl_unallocq)
+			    !list_empty(&super->vjnl_unallocq) ||
+			    !list_empty(&super->vjnl_writtenq)
 			    )
 				break;
 
@@ -117,9 +118,12 @@
 			}
 		}
 
-		/* deal with invalid data block unallocation */
+		/* deal with validity journal changes */
 		if (!list_empty(&super->vjnl_unallocq))
 			cachefs_recycle_unallocate_data_block(super);
+
+		if (!list_empty(&super->vjnl_writtenq))
+			cachefs_vj_note_write_completion(super);
 
 		/* if there's no next node, then get one */
 		if (!super->alloc_node)

Index: interface.c
===================================================================
RCS file: /home/cvs/afs/fs/cachefs/interface.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- interface.c	23 May 2003 12:59:21 -0000	1.6
+++ interface.c	23 May 2003 14:07:31 -0000	1.7
@@ -798,7 +798,10 @@
 	for (; bvec>=bio->bi_io_vec; bvec--)
 		end_io->func(end_io->cookie_data,bvec->bv_page,end_io->data);
 
+	clear_bit(CACHEFS_BLOCK_NETFSBUSY,&end_io->block->flags);
+	wake_up(&end_io->block->writewq);
 	cachefs_block_put(end_io->block);
+
 	kfree(end_io);
 	bio_put(bio);
 	_leave(" = 0");
@@ -921,12 +924,14 @@
  available:
 	kdebug("available");
 	cachefs_block_get(block);
+	set_bit(CACHEFS_BLOCK_NETFSBUSY,&block->flags);
+
 	read_unlock(&pageio->lock);
 
 	ret = -ENOMEM;
 	end_io = kmalloc(sizeof(*end_io),gfp);
 	if (!end_io)
-		goto error;
+		goto error_nb;
 
 	end_io->func		= end_io_func;
 	end_io->data		= end_io_data;
@@ -936,7 +941,7 @@
 	ret = -ENOMEM;
 	bio = bio_alloc(gfp,1);
 	if (!bio)
-		goto error;
+		goto error_nb;
 
 	bio->bi_bdev	= block->super->sb->s_bdev;
 	bio->bi_private	= end_io;
@@ -959,6 +964,10 @@
 	kleave(" = 0");
 	return 0;
 
+ error_nb:
+	clear_bit(CACHEFS_BLOCK_NETFSBUSY,&block->flags);
+	wake_up(&block->writewq);
+	goto error;
  error_i:
 	kdebug("error_i");
 	up(&inode->vfs_inode.i_sem);
@@ -966,7 +975,7 @@
  error:
 	kdebug("error");
 	up_read(&cookie->sem);
-	if (block)	cachefs_block_put(block);
+	cachefs_block_put(block);
 	if (bio)	bio_put(bio);
 	if (end_io)	kfree(end_io);
 	kleave(" = %d",ret);
@@ -994,7 +1003,12 @@
 	for (; bvec>=bio->bi_io_vec; bvec--)
 		end_io->func(end_io->cookie_data,bvec->bv_page,end_io->data);
 
+	cachefs_vj_write_complete(end_io->block);
+
+	clear_bit(CACHEFS_BLOCK_NETFSBUSY,&end_io->block->flags);
+	wake_up(&end_io->block->writewq);
 	cachefs_block_put(end_io->block);
+
 	kfree(end_io);
 	bio_put(bio);
 	_leave(" = 0");
@@ -1056,6 +1070,8 @@
  write:
 	kdebug("write [bix=%u]",block->bix);
 	cachefs_block_get(block);
+	set_bit(CACHEFS_BLOCK_NETFSBUSY,&block->flags);
+
 	read_unlock(&pageio->lock);
 
 	ret = -ENOMEM;
@@ -1094,6 +1110,8 @@
 
  error:
 	kdebug("error");
+	clear_bit(CACHEFS_BLOCK_NETFSBUSY,&block->flags);
+	wake_up(&block->writewq);
 	cachefs_block_put(block);
 	up_read(&cookie->sem);
 	if (bio)

Index: cachefs-layout.h
===================================================================
RCS file: /home/cvs/afs/fs/cachefs/cachefs-layout.h,v
retrieving revision 1.22
retrieving revision 1.23
diff -u -r1.22 -r1.23
--- cachefs-layout.h	23 May 2003 12:59:22 -0000	1.22
+++ cachefs-layout.h	23 May 2003 14:07:31 -0000	1.23
@@ -284,10 +284,10 @@
 	CACHEFS_ONDISC_UJNL_INODE_RECLAIMING,
 
 	/* data block allocation
-	 * - ino	= inode for which block is being allocated
-	 * - pgnum	= which page of inode being allocated
+	 * - ino	= inode for which block allocated
+	 * - pgnum	= page of inode being instantiated
 	 * - size	= current file size
-	 * - block	= block being allocated
+	 * - block	= block allocated
 	 * - auxblock	= (auxentry==1) block holding 2OS of alloc stack (0 if stack now empty)
 	 * - auxentry	= 0: alloc TOS leaf, 1: alloc TOS node
 	 * - upblock	= block which will point to this one
@@ -296,12 +296,17 @@
 	 */
 	CACHEFS_ONDISC_UJNL_DATA_ALLOCING,
 
-	/* beginning write on page in cache */
-	CACHEFS_ONDISC_UJNL_DATA_WRITING,
+	/* completed write on page in cache
+	 * - ino	= inode for which block was written
+	 * - pgnum	= which page of inode was written
+	 * - block	= block written
+	 * - auxmark	= v-journal entry number
+	 */
+	CACHEFS_ONDISC_UJNL_DATA_WRITTEN,
 
 	/* data block being unallocated
-	 * - ino	= inode for which block is being allocated
-	 * - pgnum	= which page of inode being allocated
+	 * - ino	= inode to which block belongs
+	 * - pgnum	= which page of inode being unallocated
 	 * - block	= block being recycled
 	 * - auxblock	= (old) front recycling node
 	 * - auxentry	= index into auxblock[] of leaf filled (or UINT_MAX if new node)

Index: cachefs-int.h
===================================================================
RCS file: /home/cvs/afs/fs/cachefs/cachefs-int.h,v
retrieving revision 1.31
retrieving revision 1.32
diff -u -r1.31 -r1.32
--- cachefs-int.h	23 May 2003 12:59:22 -0000	1.31
+++ cachefs-int.h	23 May 2003 14:07:31 -0000	1.32
@@ -162,7 +162,8 @@
 	unsigned			vjnl_count;	/* number of free entries */
 	spinlock_t			vjnl_lock;	/* allocation lock */
 	wait_queue_head_t		vjnl_alloc_wq;	/* allocation queue */
-	struct list_head		vjnl_unallocq;	/* blocks requiring unallocation */
+	struct list_head		vjnl_unallocq;	/* entries requiring unallocation */
+	struct list_head		vjnl_writtenq;	/* entries requiring clearing  */
 
 	/* writeback journal tracking */
 	unsigned long			*wbj_map;	/* bitmap of free entries (1 page) */
@@ -428,7 +429,8 @@
 extern int cachefs_vj_alloc(struct cachefs_transaction *trans, struct cachefs_inode *inode);
 extern void cachefs_vj_release(struct cachefs_super *super, struct cachefs_vj_entry *vjentry);
 extern void cachefs_vj_cancel(struct cachefs_vj_entry *vjentry);
-extern void cachefs_vj_write_complete(struct cachefs_vj_entry *vjentry);
+extern void cachefs_vj_write_complete(struct cachefs_block *block);
+extern void cachefs_vj_note_write_completion(struct cachefs_super *super);

 /*****************************************************************************/