PERFORCE change 82722 for review
soc-polytopes
soc-polytopes at FreeBSD.org
Sun Aug 28 19:07:03 GMT 2005
http://perforce.freebsd.org/chv.cgi?CH=82722
Change 82722 by soc-polytopes at 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 */
More information about the p4-projects
mailing list