]> www.infradead.org Git - users/hch/xfsprogs.git/commitdiff
xfs_logprint: decode parent pointers in ATTRI items fully
authorAllison Henderson <allison.henderson@oracle.com>
Tue, 9 Jan 2024 17:39:24 +0000 (09:39 -0800)
committerDarrick J. Wong <djwong@kernel.org>
Wed, 10 Apr 2024 00:21:30 +0000 (17:21 -0700)
This patch modifies the ATTRI print routines to look for the parent
pointer flag, and decode logged parent pointers fully when dumping log
contents.  Between the existing ATTRI: printouts and the new ones
introduced here, we can figure out what was stored in each log iovec,
as well as the higher level parent pointer that was logged.

Signed-off-by: Allison Henderson <allison.henderson@oracle.com>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
[djwong: adjust to new ondisk format]
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
libxfs/libxfs_api_defs.h
logprint/log_redo.c

index 12fa1ae97a90e5a0cdba54b857aa0a1b271c13d5..8f4b54b6a831e1799d24ae32e69bad9e7f3db118 100644 (file)
 #define xfs_log_sb                     libxfs_log_sb
 #define xfs_mode_to_ftype              libxfs_mode_to_ftype
 #define xfs_mkdir_space_res            libxfs_mkdir_space_res
+#define xfs_parent_add                 libxfs_parent_add
+#define xfs_parent_finish              libxfs_parent_finish
+#define xfs_parent_start               libxfs_parent_start
 #define xfs_perag_get                  libxfs_perag_get
 #define xfs_perag_hold                 libxfs_perag_hold
 #define xfs_perag_put                  libxfs_perag_put
index 1d55164a90ffe4b669092b2f472b69fa5800fae6..684e5f4a3f32c25a6193ff06328aeaed4ee85ce8 100644 (file)
@@ -674,6 +674,55 @@ xfs_attri_copy_log_format(
        return 1;
 }
 
