xfs
[Top] [All Lists]

[PATCH 2/2] xfs_logprint: Handle continued inode transactions

To: xfs-oss <xfs@xxxxxxxxxxx>
Subject: [PATCH 2/2] xfs_logprint: Handle continued inode transactions
From: Eric Sandeen <sandeen@xxxxxxxxxx>
Date: Thu, 01 Nov 2012 11:32:48 -0500
In-reply-to: <5092A1DE.10609@xxxxxxxxxx>
References: <5092A1DE.10609@xxxxxxxxxx>
User-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:16.0) Gecko/20121026 Thunderbird/16.0.2
xlog_print_trans_inode() has a special case for 2
specific op_head->oh_len lengths.  If it matches
sizeof(xfs_inode_log_format_32_t) or
sizeof(xfs_inode_log_format_64_t), it assumes that
it's got an inode, and attempts to convert it and
print it accordingly.

However, if we arrive here via an op header which
is continued, then the length is simply a continuation
of the previous op, and it might *randomly* match the
size of one of the inode log formats, and thus get parsed
incorrectly.

Change the caller to pass in whether or not it's a continued
op, so that it can be handled correctly.

Tested by running xfs_logprint of TEST_DEV in xfsprogs
after sequential tests; without this change it gets off
in the weeds eventually; with this fix, it lasts longer,
until it hits some other yet-unfixed logprint bug...

Signed-off-by: Eric Sandeen <sandeen@xxxxxxxxxx>
---


diff --git a/logprint/log_misc.c b/logprint/log_misc.c
index be2426e..75e221d 100644
--- a/logprint/log_misc.c
+++ b/logprint/log_misc.c
@@ -595,7 +595,7 @@ xlog_print_dir_sf(xfs_dir_shortform_t *sfp, int size)
 }
 
 int
-xlog_print_trans_inode(xfs_caddr_t *ptr, int len, int *i, int num_ops)
+xlog_print_trans_inode(xfs_caddr_t *ptr, int len, int *i, int num_ops, int 
continued)
 {
     xfs_icdinode_t        dino;
     xlog_op_header_t      *op_head;
@@ -617,8 +617,9 @@ xlog_print_trans_inode(xfs_caddr_t *ptr, int len, int *i, 
int num_ops)
     memmove(&src_lbuf, *ptr, MIN(sizeof(xfs_inode_log_format_64_t), len));
     (*i)++;                                    /* bump index */
     *ptr += len;
-    if (len == sizeof(xfs_inode_log_format_32_t) ||
-       len == sizeof(xfs_inode_log_format_64_t)) {
+    if (!continued &&
+       (len == sizeof(xfs_inode_log_format_32_t) ||
+        len == sizeof(xfs_inode_log_format_64_t))) {
        f = xfs_inode_item_format_convert((char*)&src_lbuf, len, &dst_lbuf);
        printf(_("INODE: "));
        printf(_("#regs: %d   ino: 0x%llx  flags: 0x%x   dsize: %d\n"),
@@ -932,16 +933,18 @@ xlog_print_record(int                       fd,
 
     ptr = buf;
     for (i=0; i<num_ops; i++) {
+       int continued;
+
        xlog_op_header_t *op_head = (xlog_op_header_t *)ptr;
 
        print_xlog_op_line();
        xlog_print_op_header(op_head, i, &ptr);
+       continued = (XLOG_SET(op_head->oh_flags, XLOG_WAS_CONT_TRANS) ||
+                    XLOG_SET(op_head->oh_flags, XLOG_CONTINUE_TRANS));
 
        /* print transaction data */
        if (print_no_data ||
-           ((XLOG_SET(op_head->oh_flags, XLOG_WAS_CONT_TRANS) ||
-             XLOG_SET(op_head->oh_flags, XLOG_CONTINUE_TRANS)) &&
-            be32_to_cpu(op_head->oh_len) == 0)) {
+           (continued && be32_to_cpu(op_head->oh_len) == 0)) {
            for (n = 0; n < be32_to_cpu(op_head->oh_len); n++) {
                printf("%c", *ptr);
                ptr++;
@@ -970,7 +973,7 @@ xlog_print_record(int                         fd,
                    case XFS_LI_INODE: {
                        skip = xlog_print_trans_inode(&ptr,
                                        be32_to_cpu(op_head->oh_len),
-                                       &i, num_ops);
+                                       &i, num_ops, continued);
                        break;
                    }
                    case XFS_LI_DQUOT: {


<Prev in Thread] Current Thread [Next in Thread>