Date: Fri, 19 Aug 2005 21:08:07 GMT From: soc-polytopes <soc-polytopes@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 82294 for review Message-ID: <200508192108.j7JL874a073850@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=82294 Change 82294 by soc-polytopes@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) ====
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200508192108.j7JL874a073850>