PERFORCE change 82294 for review

soc-polytopes soc-polytopes at FreeBSD.org
Fri Aug 19 21:08:09 GMT 2005


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

Change 82294 by soc-polytopes at polytopes_kafka on 2005/08/19 21:07:28

	First update, expect many more today.
	I'm merging some changes from outside the tree.

Affected files ...

.. //depot/projects/soc2005/ufsj/src/sbin/mount/mount.c#3 edit
.. //depot/projects/soc2005/ufsj/src/sbin/newfs/mkfs.c#2 edit
.. //depot/projects/soc2005/ufsj/src/sbin/newfs/newfs.c#2 edit
.. //depot/projects/soc2005/ufsj/src/sbin/newfs/newfs.h#2 edit
.. //depot/projects/soc2005/ufsj/src/sbin/tunefs/tunefs.c#3 edit
.. //depot/projects/soc2005/ufsj/src/sys/ufs/ffs/ffs_inode.c#2 edit
.. //depot/projects/soc2005/ufsj/src/sys/ufs/ffs/ffs_vfsops.c#3 edit
.. //depot/projects/soc2005/ufsj/src/sys/ufs/ffs/ffs_vnops.c#2 edit
.. //depot/projects/soc2005/ufsj/src/sys/ufs/ufs/journal.h#2 edit
.. //depot/projects/soc2005/ufsj/src/sys/ufs/ufs/ufs_inode.c#2 edit
.. //depot/projects/soc2005/ufsj/src/sys/ufs/ufs/ufs_journal.c#2 edit
.. //depot/projects/soc2005/ufsj/src/sys/ufs/ufs/ufs_vfsops.c#2 edit
.. //depot/projects/soc2005/ufsj/src/sys/ufs/ufs/ufs_vnops.c#2 edit

Differences ...

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

@@ -106,7 +106,7 @@
 	{ MNT_SOFTDEP,		"soft-updates" },
 	{ MNT_MULTILABEL,	"multilabel" },
 	{ MNT_ACLS,		"acls" },
-	{ MNT_JOURNAL,		"journalling" },
+	{ MNT_JOURNAL,		"journaling" },
 	{ 0, NULL }
 };
 

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

@@ -137,6 +137,8 @@
 		strlcpy(sblock.fs_volname, volumelabel, MAXVOLLEN);
 	if (lflag)
 		sblock.fs_flags |= FS_MULTILABEL;
+	if (Jflag)
+                sblock.fs_flags |= FS_JOURNAL;
 	/*
 	 * Validate the given file system size.
 	 * Verify that its last block can actually be accessed.
@@ -1073,3 +1075,19 @@
 		return (nextnum++);
 	return (arc4random());
 }
+
+
+/*
+ * Create a Journal file
+ * This should be pulled out so that we can make a journal file
+ * on an arbitrary fs
+ */
+
+size_t
+create_journal_file(void)
+{
+/* Find the journal inode, and create the file there */
+/* This is only in here now 
+     
+}
+  

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

@@ -116,6 +116,7 @@
 int	Oflag = 2;		/* file system format (1 => UFS1, 2 => UFS2) */
 int	Rflag;			/* regression test */
 int	Uflag;			/* enable soft updates for file system */
+int     Jflag;                  /* enable journaling on the fs */
 int	Eflag = 0;		/* exit in middle of newfs for testing */
 int	lflag;			/* enable multilabel for file system */
 int	nflag;			/* do not create .snap directory */
@@ -156,11 +157,14 @@
 	off_t mediasize;
 
 	while ((ch = getopt(argc, argv,
-	    "EL:NO:RS:T:Ua:b:c:d:e:f:g:h:i:lm:no:s:")) != -1)
+	    "EJL:NO:RS:T:Ua:b:c:d:e:f:g:h:i:lm:no:s:")) != -1)
 		switch (ch) {
 		case 'E':
 			Eflag++;
 			break;
+		case 'J':
+                        Jflag++;
+	                break;
 		case 'L':
 			volumelabel = optarg;
 			i = -1;

==== //depot/projects/soc2005/ufsj/src/sbin/newfs/newfs.h#2 (text+ko) ====

@@ -43,6 +43,7 @@
 /*
  * variables set up by front end.
  */
+extern int      Jflag;          /* enable journaling */
 extern int	Lflag;		/* add a volume label */
 extern int	Nflag;		/* run mkfs without writing file system */
 extern int	Oflag;		/* build UFS1 format file system */

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

@@ -51,8 +51,10 @@
 
 #include <ufs/ufs/ufsmount.h>
 #include <ufs/ufs/dinode.h>
+#include <ufs/ufs/journal.h>
 #include <ufs/ffs/fs.h>
 
+
 #include <ctype.h>
 #include <err.h>
 #include <fcntl.h>
@@ -410,7 +412,7 @@
 	fprintf(stderr, "%s\n%s\n%s\n%s\n",
 "usage: tunefs [-A] [-a enable | disable] [-e maxbpg] [-f avgfilesize]",
 "              [-L volname] [-l enable | disable] [-m minfree]",
-"              [-n enable | disable] [-o space | time] [-p]",
+"              [-n enable | disable] [-o space | time] [-p] [-j journal-inode]",
 "              [-s avgfpdir] special | filesystem");
 	exit(2);
 }
