Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 1 Sep 2005 04:06:12 GMT
From:      soc-polytopes <soc-polytopes@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 82954 for review
Message-ID:  <200509010406.j8146CG1066701@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=82954

Change 82954 by soc-polytopes@polytopes_kafka on 2005/09/01 04:05:23

	Checkpoint.

Affected files ...

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

Differences ...

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

@@ -115,7 +115,8 @@
 	struct ufs_journal *journal;
 	int pinned_buf_count;
 	LIST_HEAD(buffer_list, ufsj_buffer_pair) b_list;
-	void *data;
+	void *header;
+	void *footer;
 } *ufsj_thandle_t;
 
 struct ufsj_buffer_pair{
@@ -125,6 +126,8 @@
 };
 
 MALLOC_DECLARE(M_UFSJ_HEADER);
+MALLOC_DECLARE(M_UFSJ_TRANSACTION_LIST);
+MALLOC_DECLARE(M_UFSJ_BUF_PAIR);
 
 extern int ufsj_start(struct vnode *devvp, struct mount *mp, struct fs *fs,
     struct thread *td);

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

@@ -53,6 +53,9 @@
  * 6. What do we do with these pink elephants called QUOTA and SOFTUPDATES? =-)
  */
 
+/* BUGS: 1. Race condition with writing the footer. */
+
+
 struct ufs_journal {
 	uint64_t	gen;
 	off_t		start;
@@ -85,12 +88,14 @@
 static void ufsj_register_block(ufsj_thandle_t transaction, struct buf *wait_buf, struct buf *pinned_buf);
 
 
-#define UFSJ_ALLOCATE_HEADER(aa, bb)  UFS_BALLOC((aa), 0, sizeof(struct ufsj_header), FSCRED, 0, &(bb))
+#define UFSJ_ALLOCATE_HEADER(aa, bb)  UFS_BALLOC((aa), 0, sizeof(struct ufsj_header), curthread->td_ucred, 0, &(bb))
 
 /* UFSJ_CRITICAL_FREE_SPACE is in Megs, but freespace returns frags */
 #define UFSJ_MEGS_TO_FRAGS(fs, megs) (1024*1024*(fs)->fs_fsize*(megs))
 
 MALLOC_DEFINE(M_UFSJ_HEADER, "journalheader", "A UFS Journal header.");
+MALLOC_DEFINE(M_UFSJ_TRANSACTION_LIST, "transactionlist", "A list of UFS journal transactions.");
+MALLOC_DEFINE(M_UFSJ_BUF_PAIR, "bufpair", "A pair of bufs, one pinned and the other a wait condition.");
 
 /* To be called when the FS is mounted */
 int
@@ -186,6 +191,8 @@
 		printf("   jsb->j_flags=%b\n", jsb->j_flags,
 		    "\10\2ENABLED\1DIRTY\n");
 		error = 1;	/* XXX Does this really warrant an error? */
+		                /* Yes, tthis can imply that we have a null jsb,
+				   which gives lovely writes to 0x0 */
 		goto out;
 	}
 
@@ -251,7 +258,7 @@
 	struct vnode *jvp;
 	int error, jflags;
 
-        td = curthread; /* XXX */
+        td = curthread; /* Curthread gives us the correct creds (I think) */
 	ump = VFSTOUFS(mp);
 	journal = ump->um_journal;
 	jflags = 0;
@@ -311,7 +318,7 @@
 	struct ufs_journal *jnl;
 	ufsj_thandle_t transaction;
 	struct ufsj_header *hdr;
-	int error = 0;
+	int error = 0, journal_is_locked = 0;
 
 	KASSERT(u_mnt != NULL, ("ufsj_start_transaction: mountpoint is NULL."));
 	KASSERT(handle != NULL, ("ufsj_start_transaction: handle is NULL."));
@@ -342,9 +349,23 @@
 		ufsj_flush(jnl);
 	}
 
