From owner-p4-projects@FreeBSD.ORG Wed Aug 24 05:05:50 2005 Return-Path: X-Original-To: p4-projects@freebsd.org Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id E996116A421; Wed, 24 Aug 2005 05:05:49 +0000 (GMT) X-Original-To: perforce@freebsd.org Delivered-To: perforce@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id BBE8616A41F for ; Wed, 24 Aug 2005 05:05:49 +0000 (GMT) (envelope-from soc-polytopes@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [216.136.204.115]) by mx1.FreeBSD.org (Postfix) with ESMTP id 7A20543D45 for ; Wed, 24 Aug 2005 05:05:49 +0000 (GMT) (envelope-from soc-polytopes@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.13.1/8.13.1) with ESMTP id j7O55nWa010303 for ; Wed, 24 Aug 2005 05:05:49 GMT (envelope-from soc-polytopes@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.13.1/8.13.1/Submit) id j7O55nim010300 for perforce@freebsd.org; Wed, 24 Aug 2005 05:05:49 GMT (envelope-from soc-polytopes@freebsd.org) Date: Wed, 24 Aug 2005 05:05:49 GMT Message-Id: <200508240505.j7O55nim010300@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to soc-polytopes@freebsd.org using -f From: soc-polytopes To: Perforce Change Reviews Cc: Subject: PERFORCE change 82487 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 24 Aug 2005 05:05:50 -0000 http://perforce.freebsd.org/chv.cgi?CH=82487 Change 82487 by soc-polytopes@polytopes_kafka on 2005/08/24 05:05:11 Another checkpoint. Working on revamping the code that manages how we know when a transaction is complete and when to unpin our orig. buffers. Affected files ... .. //depot/projects/soc2005/ufsj/src/sys/ufs/ufs/journal.h#3 edit .. //depot/projects/soc2005/ufsj/src/sys/ufs/ufs/ufs_journal.c#3 edit Differences ... ==== //depot/projects/soc2005/ufsj/src/sys/ufs/ufs/journal.h#3 (text+ko) ==== @@ -61,6 +61,13 @@ #define UFSJ_MAX_SIZE 62 /* + * If the disk's free space drops below this level, it is critically full. + * This value is in Mega(?)bytes? + */ + +#define UFSJ_CRITICAL_FREE_SPACE 10 + +/* * A journal entry header. It contains the sector information of each of * the block in the entry, along with the size and index of the entry. * It's size is a multiple of the disk sector size, usually 512 bytes. ==== //depot/projects/soc2005/ufsj/src/sys/ufs/ufs/ufs_journal.c#3 (text+ko) ==== @@ -73,7 +73,12 @@ static int ufsj_replay(struct ufs_journal *journal); static void tbuf_done(struct buf *arg); static void ufsbuf_done(struct buf *arg) __unused; -static int ufsj_critical_full(void); +static int ufsj_critical_full(struct fs *fs); + +#define UFSJ_ALLOCATE_HEADER(aa, bb) UFS_BALLOC((aa), 0, sizeof(struct ufsj_header), FSCRED, 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)) /* To be called when the FS is mounted */ int @@ -251,34 +256,34 @@ KASSERT(u_mnt != NULL, ("ufsj_start_transaction: mountpoint is NULL.")); KASSERT(handle != NULL, ("ufsj_start_transaction: handle is NULL.")); + /* Malloc new handle and header, do this now so that we can block before + acquiring jmtx. */ + /* When do we free these? */ + h = malloc(sizeof(struct ufsj_transaction), M_UFSMNT, M_WAITOK|M_ZERO); + hdr = malloc(sizeof(struct ufsj_header), M_UFSMNT, M_WAITOK|M_ZERO); + + /* Grab the Journal from ufsmount */ + jnl = u_mnt->um_journal; + /* Lock the journal */ + mtx_lock(&jnl->jmtx); + fs = u_mnt->um_fs; - jnl = u_mnt->um_journal; vp = jnl->jvp; - if (ufsj_critical_full()){ + if (ufsj_critical_full(fs)){ 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); + error = UFSJ_ALLOCATE_HEADER(vp, bp); if (error){ - /* Do Cleanup */ + /* Did not allocate a buf */ 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); - - + /* Synch access to jnl? YES */ hdr->j_gen = jnl->gen; hdr->j_count = 0; hdr->j_type |= type; @@ -286,6 +291,9 @@ h->gen = jnl->gen; h->data = bp; h->journal = jnl; + + /* Done with journal */ + mtx_unlock(&jnl->jmtx); bp->b_data = (void *)hdr; @@ -324,8 +332,6 @@ panic("ufsj: Filled transaction"); } - /* Pin the bp */ - error = UFS_BALLOC(handle->journal->jvp, 0, sizeof(*(bp->b_data)), FSCRED, bp->b_flags, &bpc); if (error){ @@ -337,18 +343,20 @@ 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; */ + + header->sectors[header->j_count] = bpc->b_lblkno; + bp->b_iodone = ufsbuf_done; + bpc->b_iodone = tbuf_done; + + /* Pin the buffer */ + /* TODO */ + /* Write the block */ + bdwrite(bp); - bp->b_iodone = tbuf_done; + return 0; end: + brelse(bpc); return error; - - /* Adjust the bufdone pointer in the bp to call us so we know when to - * retire the transaction. - */ - - return (0); } /* @@ -360,40 +368,77 @@ ufsj_end_transaction(ufsj_thandle_t handle) { -#if 0 - printf("Ended transaction: %p\n", (void *)handle); -#endif + struct buf *bp; /* Footer */ + struct fs *fs; + struct vnode *vp; + struct ufs_journal *jnl; + int error; + + KASSERT(handle != NULL, ("ufsj_end_transaction: handle is NULL.")); + + + /* Grab the Jouranl from our handle */ + jnl = handle->journal; + + + /* Lock the journal */ + mtx_lock(&jnl->jmtx); + + fs = jnl->ump->um_fs; + vp = jnl->jvp; + /* Allocate a footer block */ + error = UFSJ_ALLOCATE_HEADER(vp, bp); + if (error) + goto end; /* 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); - /* Allocate a generate number. */ - /* Write the header, footer, and data blocks */ /* Update the journal superblock with the index and the generation */ + jnl->gen++; + jnl->tail = bp->b_lblkno; + /* Write the Journal */ + + /* Done with the journal, set it free */ + mtx_unlock(&jnl->jmtx); + return (0); + end: + + /* We're still holding the journal lock (verify this) and let it go */ + if (mtx_owned(&jnl->jmtx)) + mtx_unlock(&jnl->jmtx); + + /* We got the buffer, don't forget to let it go */ + brelse(bp); + return error; } /* bufdone callback for transaction buffers. */ static void -tbuf_done(struct buf *arg) +tbuf_done(struct buf *bp) { /* Is the transaction fully written to disk? If so then unpin the * buffers. */ + /* We can also free the header */ } /* bufdone callback for the real buffers. */ static void -ufsbuf_done(struct buf *arg) +ufsbuf_done(struct buf *bp) { /* Are all of the real buffers on disk? If so then update the * journalling superblock to so show that the transaction is retired. */ + /* We can also free the transaction handle */ } static void @@ -405,14 +450,24 @@ static int ufsj_replay(struct ufs_journal *journal) { + /* Read in the journal file from the jnl superblock */ + /* Crufty 2-Pass (not really) algorithm */ + /* 1. build up list of transactions. + 2. Order the transactions + 3. write the blocks to disk + */ return (0); } static int -ufsj_critical_full(void) +ufsj_critical_full(struct fs *fs) { - /* XXX */ - return 0; + /* Is MINFREE a good value, or is it even correct? */ + int free_space = freespace(fs, MINFREE); + if (free_space < UFSJ_MEGS_TO_FRAGS(fs, UFSJ_CRITICAL_FREE_SPACE)) + return 1; + else + return 0; }