Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 1 Sep 2005 07:00:42 GMT
From:      soc-polytopes <soc-polytopes@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 82957 for review
Message-ID:  <200509010700.j8170gp8081836@repoman.freebsd.org>

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

Change 82957 by soc-polytopes@polytopes_kafka on 2005/09/01 07:00:06

	For Scott, still have a locking issue in write_blocks

Affected files ...

.. //depot/projects/soc2005/ufsj/src/sbin/newfs/mkfs.c#3 edit
.. //depot/projects/soc2005/ufsj/src/sbin/tunefs/tunefs.c#4 edit
.. //depot/projects/soc2005/ufsj/src/sys/ufs/ufs/journal.h#7 edit
.. //depot/projects/soc2005/ufsj/src/sys/ufs/ufs/ufs_journal.c#7 edit

Differences ...

==== //depot/projects/soc2005/ufsj/src/sbin/newfs/mkfs.c#3 (text+ko) ====

@@ -1087,7 +1087,7 @@
 create_journal_file(void)
 {
 /* Find the journal inode, and create the file there */
-/* This is only in here now 
-     
+/* This is only in here now as a stub */
+ 	return 0;  
 }
   

==== //depot/projects/soc2005/ufsj/src/sbin/tunefs/tunefs.c#4 (text+ko) ====