+	printf("ufsj_start_transaction: Acquiring lock on %p\n", vp);
+	if (vn_lock(vp, LK_EXCLUSIVE|LK_NOWAIT, curthread)){
+		printf("ufsj_start_transaction: Couldn't lock vnode, giving up\n");
+		error = 1;
+		goto end;
+	}
+	journal_is_locked = 1;
+
+        ASSERT_VOP_LOCKED(vp, "ufsj_start_transaction");
+
+        printf("ufsj_start_transaction: Trying to allocate header.\n");
 	/* Allocate a block for the transaction header */
 	error = UFSJ_ALLOCATE_HEADER(vp, bp);
 
+	journal_is_locked = 0;
+	VOP_UNLOCK(vp, 0, curthread);
+
 	if (error){
 		/* Did not allocate a buf */
 		goto end;
@@ -356,7 +377,7 @@
 	hdr->j_type |= type;
   
 	transaction->gen = jnl->gen;
-	transaction->data = bp;
+	transaction->header = bp;
 	transaction->journal = jnl;
 	
 	/* Done with journal */
@@ -371,6 +392,9 @@
 	*handle = transaction;
 
  end:
+	if (journal_is_locked)
+		VOP_UNLOCK(vp, 0, curthread);
+
 	return (error);
 	
 }
@@ -386,15 +410,17 @@
 
 	struct buf *bpc;
 	struct ufsj_header *header;
-	int error;
+	int error = 0, journal_is_locked = 0;
 
 	KASSERT(handle != NULL, ("ufsj_write_blocks: NULL transaction"));
 	KASSERT(bp != NULL, ("ufsj_write_blocks: NULL buffer"));
 
-	header = handle->data;
+	header = handle->header;
 
-	if (!(bp->b_flags & BA_METAONLY))
+        /* It seems that there is no BA_METAONLY, oops!
+          if (!(bp->b_flags & BA_METAONLY))
 		panic("ufsj: Got non-metadata block(0x%X)", (unsigned int)bp);
+        */
 	
 	if (header->j_count > UFSJ_MAX_SIZE){
 		panic("ufsj: Went past the end of the journal, count: %d", (int)header->j_count);
@@ -403,11 +429,23 @@
 		panic("ufsj: Filled transaction");
 	}
 		
-	error = UFS_BALLOC(handle->journal->jvp, 0, sizeof(*(bp->b_data)), 
-	    FSCRED, bp->b_flags, &bpc);
+
+	printf("ufsj_write_blocks: Acquiring lock on %p\n", handle->journal->jvp);
+	if (vn_lock(handle->journal->jvp, LK_EXCLUSIVE|LK_CANRECURSE|LK_NOWAIT, curthread)){
+		printf("ufsj_write_blocks: Couldn't lock vnode, giving up\n");
+		error = 1;
+		goto end;
+	}
+	journal_is_locked = 1;
+        ASSERT_VOP_LOCKED(handle->journal->jvp, "ufsj_write_blocks");
+
+	error = UFS_BALLOC(handle->journal->jvp, 1, sizeof(*(bp->b_data)), 
+	    curthread->td_ucred, bp->b_flags, &bpc);
+	journal_is_locked = 0;
+	VOP_UNLOCK(handle->journal->jvp, 0, curthread);
 	if (error){
+		/* XXX: Does anymore cleanup need done? */
 		goto end;
-		/* XXX */
 	}
 
 	/* Just copy the pointer, don't copy the data */
@@ -416,7 +454,7 @@
 	header->j_count++;
 
 	/* Record where the orig. block lives */
-        header->sectors[header->j_count] = bp->b_lblkno;
+        header->sectors[header->j_count] = bpc->b_lblkno;
 	bp->b_iodone = ufsbuf_done;
         bpc->b_iodone = tbuf_done;
 
@@ -430,6 +468,8 @@
 
         return 0;
  end:
+	if (journal_is_locked)
+		VOP_UNLOCK(handle->journal->jvp, 0, curthread);
         brelse(bpc);
 	return error;
 }
