diff mbox series

[08/10] xfs: report inode health via bulkstat

Message ID 155413866259.4966.15271041361179138786.stgit@magnolia (mailing list archive)
State Superseded, archived
Headers show
Series xfs: online health tracking support | expand

Commit Message

Darrick J. Wong April 1, 2019, 5:11 p.m. UTC
From: Darrick J. Wong <darrick.wong@oracle.com>

Use space in the bulkstat ioctl structure to report any problems
observed with the inode.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 fs/xfs/libxfs/xfs_fs.h     |   13 ++++++++++++-
 fs/xfs/libxfs/xfs_health.h |    1 +
 fs/xfs/xfs_health.c        |   27 +++++++++++++++++++++++++++
 fs/xfs/xfs_itable.c        |    2 ++
 4 files changed, 42 insertions(+), 1 deletion(-)
diff mbox series

Patch

diff --git a/fs/xfs/libxfs/xfs_fs.h b/fs/xfs/libxfs/xfs_fs.h
index dc2c538e6b92..fffaead718a5 100644
--- a/fs/xfs/libxfs/xfs_fs.h
+++ b/fs/xfs/libxfs/xfs_fs.h
@@ -346,13 +346,24 @@  typedef struct xfs_bstat {
 #define	bs_projid	bs_projid_lo	/* (previously just bs_projid)	*/
 	__u16		bs_forkoff;	/* inode fork offset in bytes	*/
 	__u16		bs_projid_hi;	/* higher part of project id	*/
-	unsigned char	bs_pad[6];	/* pad space, unused		*/
+	uint16_t	bs_health;	/* sick inode metadata		*/
+	unsigned char	bs_pad[4];	/* pad space, unused		*/
 	__u32		bs_cowextsize;	/* cow extent size		*/
 	__u32		bs_dmevmask;	/* DMIG event mask		*/
 	__u16		bs_dmstate;	/* DMIG state info		*/
 	__u16		bs_aextents;	/* attribute number of extents	*/
 } xfs_bstat_t;
 
+/* bs_health flags */
+#define XFS_BS_HEALTH_INODE	(1 << 0)  /* inode core */
+#define XFS_BS_HEALTH_BMBTD	(1 << 1)  /* data fork */
+#define XFS_BS_HEALTH_BMBTA	(1 << 2)  /* attr fork */
+#define XFS_BS_HEALTH_BMBTC	(1 << 3)  /* cow fork */
+#define XFS_BS_HEALTH_DIR	(1 << 4)  /* directory */
+#define XFS_BS_HEALTH_XATTR	(1 << 5)  /* extended attributes */
+#define XFS_BS_HEALTH_SYMLINK	(1 << 6)  /* symbolic link remote target */
+#define XFS_BS_HEALTH_PARENT	(1 << 7)  /* parent pointers */
+
 /*
  * Project quota id helpers (previously projid was 16bit only
  * and using two 16bit values to hold new 32bit projid was choosen
diff --git a/fs/xfs/libxfs/xfs_health.h b/fs/xfs/libxfs/xfs_health.h
index 2d3b879da9b5..a6446d1dd8a7 100644
--- a/fs/xfs/libxfs/xfs_health.h
+++ b/fs/xfs/libxfs/xfs_health.h
@@ -204,5 +204,6 @@  xfs_inode_healthy(struct xfs_inode *ip)
 void xfs_fsop_geom_health(struct xfs_mount *mp, struct xfs_fsop_geom *geo);
 void xfs_ag_geom_health(struct xfs_mount *mp, xfs_agnumber_t agno,
 		struct xfs_ag_geometry *ageo);
+void xfs_bulkstat_health(struct xfs_inode *ip, struct xfs_bstat *bs);
 
 #endif	/* __XFS_HEALTH_H__ */
diff --git a/fs/xfs/xfs_health.c b/fs/xfs/xfs_health.c
index 5ca471bd41ad..1c9b71949410 100644
--- a/fs/xfs/xfs_health.c
+++ b/fs/xfs/xfs_health.c
@@ -316,3 +316,30 @@  xfs_ag_geom_health(
 		ageo->ag_health |= XFS_AG_GEOM_HEALTH_AG_REFCNTBT;
 	xfs_perag_put(pag);
 }
+
+/* Fill out bulkstat health info. */
+void
+xfs_bulkstat_health(
+	struct xfs_inode	*ip,
+	struct xfs_bstat	*bs)
+{
+	unsigned int		sick = xfs_inode_measure_sickness(ip);
+
+	bs->bs_health = 0;
+	if (sick & XFS_HEALTH_INO_CORE)
+		bs->bs_health |= XFS_BS_HEALTH_INODE;
+	if (sick & XFS_HEALTH_INO_BMBTD)
+		bs->bs_health |= XFS_BS_HEALTH_BMBTD;
+	if (sick & XFS_HEALTH_INO_BMBTA)
+		bs->bs_health |= XFS_BS_HEALTH_BMBTA;
+	if (sick & XFS_HEALTH_INO_BMBTC)
+		bs->bs_health |= XFS_BS_HEALTH_BMBTC;
+	if (sick & XFS_HEALTH_INO_DIR)
+		bs->bs_health |= XFS_BS_HEALTH_DIR;
+	if (sick & XFS_HEALTH_INO_XATTR)
+		bs->bs_health |= XFS_BS_HEALTH_XATTR;
+	if (sick & XFS_HEALTH_INO_SYMLINK)
+		bs->bs_health |= XFS_BS_HEALTH_SYMLINK;
+	if (sick & XFS_HEALTH_INO_PARENT)
+		bs->bs_health |= XFS_BS_HEALTH_PARENT;
+}
diff --git a/fs/xfs/xfs_itable.c b/fs/xfs/xfs_itable.c
index 1861289bf823..cff28ee73deb 100644
--- a/fs/xfs/xfs_itable.c
+++ b/fs/xfs/xfs_itable.c
@@ -18,6 +18,7 @@ 
 #include "xfs_error.h"
 #include "xfs_trace.h"
 #include "xfs_icache.h"
+#include "xfs_health.h"
 
 /*
  * Return stat information for one inode.
@@ -84,6 +85,7 @@  xfs_bulkstat_one_int(
 	buf->bs_extsize = dic->di_extsize << mp->m_sb.sb_blocklog;
 	buf->bs_extents = dic->di_nextents;
 	memset(buf->bs_pad, 0, sizeof(buf->bs_pad));
+	xfs_bulkstat_health(ip, buf);
 	buf->bs_dmevmask = dic->di_dmevmask;
 	buf->bs_dmstate = dic->di_dmstate;
 	buf->bs_aextents = dic->di_anextents;