PERFORCE change 82954 for review
soc-polytopes
soc-polytopes at FreeBSD.org
Thu Sep 1 04:06:14 GMT 2005
http://perforce.freebsd.org/chv.cgi?CH=82954
Change 82954 by soc-polytopes at polytopes_kafka on 2005/09/01 04:05:23
Checkpoint.
Affected files ...
.. //depot/projects/soc2005/ufsj/src/sys/ufs/ufs/journal.h#6 edit
.. //depot/projects/soc2005/ufsj/src/sys/ufs/ufs/ufs_journal.c#6 edit
Differences ...
==== //depot/projects/soc2005/ufsj/src/sys/ufs/ufs/journal.h#6 (text+ko) ====
@@ -115,7 +115,8 @@
struct ufs_journal *journal;
int pinned_buf_count;
LIST_HEAD(buffer_list, ufsj_buffer_pair) b_list;
- void *data;
+ void *header;
+ void *footer;
} *ufsj_thandle_t;
struct ufsj_buffer_pair{
@@ -125,6 +126,8 @@
};
MALLOC_DECLARE(M_UFSJ_HEADER);
+MALLOC_DECLARE(M_UFSJ_TRANSACTION_LIST);
+MALLOC_DECLARE(M_UFSJ_BUF_PAIR);
extern int ufsj_start(struct vnode *devvp, struct mount *mp, struct fs *fs,
struct thread *td);
==== //depot/projects/soc2005/ufsj/src/sys/ufs/ufs/ufs_journal.c#6 (text+ko) ====
@@ -53,6 +53,9 @@
* 6. What do we do with these pink elephants called QUOTA and SOFTUPDATES? =-)
*/
+/* BUGS: 1. Race condition with writing the footer. */
+
+
struct ufs_journal {
uint64_t gen;
off_t start;
@@ -85,12 +88,14 @@
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))
+#define UFSJ_ALLOCATE_HEADER(aa, bb) UFS_BALLOC((aa), 0, sizeof(struct ufsj_header), curthread->td_ucred, 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.");
+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.");
/* To be called when the FS is mounted */
int
@@ -186,6 +191,8 @@
printf(" jsb->j_flags=%b\n", jsb->j_flags,
"\10\2ENABLED\1DIRTY\n");
error = 1; /* XXX Does this really warrant an error? */
+ /* Yes, tthis can imply that we have a null jsb,
+ which gives lovely writes to 0x0 */
goto out;
}
@@ -251,7 +258,7 @@
struct vnode *jvp;
int error, jflags;
- td = curthread; /* XXX */
+ td = curthread; /* Curthread gives us the correct creds (I think) */
ump = VFSTOUFS(mp);
journal = ump->um_journal;
jflags = 0;
@@ -311,7 +318,7 @@
struct ufs_journal *jnl;
ufsj_thandle_t transaction;
struct ufsj_header *hdr;
- int error = 0;
+ 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."));
@@ -342,9 +349,23 @@
ufsj_flush(jnl);
}
+ printf("ufsj_start_transaction: Acquiring lock on %p\n", vp);
+ if (vn_lock(vp, LK_EXCLUSIVE|LK_NOWAIT, curthread)){
+ printf("ufsj_start_transaction: Couldn't lock vnode, giving up\n");
+ 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);
+ journal_is_locked = 0;
+ VOP_UNLOCK(vp, 0, curthread);
+
if (error){
/* Did not allocate a buf */
goto end;
@@ -356,7 +377,7 @@
hdr->j_type |= type;
transaction->gen = jnl->gen;
- transaction->data = bp;
+ transaction->header = bp;
transaction->journal = jnl;
/* Done with journal */
@@ -371,6 +392,9 @@
*handle = transaction;
end:
+ if (journal_is_locked)
+ VOP_UNLOCK(vp, 0, curthread);
+
return (error);
}
@@ -386,15 +410,17 @@
struct buf *bpc;
struct ufsj_header *header;
- int error;
+ int error = 0, journal_is_locked = 0;
KASSERT(handle != NULL, ("ufsj_write_blocks: NULL transaction"));
KASSERT(bp != NULL, ("ufsj_write_blocks: NULL buffer"));
- header = handle->data;
+ header = handle->header;
- if (!(bp->b_flags & BA_METAONLY))
+ /* It seems that there is no BA_METAONLY, oops!
+ if (!(bp->b_flags & BA_METAONLY))
panic("ufsj: Got non-metadata block(0x%X)", (unsigned int)bp);
+ */
if (header->j_count > UFSJ_MAX_SIZE){
panic("ufsj: Went past the end of the journal, count: %d", (int)header->j_count);
@@ -403,11 +429,23 @@
panic("ufsj: Filled transaction");
}
- error = UFS_BALLOC(handle->journal->jvp, 0, sizeof(*(bp->b_data)),
- FSCRED, bp->b_flags, &bpc);
+
+ 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");
+ error = 1;
+ goto end;
+ }
+ journal_is_locked = 1;
+ ASSERT_VOP_LOCKED(handle->journal->jvp, "ufsj_write_blocks");
+
+ error = UFS_BALLOC(handle->journal->jvp, 1, sizeof(*(bp->b_data)),
+ 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;
- /* XXX */
}
/* Just copy the pointer, don't copy the data */
@@ -416,7 +454,7 @@
header->j_count++;
/* Record where the orig. block lives */
- header->sectors[header->j_count] = bp->b_lblkno;
+ header->sectors[header->j_count] = bpc->b_lblkno;
bp->b_iodone = ufsbuf_done;
bpc->b_iodone = tbuf_done;
@@ -430,6 +468,8 @@
return 0;
end:
+ if (journal_is_locked)
+ VOP_UNLOCK(handle->journal->jvp, 0, curthread);
brelse(bpc);
return error;
}
@@ -447,7 +487,8 @@
struct fs *fs;
struct vnode *vp;
struct ufs_journal *jnl;
- int error;
+ struct ufsj_buffer_pair *pair;
+ int error = 0, journal_is_locked = 0;
KASSERT(handle != NULL, ("ufsj_end_transaction: handle is NULL."));
@@ -462,17 +503,33 @@
fs = jnl->ump->um_fs;
vp = jnl->jvp;
+ printf("ufsj_end_transaction: Acquiring lock on %p\n", vp);
+ if (vn_lock(vp, LK_EXCLUSIVE|LK_NOWAIT, curthread)){
+ printf("ufsj_end_transaction: Couldn't lock vnode, giving up\n");
+ error = 1;
+ goto end;
+ }
+ journal_is_locked = 1;
+ ASSERT_VOP_LOCKED(vp, "ufsj_end_transaction");
+
/* Allocate a footer block */
error = UFSJ_ALLOCATE_HEADER(vp, bp);
if (error)
goto end;
+ handle->footer = bp;
+
/* Allocate space in the journal. Is the journal full? If so then
* synchronously flush the blocks for the oldest transactions */
if (ufsj_critical_full(fs))
ufsj_flush(jnl);
/* Write the header, footer, and data blocks */
+ bdwrite(handle->header);
+ LIST_FOREACH(pair, &(handle->b_list), next){
+ bdwrite(pair->wait_buf);
+ }
+ bdwrite(bp);
/* Update the journal superblock with the index and the generation */
jnl->gen++;
@@ -526,7 +583,7 @@
LIST_FOREACH_SAFE(lp, &(jnl->t_list), next, lp_tmp){
ufsj_thandle_t handle = lp->t;
- struct ufsj_header *hdr = handle->data;
+ struct ufsj_header *hdr = handle->header;
int i;
for (i = 0; i < hdr->j_count; i++){
if (bp->b_lblkno == hdr->sectors[i]){
@@ -608,7 +665,21 @@
static void
ufsj_flush(struct ufs_journal *journal)
{
- return;
+ struct ufsj_transaction_list *lp;
+ struct ufsj_buffer_pair *pair;
+
+ LIST_FOREACH(lp, &(journal->t_list), next){
+ ufsj_thandle_t handle = lp->t;
+ bawrite(handle->header);
+ LIST_FOREACH(pair, &(handle->b_list), next){
+ bawrite(pair->wait_buf);
+#ifdef BAW_HAS_INCLUDED_THE_XFS_PINNING_CODE
+ bunpin(pair->pinned_buf);
+#endif
+ bawrite(pair->pinned_buf);
+ }
+ bawrite(handle->footer);
+ }
}
static int
@@ -643,14 +714,14 @@
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);
+ /* Allocate Entry */
+ entry = malloc(sizeof(struct ufsj_transaction_list), M_UFSJ_TRANSACTION_LIST, 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;
+ hdr = (struct ufsj_header *)transaction->header;
jnl = transaction->journal;
/* Lock the journal */
@@ -669,7 +740,7 @@
{
struct ufsj_buffer_pair *pair;
- pair = malloc(sizeof(struct ufsj_buffer_pair), M_UFSMNT, M_WAITOK|M_ZERO);
+ pair = malloc(sizeof(struct ufsj_buffer_pair), M_UFSJ_BUF_PAIR, M_WAITOK|M_ZERO);
if (pair == NULL){
panic("ufsj_register_block: Unable to allocate list entry.");
More information about the p4-projects
mailing list