@@ -424,6 +426,8 @@
 		(sblock.fs_flags & FS_MULTILABEL)? "enabled" : "disabled");
 	warnx("soft updates: (-n)                                 %s", 
 		(sblock.fs_flags & FS_DOSOFTDEP)? "enabled" : "disabled");
+	warnx("Journaling:   (-j)                                 %s", 
+		(sblock.fs_flags & FS_JOURNAL)? "enabled" : "disabled");
 	warnx("maximum blocks per file in a cylinder group: (-e)  %d",
 	      sblock.fs_maxbpg);
 	warnx("average file size: (-f)                            %d",

==== //depot/projects/soc2005/ufsj/src/sys/ufs/ffs/ffs_inode.c#2 (text+ko) ====

@@ -54,6 +54,7 @@
 #include <ufs/ufs/ufsmount.h>
 #include <ufs/ufs/inode.h>
 #include <ufs/ufs/ufs_extern.h>
+#include <ufs/ufs/journal.h>
 
 #include <ufs/ffs/fs.h>
 #include <ufs/ffs/ffs_extern.h>
@@ -79,10 +80,14 @@
 	struct buf *bp;
 	struct inode *ip;
 	int error;
+#ifdef UFS_JOURNAL
+        ufsj_thandle_t jnl;
+#endif
 
 	ASSERT_VOP_LOCKED(vp, "ffs_update");
 	ufs_itimes(vp);
 	ip = VTOI(vp);
+
 	if ((ip->i_flag & IN_MODIFIED) == 0 && waitfor == 0)
 		return (0);
 	ip->i_flag &= ~(IN_LAZYMOD | IN_MODIFIED);
@@ -104,6 +109,13 @@
 		brelse(bp);
 		return (error);
 	}
+
+	/* We only do writes from this point on */
+#ifdef UFS_JOURNAL
+        if (ip->i_ump->um_fs->fs_flags & FS_JOURNAL)
+		ufsj_start_transaction(ip->i_ump, &jnl, J_TYPE_WRITE);
+#endif
+
 	if (DOINGSOFTDEP(vp))
 		softdep_update_inodeblock(ip, bp, waitfor);
 	else if (ip->i_effnlink != ip->i_nlink)
