]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
xfs_scrub: use parent pointers when possible to report file operations
authorDarrick J. Wong <djwong@kernel.org>
Mon, 29 Jul 2024 23:23:21 +0000 (16:23 -0700)
committerDarrick J. Wong <djwong@kernel.org>
Tue, 30 Jul 2024 00:01:11 +0000 (17:01 -0700)
If parent pointers are available, use them to supply file paths when
doing things to files, instead of merely printing the inode number.

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
scrub/common.c

index aca596487113162e596d1271c4e964afb670f41a..f86546556f46dd6731a98c72dbf8f24c6bac8a97 100644 (file)
@@ -9,6 +9,7 @@
 #include <syslog.h>
 #include "platform_defs.h"
 #include "libfrog/paths.h"
+#include "libfrog/getparents.h"
 #include "xfs_scrub.h"
 #include "common.h"
 #include "progress.h"
@@ -405,19 +406,55 @@ scrub_render_ino_descr(
        ...)
 {
        va_list                 args;
+       size_t                  pathlen = 0;
        uint32_t                agno;
        uint32_t                agino;
        int                     ret;
 
+       if (ctx->mnt.fsgeom.flags & XFS_FSOP_GEOM_FLAGS_PARENT) {
+               struct xfs_handle handle;
+
+               memcpy(&handle.ha_fsid, ctx->fshandle, sizeof(handle.ha_fsid));
+               handle.ha_fid.fid_len = sizeof(xfs_fid_t) -
+                               sizeof(handle.ha_fid.fid_len);
+               handle.ha_fid.fid_pad = 0;
+               handle.ha_fid.fid_ino = ino;
+               handle.ha_fid.fid_gen = gen;
+
+               ret = handle_to_path(&handle, sizeof(struct xfs_handle), 4096,
+                               buf, buflen);
+               if (ret)
+                       goto report_inum;
+
+               /*
+                * Leave at least 16 bytes for the description of what went
+                * wrong.  If we can't do that, we'll use the inode number.
+                */
+               pathlen = strlen(buf);
+               if (pathlen >= buflen - 16)
+                       goto report_inum;
+
+               if (format) {
+                       buf[pathlen] = ' ';
+                       buf[pathlen + 1] = 0;
+                       pathlen++;
+               }
+
+               goto report_format;
+       }
+
+report_inum:
        agno = cvt_ino_to_agno(&ctx->mnt, ino);
        agino = cvt_ino_to_agino(&ctx->mnt, ino);
        ret = snprintf(buf, buflen, _("inode %"PRIu64" (%"PRIu32"/%"PRIu32")%s"),
                        ino, agno, agino, format ? " " : "");
        if (ret < 0 || ret >= buflen || format == NULL)
                return ret;
+       pathlen = ret;
 
+report_format:
        va_start(args, format);
-       ret += vsnprintf(buf + ret, buflen - ret, format, args);
+       pathlen += vsnprintf(buf + pathlen, buflen - pathlen, format, args);
        va_end(args);
-       return ret;
+       return pathlen;
 }