]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
xfs_logprint: Add log item printing for ATTRI and ATTRD
authorAllison Henderson <allison.henderson@oracle.com>
Wed, 22 Jun 2022 19:28:52 +0000 (14:28 -0500)
committerEric Sandeen <sandeen@sandeen.net>
Wed, 22 Jun 2022 19:28:52 +0000 (14:28 -0500)
This patch implements a new set of log printing functions to print the
ATTRI and ATTRD items and vectors in the log.  These will be used during
log dump and log recover operations.

Though most attributes are strings, the attribute operations accept
any binary payload, so we should not assume them printable.  This was
done intentionally in preparation for parent pointers.  Until parent
pointers get here, attributes have no discernible format.  So the print
routines are just a simple print or hex dump for now.

Signed-off-by: Allison Henderson <allison.henderson@oracle.com>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
Signed-off-by: Dave Chinner <david@fromorbit.com>
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
logprint/log_misc.c
logprint/log_print_all.c
logprint/log_redo.c
logprint/logprint.h

index 8aeb39b973cf2a1e675c29194261534cd206e99c..5f442b142517a7d427a10f91936062744775db36 100644 (file)
@@ -54,11 +54,47 @@ print_stars(void)
           "***********************************\n");
 }      /* print_stars */
 
+void
+print_hex_dump(char *ptr, int len) {
+       int i = 0;
+
+       for (i = 0; i < len; i++) {
+               if (i % 16 == 0)
+                       printf("%08x ", i);
+
+               printf("%02x", ptr[i]);
+
+               if ((i+1)%16 == 0)
+                       printf("\n");
+               else if ((i+1)%2 == 0)
+                       printf(" ");
+       }
+       printf("\n");
+}
+
+bool
+is_printable(char *ptr, int len) {
+       int i = 0;
+
+       for (i = 0; i < len; i++)
+               if (!isprint(ptr[i]) )
+                       return false;
+       return true;
+}
+
+void
+print_or_dump(char *ptr, int len) {
+       if (is_printable(ptr, len))
+               printf("%.*s\n", len, ptr);
+       else
+               print_hex_dump(ptr, len);
+}
+
 /*
  * Given a pointer to a data segment, print out the data as if it were
  * a log operation header.
  */
-static void
+void
 xlog_print_op_header(xlog_op_header_t  *op_head,
                     int                i,
                     char               **ptr)
@@ -972,6 +1008,17 @@ xlog_print_record(
                                        be32_to_cpu(op_head->oh_len));
                        break;
                    }
