PERFORCE change 82740 for review

soc-polytopes soc-polytopes at FreeBSD.org
Mon Aug 29 05:11:30 GMT 2005


http://perforce.freebsd.org/chv.cgi?CH=82740

Change 82740 by soc-polytopes at polytopes_kafka on 2005/08/29 05:10:44

	Everything but the playback is coded, but not fully debugged
	*mumble*lock order reversal*mumble*.

Affected files ...

.. //depot/projects/soc2005/ufsj/src/sys/ufs/ufs/journal.h#5 edit
.. //depot/projects/soc2005/ufsj/src/sys/ufs/ufs/ufs_journal.c#5 edit

Differences ...

==== //depot/projects/soc2005/ufsj/src/sys/ufs/ufs/journal.h#5 (text+ko) ====

@@ -111,11 +111,19 @@
 
 /* typedef struct ufsj_transaction*ufsj_thandle_t; */
 typedef struct ufsj_transaction{
-  uint64_t gen;
-  struct ufs_journal *journal;
-  void *data;
+	uint64_t gen;
+	struct ufs_journal *journal;
+	int pinned_buf_count;
+	LIST_HEAD(buffer_list, ufsj_buffer_pair) b_list;
+	void *data;
 } *ufsj_thandle_t;
 
+struct ufsj_buffer_pair{
+	LIST_ENTRY(ufsj_buffer_pair) next;
+	struct buf *wait_buf;
+	struct buf *pinned_buf;
+};
+
 MALLOC_DECLARE(M_UFSJ_HEADER);
 
 extern int ufsj_start(struct vnode *devvp, struct mount *mp, struct fs *fs,

==== //depot/projects/soc2005/ufsj/src/sys/ufs/ufs/ufs_journal.c#5 (text+ko) ====

@@ -76,11 +76,10 @@
 	long count;
 };
 	
-
 static void ufsj_flush(struct ufs_journal *journal);
 static int ufsj_replay(struct ufs_journal *journal);
 static void tbuf_done(struct buf *arg);
-static void ufsbuf_done(struct buf *arg) __unused;
+static void ufsbuf_done(struct buf *arg); 
 static int ufsj_critical_full(struct fs *fs);
 static void ufsj_register_transaction(ufsj_thandle_t transaction);
 static void ufsj_register_block(ufsj_thandle_t transaction, struct buf *wait_buf, struct buf *pinned_buf);
@@ -101,9 +100,10 @@
 	struct ufs_journal *journal;
 	struct ufsmount *ump;
 	struct vnode *jvp;
+	struct inode *jinode;
 	struct buf *jbp = NULL;
 	off_t jsb_off;
-	int flags, error = 0;
+	int flags, error, vop_locked = 0;
 
         td = curthread;
 
@@ -139,16 +139,53 @@
 	jsb_off = 0;
 	printf("Reading journal superblock at offset %jd\n", jsb_off);
 	error = bread(jvp, jsb_off, JSBLOCKSIZE, td->td_ucred, &jbp);
-        VOP_UNLOCK(jvp, 0, td);
+	vop_locked = 1;
 
 	if (error)
 		goto out;
 
+	/* We need to check to see if the super block exists! */
+	/* This check is from fsdbutil.c */ 
+	jinode = VTOI(jvp);
+	if ((DIP(jinode, i_mode) & IFMT) == 0){
+		/* We need to put the superblock on the disk first */
+		jsb = (struct ufsj_superblock *)jbp->b_data;
+		jsb->j_gen     = 0;
+		jsb->j_head    = 1;
+		jsb->j_tail    = jsb->j_head;
+		jsb->j_flags   = J_ENABLED;
+		jsb->j_len     = 1; /* Just us */
+		jsb->j_magic   = UFSJ_MAGIC;
+		jsb->j_fsmagic = fs->fs_magic;
+
+		printf("ufsj_start: writing initial jsb\n");
+		if ((error = bwrite(jbp)) != 0)
+			printf("Error %d writing journal superblock!\n", error);
+
+		/* I don't really want to block here, but we need to, otherwise the
+		   journal is no good */
+		/* 
+		bwait(jbp);
+		*/
+
+		printf("Re-reading journal superblock at offset %jd\n", jsb_off);
+		error = bread(jvp, jsb_off, JSBLOCKSIZE, td->td_ucred, &jbp);
+	}
+	if (vop_locked){
+		VOP_UNLOCK(jvp, 0, td);
+		vop_locked = 0;
+	}
+
 	printf("Checking journal superblock\n");
 	jsb = (struct ufsj_superblock *)jbp->b_data;
 	if ((jsb->j_magic != UFSJ_MAGIC) || (jsb->j_fsmagic != fs->fs_magic) ||
 	    ((jsb->j_flags & J_ENABLED) == 0)) {
-		error = 0;	/* XXX Does this really warrant an error? */
+		printf("The journal is hosed, you lose:\n");
+		printf("  J_MAGIC: 0x%X, j_fsmagic(0x%X) vs. fs_magic(0x%X)\n",
+		    jsb->j_magic, jsb->j_fsmagic, fs->fs_magic);
+		printf("   jsb->j_flags=%b\n", jsb->j_flags,
+		    "\10\2ENABLED\1DIRTY\n");
+		error = 1;	/* XXX Does this really warrant an error? */
 		goto out;
 	}
 
@@ -162,6 +199,9 @@
 	journal->ump = ump;
 	journal->bsize = fs->fs_bsize;
 	journal->fs = fs;
