From: Dave Chinner <dchinner@xxxxxxxxxx> Update the log recovery code to match the current 3.8-rc2 kernel code. Note: while this introduces CRC validation infrastructure, it is currently short-circuited as we cannot validate the CRC from userspace because we do not know what the size of the log buffer was that wrote the header. This information is not written into the log header anywhere, so we have no way of working out the correct number of extra headers that need to be summed. This is also a problem for the kernel code, and needs fixing. Signed-off-by: Dave Chinner <dchinner@xxxxxxxxxx> --- db/sb.c | 7 +- include/libxlog.h | 32 ++--- libxlog/xfs_log_recover.c | 301 +++++++++++++++++++++++++++----------------- logprint/log_copy.c | 2 +- logprint/log_dump.c | 2 +- logprint/log_misc.c | 4 +- logprint/log_print_all.c | 2 +- logprint/log_print_trans.c | 4 +- logprint/logprint.c | 2 +- logprint/logprint.h | 10 +- repair/phase2.c | 7 +- 11 files changed, 229 insertions(+), 144 deletions(-) diff --git a/db/sb.c b/db/sb.c index 21f38c5..d83db9c 100644 --- a/db/sb.c +++ b/db/sb.c @@ -205,12 +205,15 @@ get_sb(xfs_agnumber_t agno, xfs_sb_t *sb) } /* workaround craziness in the xlog routines */ -int xlog_recover_do_trans(xlog_t *log, xlog_recover_t *t, int p) { return 0; } +int xlog_recover_do_trans(struct xlog *log, xlog_recover_t *t, int p) +{ + return 0; +} int sb_logcheck(void) { - xlog_t log; + struct xlog log; xfs_daddr_t head_blk, tail_blk; if (mp->m_sb.sb_logstart) { diff --git a/include/libxlog.h b/include/libxlog.h index d1142ab..36ede59 100644 --- a/include/libxlog.h +++ b/include/libxlog.h @@ -24,7 +24,7 @@ * xlog_t that we actually need to get our work done, avoiding * the need to define any exotic kernel types in userland. */ -typedef struct log { +struct xlog { xfs_lsn_t l_tail_lsn; /* lsn of 1st LR w/ unflush buffers */ xfs_lsn_t l_last_sync_lsn;/* lsn of last LR on disk */ xfs_mount_t *l_mp; /* mount point */ @@ -45,7 +45,7 @@ typedef struct log { uint l_sectbb_mask; /* sector size (in BBs) * alignment mask */ int l_sectBBsize; /* size of log sector in 512 byte chunks */ -} xlog_t; +}; #include <xfs/xfs_log_recover.h> #include <xfs/xfs_buf_item.h> @@ -76,6 +76,10 @@ typedef union { #define unlikely(x) (x) #define min(a,b) ((a) < (b) ? (a) : (b)) +#define xfs_warn(mp,fmt,args...) cmn_err(CE_WARN,fmt, ## args) +#define xfs_alert(mp,fmt,args...) cmn_err(CE_ALERT,fmt, ## args) +#define xfs_hex_dump(d,n) ((void) 0) + extern void xlog_warn(char *fmt,...); extern void xlog_exit(char *fmt,...); extern void xlog_panic(char *fmt,...); @@ -88,34 +92,34 @@ extern int print_record_header; /* libxfs parameters */ extern libxfs_init_t x; -extern struct xfs_buf *xlog_get_bp(xlog_t *, int); +extern struct xfs_buf *xlog_get_bp(struct xlog *, int); extern void xlog_put_bp(struct xfs_buf *); -extern int xlog_bread(xlog_t *log, xfs_daddr_t blk_no, int nbblks, +extern int xlog_bread(struct xlog *log, xfs_daddr_t blk_no, int nbblks, xfs_buf_t *bp, xfs_caddr_t *offset); -extern int xlog_bread_noalign(xlog_t *log, xfs_daddr_t blk_no, int nbblks, - xfs_buf_t *bp); +extern int xlog_bread_noalign(struct xlog *log, xfs_daddr_t blk_no, + int nbblks, xfs_buf_t *bp); -extern int xlog_find_zeroed(xlog_t *log, xfs_daddr_t *blk_no); -extern int xlog_find_cycle_start(xlog_t *log, xfs_buf_t *bp, +extern int xlog_find_zeroed(struct xlog *log, xfs_daddr_t *blk_no); +extern int xlog_find_cycle_start(struct xlog *log, xfs_buf_t *bp, xfs_daddr_t first_blk, xfs_daddr_t *last_blk, uint cycle); -extern int xlog_find_tail(xlog_t *log, xfs_daddr_t *head_blk, +extern int xlog_find_tail(struct xlog *log, xfs_daddr_t *head_blk, xfs_daddr_t *tail_blk); -extern int xlog_test_footer(xlog_t *log); -extern int xlog_recover(xlog_t *log, int readonly); +extern int xlog_test_footer(struct xlog *log); +extern int xlog_recover(struct xlog *log, int readonly); extern void xlog_recover_print_data(xfs_caddr_t p, int len); extern void xlog_recover_print_logitem(xlog_recover_item_t *item); extern void xlog_recover_print_trans_head(xlog_recover_t *tr); -extern int xlog_print_find_oldest(xlog_t *log, xfs_daddr_t *last_blk); +extern int xlog_print_find_oldest(struct xlog *log, xfs_daddr_t *last_blk); /* for transactional view */ extern void xlog_recover_print_trans_head(xlog_recover_t *tr); extern void xlog_recover_print_trans(xlog_recover_t *trans, struct list_head *itemq, int print); -extern int xlog_do_recovery_pass(xlog_t *log, xfs_daddr_t head_blk, +extern int xlog_do_recovery_pass(struct xlog *log, xfs_daddr_t head_blk, xfs_daddr_t tail_blk, int pass); -extern int xlog_recover_do_trans(xlog_t *log, xlog_recover_t *trans, +extern int xlog_recover_do_trans(struct xlog *log, xlog_recover_t *trans, int pass); extern int xlog_header_check_recover(xfs_mount_t *mp, xlog_rec_header_t *head); diff --git a/libxlog/xfs_log_recover.c b/libxlog/xfs_log_recover.c index 23fe6fd..ad53e86 100644 --- a/libxlog/xfs_log_recover.c +++ b/libxlog/xfs_log_recover.c @@ -18,10 +18,11 @@ #include <xfs/libxlog.h> -#define xlog_unpack_data_checksum(rhead, dp, log) ((void)0) -#define xlog_clear_stale_blocks(log, tail_lsn) (0) #define xfs_readonly_buftarg(buftarg) (0) +/* avoid set-but-unused var warning. gcc is not very bright. */ +#define xlog_clear_stale_blocks(log, taillsn) ((taillsn) = (taillsn)) + /* * Verify the given count of basic blocks is valid number of blocks @@ -31,7 +32,7 @@ static inline int xlog_buf_bbcount_valid( - xlog_t *log, + struct xlog *log, int bbcount) { return bbcount > 0 && bbcount <= log->l_logBBsize; @@ -44,11 +45,11 @@ xlog_buf_bbcount_valid( */ xfs_buf_t * xlog_get_bp( - xlog_t *log, + struct xlog *log, int nbblks) { if (!xlog_buf_bbcount_valid(log, nbblks)) { - xlog_warn("XFS: Invalid block length (0x%x) given for buffer", + xfs_warn(log->l_mp, "Invalid block length (0x%x) for buffer", nbblks); XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_HIGH, log->l_mp); return NULL; @@ -57,7 +58,7 @@ xlog_get_bp( /* * We do log I/O in units of log sectors (a power-of-2 * multiple of the basic block size), so we round up the - * requested size to acommodate the basic blocks required + * requested size to accommodate the basic blocks required * for complete log sectors. * * In addition, the buffer may be used for a non-sector- @@ -68,12 +69,11 @@ xlog_get_bp( * an issue. Nor will this be a problem if the log I/O is * done in basic blocks (sector size 1). But otherwise we * extend the buffer by one extra log sector to ensure - * there's space to accomodate this possiblility. + * there's space to accommodate this possibility. */ if (nbblks > 1 && log->l_sectBBsize > 1) nbblks += log->l_sectBBsize; - if (log->l_sectBBsize) - nbblks = round_up(nbblks, log->l_sectBBsize); + nbblks = round_up(nbblks, log->l_sectBBsize); return libxfs_getbufr(log->l_dev, (xfs_daddr_t)-1, nbblks); } @@ -91,57 +91,54 @@ xlog_put_bp( */ STATIC xfs_caddr_t xlog_align( - xlog_t *log, + struct xlog *log, xfs_daddr_t blk_no, int nbblks, - xfs_buf_t *bp) + struct xfs_buf *bp) { - xfs_daddr_t offset = 0; - - if (log->l_sectBBsize) - offset = blk_no & ((xfs_daddr_t)log->l_sectBBsize - 1); + xfs_daddr_t offset = blk_no & ((xfs_daddr_t)log->l_sectBBsize - 1); - ASSERT(BBTOB(offset + nbblks) <= XFS_BUF_SIZE(bp)); - return XFS_BUF_PTR(bp) + BBTOB(offset); + ASSERT(offset + nbblks <= bp->b_length); + return bp->b_addr + BBTOB(offset); } + /* * nbblks should be uint, but oh well. Just want to catch that 32-bit length. */ int xlog_bread_noalign( - xlog_t *log, + struct xlog *log, xfs_daddr_t blk_no, int nbblks, - xfs_buf_t *bp) + struct xfs_buf *bp) { if (!xlog_buf_bbcount_valid(log, nbblks)) { - xlog_warn("XFS: Invalid block length (0x%x) given for buffer", + xfs_warn(log->l_mp, "Invalid block length (0x%x) for buffer", nbblks); XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_HIGH, log->l_mp); return EFSCORRUPTED; } - if (log->l_sectBBsize > 1) { - blk_no = round_down(blk_no, log->l_sectBBsize); - nbblks = round_up(nbblks, log->l_sectBBsize); - } + blk_no = round_down(blk_no, log->l_sectBBsize); + nbblks = round_up(nbblks, log->l_sectBBsize); ASSERT(nbblks > 0); ASSERT(BBTOB(nbblks) <= XFS_BUF_SIZE(bp)); XFS_BUF_SET_ADDR(bp, log->l_logBBstart + blk_no); XFS_BUF_SET_COUNT(bp, BBTOB(nbblks)); + bp->b_error = 0; return libxfs_readbufr(log->l_dev, XFS_BUF_ADDR(bp), bp, nbblks, 0); } int xlog_bread( - xlog_t *log, + struct xlog *log, xfs_daddr_t blk_no, int nbblks, - xfs_buf_t *bp, + struct xfs_buf *bp, xfs_caddr_t *offset) { int error; @@ -155,6 +152,35 @@ xlog_bread( } /* + * Read at an offset into the buffer. Returns with the buffer in it's original + * state regardless of the result of the read. + */ +STATIC int +xlog_bread_offset( + struct xlog *log, + xfs_daddr_t blk_no, /* block to read from */ + int nbblks, /* blocks to read */ + struct xfs_buf *bp, + xfs_caddr_t offset) +{ + xfs_caddr_t orig_offset = bp->b_addr; + int orig_len = bp->b_bcount; + int error, error2; + + error = XFS_BUF_SET_PTR(bp, offset, BBTOB(nbblks)); + if (error) + return error; + + error = xlog_bread_noalign(log, blk_no, nbblks, bp); + + /* must reset buffer pointer even on error */ + error2 = XFS_BUF_SET_PTR(bp, orig_offset, orig_len); + if (error) + return error; + return error2; +} + +/* * This routine finds (to an approximation) the first block in the physical * log which contains the given cycle. It uses a binary search algorithm. * Note that the algorithm can not be perfect because the disk will not @@ -162,8 +188,8 @@ xlog_bread( */ int xlog_find_cycle_start( - xlog_t *log, - xfs_buf_t *bp, + struct xlog *log, + struct xfs_buf *bp, xfs_daddr_t first_blk, xfs_daddr_t *last_blk, uint cycle) @@ -205,7 +231,7 @@ xlog_find_cycle_start( */ STATIC int xlog_find_verify_cycle( - xlog_t *log, + struct xlog *log, xfs_daddr_t start_blk, int nbblks, uint stop_on_cycle_no, @@ -225,9 +251,11 @@ xlog_find_verify_cycle( * a log sector, or we're out of luck. */ bufblks = 1 << ffs(nbblks); + while (bufblks > log->l_logBBsize) + bufblks >>= 1; while (!(bp = xlog_get_bp(log, bufblks))) { bufblks >>= 1; - if (bufblks < MAX(log->l_sectBBsize, 1)) + if (bufblks < log->l_sectBBsize) return ENOMEM; } @@ -272,7 +300,7 @@ out: */ STATIC int xlog_find_verify_log_record( - xlog_t *log, + struct xlog *log, xfs_daddr_t start_blk, xfs_daddr_t *last_blk, int extra_bblks) @@ -302,8 +330,8 @@ xlog_find_verify_log_record( for (i = (*last_blk) - 1; i >= 0; i--) { if (i < start_blk) { /* valid log record not found */ - xlog_warn( - "XFS: Log inconsistent (didn't find previous header)"); + xfs_warn(log->l_mp, + "Log inconsistent (didn't find previous header)"); ASSERT(0); error = XFS_ERROR(EIO); goto out; @@ -317,7 +345,7 @@ xlog_find_verify_log_record( head = (xlog_rec_header_t *)offset; - if (XLOG_HEADER_MAGIC_NUM == be32_to_cpu(head->h_magicno)) + if (head->h_magicno == cpu_to_be32(XLOG_HEADER_MAGIC_NUM)) break; if (!smallmem) @@ -382,7 +410,7 @@ out: */ STATIC int xlog_find_head( - xlog_t *log, + struct xlog *log, xfs_daddr_t *return_head_blk) { xfs_buf_t *bp; @@ -403,12 +431,12 @@ xlog_find_head( * mkfs etc write a dummy unmount record to a fresh * log so we can store the uuid in there */ - xlog_warn("XFS: totally zeroed log"); + xfs_warn(log->l_mp, "totally zeroed log"); } return 0; } else if (error) { - xlog_warn("XFS: empty log check failed"); + xfs_warn(log->l_mp, "empty log check failed"); return error; } @@ -631,7 +659,7 @@ validate_head: xlog_put_bp(bp); if (error) - xlog_warn("XFS: failed to find log head"); + xfs_warn(log->l_mp, "failed to find log head"); return error; } @@ -653,7 +681,7 @@ validate_head: */ int xlog_find_tail( - xlog_t *log, + struct xlog *log, xfs_daddr_t *head_blk, xfs_daddr_t *tail_blk) { @@ -699,7 +727,7 @@ xlog_find_tail( if (error) goto done; - if (XLOG_HEADER_MAGIC_NUM == be32_to_cpu(*(__be32 *)offset)) { + if (*(__be32 *)offset == cpu_to_be32(XLOG_HEADER_MAGIC_NUM)) { found = 1; break; } @@ -716,15 +744,15 @@ xlog_find_tail( if (error) goto done; - if (XLOG_HEADER_MAGIC_NUM == - be32_to_cpu(*(__be32 *)offset)) { + if (*(__be32 *)offset == + cpu_to_be32(XLOG_HEADER_MAGIC_NUM)) { found = 2; break; } } } if (!found) { - xlog_warn("XFS: xlog_find_tail: couldn't find sync record"); + xfs_warn(log->l_mp, "%s: couldn't find sync record", __func__); ASSERT(0); return XFS_ERROR(EIO); } @@ -750,9 +778,9 @@ xlog_find_tail( log->l_curr_cycle++; atomic64_set(&log->l_tail_lsn, be64_to_cpu(rhead->h_tail_lsn)); atomic64_set(&log->l_last_sync_lsn, be64_to_cpu(rhead->h_lsn)); - xlog_assign_grant_head(&log->l_grant_reserve_head, log->l_curr_cycle, + xlog_assign_grant_head(&log->l_reserve_head.grant, log->l_curr_cycle, BBTOB(log->l_curr_block)); - xlog_assign_grant_head(&log->l_grant_write_head, log->l_curr_cycle, + xlog_assign_grant_head(&log->l_write_head.grant, log->l_curr_cycle, BBTOB(log->l_curr_block)); /* @@ -840,7 +868,7 @@ done: xlog_put_bp(bp); if (error) - xlog_warn("XFS: failed to locate log tail"); + xfs_warn(log->l_mp, "failed to locate log tail"); return error; } @@ -862,7 +890,7 @@ done: */ int xlog_find_zeroed( - xlog_t *log, + struct xlog *log, xfs_daddr_t *blk_no) { xfs_buf_t *bp; @@ -904,7 +932,8 @@ xlog_find_zeroed( * the first block must be 1. If it's not, maybe we're * not looking at a log... Bail out. */ - xlog_warn("XFS: Log inconsistent or not a log (last==0, first!=1)"); + xfs_warn(log->l_mp, + "Log inconsistent or not a log (last==0, first!=1)"); return XFS_ERROR(EINVAL); } @@ -1002,8 +1031,8 @@ xlog_recover_add_item( STATIC int xlog_recover_add_to_cont_trans( - struct log *log, - xlog_recover_t *trans, + struct xlog *log, + struct xlog_recover *trans, xfs_caddr_t dp, int len) { @@ -1025,7 +1054,7 @@ xlog_recover_add_to_cont_trans( old_ptr = item->ri_buf[item->ri_cnt-1].i_addr; old_len = item->ri_buf[item->ri_cnt-1].i_len; - ptr = kmem_realloc(old_ptr, len+old_len, old_len, 0u); + ptr = kmem_realloc(old_ptr, len+old_len, old_len, KM_SLEEP); memcpy(&ptr[old_len], dp, len); /* d, s, l */ item->ri_buf[item->ri_cnt-1].i_len += len; item->ri_buf[item->ri_cnt-1].i_addr = ptr; @@ -1048,8 +1077,8 @@ xlog_recover_add_to_cont_trans( */ STATIC int xlog_recover_add_to_trans( - struct log *log, - xlog_recover_t *trans, + struct xlog *log, + struct xlog_recover *trans, xfs_caddr_t dp, int len) { @@ -1062,8 +1091,8 @@ xlog_recover_add_to_trans( if (list_empty(&trans->r_itemq)) { /* we need to catch log corruptions here */ if (*(uint *)dp != XFS_TRANS_HEADER_MAGIC) { - xlog_warn("XFS: xlog_recover_add_to_trans: " - "bad header magic number"); + xfs_warn(log->l_mp, "%s: bad header magic number", + __func__); ASSERT(0); return XFS_ERROR(EIO); } @@ -1090,8 +1119,8 @@ xlog_recover_add_to_trans( if (item->ri_total == 0) { /* first region to be added */ if (in_f->ilf_size == 0 || in_f->ilf_size > XLOG_MAX_REGIONS_IN_ITEM) { - xlog_warn( - "XFS: bad number of regions (%d) in inode log format", + xfs_warn(log->l_mp, + "bad number of regions (%d) in inode log format", in_f->ilf_size); ASSERT(0); return XFS_ERROR(EIO); @@ -1144,7 +1173,7 @@ xlog_recover_free_trans( */ STATIC int xlog_recover_commit_trans( - struct log *log, + struct xlog *log, struct xlog_recover *trans, int pass) { @@ -1163,7 +1192,7 @@ xlog_recover_unmount_trans( xlog_recover_t *trans) { /* Do nothing now */ - xlog_warn("XFS: xlog_recover_unmount_trans: Unmount LR"); + xfs_warn(log->l_mp, "%s: Unmount LR", __func__); return 0; } @@ -1178,9 +1207,9 @@ xlog_recover_unmount_trans( */ STATIC int xlog_recover_process_data( - xlog_t *log, + struct xlog *log, struct hlist_head rhash[], - xlog_rec_header_t *rhead, + struct xlog_rec_header *rhead, xfs_caddr_t dp, int pass) { @@ -1206,8 +1235,8 @@ xlog_recover_process_data( dp += sizeof(xlog_op_header_t); if (ohead->oh_clientid != XFS_TRANSACTION && ohead->oh_clientid != XFS_LOG) { - xlog_warn( - "XFS: xlog_recover_process_data: bad clientid"); + xfs_warn(log->l_mp, "%s: bad clientid 0x%x", + __func__, ohead->oh_clientid); ASSERT(0); return (XFS_ERROR(EIO)); } @@ -1220,8 +1249,8 @@ xlog_recover_process_data( be64_to_cpu(rhead->h_lsn)); } else { if (dp + be32_to_cpu(ohead->oh_len) > lp) { - xlog_warn( - "XFS: xlog_recover_process_data: bad length"); + xfs_warn(log->l_mp, "%s: bad length 0x%x", + __func__, be32_to_cpu(ohead->oh_len)); return (XFS_ERROR(EIO)); } flags = ohead->oh_flags & ~XLOG_END_TRANS; @@ -1241,8 +1270,8 @@ xlog_recover_process_data( be32_to_cpu(ohead->oh_len)); break; case XLOG_START_TRANS: - xlog_warn( - "XFS: xlog_recover_process_data: bad transaction"); + xfs_warn(log->l_mp, "%s: bad transaction", + __func__); ASSERT(0); error = XFS_ERROR(EIO); break; @@ -1252,8 +1281,8 @@ xlog_recover_process_data( dp, be32_to_cpu(ohead->oh_len)); break; default: - xlog_warn( - "XFS: xlog_recover_process_data: bad flag"); + xfs_warn(log->l_mp, "%s: bad flag 0x%x", + __func__, flags); ASSERT(0); error = XFS_ERROR(EIO); break; @@ -1267,13 +1296,64 @@ xlog_recover_process_data( return 0; } -STATIC void +/* + * Upack the log buffer data and crc check it. If the check fails, issue a + * warning if and only if the CRC in the header is non-zero. This makes the + * check an advisory warning, and the zero CRC check will prevent failure + * warnings from being emitted when upgrading the kernel from one that does not + * add CRCs by default. + * + * When filesystems are CRC enabled, this CRC mismatch becomes a fatal log + * corruption failure + * + * XXX: we cannot calculate the CRC here without knowing the number of extra + * headers taht were CRC'd in log write. This information is derived from the + * in-core log buffer size, and is not written to the log! Hence for now we + * simple *cannot* verify the CRCs, and so we short circuit it. + */ +#define xlog_cksum(l,r,dp,len) ((r)->h_crc) +STATIC int +xlog_unpack_data_crc( + struct xlog_rec_header *rhead, + xfs_caddr_t dp, + struct xlog *log) +{ + __le32 crc; + + crc = xlog_cksum(log, rhead, dp, be32_to_cpu(rhead->h_len)); + if (crc != rhead->h_crc) { + if (rhead->h_crc || xfs_sb_version_hascrc(&log->l_mp->m_sb)) { + xfs_alert(log->l_mp, + "log record CRC mismatch: found 0x%x, expected 0x%x.\n", + le32_to_cpu(rhead->h_crc), + le32_to_cpu(crc)); + xfs_hex_dump(dp, 32); + } + + /* + * If we've detected a log record corruption, then we can't + * recover past this point. Abort recovery if we are enforcing + * CRC protection by punting an error back up the stack. + */ + if (xfs_sb_version_hascrc(&log->l_mp->m_sb)) + return EFSCORRUPTED; + } + + return 0; +} + +STATIC int xlog_unpack_data( - xlog_rec_header_t *rhead, + struct xlog_rec_header *rhead, xfs_caddr_t dp, - xlog_t *log) + struct xlog *log) { int i, j, k; + int error; + + error = xlog_unpack_data_crc(rhead, dp, log); + if (error) + return error; for (i = 0; i < BTOBB(be32_to_cpu(rhead->h_len)) && i < (XLOG_HEADER_CYCLE_SIZE / BBSIZE); i++) { @@ -1290,17 +1370,19 @@ xlog_unpack_data( dp += BBSIZE; } } + + return 0; } STATIC int xlog_valid_rec_header( - xlog_t *log, - xlog_rec_header_t *rhead, + struct xlog *log, + struct xlog_rec_header *rhead, xfs_daddr_t blkno) { int hlen; - if (unlikely(be32_to_cpu(rhead->h_magicno) != XLOG_HEADER_MAGIC_NUM)) { + if (unlikely(rhead->h_magicno != cpu_to_be32(XLOG_HEADER_MAGIC_NUM))) { XFS_ERROR_REPORT("xlog_valid_rec_header(1)", XFS_ERRLEVEL_LOW, log->l_mp); return XFS_ERROR(EFSCORRUPTED); @@ -1308,7 +1390,7 @@ xlog_valid_rec_header( if (unlikely( (!rhead->h_version || (be32_to_cpu(rhead->h_version) & (~XLOG_VERSION_OKBITS))))) { - xlog_warn("XFS: %s: unrecognised log version (%d).", + xfs_warn(log->l_mp, "%s: unrecognised log version (%d).", __func__, be32_to_cpu(rhead->h_version)); return XFS_ERROR(EIO); } @@ -1338,7 +1420,7 @@ xlog_valid_rec_header( */ int xlog_do_recovery_pass( - xlog_t *log, + struct xlog *log, xfs_daddr_t head_blk, xfs_daddr_t tail_blk, int pass) @@ -1421,9 +1503,13 @@ xlog_do_recovery_pass( if (error) goto bread_err2; - xlog_unpack_data(rhead, offset, log); - if ((error = xlog_recover_process_data(log, - rhash, rhead, offset, pass))) + error = xlog_unpack_data(rhead, offset, log); + if (error) + goto bread_err2; + + error = xlog_recover_process_data(log, + rhash, rhead, offset, pass); + if (error) goto bread_err2; blk_no += bblks + hblks; } @@ -1438,7 +1524,7 @@ xlog_do_recovery_pass( /* * Check for header wrapping around physical end-of-log */ - offset = XFS_BUF_PTR(hbp); + offset = hbp->b_addr; split_hblks = 0; wrapped_hblks = 0; if (blk_no + hblks <= log->l_logBBsize) { @@ -1474,19 +1560,9 @@ xlog_do_recovery_pass( * - order is important. */ wrapped_hblks = hblks - split_hblks; - error = XFS_BUF_SET_PTR(hbp, - offset + BBTOB(split_hblks), - BBTOB(hblks - split_hblks)); - if (error) - goto bread_err2; - - error = xlog_bread_noalign(log, 0, - wrapped_hblks, hbp); - if (error) - goto bread_err2; - - error = XFS_BUF_SET_PTR(hbp, offset, - BBTOB(hblks)); + error = xlog_bread_offset(log, 0, + wrapped_hblks, hbp, + offset + BBTOB(split_hblks)); if (error) goto bread_err2; } @@ -1508,7 +1584,7 @@ xlog_do_recovery_pass( } else { /* This log record is split across the * physical end of log */ - offset = XFS_BUF_PTR(dbp); + offset = dbp->b_addr; split_bblks = 0; if (blk_no != log->l_logBBsize) { /* some data is before the physical @@ -1537,25 +1613,20 @@ xlog_do_recovery_pass( * _first_, then the log start (LR header end) * - order is important. */ - error = XFS_BUF_SET_PTR(dbp, - offset + BBTOB(split_bblks), - BBTOB(bblks - split_bblks)); + error = xlog_bread_offset(log, 0, + bblks - split_bblks, dbp, + offset + BBTOB(split_bblks)); if (error) goto bread_err2; + } - error = xlog_bread_noalign(log, wrapped_hblks, - bblks - split_bblks, - dbp); - if (error) - goto bread_err2; + error = xlog_unpack_data(rhead, offset, log); + if (error) + goto bread_err2; - error = XFS_BUF_SET_PTR(dbp, offset, h_size); - if (error) - goto bread_err2; - } - xlog_unpack_data(rhead, offset, log); - if ((error = xlog_recover_process_data(log, rhash, - rhead, offset, pass))) + error = xlog_recover_process_data(log, rhash, + rhead, offset, pass); + if (error) goto bread_err2; blk_no += bblks; } @@ -1580,9 +1651,13 @@ xlog_do_recovery_pass( if (error) goto bread_err2; - xlog_unpack_data(rhead, offset, log); - if ((error = xlog_recover_process_data(log, rhash, - rhead, offset, pass))) + error = xlog_unpack_data(rhead, offset, log); + if (error) + goto bread_err2; + + error = xlog_recover_process_data(log, rhash, + rhead, offset, pass); + if (error) goto bread_err2; blk_no += bblks + hblks; } diff --git a/logprint/log_copy.c b/logprint/log_copy.c index fd36317..f6ef0e9 100644 --- a/logprint/log_copy.c +++ b/logprint/log_copy.c @@ -24,7 +24,7 @@ void xfs_log_copy( - xlog_t *log, + struct xlog *log, int fd, char *filename) { diff --git a/logprint/log_dump.c b/logprint/log_dump.c index 1975b1b..a333077 100644 --- a/logprint/log_dump.c +++ b/logprint/log_dump.c @@ -24,7 +24,7 @@ void xfs_log_dump( - xlog_t *log, + struct xlog *log, int fd, int print_block_start) { diff --git a/logprint/log_misc.c b/logprint/log_misc.c index c480795..4277a48 100644 --- a/logprint/log_misc.c +++ b/logprint/log_misc.c @@ -816,7 +816,7 @@ xlog_print_trans_dquot(xfs_caddr_t *ptr, int len, int *i, int num_ops) */ void -xlog_print_lseek(xlog_t *log, int fd, xfs_daddr_t blkno, int whence) +xlog_print_lseek(struct xlog *log, int fd, xfs_daddr_t blkno, int whence) { #define BBTOOFF64(bbs) (((xfs_off_t)(bbs)) << BBSHIFT) xfs_off_t offset; @@ -1265,7 +1265,7 @@ xlog_print_extended_headers( /* * This code is gross and needs to be rewritten. */ -void xfs_log_print(xlog_t *log, +void xfs_log_print(struct xlog *log, int fd, int print_block_start) { diff --git a/logprint/log_print_all.c b/logprint/log_print_all.c index cbc51d9..44fb4c4 100644 --- a/logprint/log_print_all.c +++ b/logprint/log_print_all.c @@ -23,7 +23,7 @@ */ int xlog_print_find_oldest( - struct log *log, + struct xlog *log, xfs_daddr_t *last_blk) { xfs_buf_t *bp; diff --git a/logprint/log_print_trans.c b/logprint/log_print_trans.c index 7405772..86e1c42 100644 --- a/logprint/log_print_trans.c +++ b/logprint/log_print_trans.c @@ -30,7 +30,7 @@ xlog_recover_print_trans_head( int xlog_recover_do_trans( - xlog_t *log, + struct xlog *log, xlog_recover_t *trans, int pass) { @@ -40,7 +40,7 @@ xlog_recover_do_trans( void xfs_log_print_trans( - xlog_t *log, + struct xlog *log, int print_block_start) { xfs_daddr_t head_blk, tail_blk; diff --git a/logprint/logprint.c b/logprint/logprint.c index 482fd4e..2a01780 100644 --- a/logprint/logprint.c +++ b/logprint/logprint.c @@ -128,7 +128,7 @@ main(int argc, char **argv) int c; int logfd; char *copy_file = NULL; - xlog_t log = {0}; + struct xlog log = {0}; xfs_mount_t mount; setlocale(LC_ALL, ""); diff --git a/logprint/logprint.h b/logprint/logprint.h index df4cea3..933c9e6 100644 --- a/logprint/logprint.h +++ b/logprint/logprint.h @@ -34,12 +34,12 @@ extern int print_no_print; /* exports */ extern char *trans_type[]; -extern void xlog_print_lseek(xlog_t *, int, xfs_daddr_t, int); +extern void xlog_print_lseek(struct xlog *, int, xfs_daddr_t, int); -extern void xfs_log_copy(xlog_t *, int, char *); -extern void xfs_log_dump(xlog_t *, int, int); -extern void xfs_log_print(xlog_t *, int, int); -extern void xfs_log_print_trans(xlog_t *, int); +extern void xfs_log_copy(struct xlog *, int, char *); +extern void xfs_log_dump(struct xlog *, int, int); +extern void xfs_log_print(struct xlog *, int, int); +extern void xfs_log_print_trans(struct xlog *, int); extern void print_xlog_record_line(void); extern void print_xlog_op_line(void); diff --git a/repair/phase2.c b/repair/phase2.c index 9fd591c..23b457a 100644 --- a/repair/phase2.c +++ b/repair/phase2.c @@ -29,13 +29,16 @@ void set_mp(xfs_mount_t *mpp); /* workaround craziness in the xlog routines */ -int xlog_recover_do_trans(xlog_t *log, xlog_recover_t *t, int p) { return 0; } +int xlog_recover_do_trans(struct xlog *log, xlog_recover_t *t, int p) +{ + return 0; +} static void zero_log(xfs_mount_t *mp) { int error; - xlog_t log; + struct xlog log; xfs_daddr_t head_blk, tail_blk; dev_t logdev = (mp->m_sb.sb_logstart == 0) ? x.logdev : x.ddev; -- 1.7.10 _______________________________________________ xfs mailing list xfs@xxxxxxxxxxx http://oss.sgi.com/mailman/listinfo/xfs