+                   case XFS_LI_ATTRI: {
+                       skip = xlog_print_trans_attri(&ptr,
+                                       be32_to_cpu(op_head->oh_len),
+                                       &i);
+                       break;
+                   }
+                   case XFS_LI_ATTRD: {
+                       skip = xlog_print_trans_attrd(&ptr,
+                                       be32_to_cpu(op_head->oh_len));
+                       break;
+                   }
                    case XFS_LI_RUI: {
                        skip = xlog_print_trans_rui(&ptr,
                                        be32_to_cpu(op_head->oh_len),
index f601f429f77d98d49889201a0914e1c29eae19c8..f7c32d6abad8180eed96fded1b20c4e00828c864 100644 (file)
@@ -416,6 +416,12 @@ xlog_recover_print_logitem(
        case XFS_LI_EFI:
                xlog_recover_print_efi(item);
                break;
+       case XFS_LI_ATTRD:
+               xlog_recover_print_attrd(item);
+               break;
+       case XFS_LI_ATTRI:
+               xlog_recover_print_attri(item);
+               break;
        case XFS_LI_RUD:
                xlog_recover_print_rud(item);
                break;
@@ -468,6 +474,12 @@ xlog_recover_print_item(
        case XFS_LI_EFI:
                printf("EFI");
                break;
+       case XFS_LI_ATTRD:
+               printf("ATTRD");
+               break;
+       case XFS_LI_ATTRI:
+               printf("ATTRI");
+               break;
        case XFS_LI_RUD:
                printf("RUD");
                break;
index 297e203d097609ccba590363c2d9ef50fbc1c890..1974382d2da3d9225673140202c86604a3df5191 100644 (file)
@@ -653,3 +653,197 @@ xlog_recover_print_bud(
        f = item->ri_buf[0].i_addr;
        xlog_print_trans_bud(&f, sizeof(struct xfs_bud_log_format));
 }
+
+/* Attr Items */
+
+static int
+xfs_attri_copy_log_format(
+       char                            *buf,
+       uint                            len,
+       struct xfs_attri_log_format     *dst_attri_fmt)
+{
+       uint dst_len = sizeof(struct xfs_attri_log_format);
+
+       if (len == dst_len) {
+               memcpy((char *)dst_attri_fmt, buf, len);
+               return 0;
+       }
+
+       fprintf(stderr, _("%s: bad size of attri format: %u; expected %u\n"),
+               progname, len, dst_len);
+       return 1;
+}
+
+int
+xlog_print_trans_attri(
+       char                            **ptr,
+       uint                            src_len,
+       int                             *i)
+{
+       struct xfs_attri_log_format     *src_f = NULL;
+       xlog_op_header_t                *head = NULL;
+       uint                            dst_len;
+       int                             error = 0;
+
+       dst_len = sizeof(struct xfs_attri_log_format);
+       if (src_len != dst_len) {
+               fprintf(stderr, _("%s: bad size of attri format: %u; expected %u\n"),
+                               progname, src_len, dst_len);
+               return 1;
+       }
+
+       /*
+        * memmove to ensure 8-byte alignment for the long longs in
+        * xfs_attri_log_format_t structure
+        */
+       src_f = malloc(src_len);
+       if (!src_f) {
+               fprintf(stderr, _("%s: xlog_print_trans_attri: malloc failed\n"),
+                               progname);
+               exit(1);
+       }
+       memmove((char*)src_f, *ptr, src_len);
+       *ptr += src_len;
+
+       printf(_("ATTRI:  #regs: %d     name_len: %d, value_len: %d  id: 0x%llx\n"),
+               src_f->alfi_size, src_f->alfi_name_len, src_f->alfi_value_len,
+                               (unsigned long long)src_f->alfi_id);
+
+       if (src_f->alfi_name_len > 0) {
+               printf(_("\n"));
+               (*i)++;
+               head = (xlog_op_header_t *)*ptr;
+               xlog_print_op_header(head, *i, ptr);
+               error = xlog_print_trans_attri_name(ptr, be32_to_cpu(head->oh_len));
+               if (error)
+                       goto error;
+       }
+
+       if (src_f->alfi_value_len > 0) {
+               printf(_("\n"));
+               (*i)++;
+               head = (xlog_op_header_t *)*ptr;
+               xlog_print_op_header(head, *i, ptr);
+               error = xlog_print_trans_attri_value(ptr, be32_to_cpu(head->oh_len),
+                               src_f->alfi_value_len);
+       }
+error:
+       free(src_f);
+
+       return error;
+}      /* xlog_print_trans_attri */
+
+int
+xlog_print_trans_attri_name(
+       char                            **ptr,
+       uint                            src_len)
+{
+       printf(_("ATTRI:  name len:%u\n"), src_len);
+       print_or_dump(*ptr, src_len);
+
+       *ptr += src_len;
+
+       return 0;
+}      /* xlog_print_trans_attri */
+
+int
+xlog_print_trans_attri_value(
+       char                            **ptr,
+       uint                            src_len,
+       int                             value_len)
+{
+       int len = min(value_len, src_len);
+
+       printf(_("ATTRI:  value len:%u\n"), value_len);
+       print_or_dump(*ptr, len);
+
+       *ptr += src_len;
+
+       return 0;
+}      /* xlog_print_trans_attri_value */
+
+void
+xlog_recover_print_attri(
+       struct xlog_recover_item        *item)
+{
+       struct xfs_attri_log_format     *f, *src_f = NULL;
+       uint                            src_len, dst_len;
+
+       int                             region = 0;
+
+       src_f = (struct xfs_attri_log_format *)item->ri_buf[0].i_addr;
+       src_len = item->ri_buf[region].i_len;
+
+       /*
+        * An xfs_attri_log_format structure contains a attribute name and
+        * variable length value  as the last field.
+        */
+       dst_len = sizeof(struct xfs_attri_log_format);
+
+       if ((f = ((struct xfs_attri_log_format *)malloc(dst_len))) == NULL) {
+               fprintf(stderr, _("%s: xlog_recover_print_attri: malloc failed\n"),
+                       progname);
+               exit(1);
+       }
+       if (xfs_attri_copy_log_format((char*)src_f, src_len, f))
+               goto out;
+
+       printf(_("ATTRI:  #regs: %d     name_len: %d, value_len: %d  id: 0x%llx\n"),
+               f->alfi_size, f->alfi_name_len, f->alfi_value_len, (unsigned long long)f->alfi_id);
+
+       if (f->alfi_name_len > 0) {
+               region++;
+               printf(_("ATTRI:  name len:%u\n"), f->alfi_name_len);
+               print_or_dump((char *)item->ri_buf[region].i_addr,
+                              f->alfi_name_len);
+       }
+
+       if (f->alfi_value_len > 0) {
+               int len = f->alfi_value_len;
+
+               if (len > MAX_ATTR_VAL_PRINT)
+                       len = MAX_ATTR_VAL_PRINT;
+
+               region++;
+               printf(_("ATTRI:  value len:%u\n"), f->alfi_value_len);
+               print_or_dump((char *)item->ri_buf[region].i_addr, len);
+       }
+
+out:
+       free(f);
+
+}
+
+int
+xlog_print_trans_attrd(char **ptr, uint len)
+{
+       struct xfs_attrd_log_format *f;
+       struct xfs_attrd_log_format lbuf;
+       uint core_size = sizeof(struct xfs_attrd_log_format);
+
+       memcpy(&lbuf, *ptr, MIN(core_size, len));
+       f = &lbuf;
+       *ptr += len;
+       if (len >= core_size) {
+               printf(_("ATTRD:  #regs: %d     id: 0x%llx\n"),
+                       f->alfd_size,
+                       (unsigned long long)f->alfd_alf_id);
+               return 0;
+       } else {
+               printf(_("ATTRD: Not enough data to decode further\n"));
+               return 1;
+       }
+}      /* xlog_print_trans_attrd */
+
+void
+xlog_recover_print_attrd(
+       struct xlog_recover_item                *item)
+{
+       struct xfs_attrd_log_format     *f;
+
+       f = (struct xfs_attrd_log_format *)item->ri_buf[0].i_addr;
+
+       printf(_("      ATTRD:  #regs: %d       id: 0x%llx\n"),
+               f->alfd_size,
+               (unsigned long long)f->alfd_alf_id);
+}
index 38a7d3fa80a95e1f108ce3c77e0bbd7c74fca59d..b4479c240d94bc27aed00bb9d5b4e17cb579d5d5 100644 (file)
@@ -29,6 +29,9 @@ extern void xfs_log_print_trans(struct xlog *, int);
 extern void print_xlog_record_line(void);
 extern void print_xlog_op_line(void);
 extern void print_stars(void);
+extern void print_hex_dump(char* ptr, int len);
+extern bool is_printable(char* ptr, int len);
+extern void print_or_dump(char* ptr, int len);
 
 extern struct xfs_inode_log_format *
        xfs_inode_item_format_convert(char *, uint, struct xfs_inode_log_format *);
@@ -53,4 +56,13 @@ extern void xlog_recover_print_bui(struct xlog_recover_item *item);
 extern int xlog_print_trans_bud(char **ptr, uint len);
 extern void xlog_recover_print_bud(struct xlog_recover_item *item);
 
+#define MAX_ATTR_VAL_PRINT     128
+
+extern int xlog_print_trans_attri(char **ptr, uint src_len, int *i);
+extern int xlog_print_trans_attri_name(char **ptr, uint src_len);
+extern int xlog_print_trans_attri_value(char **ptr, uint src_len, int value_len);
+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);
 #endif /* LOGPRINT_H */