PERFORCE change 82957 for review
soc-polytopes
soc-polytopes at FreeBSD.org
Thu Sep 1 07:00:44 GMT 2005
http://perforce.freebsd.org/chv.cgi?CH=82957
Change 82957 by soc-polytopes at polytopes_kafka on 2005/09/01 07:00:06
For Scott, still have a locking issue in write_blocks
Affected files ...
.. //depot/projects/soc2005/ufsj/src/sbin/newfs/mkfs.c#3 edit
.. //depot/projects/soc2005/ufsj/src/sbin/tunefs/tunefs.c#4 edit
.. //depot/projects/soc2005/ufsj/src/sys/ufs/ufs/journal.h#7 edit
.. //depot/projects/soc2005/ufsj/src/sys/ufs/ufs/ufs_journal.c#7 edit
Differences ...
==== //depot/projects/soc2005/ufsj/src/sbin/newfs/mkfs.c#3 (text+ko) ====
@@ -1087,7 +1087,7 @@
create_journal_file(void)
{
/* Find the journal inode, and create the file there */
-/* This is only in here now
-
+/* This is only in here now as a stub */
+ return 0;
}
==== //depot/projects/soc2005/ufsj/src/sbin/tunefs/tunefs.c#4 (text+ko) ====
@@ -297,9 +297,11 @@
}
if (jflag) {
name = "journalling";
- if (jvalue == 0)
+ if (jvalue == 0) {
sblock.fs_flags &= ~FS_JOURNAL;
- else {
+ } else if (sblock.fs_flags & FS_DOSOFTDEP) {
+ warnx("Soft updates is already enabled, cannot journal.");
+ } else {
sblock.fs_flags |= FS_JOURNAL;
sblock.fs_journal_inode = jvalue;
}
@@ -346,6 +348,9 @@
else if (sblock.fs_clean == 0) {
warnx("%s cannot be enabled until fsck is run",
name);
+ } else if (sblock.fs_flags & FS_JOURNAL) {
+ warnx("%s cannot be enabled while journaling is enabled",
+ name);
} else {
sblock.fs_flags |= FS_DOSOFTDEP;
warnx("%s set", name);
==== //depot/projects/soc2005/ufsj/src/sys/ufs/ufs/journal.h#7 (text+ko) ====
@@ -25,6 +25,11 @@
*/
/*
+ Special thanks to Google for choosing this project as part of
+ the Google Summer of Code.
+*/
+
+/*
* UFS Journal structures and definitions
*/
==== //depot/projects/soc2005/ufsj/src/sys/ufs/ufs/ufs_journal.c#7 (text+ko) ====
@@ -53,7 +53,11 @@
* 6. What do we do with these pink elephants called QUOTA and SOFTUPDATES? =-)
*/
-/* BUGS: 1. Race condition with writing the footer. */
+/*
+ BUGS: 1. Race condition with writing the footer.
+ 2. Until the buffer pinning is patched in, out of order writes
+ 3. Data integrity is not yet ensured.
+*/
struct ufs_journal {
@@ -88,7 +92,7 @@
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), curthread->td_ucred, 0, &(bb))
+#define UFSJ_ALLOCATE_HEADER(vp, offset, bp) UFS_BALLOC((vp), (offset), sizeof(struct ufsj_header), curthread->td_ucred, 0, &(bp))
/* UFSJ_CRITICAL_FREE_SPACE is in Megs, but freespace returns frags */
#define UFSJ_MEGS_TO_FRAGS(fs, megs) (1024*1024*(fs)->fs_fsize*(megs))
@@ -97,6 +101,31 @@
MALLOC_DEFINE(M_UFSJ_TRANSACTION_LIST, "transactionlist", "A list of UFS journal transactions.");
MALLOC_DEFINE(M_UFSJ_BUF_PAIR, "bufpair", "A pair of bufs, one pinned and the other a wait condition.");
+
+/* A handy macro to avoid duplicating the jsb sync code */
+#define SYNC_JOURNAL(jvp, jbp, journal, error, routine_name) \
+do { \
+ struct ufsj_superblock *jsb; \
+ /* Write the Journal */ \
+ printf("%s: reading jsb\n", (routine_name)); \
+ if (((error) = bread((jvp), (journal)->jsb_off, JSBLOCKSIZE, \
+ NOCRED, &(jbp))) == 0) { \
+ jsb = (struct ufsj_superblock *) (jbp)->b_data; \
+ jsb->j_gen = (journal)->gen; \
+ jsb->j_head = (journal)->head; \
+ jsb->j_tail = (journal)->tail; \
+ printf("%s: writing jsb\n", (routine_name)); \
+ if (((error) = bwrite((jbp))) != 0) \
+ printf("Error %d writing journal superblock!\n", (error)); \
+ } else { \
+ printf("%s: read of sb failed\n", (routine_name)); \
+ brelse((jbp)); \
+ } \
+} while(0)
+
+
+
+
/* To be called when the FS is mounted */
int
ufsj_start(struct vnode *devvp, struct mount *mp, struct fs *fs, struct thread *td)
@@ -207,7 +236,7 @@
journal->bsize = fs->fs_bsize;
journal->fs = fs;
- printf("Setting ump->um_journal to 0x%p\n", (void *)journal);
+ printf("Setting ump->um_journal to %p\n", (void *)journal);
ump->um_journal = journal;
flags = jsb->j_flags;
@@ -318,29 +347,31 @@
struct ufs_journal *jnl;
ufsj_thandle_t transaction;
struct ufsj_header *hdr;
+ uma_zone_t zone;
int error = 0, journal_is_locked = 0;
KASSERT(u_mnt != NULL, ("ufsj_start_transaction: mountpoint is NULL."));
KASSERT(handle != NULL, ("ufsj_start_transaction: handle is NULL."));
/* Grab the Journal from ufsmount */
jnl = u_mnt->um_journal;
+ zone = jnl->tzone;
- /* 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);
+ hdr = malloc(sizeof(struct ufsj_header), M_UFSJ_HEADER, M_WAITOK|M_ZERO);
+ transaction = uma_zalloc(jnl->tzone, M_WAITOK|M_ZERO);
- /* We need to spin until we get a memory lock, since we hold the journal lock! */
+ /* Don't need to spin, but could have failures */
if (!hdr){
- panic("FUCK!");
+ panic("ufsj_start_transaction: Unable to allocate header.");
} else if (!transaction){
- panic("FUCK AND FUCK AGAIN!");
+ panic("ufsj_start_transaction: Unable to allocate transaction.");
}
+
+ /* Lock the journal */
+ mtx_lock(&jnl->jmtx);
+
fs = u_mnt->um_fs;
vp = jnl->jvp;
@@ -355,13 +386,17 @@
error = 1;
goto end;
}
+
journal_is_locked = 1;
ASSERT_VOP_LOCKED(vp, "ufsj_start_transaction");
printf("ufsj_start_transaction: Trying to allocate header.\n");
/* Allocate a block for the transaction header */
- error = UFSJ_ALLOCATE_HEADER(vp, bp);
+ error = UFSJ_ALLOCATE_HEADER(vp, jnl->next, bp);
+
+ /* Point to the next blkno */
+ jnl->next++;
journal_is_locked = 0;
VOP_UNLOCK(vp, 0, curthread);
@@ -391,6 +426,7 @@
*handle = transaction;
+ printf("ufsj_start_transaction: Transaction created successfully\n");
end:
if (journal_is_locked)
VOP_UNLOCK(vp, 0, curthread);
@@ -410,6 +446,7 @@
struct buf *bpc;
struct ufsj_header *header;
+ struct ufs_journal *jnl;
int error = 0, journal_is_locked = 0;
KASSERT(handle != NULL, ("ufsj_write_blocks: NULL transaction"));
@@ -430,6 +467,8 @@
}
+ jnl = handle->journal;
+ mtx_lock(&jnl->jmtx);
printf("ufsj_write_blocks: Acquiring lock on %p\n", handle->journal->jvp);
if (vn_lock(handle->journal->jvp, LK_EXCLUSIVE|LK_CANRECURSE|LK_NOWAIT, curthread)){
printf("ufsj_write_blocks: Couldn't lock vnode, giving up\n");
@@ -439,27 +478,33 @@
journal_is_locked = 1;
ASSERT_VOP_LOCKED(handle->journal->jvp, "ufsj_write_blocks");
- error = UFS_BALLOC(handle->journal->jvp, 1, sizeof(*(bp->b_data)),
+ printf("ufsj_write_blocks: Trying to get buffer copy, lblk: %ld sz: %ld\n",
+ (long)jnl->next, (long)jnl->fs->fs_bsize);
+ error = UFS_BALLOC(handle->journal->jvp, jnl->next, jnl->fs->fs_bsize,
curthread->td_ucred, bp->b_flags, &bpc);
+
journal_is_locked = 0;
VOP_UNLOCK(handle->journal->jvp, 0, curthread);
if (error){
/* XXX: Does anymore cleanup need done? */
goto end;
}
+ jnl->next++;
+ mtx_unlock(&jnl->jmtx);
/* Just copy the pointer, don't copy the data */
bpc->b_data = bp->b_data;
header->j_count++;
- /* Record where the orig. block lives */
header->sectors[header->j_count] = bpc->b_lblkno;
bp->b_iodone = ufsbuf_done;
bpc->b_iodone = tbuf_done;
/* Pin the buffer */
- /* TODO */
+#ifdef BAW_HAS_INCLUDED_THE_XFS_PINNING_CODE
+ bpin(bp);
+#endif
/* Write the block */
bdwrite(bp);
@@ -468,6 +513,8 @@
return 0;
end:
+ if (mtx_owned(&jnl->jmtx))
+ mtx_unlock(&jnl->jmtx);
if (journal_is_locked)
VOP_UNLOCK(handle->journal->jvp, 0, curthread);
brelse(bpc);
@@ -488,6 +535,7 @@
struct vnode *vp;
struct ufs_journal *jnl;
struct ufsj_buffer_pair *pair;
+ struct buf *jbp;
int error = 0, journal_is_locked = 0;
KASSERT(handle != NULL, ("ufsj_end_transaction: handle is NULL."));
@@ -513,10 +561,11 @@
ASSERT_VOP_LOCKED(vp, "ufsj_end_transaction");
/* Allocate a footer block */
- error = UFSJ_ALLOCATE_HEADER(vp, bp);
+ error = UFSJ_ALLOCATE_HEADER(vp, jnl->next, bp);
if (error)
goto end;
+ jnl->next++;
handle->footer = bp;
/* Allocate space in the journal. Is the journal full? If so then
@@ -535,7 +584,7 @@
jnl->gen++;
jnl->tail = bp->b_lblkno;
- /* Write the Journal */
+ SYNC_JOURNAL(jnl->jvp, jbp, jnl, error, "ufsj_end_transaction");
/* Done with the journal, set it free */
mtx_unlock(&jnl->jmtx);
@@ -605,7 +654,9 @@
}
if (journal_updated){
- /* sync jsb and jnl */
+ struct buf *jbp;
+ int error = 0;
+ SYNC_JOURNAL(jnl->jvp, jbp, jnl, error, "ufsbuf_done");
}
mtx_unlock(&jnl->jmtx);
@@ -667,18 +718,20 @@
{
struct ufsj_transaction_list *lp;
struct ufsj_buffer_pair *pair;
+ int error = 0;
LIST_FOREACH(lp, &(journal->t_list), next){
ufsj_thandle_t handle = lp->t;
- bawrite(handle->header);
+ /* FIXME: How do we handle errors */
+ error = bwrite(handle->header);
LIST_FOREACH(pair, &(handle->b_list), next){
- bawrite(pair->wait_buf);
+ error = bwrite(pair->wait_buf);
#ifdef BAW_HAS_INCLUDED_THE_XFS_PINNING_CODE
bunpin(pair->pinned_buf);
#endif
- bawrite(pair->pinned_buf);
+ error = bwrite(pair->pinned_buf);
}
- bawrite(handle->footer);
+ error = bwrite(handle->footer);
}
}
@@ -691,6 +744,13 @@
2. Order the transactions
3. write the blocks to disk
*/
+ /* Read jnl->head */
+ /* while (cur_blk != jnl->tail)
+ getblk cur_blk
+ write_blk to real location
+ cur_blk = header->*mumble*
+ */
+
return (0);
}
More information about the p4-projects
mailing list