From 72c5917e898d62298e1b55a37a458c05bf8ccc79 Mon Sep 17 00:00:00 2001 From: Nathan Scott Date: Mon, 2 Jun 2003 01:40:16 +0000 Subject: [PATCH] Fix xfs_logprint handling of version 2 logs, sync libxlog with recovery code --- libxlog/xfs_log_recover.c | 163 +++++++++++++++++-------------------- logprint/log_print_trans.c | 36 ++++---- 2 files changed, 94 insertions(+), 105 deletions(-) diff --git a/libxlog/xfs_log_recover.c b/libxlog/xfs_log_recover.c index 09fa2797c..4ceba1de1 100644 --- a/libxlog/xfs_log_recover.c +++ b/libxlog/xfs_log_recover.c @@ -1187,6 +1187,45 @@ xlog_recover_process_data( return 0; } +STATIC int +xlog_valid_rec_header( + xlog_t *log, + xlog_rec_header_t *rhead, + xfs_daddr_t blkno) +{ + int bblks; + + if (unlikely( + (INT_GET(rhead->h_magicno, ARCH_CONVERT) != + XLOG_HEADER_MAGIC_NUM))) { + XFS_ERROR_REPORT("xlog_valid_rec_header(1)", + XFS_ERRLEVEL_LOW, log->l_mp); + return XFS_ERROR(EFSCORRUPTED); + } + if (unlikely( + (INT_ISZERO(rhead->h_version, ARCH_CONVERT) || + (INT_GET(rhead->h_version, ARCH_CONVERT) & + (~XLOG_VERSION_OKBITS)) != 0))) { + xlog_warn("XFS: %s: unrecognised log version (%d).", + __FUNCTION__, INT_GET(rhead->h_version, ARCH_CONVERT)); + return XFS_ERROR(EIO); + } + + /* LR body must have data or it wouldn't have been written */ + bblks = INT_GET(rhead->h_len, ARCH_CONVERT); + if (unlikely( bblks <= 0 || bblks > INT_MAX )) { + XFS_ERROR_REPORT("xlog_valid_rec_header(2)", + XFS_ERRLEVEL_LOW, log->l_mp); + return XFS_ERROR(EFSCORRUPTED); + } + if (unlikely( blkno > log->l_logBBsize || blkno > INT_MAX )) { + XFS_ERROR_REPORT("xlog_valid_rec_header(3)", + XFS_ERRLEVEL_LOW, log->l_mp); + return XFS_ERROR(EFSCORRUPTED); + } + return 0; +} + /* * Read the log from tail to head and process the log records found. * Handle the two cases where the tail and head are in the same cycle @@ -1211,6 +1250,8 @@ xlog_do_recovery_pass( int hblks, split_hblks, wrapped_hblks; xlog_recover_t *rhash[XLOG_RHASH_SIZE]; + ASSERT(head_blk != tail_blk); + /* * Read the header of the tail block and get the iclog buffer size from * h_size. Use this to tell how many sectors make up the log header. @@ -1228,21 +1269,10 @@ xlog_do_recovery_pass( goto bread_err1; offset = xlog_align(log, tail_blk, 1, hbp); rhead = (xlog_rec_header_t *)offset; - if (unlikely( - (INT_GET(rhead->h_magicno, ARCH_CONVERT) != - XLOG_HEADER_MAGIC_NUM) || - (INT_ISZERO(rhead->h_version, ARCH_CONVERT)) || - (INT_GET(rhead->h_version, ARCH_CONVERT) & - (~XLOG_VERSION_OKBITS)) != 0)) { - xlog_warn("XFS: %s: bad log magic/version (0x%x/%d)", - __FUNCTION__, - INT_GET(rhead->h_magicno, ARCH_CONVERT), - INT_GET(rhead->h_version, ARCH_CONVERT)); - error = XFS_ERROR(EIO); + error = xlog_valid_rec_header(log, rhead, tail_blk); + if (error) goto bread_err1; - } h_size = INT_GET(rhead->h_size, ARCH_CONVERT); - if ((INT_GET(rhead->h_version, ARCH_CONVERT) & XLOG_VERSION_2) && (h_size > XLOG_HEADER_CYCLE_SIZE)) { @@ -1276,47 +1306,21 @@ xlog_do_recovery_pass( goto bread_err2; offset = xlog_align(log, blk_no, hblks, hbp); rhead = (xlog_rec_header_t *)offset; - ASSERT(INT_GET(rhead->h_magicno, ARCH_CONVERT) == - XLOG_HEADER_MAGIC_NUM); - ASSERT(BTOBB(INT_GET(rhead->h_len, ARCH_CONVERT) <= - INT_MAX)); - /* blocks in data section */ - bblks = (int)BTOBB(INT_GET(rhead->h_len, ARCH_CONVERT)); - - if (unlikely( - (INT_GET(rhead->h_magicno, ARCH_CONVERT) != - XLOG_HEADER_MAGIC_NUM) || - (BTOBB(INT_GET(rhead->h_len, ARCH_CONVERT) > - INT_MAX)) || - (bblks <= 0) || - (blk_no > log->l_logBBsize))) { - XFS_ERROR_REPORT("xlog_do_recovery_pass(1)", - XFS_ERRLEVEL_LOW, log->l_mp); - error = EFSCORRUPTED; + error = xlog_valid_rec_header(log, rhead, blk_no); + if (error) goto bread_err2; - } - if ((INT_GET(rhead->h_version, ARCH_CONVERT) & - (~XLOG_VERSION_OKBITS)) != 0) { - xlog_warn( - "XFS: xlog_do_recovery_pass: unrecognised log version number."); - error = XFS_ERROR(EIO); - goto bread_err2; - } /* blocks in data section */ bblks = (int)BTOBB(INT_GET(rhead->h_len, ARCH_CONVERT)); - if (bblks > 0) { - if ((error = xlog_bread(log, blk_no + hblks, - bblks, dbp))) - goto bread_err2; - offset = xlog_align(log, blk_no + hblks, - bblks, dbp); - xlog_unpack_data(rhead, offset, log); - if ((error = xlog_recover_process_data(log, + error = xlog_bread(log, blk_no + hblks, bblks, dbp); + if (error) + goto bread_err2; + offset = xlog_align(log, blk_no + hblks, bblks, dbp); + xlog_unpack_data(rhead, offset, log); + if ((error = xlog_recover_process_data(log, rhash, rhead, offset, pass))) - goto bread_err2; - } - blk_no += (bblks+hblks); + goto bread_err2; + blk_no += bblks + hblks; } } else { /* @@ -1329,17 +1333,17 @@ xlog_do_recovery_pass( /* * Check for header wrapping around physical end-of-log */ + offset = NULL; + split_hblks = 0; wrapped_hblks = 0; - if (blk_no+hblks <= log->l_logBBsize) { + if (blk_no + hblks <= log->l_logBBsize) { /* Read header in one read */ - if ((error = xlog_bread(log, blk_no, - hblks, hbp))) + error = xlog_bread(log, blk_no, hblks, hbp); + if (error) goto bread_err2; offset = xlog_align(log, blk_no, hblks, hbp); } else { /* This LR is split across physical log end */ - offset = NULL; - split_hblks = 0; if (blk_no != log->l_logBBsize) { /* some data before physical log end */ ASSERT(blk_no <= INT_MAX); @@ -1368,8 +1372,8 @@ xlog_do_recovery_pass( bufaddr + BBTOB(split_hblks), BBTOB(hblks - split_hblks)); wrapped_hblks = hblks - split_hblks; - if ((error = xlog_bread(log, 0, - wrapped_hblks, hbp))) + error = xlog_bread(log, 0, wrapped_hblks, hbp); + if (error) goto bread_err2; XFS_BUF_SET_PTR(hbp, bufaddr, hblks); if (!offset) @@ -1377,33 +1381,18 @@ xlog_do_recovery_pass( wrapped_hblks, hbp); } rhead = (xlog_rec_header_t *)offset; - ASSERT(INT_GET(rhead->h_magicno, ARCH_CONVERT) == - XLOG_HEADER_MAGIC_NUM); - ASSERT(BTOBB(INT_GET(rhead->h_len, ARCH_CONVERT) <= - INT_MAX)); - bblks = (int)BTOBB(INT_GET(rhead->h_len, ARCH_CONVERT)); - - /* LR body must have data or it wouldn't have been - * written */ - ASSERT(bblks > 0); - blk_no += hblks; /* successfully read header */ - - if (unlikely( - (INT_GET(rhead->h_magicno, ARCH_CONVERT) != - XLOG_HEADER_MAGIC_NUM) || - (BTOBB(INT_GET(rhead->h_len, ARCH_CONVERT) > - INT_MAX)) || - (bblks <= 0))) { - XFS_ERROR_REPORT("xlog_do_recovery_pass(2)", - XFS_ERRLEVEL_LOW, log->l_mp); - error = EFSCORRUPTED; + error = xlog_valid_rec_header(log, rhead, + split_hblks ? blk_no : 0); + if (error) goto bread_err2; - } + + bblks = (int)BTOBB(INT_GET(rhead->h_len, ARCH_CONVERT)); + blk_no += hblks; /* Read in data for log record */ - if (blk_no+bblks <= log->l_logBBsize) { - if ((error = xlog_bread(log, blk_no, - bblks, dbp))) + if (blk_no + bblks <= log->l_logBBsize) { + error = xlog_bread(log, blk_no, bblks, dbp); + if (error) goto bread_err2; offset = xlog_align(log, blk_no, bblks, dbp); } else { @@ -1452,7 +1441,7 @@ xlog_do_recovery_pass( } xlog_unpack_data(rhead, offset, log); if ((error = xlog_recover_process_data(log, rhash, - rhead, offset, pass))) + rhead, offset, pass))) goto bread_err2; blk_no += bblks; } @@ -1466,20 +1455,18 @@ xlog_do_recovery_pass( goto bread_err2; offset = xlog_align(log, blk_no, hblks, hbp); rhead = (xlog_rec_header_t *)offset; - ASSERT(INT_GET(rhead->h_magicno, ARCH_CONVERT) == - XLOG_HEADER_MAGIC_NUM); - ASSERT(BTOBB(INT_GET(rhead->h_len, ARCH_CONVERT) <= - INT_MAX)); + error = xlog_valid_rec_header(log, rhead, blk_no); + if (error) + goto bread_err2; bblks = (int)BTOBB(INT_GET(rhead->h_len, ARCH_CONVERT)); - ASSERT(bblks > 0); if ((error = xlog_bread(log, blk_no+hblks, bblks, dbp))) goto bread_err2; offset = xlog_align(log, blk_no+hblks, bblks, dbp); xlog_unpack_data(rhead, offset, log); if ((error = xlog_recover_process_data(log, rhash, - rhead, offset, pass))) + rhead, offset, pass))) goto bread_err2; - blk_no += (bblks+hblks); + blk_no += bblks + hblks; } } diff --git a/logprint/log_print_trans.c b/logprint/log_print_trans.c index eb9cc88ac..3b8ce8b24 100644 --- a/logprint/log_print_trans.c +++ b/logprint/log_print_trans.c @@ -34,32 +34,33 @@ void xlog_recover_print_trans_head( - xlog_recover_t *tr) + xlog_recover_t *tr) { printf("TRANS: tid:0x%x type:%s #items:%d trans:0x%x q:0x%lx\n", tr->r_log_tid, trans_type[tr->r_theader.th_type], tr->r_theader.th_num_items, tr->r_theader.th_tid, (long)tr->r_itemq); -} /* xlog_recover_print_trans_head */ +} int -xlog_recover_do_trans(xlog_t *log, - xlog_recover_t *trans, - int pass) +xlog_recover_do_trans( + xlog_t *log, + xlog_recover_t *trans, + int pass) { xlog_recover_print_trans(trans, trans->r_itemq, 3); return 0; -} /* xlog_recover_do_trans */ - +} void -xfs_log_print_trans(xlog_t *log, - int print_block_start) +xfs_log_print_trans( + xlog_t *log, + int print_block_start) { xfs_daddr_t head_blk, tail_blk; if (xlog_find_tail(log, &head_blk, &tail_blk, 0)) - exit(1); + exit(1); printf(" log tail: %lld head: %lld state: %s\n", (long long)tail_blk, @@ -67,14 +68,15 @@ xfs_log_print_trans(xlog_t *log, (tail_blk == head_blk)?"":""); if (print_block_start != -1) { - printf(" override tail: %lld\n", - (long long)print_block_start); - tail_blk = print_block_start; + printf(" override tail: %d\n", print_block_start); + tail_blk = print_block_start; } printf("\n"); - print_record_header=1; - if (xlog_do_recovery_pass(log, head_blk, tail_blk, XLOG_RECOVER_PASS1)) - exit(1); + print_record_header = 1; -} /* xfs_log_print_trans */ + if (head_blk == tail_blk) + return; + if (xlog_do_recovery_pass(log, head_blk, tail_blk, XLOG_RECOVER_PASS1)) + exit(1); +} -- 2.47.2