PERFORCE change 82740 for review
soc-polytopes
soc-polytopes at FreeBSD.org
Mon Aug 29 05:11:30 GMT 2005
http://perforce.freebsd.org/chv.cgi?CH=82740
Change 82740 by soc-polytopes at 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 */
More information about the p4-projects
mailing list