Date: Mon, 29 Aug 2005 05:11:28 GMT From: soc-polytopes <soc-polytopes@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 82740 for review Message-ID: <200508290511.j7T5BSNe012738@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=82740 Change 82740 by soc-polytopes@polytopes_kafka on 2005/08/29 05:10:44 Everything but the playback is coded, but not fully debugged *mumble*lock order reversal*mumble*. Affected files ... .. //depot/projects/soc2005/ufsj/src/sys/ufs/ufs/journal.h#5 edit .. //depot/projects/soc2005/ufsj/src/sys/ufs/ufs/ufs_journal.c#5 edit Differences ... ==== //depot/projects/soc2005/ufsj/src/sys/ufs/ufs/journal.h#5 (text+ko) ==== @@ -111,11 +111,19 @@ /* typedef struct ufsj_transaction*ufsj_thandle_t; */ typedef struct ufsj_transaction{ - uint64_t gen; - struct ufs_journal *journal; - void *data; + uint64_t gen; + struct ufs_journal *journal; + int pinned_buf_count; + LIST_HEAD(buffer_list, ufsj_buffer_pair) b_list; + void *data; } *ufsj_thandle_t; +struct ufsj_buffer_pair{ + LIST_ENTRY(ufsj_buffer_pair) next; + struct buf *wait_buf; + struct buf *pinned_buf; +}; + MALLOC_DECLARE(M_UFSJ_HEADER); extern int ufsj_start(struct vnode *devvp, struct mount *mp, struct fs *fs, ==== //depot/projects/soc2005/ufsj/src/sys/ufs/ufs/ufs_journal.c#5 (text+ko) ==== @@ -76,11 +76,10 @@ long count; }; - static void ufsj_flush(struct ufs_journal *journal); static int ufsj_replay(struct ufs_journal *journal); static void tbuf_done(struct buf *arg); -static void ufsbuf_done(struct buf *arg) __unused; +static void ufsbuf_done(struct buf *arg); static int ufsj_critical_full(struct fs *fs); static void ufsj_register_transaction(ufsj_thandle_t transaction); static void ufsj_register_block(ufsj_thandle_t transaction, struct buf *wait_buf, struct buf *pinned_buf); @@ -101,9 +100,10 @@ struct ufs_journal *journal; struct ufsmount *ump; struct vnode *jvp; + struct inode *jinode; struct buf *jbp = NULL; off_t jsb_off; - int flags, error = 0; + int flags, error, vop_locked = 0; td = curthread; @@ -139,16 +139,53 @@ 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, td); + vop_locked = 1; if (error) goto out; + /* We need to check to see if the super block exists! */ + /* This check is from fsdbutil.c */ + jinode = VTOI(jvp); + if ((DIP(jinode, i_mode) & IFMT) == 0){ + /* We need to put the superblock on the disk first */ + jsb = (struct ufsj_superblock *)jbp->b_data; + jsb->j_gen = 0; + jsb->j_head = 1; + jsb->j_tail = jsb->j_head; + jsb->j_flags = J_ENABLED; + jsb->j_len = 1; /* Just us */ + jsb->j_magic = UFSJ_MAGIC; + jsb->j_fsmagic = fs->fs_magic; + + printf("ufsj_start: writing initial jsb\n"); + if ((error = bwrite(jbp)) != 0) + printf("Error %d writing journal superblock!\n", error); + + /* I don't really want to block here, but we need to, otherwise the + journal is no good */ + /* + bwait(jbp); + */ + + printf("Re-reading journal superblock at offset %jd\n", jsb_off); + error = bread(jvp, jsb_off, JSBLOCKSIZE, td->td_ucred, &jbp); + } + if (vop_locked){ + VOP_UNLOCK(jvp, 0, td); + vop_locked = 0; + } + printf("Checking journal superblock\n"); jsb = (struct ufsj_superblock *)jbp->b_data; if ((jsb->j_magic != UFSJ_MAGIC) || (jsb->j_fsmagic != fs->fs_magic) || ((jsb->j_flags & J_ENABLED) == 0)) { - error = 0; /* XXX Does this really warrant an error? */ + printf("The journal is hosed, you lose:\n"); + printf(" J_MAGIC: 0x%X, j_fsmagic(0x%X) vs. fs_magic(0x%X)\n", + jsb->j_magic, jsb->j_fsmagic, fs->fs_magic); + printf(" jsb->j_flags=%b\n", jsb->j_flags, + "\10\2ENABLED\1DIRTY\n"); + error = 1; /* XXX Does this really warrant an error? */ goto out; } @@ -162,6 +199,9 @@ journal->ump = ump; journal->bsize = fs->fs_bsize; journal->fs = fs; + + printf("Setting ump->um_journal to 0x%p\n", (void *)journal); + ump->um_journal = journal; flags = jsb->j_flags; jvp->v_vflag |= VV_SYSTEM; @@ -188,6 +228,11 @@ return (0); out: + if (vop_locked){ + VOP_UNLOCK(jvp, 0, td); + vop_locked = 0; + } + if (jbp != NULL) brelse(jbp); vrele(jvp); @@ -317,8 +362,12 @@ /* Done with journal */ mtx_unlock(&jnl->jmtx); + /* What was I going to do with this? */ bp->b_data = (void *)hdr; + transaction->pinned_buf_count = 0; + LIST_INIT(&(transaction->b_list)); + *handle = transaction; end: @@ -449,9 +498,9 @@ return error; } -/* bufdone callback for transaction buffers. */ +/* bufdone callback for the real buffers. */ static void -tbuf_done(struct buf *bp) +ufsbuf_done(struct buf *bp) { struct mount *mp; @@ -469,11 +518,12 @@ ump = VFSTOUFS(mp); jnl = ump->um_journal; -/* Is the transaction fully written to disk? If so then unpin the - * buffers. - */ mtx_lock(&jnl->jmtx); + /* Are all of the real buffers on disk? If so then update the + * journalling superblock to so show that the transaction is retired. + */ + LIST_FOREACH_SAFE(lp, &(jnl->t_list), next, lp_tmp){ ufsj_thandle_t handle = lp->t; struct ufsj_header *hdr = handle->data; @@ -504,14 +554,55 @@ mtx_unlock(&jnl->jmtx); } -/* bufdone callback for the real buffers. */ +/* bufdone callback for transaction buffers. */ static void -ufsbuf_done(struct buf *bp) +tbuf_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 */ + struct mount *mp; + struct ufsmount *ump; + struct vnode *vp; + struct ufs_journal *jnl; + struct ufsj_buffer_pair *pair; + struct ufsj_transaction_list *lp; /* To iterate over transactions */ + + KASSERT((bp != NULL), ("tbuf_done: got null bp, strange")); + + vp = bp->b_vp; + mp = vp->v_mount; + ump = VFSTOUFS(mp); + jnl = ump->um_journal; + + mtx_lock(&jnl->jmtx); + +/* Is the transaction fully written to disk? If so then unpin the + * buffers. + */ + LIST_FOREACH(lp, &(jnl->t_list), next){ + ufsj_thandle_t handle = lp->t; + LIST_FOREACH(pair, &(handle->b_list), next){ + if (pair->wait_buf->b_lblkno == bp->b_lblkno){ + handle->pinned_buf_count--; + } + } + if (handle->pinned_buf_count == 0){ + /* No more waiting bufs, pin the real bufs */ + /* and free the transaction list */ + pair = LIST_FIRST(&(handle->b_list)); + while (pair != NULL) { + struct ufsj_buffer_pair *p2; + /* Unpin the buffer */ +#ifdef BAW_HAS_INCLUDED_THE_XFS_PINNING_CODE + bunpin(pair->pinned_buf); +#endif + p2 = LIST_NEXT(pair, next); + free(pair, M_UFSMNT); + pair = p2; + } + /* Shouldn't need this */ + LIST_INIT(&(handle->b_list)); + } + } + mtx_unlock(&jnl->jmtx); } static void @@ -555,6 +646,10 @@ /* Allocate entry -- FIXME: malloc type */ entry = malloc(sizeof(struct ufsj_transaction_list), M_UFSMNT, M_WAITOK|M_ZERO); + if (entry == NULL){ + panic("ufsj_register_transaction: We were unable to allocate a new entry."); + } + hdr = (struct ufsj_header *)transaction->data; jnl = transaction->journal; @@ -568,13 +663,24 @@ /* Unlock the journal */ mtx_unlock(&jnl->jmtx); - - return; } static void ufsj_register_block(ufsj_thandle_t transaction, struct buf *wait_buf, struct buf *pinned_buf) { - return; + struct ufsj_buffer_pair *pair; + + pair = malloc(sizeof(struct ufsj_buffer_pair), M_UFSMNT, M_WAITOK|M_ZERO); + + if (pair == NULL){ + panic("ufsj_register_block: Unable to allocate list entry."); + } + + pair->wait_buf = wait_buf; + pair->pinned_buf = pinned_buf; + + transaction->pinned_buf_count++; + + LIST_INSERT_HEAD(&(transaction->b_list), pair, next); } #endif /* UFS_JOURNAL */
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200508290511.j7T5BSNe012738>