Date: Sun, 28 Aug 2005 19:07:01 GMT From: soc-polytopes <soc-polytopes@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 82722 for review Message-ID: <200508281907.j7SJ71WJ033689@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=82722 Change 82722 by soc-polytopes@polytopes_kafka on 2005/08/28 19:06:51 Half of the buf managment committed. Stay tuned for part 2. Affected files ... .. //depot/projects/soc2005/ufsj/src/sys/ufs/ufs/journal.h#4 edit .. //depot/projects/soc2005/ufsj/src/sys/ufs/ufs/ufs_journal.c#4 edit Differences ... ==== //depot/projects/soc2005/ufsj/src/sys/ufs/ufs/journal.h#4 (text+ko) ==== @@ -116,6 +116,8 @@ void *data; } *ufsj_thandle_t; +MALLOC_DECLARE(M_UFSJ_HEADER); + extern int ufsj_start(struct vnode *devvp, struct mount *mp, struct fs *fs, struct thread *td); extern int ufsj_stop(struct mount *mp, int flags, struct thread *td); ==== //depot/projects/soc2005/ufsj/src/sys/ufs/ufs/ufs_journal.c#4 (text+ko) ==== @@ -67,19 +67,32 @@ uma_zone_t tzone; struct mtx jmtx; struct fs *fs; + LIST_HEAD(transaction_list, ufsj_transaction_list) t_list; }; +struct ufsj_transaction_list{ + LIST_ENTRY(ufsj_transaction_list) next; + ufsj_thandle_t t; + 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 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); + #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)) +MALLOC_DEFINE(M_UFSJ_HEADER, "journalheader", "A UFS Journal header."); + /* To be called when the FS is mounted */ int ufsj_start(struct vnode *devvp, struct mount *mp, struct fs *fs, struct thread *td) @@ -155,6 +168,8 @@ brelse(jbp); jbp = NULL; + LIST_INIT(&(journal->t_list)); + mtx_init(&journal->jmtx, "jmtx", "Journal lock", MTX_DEF); journal->tzone = uma_zcreate("Journal tranactions", sizeof(ufsj_thandle_t), NULL, NULL, NULL, NULL, 0, M_WAITOK); @@ -249,25 +264,32 @@ struct fs *fs; struct vnode *vp; struct ufs_journal *jnl; - ufsj_thandle_t h; + ufsj_thandle_t transaction; 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.")); - - /* 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); + + /* Malloc new handle and header, do this now so that we can block before + acquiring jmtx. */ + /* This is NOT good, we don't want to sleep with the lock */ + /* What is the malloc type of a header? */ + hdr = malloc(sizeof(struct ufsj_header), M_UFSJ_HEADER, M_NOWAIT|M_ZERO); + transaction = uma_zalloc(jnl->tzone, M_NOWAIT|M_ZERO); + /* We need to spin until we get a memory lock, since we hold the journal lock! */ + if (!hdr){ + panic("FUCK!"); + } else if (!transaction){ + panic("FUCK AND FUCK AGAIN!"); + } + fs = u_mnt->um_fs; vp = jnl->jvp; @@ -288,16 +310,16 @@ hdr->j_count = 0; hdr->j_type |= type; - h->gen = jnl->gen; - h->data = bp; - h->journal = jnl; + transaction->gen = jnl->gen; + transaction->data = bp; + transaction->journal = jnl; /* Done with journal */ mtx_unlock(&jnl->jmtx); bp->b_data = (void *)hdr; - *handle = h; + *handle = transaction; end: return (error); @@ -344,7 +366,8 @@ header->j_count++; - header->sectors[header->j_count] = bpc->b_lblkno; + /* Record where the orig. block lives */ + header->sectors[header->j_count] = bp->b_lblkno; bp->b_iodone = ufsbuf_done; bpc->b_iodone = tbuf_done; @@ -353,6 +376,9 @@ /* Write the block */ bdwrite(bp); + /* Register action */ + ufsj_register_block(handle, bpc, bp); + return 0; end: brelse(bpc); @@ -407,6 +433,9 @@ /* Done with the journal, set it free */ mtx_unlock(&jnl->jmtx); + + /* Register transaction (Journal doesn't need to be locked) */ + ufsj_register_transaction(handle); return (0); end: @@ -425,10 +454,54 @@ tbuf_done(struct buf *bp) { - /* Is the transaction fully written to disk? If so then unpin the - * buffers. - */ - /* We can also free the header */ + struct mount *mp; + struct ufsmount *ump; + struct vnode *vp; + struct ufsj_transaction_list *lp; + struct ufsj_transaction_list *lp_tmp; + struct ufs_journal *jnl; + int journal_updated = 0; + + KASSERT((bp != NULL), ("tbuf_done: got null bp, strange")); + + vp = bp->b_vp; + mp = vp->v_mount; + ump = VFSTOUFS(mp); + jnl = ump->um_journal; + +/* Is the transaction fully written to disk? If so then unpin the + * buffers. + */ + mtx_lock(&jnl->jmtx); + + LIST_FOREACH_SAFE(lp, &(jnl->t_list), next, lp_tmp){ + ufsj_thandle_t handle = lp->t; + struct ufsj_header *hdr = handle->data; + int i; + for (i = 0; i < hdr->j_count; i++){ + if (bp->b_lblkno == hdr->sectors[i]){ + /* Found this block in a transaction */ + lp->count--; + if (lp->count == 0){ + /* Transaction is totally written */ + LIST_REMOVE(lp, next); + uma_zfree(jnl->tzone, handle); + free(hdr, M_UFSJ_HEADER); + free(lp, M_UFSMNT); + /* Update journal to mark transaction finished */ + journal_updated = 1; + break; + } + } + } + + } + + if (journal_updated){ + /* sync jsb and jnl */ + } + + mtx_unlock(&jnl->jmtx); } /* bufdone callback for the real buffers. */ @@ -471,5 +544,38 @@ } +static void ufsj_register_transaction(ufsj_thandle_t transaction) +{ + struct ufs_journal *jnl; + struct ufsj_transaction_list *entry; + struct ufsj_header *hdr; + + KASSERT(transaction != NULL, ("ufsj_register_transaction: mountpoint is NULL.")); + + /* Allocate entry -- FIXME: malloc type */ + entry = malloc(sizeof(struct ufsj_transaction_list), M_UFSMNT, M_WAITOK|M_ZERO); + + hdr = (struct ufsj_header *)transaction->data; + jnl = transaction->journal; + + /* Lock the journal */ + mtx_lock(&jnl->jmtx); + + entry->t = transaction; + entry->count = hdr->j_count; /* We're not counting the header and the footer, should we? */ + + LIST_INSERT_HEAD(&(jnl->t_list), entry, next); + + /* 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; +} + #endif /* UFS_JOURNAL */
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200508281907.j7SJ71WJ033689>