@@ -297,9 +297,11 @@
 	}
 	if (jflag) {
 		name = "journalling";
-		if (jvalue == 0)
+		if (jvalue == 0) {
 			sblock.fs_flags &= ~FS_JOURNAL;
-		else {
+		} else if (sblock.fs_flags & FS_DOSOFTDEP) {
+			warnx("Soft updates is already enabled, cannot journal.");
+		} else {
 			sblock.fs_flags |= FS_JOURNAL;
 			sblock.fs_journal_inode = jvalue;
 		}
@@ -346,6 +348,9 @@
 			else if (sblock.fs_clean == 0) {
 				warnx("%s cannot be enabled until fsck is run",
 				    name);
+			} else if (sblock.fs_flags & FS_JOURNAL) {
+				warnx("%s cannot be enabled while journaling is enabled",
+				    name);
 			} else {
  				sblock.fs_flags |= FS_DOSOFTDEP;
  				warnx("%s set", name);

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

@@ -25,6 +25,11 @@
  */
 
 /*
+  Special thanks to Google for choosing this project as part of
+   the Google Summer of Code.
+*/
+
+/*
  * UFS Journal structures and definitions
  */
 

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

@@ -53,7 +53,11 @@
  * 6. What do we do with these pink elephants called QUOTA and SOFTUPDATES? =-)
  */
 
-/* BUGS: 1. Race condition with writing the footer. */
+/*
+  BUGS: 1. Race condition with writing the footer.
+        2. Until the buffer pinning is patched in, out of order writes
+	3. Data integrity is not yet ensured.
+*/
 
 
 struct ufs_journal {
@@ -88,7 +92,7 @@
 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), curthread->td_ucred, 0, &(bb))
+#define UFSJ_ALLOCATE_HEADER(vp, offset, bp)  UFS_BALLOC((vp), (offset), sizeof(struct ufsj_header), curthread->td_ucred, 0, &(bp))
 
 /* UFSJ_CRITICAL_FREE_SPACE is in Megs, but freespace returns frags */
 #define UFSJ_MEGS_TO_FRAGS(fs, megs) (1024*1024*(fs)->fs_fsize*(megs))
@@ -97,6 +101,31 @@
 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.");
 
+
+/* A handy macro to avoid duplicating the jsb sync code */
+#define SYNC_JOURNAL(jvp, jbp, journal, error, routine_name)                         \
+do {                                                                                 \
+        struct ufsj_superblock *jsb;                                                 \
+	/* Write the Journal */                                                      \
+	printf("%s: reading jsb\n", (routine_name));                                 \
+	if (((error) = bread((jvp), (journal)->jsb_off, JSBLOCKSIZE,                 \
+	    NOCRED, &(jbp))) == 0) {                                                 \
+		jsb = (struct ufsj_superblock *) (jbp)->b_data;                      \
+		jsb->j_gen = (journal)->gen;                                         \
+		jsb->j_head = (journal)->head;                                       \
+		jsb->j_tail = (journal)->tail;                                       \
+		printf("%s: writing jsb\n", (routine_name));                         \
+		if (((error) = bwrite((jbp))) != 0)                                  \
+			printf("Error %d writing journal superblock!\n", (error));   \
+	} else  {                                                                    \
+		printf("%s: read of sb failed\n", (routine_name));                   \
+		brelse((jbp));                                                       \
+	}                                                                            \
+} while(0)
+
+
+
+
 /* To be called when the FS is mounted */
 int
 ufsj_start(struct vnode *devvp, struct mount *mp, struct fs *fs, struct thread *td)
@@ -207,7 +236,7 @@
 	journal->bsize = fs->fs_bsize;
 	journal->fs = fs;
 
-	printf("Setting ump->um_journal to 0x%p\n", (void *)journal);
+	printf("Setting ump->um_journal to %p\n", (void *)journal);
 	
 	ump->um_journal = journal;
 	flags = jsb->j_flags;
@@ -318,29 +347,31 @@
 	struct ufs_journal *jnl;
 	ufsj_thandle_t transaction;
 	struct ufsj_header *hdr;
+	uma_zone_t zone;
 	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."));
 	/* Grab the Journal from ufsmount */
 	jnl = u_mnt->um_journal;
+	zone = jnl->tzone;
 
-	/* Lock the journal */
-	mtx_lock(&jnl->jmtx);
- 
 	/* Malloc new handle and header, do this now so that we can block before
 	   acquiring jmtx. */
         /* This is NOT good, we don't want to sleep with the lock */
-        /* What is the malloc type of a header? */
-	hdr = malloc(sizeof(struct ufsj_header), M_UFSJ_HEADER, M_NOWAIT|M_ZERO);
-	transaction   = uma_zalloc(jnl->tzone, M_NOWAIT|M_ZERO);
+	hdr = malloc(sizeof(struct ufsj_header), M_UFSJ_HEADER, M_WAITOK|M_ZERO);
+	transaction   = uma_zalloc(jnl->tzone, M_WAITOK|M_ZERO);
 
-        /* We need to spin until we get a memory lock, since we hold the journal lock! */
+        /* Don't need to spin, but could have failures */
         if (!hdr){
-          panic("FUCK!");
+          panic("ufsj_start_transaction: Unable to allocate header.");
         } else if (!transaction){
-          panic("FUCK AND FUCK AGAIN!");
+          panic("ufsj_start_transaction: Unable to allocate transaction.");
         }
+
+	/* Lock the journal */
+	mtx_lock(&jnl->jmtx);
+ 
         
 	fs = u_mnt->um_fs;
 	vp = jnl->jvp;
@@ -355,13 +386,17 @@
 		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);
+	error = UFSJ_ALLOCATE_HEADER(vp, jnl->next, bp);
+
+	/* Point to the next blkno */
+	jnl->next++;
 
 	journal_is_locked = 0;
 	VOP_UNLOCK(vp, 0, curthread);
@@ -391,6 +426,7 @@
 
 	*handle = transaction;
 
+	printf("ufsj_start_transaction: Transaction created successfully\n");
  end:
 	if (journal_is_locked)
 		VOP_UNLOCK(vp, 0, curthread);
@@ -410,6 +446,7 @@
 
 	struct buf *bpc;
 	struct ufsj_header *header;
+	struct ufs_journal *jnl;
 	int error = 0, journal_is_locked = 0;
 
 	KASSERT(handle != NULL, ("ufsj_write_blocks: NULL transaction"));
@@ -430,6 +467,8 @@
 	}
 		
 
+	jnl = handle->journal;
+	mtx_lock(&jnl->jmtx);
 	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");
@@ -439,27 +478,33 @@
 	journal_is_locked = 1;
         ASSERT_VOP_LOCKED(handle->journal->jvp, "ufsj_write_blocks");
 
