Ok, this is enough to be able to replay the journal log. I'm assuming *dip
was never updated through aliasing, but it would be good if someone could
double check that.
Running fsck -f still dies, but at least this should be enough to recover
from a power failure.
--
Ivan
diff -ur jfsutils-1.1.11.orig/libfs/log_work.c jfsutils-1.1.11/libfs/log_work.c
--- jfsutils-1.1.11.orig/libfs/log_work.c 2006-06-04 17:37:29.000000000
-0400
+++ jfsutils-1.1.11/libfs/log_work.c 2008-09-17 12:50:18.123057616 -0400
@@ -2412,7 +2412,7 @@
xad_t *xad_p;
pxd_t pxd1;
struct iag_data *imp;
- struct dinode *dip = 0;
+ struct dinode dip;
int32_t xlen, xlength;
int16_t nword;
int8_t upd_possible = 0;
@@ -2713,7 +2713,7 @@
*/
if (ino_rem == 0) { /* inode base segment */
- dip = (struct dinode *) data;
+ memcpy(&dip, data, sizeof(dip));
if (ln == 1) {
/* ibase only */
if (db->db_ibase & mask_8)
@@ -2798,7 +2798,7 @@
* this case, we will mark block map to show
* the whole inode extent (all 4 pages) as
* allocated */
- allocate = (dip->di_nlink != 0);
+ allocate = (dip.di_nlink != 0);
inoext_alloc |= allocate;
/*
* There is only one fileset per aggregate, so
@@ -2807,8 +2807,8 @@
*/
if (ld->log.redopage.inode == FILESYSTEM_I) {
rc = markImap(&vopen[vol].fsimap_lst,
-
__le32_to_cpu(dip->di_number),
- dip->di_ixpxd, allocate,
vol);
+
__le32_to_cpu(dip.di_number),
+ dip.di_ixpxd, allocate,
vol);
if (rc) {
fsck_send_msg(lrdo_UPPGMIMPFAIL, rc);
return (rc);
@@ -2824,7 +2824,7 @@
*/
if (!allocate)
- doNoRedoFile(ld,
__le32_to_cpu(dip->di_number));
+ doNoRedoFile(ld,
__le32_to_cpu(dip.di_number));
}
} else if ((ld->log.redopage.type & (LOG_BTROOT | LOG_XTREE))
== (LOG_BTROOT | LOG_XTREE)) {
@@ -3107,7 +3107,7 @@
/*
* figure out which IAG and which extent
*/
- iag_num =
INOTOIAG(__le32_to_cpu(dip->di_number));
+ iag_num =
INOTOIAG(__le32_to_cpu(dip.di_number));
imp = vopen[vol].fsimap_lst.imap_wsp[(iag_num +
1)
].imap_data;
@@ -3121,18 +3121,18 @@
].imap_data;
}
/* end first touch to this IAG */
- ino = __le32_to_cpu(dip->di_number) &
(INOSPERIAG - 1);
+ ino = __le32_to_cpu(dip.di_number) &
(INOSPERIAG - 1);
extno = ino >> L2INOSPEREXT;
/*
* make sure the IAG points to it correctly
*/
- imp->inoext[extno] = dip->di_ixpxd;
+ imp->inoext[extno] = dip.di_ixpxd;
}
/* end fileset owned */
/*
* make sure the block map shows it allocated
*/
- rc = markBmap((struct dmap *) vopen[vol].bmap_ctl,
dip->di_ixpxd, 1, vol);
+ rc = markBmap((struct dmap *) vopen[vol].bmap_ctl,
dip.di_ixpxd, 1, vol);
if (rc) {
fsck_send_msg(lrdo_UPPGMBMPFAIL, rc);
return (rc);
diff -ur jfsutils-1.1.11.orig/libfs/super.c jfsutils-1.1.11/libfs/super.c
--- jfsutils-1.1.11.orig/libfs/super.c 2005-11-22 15:43:55.000000000 -0500
+++ jfsutils-1.1.11/libfs/super.c 2008-09-15 22:16:05.201266777 -0400
@@ -162,14 +162,14 @@
*/
int ujfs_put_superblk(FILE *fp, struct superblock *sb, int16_t is_primary)
{
- char buf[SIZE_OF_SUPER];
+ struct superblock buf[(SIZE_OF_SUPER+sizeof(*sb)-1)/sizeof(*sb)];
int rc;
memset(buf, 0, SIZE_OF_SUPER);
memcpy(buf, sb, sizeof (*sb));
/* swap if on big endian machine */
- ujfs_swap_superblock((struct superblock *) buf);
+ ujfs_swap_superblock(buf);
rc = ujfs_rw_diskblocks(fp, (is_primary ? SUPER1_OFF : SUPER2_OFF),
SIZE_OF_SUPER, buf, PUT);