+static void
+dump_pptr(
+       const char                      *tag,
+       const void                      *name_ptr,
+       unsigned int                    name_len,
+       const void                      *value_ptr,
+       unsigned int                    value_len)
+{
+       const struct xfs_parent_rec     *rec = value_ptr;
+
+       if (value_len < sizeof(struct xfs_parent_rec)) {
+               printf("PPTR: %s CORRUPT\n", tag);
+               return;
+       }
+
+       printf("PPTR: %s attr_namelen %u attr_valuelen %u\n", tag, name_len, value_len);
+       printf("PPTR: %s parent_ino %llu parent_gen %u name '%.*s'\n",
+                       tag,
+                       (unsigned long long)be64_to_cpu(rec->p_ino),
+                       (unsigned int)be32_to_cpu(rec->p_gen),
+                       name_len,
+                       (char *)name_ptr);
+}
+
+static void
+dump_pptr_update(
+       const void      *name_ptr,
+       unsigned int    name_len,
+       const void      *new_name_ptr,
+       unsigned int    new_name_len,
+       const void      *value_ptr,
+       unsigned int    value_len,
+       const void      *new_value_ptr,
+       unsigned int    new_value_len)
+{
+       if (new_name_ptr && name_ptr) {
+               dump_pptr("OLDNAME", name_ptr, name_len, value_ptr, value_len);
+               dump_pptr("NEWNAME", new_name_ptr, new_name_len, new_value_ptr,
+                               new_value_len);
+               return;
+       }
+
+       if (name_ptr)
+               dump_pptr("NAME", name_ptr, name_len, value_ptr, value_len);
+       if (new_name_ptr)
+               dump_pptr("NEWNAME", new_name_ptr, new_name_len, new_value_ptr,
+                               new_value_len);
+}
+
 static inline unsigned int
 xfs_attr_log_item_op(const struct xfs_attri_log_format *attrp)
 {
@@ -688,6 +737,10 @@ xlog_print_trans_attri(
 {
        struct xfs_attri_log_format     *src_f = NULL;
        xlog_op_header_t                *head = NULL;
+       void                            *name_ptr = NULL;
+       void                            *new_name_ptr = NULL;
+       void                            *value_ptr = NULL;
+       void                            *new_value_ptr = NULL;
        uint                            dst_len;
        unsigned int                    name_len = 0;
        unsigned int                    new_name_len = 0;
@@ -742,6 +795,7 @@ xlog_print_trans_attri(
                (*i)++;
                head = (xlog_op_header_t *)*ptr;
                xlog_print_op_header(head, *i, ptr);
+               name_ptr = *ptr;
                error = xlog_print_trans_attri_name(ptr,
                                be32_to_cpu(head->oh_len), "name");
                if (error)
@@ -753,6 +807,7 @@ xlog_print_trans_attri(
                (*i)++;
                head = (xlog_op_header_t *)*ptr;
                xlog_print_op_header(head, *i, ptr);
+               new_name_ptr = *ptr;
                error = xlog_print_trans_attri_name(ptr,
                                be32_to_cpu(head->oh_len), "newname");
                if (error)
@@ -764,6 +819,7 @@ xlog_print_trans_attri(
                (*i)++;
                head = (xlog_op_header_t *)*ptr;
                xlog_print_op_header(head, *i, ptr);
+               value_ptr = *ptr;
                error = xlog_print_trans_attri_value(ptr,
                                be32_to_cpu(head->oh_len), value_len, "value");
                if (error)
@@ -775,12 +831,19 @@ xlog_print_trans_attri(
                (*i)++;
                head = (xlog_op_header_t *)*ptr;
                xlog_print_op_header(head, *i, ptr);
+               new_value_ptr = *ptr;
                error = xlog_print_trans_attri_value(ptr,
                                be32_to_cpu(head->oh_len), new_value_len,
                                "newvalue");
                if (error)
                        goto error;
        }
+
+       if (src_f->alfi_attr_filter & XFS_ATTR_PARENT)
+               dump_pptr_update(name_ptr, name_len,
+                                new_name_ptr, new_name_len,
+                                value_ptr, value_len,
+                                new_value_ptr, new_value_len);
 error:
        free(src_f);
 
@@ -823,6 +886,10 @@ xlog_recover_print_attri(
        struct xlog_recover_item        *item)
 {
        struct xfs_attri_log_format     *f, *src_f = NULL;
+       void                            *name_ptr = NULL;
+       void                            *new_name_ptr = NULL;
+       void                            *value_ptr = NULL;
+       void                            *new_value_ptr = NULL;
        uint                            src_len, dst_len;
        unsigned int                    name_len = 0;
        unsigned int                    new_name_len = 0;
@@ -874,6 +941,7 @@ xlog_recover_print_attri(
                printf(_("ATTRI:  name len:%u\n"), name_len);
                print_or_dump((char *)item->ri_buf[region].i_addr,
                               name_len);
+               name_ptr = item->ri_buf[region].i_addr;
        }
 
        if (new_name_len > 0) {
@@ -881,6 +949,7 @@ xlog_recover_print_attri(
                printf(_("ATTRI:  newname len:%u\n"), new_name_len);
                print_or_dump((char *)item->ri_buf[region].i_addr,
                               new_name_len);
+               new_name_ptr = item->ri_buf[region].i_addr;
        }
 
        if (value_len > 0) {
@@ -889,6 +958,7 @@ xlog_recover_print_attri(
                region++;
                printf(_("ATTRI:  value len:%u\n"), value_len);
                print_or_dump((char *)item->ri_buf[region].i_addr, len);
+               value_ptr = item->ri_buf[region].i_addr;
        }
 
        if (new_value_len > 0) {
@@ -897,8 +967,15 @@ xlog_recover_print_attri(
                region++;
                printf(_("ATTRI:  newvalue len:%u\n"), new_value_len);
                print_or_dump((char *)item->ri_buf[region].i_addr, len);
+               new_value_ptr = item->ri_buf[region].i_addr;
        }
 
+       if (src_f->alfi_attr_filter & XFS_ATTR_PARENT)
+               dump_pptr_update(name_ptr, name_len,
+                                new_name_ptr, new_name_len,
+                                value_ptr, value_len,
+                                new_value_ptr, new_value_len);
+
 out:
        free(f);