]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
Fix xfs_logprint handling of version 2 logs, sync libxlog with recovery code
authorNathan Scott <nathans@sgi.com>
Mon, 2 Jun 2003 01:40:16 +0000 (01:40 +0000)
committerNathan Scott <nathans@sgi.com>
Mon, 2 Jun 2003 01:40:16 +0000 (01:40 +0000)
libxlog/xfs_log_recover.c
logprint/log_print_trans.c

index 09fa2797cf7d7a22685ab122b5f5b4bf3d98f184..4ceba1de1658597b914d9040d3ff4b324e87247d 100644 (file)
@@ -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;
                }
        }
 
index eb9cc88acc93a2cd47320147e3b7452777150c14..3b8ce8b249f1a9c94baba2f60c837eeb3bccb23e 100644 (file)
 
 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)?"<CLEAN>":"<DIRTY>");
 
        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);
+}