-	error = UFS_BALLOC(handle->journal->jvp, 1, sizeof(*(bp->b_data)), 
+	printf("ufsj_write_blocks: Trying to get buffer copy, lblk: %ld sz: %ld\n",
+	    (long)jnl->next, (long)jnl->fs->fs_bsize);
+	error = UFS_BALLOC(handle->journal->jvp, jnl->next, jnl->fs->fs_bsize,
 	    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;
 	}
+	jnl->next++;
+	mtx_unlock(&jnl->jmtx);
 
 	/* Just copy the pointer, don't copy the data */
 	bpc->b_data = bp->b_data;
   
 	header->j_count++;
 
-	/* Record where the orig. block lives */
         header->sectors[header->j_count] = bpc->b_lblkno;
 	bp->b_iodone = ufsbuf_done;
         bpc->b_iodone = tbuf_done;
 
 	/* Pin the buffer */
-	/* TODO */
+#ifdef BAW_HAS_INCLUDED_THE_XFS_PINNING_CODE
+	bpin(bp);
+#endif
         /* Write the block */
 	bdwrite(bp);
 
@@ -468,6 +513,8 @@
 
         return 0;
  end:
+	if (mtx_owned(&jnl->jmtx))
+		mtx_unlock(&jnl->jmtx);
 	if (journal_is_locked)
 		VOP_UNLOCK(handle->journal->jvp, 0, curthread);
         brelse(bpc);
@@ -488,6 +535,7 @@
 	struct vnode *vp;
 	struct ufs_journal *jnl;
 	struct ufsj_buffer_pair *pair;
+	struct buf *jbp;
 	int error = 0, journal_is_locked = 0;
 	
 	KASSERT(handle != NULL, ("ufsj_end_transaction: handle is NULL."));
@@ -513,10 +561,11 @@
         ASSERT_VOP_LOCKED(vp, "ufsj_end_transaction");
 
 	/* Allocate a footer block */
-	error = UFSJ_ALLOCATE_HEADER(vp, bp);
+	error = UFSJ_ALLOCATE_HEADER(vp, jnl->next, bp);
 	if (error)
 		goto end;
 
+	jnl->next++;
 	handle->footer = bp;
 
 	/* Allocate space in the journal.  Is the journal full?  If so then
@@ -535,7 +584,7 @@
 	jnl->gen++;
 	jnl->tail = bp->b_lblkno;
 
-	/* Write the Journal */
+	SYNC_JOURNAL(jnl->jvp, jbp, jnl, error, "ufsj_end_transaction");
 
 	/* Done with the journal, set it free */
 	mtx_unlock(&jnl->jmtx);
@@ -605,7 +654,9 @@
 	}
 	
 	if (journal_updated){
-		/* sync jsb and jnl */
+		struct buf *jbp;
+		int error = 0;
+		SYNC_JOURNAL(jnl->jvp, jbp, jnl, error, "ufsbuf_done");
 	}
 
 	mtx_unlock(&jnl->jmtx);
@@ -667,18 +718,20 @@
 {
 	struct ufsj_transaction_list *lp;
 	struct ufsj_buffer_pair *pair;
+	int error = 0;
 
 	LIST_FOREACH(lp, &(journal->t_list), next){
 		ufsj_thandle_t handle = lp->t;
-		bawrite(handle->header);
+		/* FIXME: How do we handle errors */
+		error = bwrite(handle->header);
 		LIST_FOREACH(pair, &(handle->b_list), next){
-			bawrite(pair->wait_buf);
+			error = bwrite(pair->wait_buf);
 #ifdef BAW_HAS_INCLUDED_THE_XFS_PINNING_CODE
 			bunpin(pair->pinned_buf);
 #endif
-			bawrite(pair->pinned_buf);
+			error = bwrite(pair->pinned_buf);
 		}
-		bawrite(handle->footer);
+		error = bwrite(handle->footer);
 	}	
 }
 
@@ -691,6 +744,13 @@
            2. Order the transactions
            3. write the blocks to disk
         */
+	/* Read jnl->head */
+	/* while (cur_blk != jnl->tail)
+	   getblk cur_blk
+	   write_blk to real location
+	   cur_blk = header->*mumble*
+	*/
+	     
 	return (0);
 }
 



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