@@ -91,7 +91,7 @@ The output will have the same format that
.BR "xfs_info" "(8)"
prints when querying a filesystem.
.TP
-.BI "health [ \-a agno] [ \-c ] [ \-f ] [ \-i inum ] [ \-q ] [ paths ]"
+.BI "health [ \-a agno] [ \-c ] [ \-f ] [ \-i inum ] [ \-n ] [ \-q ] [ paths ]"
Reports the health of the given group of filesystem metadata.
.RS 1.0i
.PD 0
@@ -111,6 +111,11 @@ Report on the health of metadata that affect the entire filesystem.
.B \-i inum
Report on the health of a specific inode.
.TP
+.B \-n
+When reporting on the health of a file, try to report the full file path,
+if possible.
+This option is disabled by default to minimize runtime.
+.TP
.B \-q
Report only unhealthy metadata.
.TP
@@ -6,12 +6,20 @@ TOPDIR = ..
include $(TOPDIR)/include/builddefs
LTCOMMAND = xfs_spaceman
-HFILES = init.h space.h
-CFILES = info.c init.c file.c health.c prealloc.c trim.c
+HFILES = \
+ init.h \
+ space.h
+CFILES = \
+ file.c \
+ health.c \
+ info.c \
+ init.c \
+ prealloc.c \
+ trim.c
LSRCFILES = xfs_info.sh
-LLDLIBS = $(LIBXCMD) $(LIBFROG)
-LTDEPENDENCIES = $(LIBXCMD) $(LIBFROG)
+LLDLIBS = $(LIBHANDLE) $(LIBXCMD) $(LIBFROG)
+LTDEPENDENCIES = $(LIBHANDLE) $(LIBXCMD) $(LIBFROG)
LLDFLAGS = -static
ifeq ($(ENABLE_EDITLINE),yes)
@@ -14,6 +14,7 @@
#include "libfrog/paths.h"
#include "libfrog/fsgeom.h"
#include "space.h"
+#include "handle.h"
static cmdinfo_t print_cmd;
@@ -106,6 +107,12 @@ addfile(
file->name = filename;
memcpy(&file->xfd, xfd, sizeof(struct xfs_fd));
memcpy(&file->fs_path, fs_path, sizeof(file->fs_path));
+
+ /* Try to capture a fs handle for reporting paths. */
+ file->fshandle = NULL;
+ file->fshandle_len = 0;
+ path_to_fshandle(filename, &file->fshandle, &file->fshandle_len);
+
return 0;
}
@@ -13,11 +13,13 @@
#include "libfrog/fsgeom.h"
#include "libfrog/bulkstat.h"
#include "space.h"
+#include "libfrog/getparents.h"
static cmdinfo_t health_cmd;
static unsigned long long reported;
static bool comprehensive;
static bool quiet;
+static bool report_paths;
static bool has_realtime(const struct xfs_fsop_geom *g)
{
@@ -265,6 +267,38 @@ report_file_health(
#define BULKSTAT_NR (128)
+static void
+report_inode(
+ const struct xfs_bulkstat *bs)
+{
+ char descr[PATH_MAX];
+ int ret;
+
+ if (report_paths && file->fshandle &&
+ (file->xfd.fsgeom.flags & XFS_FSOP_GEOM_FLAGS_PARENT)) {
+ struct xfs_handle handle;
+
+ memcpy(&handle.ha_fsid, file->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 = bs->bs_ino;
+ handle.ha_fid.fid_gen = bs->bs_gen;
+
+ ret = handle_to_path(&handle, sizeof(struct xfs_handle), 0,
+ descr, sizeof(descr) - 1);
+ if (ret)
+ goto report_inum;
+
+ goto report_status;
+ }
+
+report_inum:
+ snprintf(descr, sizeof(descr) - 1, _("inode %"PRIu64), bs->bs_ino);
+report_status:
+ report_sick(descr, inode_flags, bs->bs_sick, bs->bs_checked);
+}
+
/*
* Report on all files' health for a given @agno. If @agno is NULLAGNUMBER,
* report on all files in the filesystem.
@@ -274,7 +308,6 @@ report_bulkstat_health(
xfs_agnumber_t agno)
{
struct xfs_bulkstat_req *breq;
- char descr[256];
uint32_t i;
int error;
@@ -292,13 +325,8 @@ report_bulkstat_health(
error = -xfrog_bulkstat(&file->xfd, breq);
if (error)
break;
- for (i = 0; i < breq->hdr.ocount; i++) {
- snprintf(descr, sizeof(descr) - 1, _("inode %"PRIu64),
- breq->bulkstat[i].bs_ino);
- report_sick(descr, inode_flags,
- breq->bulkstat[i].bs_sick,
- breq->bulkstat[i].bs_checked);
- }
+ for (i = 0; i < breq->hdr.ocount; i++)
+ report_inode(&breq->bulkstat[i]);
} while (breq->hdr.ocount > 0);
if (error)
@@ -308,7 +336,7 @@ report_bulkstat_health(
return error;
}
-#define OPT_STRING ("a:cfi:q")
+#define OPT_STRING ("a:cfi:nq")
/* Report on health problems in XFS filesystem. */
static int
@@ -323,6 +351,7 @@ health_f(
int ret;
reported = 0;
+ report_paths = false;
if (file->xfd.fsgeom.version != XFS_FSOP_GEOM_VERSION_V5) {
perror("health");
@@ -358,6 +387,9 @@ health_f(
return 1;
}
break;
+ case 'n':
+ report_paths = true;
+ break;
case 'q':
quiet = true;
break;
@@ -445,6 +477,7 @@ health_help(void)
" -c -- Report on the health of all inodes.\n"
" -f -- Report health of the overall filesystem.\n"
" -i inum -- Report health of a given inode number.\n"
+" -n -- Try to report file names.\n"
" -q -- Only report unhealthy metadata.\n"
" paths -- Report health of the given file path.\n"
"\n"));
@@ -456,7 +489,7 @@ static cmdinfo_t health_cmd = {
.cfunc = health_f,
.argmin = 0,
.argmax = -1,
- .args = "[-a agno] [-c] [-f] [-i inum] [-q] [paths]",
+ .args = "[-a agno] [-c] [-f] [-i inum] [-n] [-q] [paths]",
.flags = CMD_FLAG_ONESHOT,
.help = health_help,
};
@@ -10,6 +10,9 @@ struct fileio {
struct xfs_fd xfd; /* XFS runtime support context */
struct fs_path fs_path; /* XFS path information */
char *name; /* file name at time of open */
+
+ void *fshandle;
+ size_t fshandle_len;
};
extern struct fileio *filetable; /* open file table */