📄 logredo.c
字号:
* * Not forgetting to reset di_ixpxd since they are in different * inode extents. */ memcpy((void *) &temp_pxd, (void *) &(dip1->di_ixpxd), sizeof (pxd_t)); memcpy(dip1, dip2, DISIZE); memcpy((void *) &(dip1->di_ixpxd), (void *) &temp_pxd, sizeof (pxd_t)); if (ujfs_rw_diskblocks(fp, AITBL_OFF, PSIZE, dip, PUT)) { fsck_send_msg(lrdo_EXTFSWRITEBLKFAIL1, AITBL_OFF); goto errout; } /* * backout bmap file to fs size: * * trim xtree to range specified by i_size: * xtree has been grown in append mode and * written from right to left, bottom-up; */ barrier = __le64_to_cpu(dip1->di_size) >> sbp->s_l2bsize; /* start with root */ xaddr = 0; p = (xtpage_t *) & dip1->di_btroot; lmxflag = p->header.flag; p->header.next = 0; if (lmxflag & BT_INTERNAL) { /* save leftmost child xtpage xaddr */ lmchild = addressXAD(&p->xad[XTENTRYSTART]); } /* * scan each level of xtree via leftmost descend */ while (1) { /* * scan each xtpage of current level of xtree */ while (1) { /* * scan each xad in current xtpage */ for (i = XTENTRYSTART; i < p->header.nextindex; i++) { /* test if extent is of interest */ xoff = offsetXAD(&p->xad[i]); if (xoff < barrier) continue; /* * barrier met in current page */ assert(i > XTENTRYSTART); /* update current page */ p->header.nextindex = i; if (xaddr) { /* discard further right sibling * pages */ p->header.next = 0; if (ujfs_rw_diskblocks(fp, t64, PSIZE, p, PUT)) { fsck_send_msg(lrdo_EXTFSWRITEBLKFAIL2, (long long) t64); goto errout; } } goto nextLevel; } /* end for current xtpage scan */ /* barrier was not met in current page */ /* read in next/right sibling xtpage */ xaddr = p->header.next; if (xaddr) { if (xaddr >= barrier) { p->header.next = 0; if (ujfs_rw_diskblocks(fp, t64, PSIZE, p, PUT)) { fsck_send_msg(lrdo_EXTFSWRITEBLKFAIL3, (long long) t64); break; } } t64 = xaddr << sbp->s_l2bsize; if (ujfs_rw_diskblocks(fp, t64, PSIZE, bp, GET)) { fsck_send_msg(lrdo_EXTFSREADBLKFAIL3, (long long) t64); goto errout; } p = (xtpage_t *) bp; } else break; } /* end while current level scan */ /* * descend: read leftmost xtpage of next lower level of xtree */ nextLevel: if (lmxflag & BT_INTERNAL) { /* get the leftmost child page */ xaddr = lmchild; t64 = xaddr << sbp->s_l2bsize; if (ujfs_rw_diskblocks(fp, t64, PSIZE, bp, GET)) { fsck_send_msg(lrdo_EXTFSREADBLKFAIL4, (long long) t64); goto errout; } p = (xtpage_t *) bp; lmxflag = p->header.flag; if (lmxflag & BT_INTERNAL) { /* save leftmost child xtpage xaddr */ lmchild = addressXAD(&p->xad[XTENTRYSTART]); } } else break; } /* end while level scan */ /* * reconstruct map; * * readBmap() init blocks beyond fs size in the last * partial dmap page as allocated which might have been * marked as free by extendfs(); */ /* fake log opend/validated */ Log.serial = sbp->s_logserial; /* * reconstruct maps */ /* open LV and initialize maps */ if (logredoInit()) { fsck_send_msg(lrdo_EXTFSINITLOGREDOFAIL); goto errout; } /* bypass log replay */ /* update/write maps */ updateMaps(0); /* * reformat log * * request reformat original log (which might have been * overwritten by extendfs() and set superblock clean */ jfs_logform(fp, sbp->s_bsize, sbp->s_l2bsize, sbp->s_flag, addressPXD(&sbp->s_logpxd), lengthPXD(&sbp->s_logpxd), NULL, NULL); /* update superblock */ updateSuper(0); fsck_send_msg(lrdo_REXTNDTOPRE); return 0; /* * recover post-extendfs state */ postx: /* * update 2ndary bam inode */ /* read 2ndary block allocation map inode */ t64 = addressPXD(&sbp->s_ait2) << sbp->s_l2bsize; if (ujfs_rw_diskblocks(fp, t64, PSIZE, bp, GET)) { fsck_send_msg(lrdo_EXTFSREADBLKFAIL5, (long long) t64); goto errout; } dip2 = (struct dinode *) bp; dip2 += BMAP_I; /* * Reset 2ndary bam inode with primary bam inode * Not forgetting to reset di_ixpxd since they are in different * inode extents. */ memcpy((void *) &temp_pxd, (void *) &(dip2->di_ixpxd), sizeof (pxd_t)); memcpy(dip2, dip1, DISIZE); memcpy((void *) &(dip2->di_ixpxd), (void *) &temp_pxd, sizeof (pxd_t)); if (ujfs_rw_diskblocks(fp, t64, PSIZE, bp, PUT)) { fsck_send_msg(lrdo_EXTFSWRITEBLKFAIL4, (long long) t64); goto errout; } /* * update superblock */ if (!(sbp->s_state & (FM_DIRTY | FM_LOGREDO))) sbp->s_state = FM_CLEAN; else sbp->s_state &= ~FM_EXTENDFS; sbp->s_size = sbp->s_xsize; sbp->s_agsize = agsize; sbp->s_fsckpxd = sbp->s_xfsckpxd; sbp->s_fscklog = 0; sbp->s_logpxd = sbp->s_xlogpxd; sbp->s_logserial = 1; if (rdwrSuper(fp, sbp, PB_UPDATE)) { fsck_send_msg(lrdo_EXTFSWRITEFSSUPERFAIL); goto errout; } /* * finalize log * * note: new log is valid; */ /* read log superblock */ t64 = (addressPXD(&sbp->s_logpxd) << sbp->s_l2bsize) + LOGPSIZE; if (ujfs_rw_diskblocks(fp, t64, LOGPSIZE, &logsup, GET)) { fsck_send_msg(lrdo_EXTFSREADLOGSUPFAIL); goto errout; } logsup.end = findEndOfLog(); logsup.state = LOGREDONE; if (ujfs_rw_diskblocks(fp, t64, LOGPSIZE, &logsup, PUT)) { fsck_send_msg(lrdo_EXTFSWRITELOGSUPFAIL); goto errout; } fsck_send_msg(lrdo_REXTNDTOPOST); return 0; errout: fsck_send_msg(lrdo_REXTNDFAIL, errno); return (EXTENDFS_FAILRECOV);}/* * * NAME: alloc_dmap_bitrec * * FUNCTION: This routine allocates memory by calling the chkdsk * alloc_wrksp() routine (because that will allocate high * memory during autocheck). If that fails then logredo * cannot continue bmap processing, so it will set a flag * and make the storage aleady allocated to the bmap * available for other uses. * was successfully allocated and there's enough of it left, * this routine will return a piece of it. */int alloc_dmap_bitrec(struct dmap_bitmaps ** dmap_bitrec){ int adb_rc = 0; int intermed_rc = 0; *dmap_bitrec = NULL; intermed_rc = alloc_wrksp((uint32_t) (sizeof (struct dmap_bitmaps)), 0, /* not meaningful from logredo */ -1, /* I am logredo */ (void **) dmap_bitrec); if ((intermed_rc != 0) || ((*dmap_bitrec) == NULL)) { Insuff_memory_for_maps = -1; available_stg_addr = bmap_stg_addr; available_stg_bytes = bmap_stg_bytes; /* * initialize the storage for its new use */ memset((void *) available_stg_addr, 0, available_stg_bytes); } return (adb_rc);} /* end alloc_dmap_bitrec() *//* * * NAME: alloc_storage * * FUNCTION: This routine allocates memory by calling the chkdsk * alloc_wrksp() routine (because that will allocate high * memory during autocheck). If that fails and the bmap * was successfully allocated and there's enough of it left, * this routine will return a piece of it. */int alloc_storage(int32_t size_in_bytes, void **addr_stg_ptr, int32_t * bmap_stg_returned){ int as_rc = 0; int intermed_rc = 0; *bmap_stg_returned = 0; /* assume we'll get it the usual way */ *addr_stg_ptr = NULL; intermed_rc = alloc_wrksp((uint32_t) size_in_bytes, 0, -1, addr_stg_ptr); if ((intermed_rc != 0) || ((*addr_stg_ptr) == NULL)) { if ((!Insuff_memory_for_maps) && (bmap_stg_addr != NULL)) { /* * we did allocate storage for the bmap * and haven't started cannibalizing it yet */ Insuff_memory_for_maps = -1; available_stg_addr = bmap_stg_addr; available_stg_bytes = bmap_stg_bytes; /* * initialize the storage for its new use */ memset((void *) available_stg_addr, 0, available_stg_bytes); } /* end we did allocate storage for the bmap... */ if (Insuff_memory_for_maps & (available_stg_bytes != 0)) { /* * we may be able to go on anyway */ if (available_stg_bytes < size_in_bytes) { /* * not enough here */ return (ENOMEM0); } else { /* we can scavenge the memory we need */ *addr_stg_ptr = available_stg_addr; available_stg_bytes -= size_in_bytes; available_stg_addr = (char *) (available_stg_addr + size_in_bytes); *bmap_stg_returned = -1; } } else { return (ENOMEM1); } } return (as_rc);}#ifdef _JFS_WIP/* * nfsisloaded() * * check whether nfs is loaded */static int nfsisloaded(){ int sav_errno; int (*entry) (); if (entry = load("/usr/sbin/probe", 0, 0)) return (1); if (errno == ENOEXEC) { DBG_TRACE(("%s: nfs is not loaded\n", prog)) return (0); } sav_errno = errno; DBG_TRACE(("%s: ", prog)) errno = sav_errno; perror("load"); return (0);}#endif /* _JFS_WIP */#ifdef _JFS_DEBUG/* * xdump() * * hex dump */xdump(char *saddr, int count){#define LINESZ 60#define ASCIISTRT 40#define HEXEND 36 int i, j, k, hexdigit; int c; char *hexchar; char linebuf[LINESZ + 1]; char prevbuf[LINESZ + 1]; char *linestart; int asciistart; char asterisk = ' '; void x_scpy(); int x_scmp(); hexchar = "0123456789ABCDEF"; prevbuf[0] = '\0'; i = (int) saddr % 4; if (i != 0) saddr = saddr - i; for (i = 0; i < count;) { for (j = 0; j < LINESZ; j++) linebuf[j] = ' '; linestart = saddr; asciistart = ASCIISTRT; for (j = 0; j < HEXEND;) { for (k = 0; k < 4; k++) { c = *(saddr++) & 0xFF; if ((c >= 0x20) && (c <= 0x7e)) linebuf[asciistart++] = (char) c; else linebuf[asciistart++] = '.'; hexdigit = c >> 4; linebuf[j++] = hexchar[hexdigit]; hexdigit = c & 0x0f; linebuf[j++] = hexchar[hexdigit]; i++; } if (i >= count) break; linebuf[j++] = ' '; } linebuf[LINESZ] = '\0'; if (((j = x_scmp(linebuf, prevbuf)) == 0) && (i < count)) { if (asterisk == ' ') { asterisk = '*'; DBG_TRACE((" *\n")) } } else { DBG_TRACE((" %x %s\n", linestart, linebuf)) asterisk = ' '; x_scpy(prevbuf, linebuf); } } return (0);}int x_scmp(char *s1, char *s2){ while ((*s1) && (*s1 == *s2)) { s1++; s2++; } if (*s1 || *s2) return (-1); else return (0);}void x_scpy(char *s1, char *s2){ while ((*s1 = *s2) != '\0') { s1++; s2++; }}prtdesc(struct lrd *ld){ switch (ld->log.redopage.type) { case LOG_XTREE: DBG_TRACE((" REDOPAGE:XTREE\n ")) break; case (LOG_XTREE | LOG_NEW): DBG_TRACE((" REDOPAGE:XTREE_NEW\n ")) break; case (LOG_BTROOT | LOG_XTREE): DBG_TRACE((" REDOPAGE:BTROOT_XTREE\n ")) break; case LOG_DTREE: DBG_TRACE((" REDOPAGE:DTREE\n ")) break; case (LOG_DTREE | LOG_NEW): DBG_TRACE((" REDOPAGE:DTREE_NEW \n ")) break; case (LOG_DTREE | LOG_EXTEND): DBG_TRACE((" REDOPAGE:DTREE_EXTEND\n ")) break; case (LOG_BTROOT | LOG_DTREE): DBG_TRACE((" REDOPAGE:BTROOT_DTREE\n ")) break; case (LOG_BTROOT | LOG_DTREE | LOG_NEW): DBG_TRACE((" REDOPAGE:BTROOT_DTREE.NEW\n ")) break; case LOG_INODE: /* * logredo() updates imap for alloc of inode. */ DBG_TRACE((" REDOPAGE:INODE\n ")) break; case LOG_EA: DBG_TRACE((" REDOPAGE:EA\n ")) break; case LOG_DATA: DBG_TRACE((" REDOPAGE:DATA\n ")) break; } return (0);}#endif /* _JFS_DEBUG */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -