]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
xfs_logprint: support dumping exchmaps log items
authorDarrick J. Wong <djwong@kernel.org>
Mon, 29 Jul 2024 23:23:00 +0000 (16:23 -0700)
committerDarrick J. Wong <djwong@kernel.org>
Tue, 30 Jul 2024 00:01:06 +0000 (17:01 -0700)
Support dumping exchmaps log items.

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
logprint/log_misc.c
logprint/log_print_all.c
logprint/log_redo.c
logprint/logprint.h

index 9d38113402f4f7a0068420e73c16bcc0eb8790a5..8e86ac347fa9632ef799b0e454564d34f60f7f40 100644 (file)
@@ -1052,6 +1052,17 @@ xlog_print_record(
                                        be32_to_cpu(op_head->oh_len));
                        break;
                    }
+                   case XFS_LI_XMI: {
+                       skip = xlog_print_trans_xmi(&ptr,
+                                       be32_to_cpu(op_head->oh_len),
+                                       continued);
+                       break;
+                   }
+                   case XFS_LI_XMD: {
+                       skip = xlog_print_trans_xmd(&ptr,
+                                       be32_to_cpu(op_head->oh_len));
+                       break;
+                   }
                    case XFS_LI_QUOTAOFF: {
                        skip = xlog_print_trans_qoff(&ptr,
                                        be32_to_cpu(op_head->oh_len));
index f436e10917d850b748579f93565e32252e24751e..a4a5e41f17fa64c273a471693a01f5b3d09654a7 100644 (file)
@@ -440,6 +440,12 @@ xlog_recover_print_logitem(
        case XFS_LI_BUI:
                xlog_recover_print_bui(item);
                break;
+       case XFS_LI_XMD:
+               xlog_recover_print_xmd(item);
+               break;
+       case XFS_LI_XMI:
+               xlog_recover_print_xmi(item);
+               break;
        case XFS_LI_DQUOT:
                xlog_recover_print_dquot(item);
                break;
@@ -498,6 +504,12 @@ xlog_recover_print_item(
        case XFS_LI_BUI:
                printf("BUI");
                break;
+       case XFS_LI_XMD:
+               printf("XMD");
+               break;
+       case XFS_LI_XMI:
+               printf("XMI");
+               break;
        case XFS_LI_DQUOT:
                printf("DQ ");
                break;
index edf7e0fbfa90a50fd43a1a968a4c9b4716a7b4a7..ca6dadd7551a5bc6cf685a4aaad51c6480f6c165 100644 (file)
@@ -847,3 +847,131 @@ xlog_recover_print_attrd(
                f->alfd_size,
                (unsigned long long)f->alfd_alf_id);
 }
+
+/* Atomic Extent Swapping Items */
+
+static int
+xfs_xmi_copy_format(
+       struct xfs_xmi_log_format *xmi,
+       uint                      len,
+       struct xfs_xmi_log_format *dst_fmt,
+       int                       continued)
+{
+       if (len == sizeof(struct xfs_xmi_log_format) || continued) {
+               memcpy(dst_fmt, xmi, len);
+               return 0;
+       }
+       fprintf(stderr, _("%s: bad size of XMI format: %u; expected %zu\n"),
+               progname, len, sizeof(struct xfs_xmi_log_format));
+       return 1;
+}
+
+int
+xlog_print_trans_xmi(
+       char                    **ptr,
+       uint                    src_len,
+       int                     continued)
+{
+       struct xfs_xmi_log_format *src_f, *f = NULL;
+       int                     error = 0;
+
+       src_f = malloc(src_len);
+       if (src_f == NULL) {
+               fprintf(stderr, _("%s: %s: malloc failed\n"),
+                       progname, __func__);
+               exit(1);
+       }
+       memcpy(src_f, *ptr, src_len);
+       *ptr += src_len;
+
+       /* convert to native format */
+       if (continued && src_len < sizeof(struct xfs_xmi_log_format)) {
+               printf(_("XMI: Not enough data to decode further\n"));
+               error = 1;
+               goto error;
+       }
+
+       f = malloc(sizeof(struct xfs_xmi_log_format));
+       if (f == NULL) {
+               fprintf(stderr, _("%s: %s: malloc failed\n"),
+                       progname, __func__);
+               exit(1);
+       }
+       if (xfs_xmi_copy_format(src_f, src_len, f, continued)) {
+               error = 1;
+               goto error;
+       }
+
+       printf(_("XMI:  #regs: %d       num_extents: 1  id: 0x%llx\n"),
+               f->xmi_size, (unsigned long long)f->xmi_id);
+
+       if (continued) {
+               printf(_("XMI extent data skipped (CONTINUE set, no space)\n"));
+               goto error;
+       }
+
+       printf("(ino1: 0x%llx, igen1: 0x%x, ino2: 0x%llx, igen2: 0x%x, off1: %lld, off2: %lld, len: %lld, flags: 0x%llx)\n",
+               (unsigned long long)f->xmi_inode1,
+               (unsigned int)f->xmi_igen1,
+               (unsigned long long)f->xmi_inode2,
+               (unsigned int)f->xmi_igen2,
+               (unsigned long long)f->xmi_startoff1,
+               (unsigned long long)f->xmi_startoff2,
+               (unsigned long long)f->xmi_blockcount,
+               (unsigned long long)f->xmi_flags);
+error:
+       free(src_f);
+       free(f);
+       return error;
+}
+
+void
+xlog_recover_print_xmi(
+       struct xlog_recover_item        *item)
+{
+       char                            *src_f;
+       uint                            src_len;
+
+       src_f = item->ri_buf[0].i_addr;
+       src_len = item->ri_buf[0].i_len;
+
+       xlog_print_trans_xmi(&src_f, src_len, 0);
+}
+
+int
+xlog_print_trans_xmd(
+       char                            **ptr,
+       uint                            len)
+{
+       struct xfs_xmd_log_format       *f;
+       struct xfs_xmd_log_format       lbuf;
+
+       /* size without extents at end */
+       uint core_size = sizeof(struct xfs_xmd_log_format);
+
+       memcpy(&lbuf, *ptr, min(core_size, len));
+       f = &lbuf;
+       *ptr += len;
+       if (len >= core_size) {
+               printf(_("XMD:  #regs: %d                        id: 0x%llx\n"),
+                       f->xmd_size,
+                       (unsigned long long)f->xmd_xmi_id);
+
+               /* don't print extents as they are not used */
+
+               return 0;
+       } else {
+               printf(_("XMD: Not enough data to decode further\n"));
+               return 1;
+       }
+}
+
+void
+xlog_recover_print_xmd(
+       struct xlog_recover_item        *item)
+{
+       char                            *f;
+
+       f = item->ri_buf[0].i_addr;
+       xlog_print_trans_xmd(&f, sizeof(struct xfs_xmd_log_format));
+}
index b4479c240d94bc27aed00bb9d5b4e17cb579d5d5..25c043485cbb8a9635f5e97f3de658fabf7404e7 100644 (file)
@@ -65,4 +65,10 @@ extern void xlog_recover_print_attri(struct xlog_recover_item *item);
 extern int xlog_print_trans_attrd(char **ptr, uint len);
 extern void xlog_recover_print_attrd(struct xlog_recover_item *item);
 extern void xlog_print_op_header(xlog_op_header_t *op_head, int i, char **ptr);
+
+int xlog_print_trans_xmi(char **ptr, uint src_len, int continued);
+void xlog_recover_print_xmi(struct xlog_recover_item *item);
+int xlog_print_trans_xmd(char **ptr, uint len);
+void xlog_recover_print_xmd(struct xlog_recover_item *item);
+
 #endif /* LOGPRINT_H */