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