@@ -447,7 +487,8 @@
 	struct fs *fs;
 	struct vnode *vp;
 	struct ufs_journal *jnl;
-	int error;
+	struct ufsj_buffer_pair *pair;
+	int error = 0, journal_is_locked = 0;
 	
 	KASSERT(handle != NULL, ("ufsj_end_transaction: handle is NULL."));
  
@@ -462,17 +503,33 @@
 	fs = jnl->ump->um_fs;
 	vp = jnl->jvp;
 	
+	printf("ufsj_end_transaction: Acquiring lock on %p\n", vp);
+	if (vn_lock(vp, LK_EXCLUSIVE|LK_NOWAIT, curthread)){
+		printf("ufsj_end_transaction: Couldn't lock vnode, giving up\n");
+		error = 1;
+		goto end;
+	}
+	journal_is_locked = 1;
+        ASSERT_VOP_LOCKED(vp, "ufsj_end_transaction");
+
 	/* Allocate a footer block */
 	error = UFSJ_ALLOCATE_HEADER(vp, bp);
 	if (error)
 		goto end;
 
+	handle->footer = bp;
+
 	/* Allocate space in the journal.  Is the journal full?  If so then
 	 * synchronously flush the blocks for the oldest transactions */
 	if (ufsj_critical_full(fs))
 		ufsj_flush(jnl);
 
 	/* Write the header, footer, and data blocks */
+	bdwrite(handle->header);
+	LIST_FOREACH(pair, &(handle->b_list), next){
+		bdwrite(pair->wait_buf);
+	}
+	bdwrite(bp);
 
 	/* Update the journal superblock with the index and the generation */
 	jnl->gen++;
@@ -526,7 +583,7 @@
 
 	LIST_FOREACH_SAFE(lp, &(jnl->t_list), next, lp_tmp){
 		ufsj_thandle_t handle = lp->t;
-		struct ufsj_header *hdr = handle->data;
+		struct ufsj_header *hdr = handle->header;
 		int i;
 		for (i = 0; i < hdr->j_count; i++){
 			if (bp->b_lblkno == hdr->sectors[i]){
@@ -608,7 +665,21 @@
 static void
 ufsj_flush(struct ufs_journal *journal)
 {
-	return;
+	struct ufsj_transaction_list *lp;
+	struct ufsj_buffer_pair *pair;
+
+	LIST_FOREACH(lp, &(journal->t_list), next){
+		ufsj_thandle_t handle = lp->t;
+		bawrite(handle->header);
+		LIST_FOREACH(pair, &(handle->b_list), next){
+			bawrite(pair->wait_buf);
+#ifdef BAW_HAS_INCLUDED_THE_XFS_PINNING_CODE
+			bunpin(pair->pinned_buf);
+#endif
+			bawrite(pair->pinned_buf);
+		}
+		bawrite(handle->footer);
+	}	
 }
 
 static int
@@ -643,14 +714,14 @@
 
 	KASSERT(transaction != NULL, ("ufsj_register_transaction: mountpoint is NULL."));
 
-	/* Allocate entry  -- FIXME: malloc type */
-	entry = malloc(sizeof(struct ufsj_transaction_list), M_UFSMNT, M_WAITOK|M_ZERO);
+	/* Allocate Entry */
+	entry = malloc(sizeof(struct ufsj_transaction_list), M_UFSJ_TRANSACTION_LIST, 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;
+	hdr = (struct ufsj_header *)transaction->header;
 	jnl = transaction->journal;
 
 	/* Lock the journal */
@@ -669,7 +740,7 @@
 {
 	struct ufsj_buffer_pair *pair;
 
-	pair = malloc(sizeof(struct ufsj_buffer_pair), M_UFSMNT, M_WAITOK|M_ZERO);
+	pair = malloc(sizeof(struct ufsj_buffer_pair), M_UFSJ_BUF_PAIR, M_WAITOK|M_ZERO);
 
         if (pair == NULL){
 		panic("ufsj_register_block: Unable to allocate list entry.");



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200509010406.j8146CG1066701>