Skip site navigation (1)Skip section navigation (2)
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>