@@ -115,13 +127,33 @@
 		*((struct ufs2_dinode *)bp->b_data +
 		    ino_to_fsbo(fs, ip->i_number)) = *ip->i_din2;
 	if (waitfor && !DOINGASYNC(vp)) {
-		return (bwrite(bp));
+#ifdef UFS_JOURNAL
+		if (ip->i_ump->um_fs->fs_flags & FS_JOURNAL){
+			ufsj_write_blocks(jnl, bp);
+			ufsj_end_transaction(jnl);
+			return(0); /* BAW: Correct return value? */
+		} else 
+#endif
+			return (bwrite(bp));
 	} else if (vm_page_count_severe() || buf_dirty_count_severe()) {
-		return (bwrite(bp));
+#ifdef UFS_JOURNAL
+		if (ip->i_ump->um_fs->fs_flags & FS_JOURNAL){
+			ufsj_write_blocks(jnl, bp);
+			ufsj_end_transaction(jnl);
+			return(0); /* BAW: Correct return value? */
+		} else
+#endif
+			return (bwrite(bp));
 	} else {
 		if (bp->b_bufsize == fs->fs_bsize)
 			bp->b_flags |= B_CLUSTEROK;
-		bdwrite(bp);
+#ifdef UFS_JOURNAL
+		if (ip->i_ump->um_fs->fs_flags & FS_JOURNAL){
+			ufsj_write_blocks(jnl, bp);
+			ufsj_end_transaction(jnl);
+		} else
+#endif
+			bdwrite(bp);
 		return (0);
 	}
 }

==== //depot/projects/soc2005/ufsj/src/sys/ufs/ffs/ffs_vfsops.c#3 (text+ko) ====


==== //depot/projects/soc2005/ufsj/src/sys/ufs/ffs/ffs_vnops.c#2 (text+ko) ====


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

@@ -102,7 +102,12 @@
 /* The kernel journalling API */
 #ifdef _KERNEL
 
-typedef struct ufsj_transaction *ufsj_thandle_t;
+/* typedef struct ufsj_transaction*ufsj_thandle_t; */
+typedef struct ufsj_transaction{
+  uint64_t gen;
+  struct ufs_journal *journal;
+  void *data;
+} *ufsj_thandle_t;
 
 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_inode.c#2 (text+ko) ====


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

@@ -71,8 +71,9 @@
 
 static void ufsj_flush(struct ufs_journal *journal);
 static int ufsj_replay(struct ufs_journal *journal);
-static void tbuf_done(void *arg) __unused;
-static void ufsbuf_done(void *arg) __unused;
+static void tbuf_done(struct buf *arg);
+static void ufsbuf_done(struct buf *arg) __unused;
+static int ufsj_critical_full(void);
 
 /* To be called when the FS is mounted */
 int
@@ -86,6 +87,8 @@
 	off_t jsb_off;
 	int flags, error = 0;
 
+        td = curthread;
+
 	printf("ufsj_start called\n");
 	ump = VFSTOUFS(mp);
 	if (ump == NULL) {
@@ -118,7 +121,8 @@
 	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, curthread);
+        VOP_UNLOCK(jvp, 0, td);
+
 	if (error)
 		goto out;
 
@@ -182,6 +186,7 @@
 	struct vnode *jvp;
 	int error, jflags;
 
+        td = curthread; /* XXX */
 	ump = VFSTOUFS(mp);
 	journal = ump->um_journal;
 	jflags = 0;
