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);

Reply via email to