+
+	printf("Setting ump->um_journal to 0x%p\n", (void *)journal);
+	
 	ump->um_journal = journal;
 	flags = jsb->j_flags;
 	jvp->v_vflag |= VV_SYSTEM;
@@ -188,6 +228,11 @@
 	return (0);
 
 out:
+	if (vop_locked){
+		VOP_UNLOCK(jvp, 0, td);
+		vop_locked = 0;
+	}
+
 	if (jbp != NULL)
 		brelse(jbp);
 	vrele(jvp);
@@ -317,8 +362,12 @@
 	/* Done with journal */
 	mtx_unlock(&jnl->jmtx);
 
+	/* What was I going to do with this? */
 	bp->b_data = (void *)hdr;
 
+	transaction->pinned_buf_count = 0;
+	LIST_INIT(&(transaction->b_list));
+
 	*handle = transaction;
 
  end:
@@ -449,9 +498,9 @@
 	return error;
 }
 
-/* bufdone callback for transaction buffers. */
+/* bufdone callback for the real buffers. */
 static void
-tbuf_done(struct buf  *bp)
+ufsbuf_done(struct buf  *bp)
 {
 
 	struct mount *mp;
@@ -469,11 +518,12 @@
 	ump = VFSTOUFS(mp);
 	jnl = ump->um_journal;
 
-/* Is the transaction fully written to disk?  If so then unpin the
- * buffers.
- */
 	mtx_lock(&jnl->jmtx);
 
+	/* Are all of the real buffers on disk?  If so then update the
+	 * journalling superblock to so show that the transaction is retired.
+	 */
+
 	LIST_FOREACH_SAFE(lp, &(jnl->t_list), next, lp_tmp){
 		ufsj_thandle_t handle = lp->t;
 		struct ufsj_header *hdr = handle->data;
@@ -504,14 +554,55 @@
 	mtx_unlock(&jnl->jmtx);
 }
 
-/* bufdone callback for the real buffers. */
+/* bufdone callback for transaction buffers. */
 static void
-ufsbuf_done(struct buf  *bp)
+tbuf_done(struct buf  *bp)
 {
-	/* Are all of the real buffers on disk?  If so then update the
-	 * journalling superblock to so show that the transaction is retired.
-	 */
-	/* We can also free the transaction handle */
+	struct mount *mp;
+	struct ufsmount *ump;
+	struct vnode *vp;
+	struct ufs_journal *jnl;
+	struct ufsj_buffer_pair *pair;
+	struct ufsj_transaction_list *lp; /* To iterate over transactions */
+
+	KASSERT((bp != NULL), ("tbuf_done: got null bp, strange"));
+	
+	vp = bp->b_vp;
+	mp = vp->v_mount;
+	ump = VFSTOUFS(mp);
+	jnl = ump->um_journal;
+
+	mtx_lock(&jnl->jmtx);
+
+/* Is the transaction fully written to disk?  If so then unpin the
+ * buffers.
+ */
+	LIST_FOREACH(lp, &(jnl->t_list), next){
+		ufsj_thandle_t handle = lp->t;
+		LIST_FOREACH(pair, &(handle->b_list), next){
+			if (pair->wait_buf->b_lblkno == bp->b_lblkno){
+				handle->pinned_buf_count--;
+			}
+		}
+		if (handle->pinned_buf_count == 0){
+			/* No more waiting bufs, pin the real bufs */
+			/* and free the transaction list */
+			pair = LIST_FIRST(&(handle->b_list));
+			while (pair != NULL) {
+				struct ufsj_buffer_pair *p2;
+				/* Unpin the buffer */
+#ifdef BAW_HAS_INCLUDED_THE_XFS_PINNING_CODE
+				bunpin(pair->pinned_buf);
+#endif
+				p2 = LIST_NEXT(pair, next);
+				free(pair, M_UFSMNT);
+				pair = p2;
+			}
+			/* Shouldn't need this */
+			LIST_INIT(&(handle->b_list));
+		}
+	}
+	mtx_unlock(&jnl->jmtx);
 }
 
 static void
@@ -555,6 +646,10 @@
 	/* Allocate entry  -- FIXME: malloc type */
 	entry = malloc(sizeof(struct ufsj_transaction_list), M_UFSMNT, M_WAITOK|M_ZERO);
 
+	if (entry == NULL){
+		panic("ufsj_register_transaction: We were unable to allocate a new entry.");
+        }
+
 	hdr = (struct ufsj_header *)transaction->data;
 	jnl = transaction->journal;
 
@@ -568,13 +663,24 @@
 
 	/* Unlock the journal */
 	mtx_unlock(&jnl->jmtx);
-
-	return;
 }
   
 static void ufsj_register_block(ufsj_thandle_t transaction, struct buf *wait_buf, struct buf *pinned_buf)
 {
-	return;
+	struct ufsj_buffer_pair *pair;
+
+	pair = malloc(sizeof(struct ufsj_buffer_pair), M_UFSMNT, M_WAITOK|M_ZERO);
+
+        if (pair == NULL){
+		panic("ufsj_register_block: Unable to allocate list entry.");
+	}
+
+	pair->wait_buf = wait_buf;
+	pair->pinned_buf = pinned_buf;
+
+	transaction->pinned_buf_count++;
+
+	LIST_INSERT_HEAD(&(transaction->b_list), pair, next);
 }
 
 #endif /* UFS_JOURNAL */


More information about the p4-projects mailing list