@@ -235,15 +240,60 @@
 int
 ufsj_start_transaction(struct ufsmount *u_mnt, ufsj_thandle_t *handle, int type)
 {
+	struct buf *bp;
+	struct fs *fs;
+	struct vnode *vp;
+	struct ufs_journal *jnl;
+	ufsj_thandle_t h;
+	struct ufsj_header *hdr;
+	int error = 0;
+
+	KASSERT(u_mnt != NULL, ("ufsj_start_transaction: mountpoint is NULL."));
+	KASSERT(handle != NULL, ("ufsj_start_transaction: handle is NULL."));
+ 
 
-	/* Check to see if the on-disk journal is critically full, try to
-	 * flush it if so.
-	 */
+	fs = u_mnt->um_fs;
+	jnl = u_mnt->um_journal;
+	vp = jnl->jvp;
+
+	if (ufsj_critical_full()){
+		ufsj_flush(jnl);
+	}
 
 	/* Allocate a block for the transaction header */
+	/* Think that this is not the correct function */
+	/* Does anyone know what the second arg to balloc should be? */
+	/* NOCRED, FSCRED?  We do not want the cred of the invoker */
+	/* Do we need flags? (I think probably) */
+
+	error = UFS_BALLOC(vp, 0, sizeof(struct ufsj_header),
+	    FSCRED, 0, &bp);
+
+	if (error){
+		/* Do Cleanup */
+		goto end;
+	}
+
+	/* Malloc new handle and header */
+	h   = malloc(sizeof(struct ufsj_transaction), M_UFSMNT, M_WAITOK|M_ZERO);
+	hdr = malloc(sizeof(struct ufsj_header), M_UFSMNT, M_WAITOK|M_ZERO);
+
+  
+	hdr->j_gen = jnl->gen;
+	hdr->j_count = 0;
+	hdr->j_type |= type;
+  
+	h->gen = jnl->gen;
+	h->data = bp;
+	h->journal = jnl;
+
+	bp->b_data = (void *)hdr;
+
+	*handle = h;
 
-	/* Done?  Assign *handle */
-	return (0);
+ end:
+	return (error);
+	
 }
 
 /*
@@ -255,15 +305,44 @@
 ufsj_write_blocks(ufsj_thandle_t handle, struct buf *bp)
 {
 
+	struct buf *bpc;
+	struct ufsj_header *header;
+	int error;
+
+	KASSERT(handle != NULL, ("ufsj_write_blocks: NULL transaction"));
+	KASSERT(bp != NULL, ("ufsj_write_blocks: NULL buffer"));
+
+	header = handle->data;
+
+	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);
+	} else if (header->j_count == UFSJ_MAX_SIZE){
+		/* XXX -- Need to handle this case */
+		panic("ufsj: Filled transaction");
+	}
+		
 	/* Pin the bp */
 
-	/* Is the header full?  If so, then what?  Close the transaction?
-	 * Chain it to a new transaction?  Extend the header?
-	 */
+	error = UFS_BALLOC(handle->journal->jvp, 0, sizeof(*(bp->b_data)), 
+	    FSCRED, bp->b_flags, &bpc);
+	if (error){
+		goto end;
+		/* XXX */
+	}
 
-	/* Allocate an empty block to mirror the data */
+	/* Just copy the pointer, don't copy the data */
+	bpc->b_data = bp->b_data;
+  
+	header->j_count++;
+	/* How do we set the lba to bpc? */
+/*	header->sectors[header->j_count] = (daddr_t)bpc; */
 
-	/* Update the header with the count and the lba */
+	bp->b_iodone = tbuf_done;
+ end:
+	return error;
 
 	/* Adjust the bufdone pointer in the bp to call us so we know when to
 	 * retire the transaction.
@@ -281,6 +360,9 @@
 ufsj_end_transaction(ufsj_thandle_t handle)
 {
 
+#if 0
+	printf("Ended transaction: %p\n", (void *)handle);
+#endif
 	/* Allocate a footer block */
 
 	/* Allocate space in the journal.  Is the journal full?  If so then
@@ -297,7 +379,7 @@
 
 /* bufdone callback for transaction buffers. */
 static void
-tbuf_done(void *arg)
+tbuf_done(struct buf  *arg)
 {
 
 	/* Is the transaction fully written to disk?  If so then unpin the
@@ -307,7 +389,7 @@
 
 /* bufdone callback for the real buffers. */
 static void
-ufsbuf_done(void *arg)
+ufsbuf_done(struct buf  *arg)
 {
 	/* Are all of the real buffers on disk?  If so then update the
 	 * journalling superblock to so show that the transaction is retired.
@@ -326,4 +408,13 @@
 	return (0);
 }
 
+static int
+ufsj_critical_full(void)
+{
+	/* XXX */
+	return 0;
+}
+
+
 #endif /* UFS_JOURNAL */
+

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


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



More information about the p4-projects mailing list