diff mbox series

[21/26] xfs_db: support printing time limits

Message ID 160375538229.881414.12318967122326451609.stgit@magnolia
State Accepted
Headers show
Series xfsprogs: widen timestamps to deal with y2038 | expand

Commit Message

Darrick J. Wong Oct. 26, 2020, 11:36 p.m. UTC
From: Darrick J. Wong <darrick.wong@oracle.com>

Support printing the minimum and maxium timestamp limits on this
filesystem.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 db/Makefile       |    3 +
 db/command.c      |    1 
 db/command.h      |    1 
 db/timelimit.c    |  160 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 man/man8/xfs_db.8 |   23 ++++++++
 5 files changed, 187 insertions(+), 1 deletion(-)
 create mode 100644 db/timelimit.c

Comments

Christoph Hellwig Oct. 29, 2020, 9:50 a.m. UTC | #1
Looks good,

Reviewed-by: Christoph Hellwig <hch@lst.de>
diff mbox series

Patch

diff --git a/db/Makefile b/db/Makefile
index 67908a2c3c98..beafb1058269 100644
--- a/db/Makefile
+++ b/db/Makefile
@@ -14,7 +14,8 @@  HFILES = addr.h agf.h agfl.h agi.h attr.h attrshort.h bit.h block.h bmap.h \
 	io.h logformat.h malloc.h metadump.h output.h print.h quit.h sb.h \
 	sig.h strvec.h text.h type.h write.h attrset.h symlink.h fsmap.h \
 	fuzz.h
-CFILES = $(HFILES:.h=.c) btdump.c btheight.c convert.c info.c namei.c
+CFILES = $(HFILES:.h=.c) btdump.c btheight.c convert.c info.c namei.c \
+	timelimit.c
 LSRCFILES = xfs_admin.sh xfs_ncheck.sh xfs_metadump.sh
 
 LLDLIBS	= $(LIBXFS) $(LIBXLOG) $(LIBFROG) $(LIBUUID) $(LIBRT) $(LIBPTHREAD)
diff --git a/db/command.c b/db/command.c
index 053097742b12..02f778b9316b 100644
--- a/db/command.c
+++ b/db/command.c
@@ -140,4 +140,5 @@  init_commands(void)
 	write_init();
 	dquot_init();
 	fuzz_init();
+	timelimit_init();
 }
diff --git a/db/command.h b/db/command.h
index bf130e63c85c..fd5cead9be78 100644
--- a/db/command.h
+++ b/db/command.h
@@ -33,3 +33,4 @@  extern void		btdump_init(void);
 extern void		info_init(void);
 extern void		btheight_init(void);
 extern void		namei_init(void);
+extern void		timelimit_init(void);
diff --git a/db/timelimit.c b/db/timelimit.c
new file mode 100644
index 000000000000..53a0a399a7f2
--- /dev/null
+++ b/db/timelimit.c
@@ -0,0 +1,160 @@ 
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2020 Oracle.  All Rights Reserved.
+ * Author: Darrick J. Wong <darrick.wong@oracle.com>
+ */
+#include "libxfs.h"
+#include "command.h"
+#include "output.h"
+#include "init.h"
+
+enum show_what {
+	SHOW_AUTO,
+	SHOW_CLASSIC,
+	SHOW_BIGTIME,
+};
+
+
+enum print_how {
+	PRINT_RAW,
+	PRINT_PRETTY,
+	PRINT_COMPACT,
+};
+
+static void
+show_limit(
+	const char	*tag,
+	int64_t		limit,
+	enum print_how	how)
+{
+	if (how == PRINT_COMPACT) {
+		dbprintf("%" PRId64 " ", limit);
+		return;
+	}
+
+	if (how == PRINT_PRETTY && limit <= LONG_MAX && limit >= LONG_MIN) {
+		time_t	tt = limit;
+		char	*c;
+
+		c = ctime(&tt);
+		if (c) {
+			dbprintf("%s = %24.24s\n", tag, c);
+			return;
+		}
+	}
+
+	dbprintf("%s = %" PRId64 "\n", tag, limit);
+}
+
+static void
+show_limits(
+	enum show_what	whatkind,
+	enum print_how	how)
+{
+	enum print_how	grace_how = how;
+
+	switch (whatkind) {
+	case SHOW_AUTO:
+		/* should never get here */
+		break;
+	case SHOW_CLASSIC:
+		show_limit("time.min", XFS_LEGACY_TIME_MIN, how);
+		show_limit("time.max", XFS_LEGACY_TIME_MAX, how);
+		show_limit("dqtimer.min", XFS_DQ_LEGACY_EXPIRY_MIN, how);
+		show_limit("dqtimer.max", XFS_DQ_LEGACY_EXPIRY_MAX, how);
+		break;
+	case SHOW_BIGTIME:
+		show_limit("time.min",
+				xfs_bigtime_to_unix(XFS_BIGTIME_TIME_MIN), how);
+		show_limit("time.max",
+				xfs_bigtime_to_unix(XFS_BIGTIME_TIME_MAX), how);
+		show_limit("dqtimer.min",
+				xfs_dq_bigtime_to_unix(XFS_DQ_BIGTIME_EXPIRY_MIN),
+				how);
+		show_limit("dqtimer.max",
+				xfs_dq_bigtime_to_unix(XFS_DQ_BIGTIME_EXPIRY_MAX),
+				how);
+		break;
+	}
+
+	/* grace periods are always integers */
+	if (grace_how != PRINT_COMPACT)
+		grace_how = PRINT_RAW;
+	show_limit("dqgrace.min", XFS_DQ_GRACE_MIN, grace_how);
+	show_limit("dqgrace.min", XFS_DQ_GRACE_MAX, grace_how);
+
+	if (how == PRINT_COMPACT)
+		dbprintf("\n");
+}
+
+static int
+timelimit_f(
+	int		argc,
+	char		**argv)
+{
+	enum show_what	whatkind = SHOW_AUTO;
+	enum print_how	how = PRINT_RAW;
+	int		i;
+
+	for (i = 1; i < argc; i++) {
+		if (!strcmp("--classic", argv[i]))
+			whatkind = SHOW_CLASSIC;
+		else if (!strcmp("--bigtime", argv[i]))
+			whatkind = SHOW_BIGTIME;
+		else if (!strcmp("--pretty", argv[i]))
+			how = PRINT_PRETTY;
+		else if (!strcmp("--compact", argv[i]))
+			how = PRINT_COMPACT;
+		else {
+			dbprintf(_("%s: bad option for timelimit command\n"),
+					argv[i]);
+			return 1;
+		}
+	}
+
+	if (whatkind == SHOW_AUTO) {
+		if (xfs_sb_version_hasbigtime(&mp->m_sb))
+			whatkind = SHOW_BIGTIME;
+		else
+			whatkind = SHOW_CLASSIC;
+	}
+
+	show_limits(whatkind, how);
+	return 0;
+}
+
+static void
+timelimit_help(void)
+{
+	dbprintf(_(
+"\n"
+" Print the minimum and maximum supported values for inode timestamps,\n"
+" disk quota expiration timers, and disk quota grace periods supported\n"
+" by this filesystem.\n"
+"\n"
+" Options:\n"
+"   --classic -- Force printing of the classic time limits.\n"
+"   --bigtime -- Force printing of the bigtime limits.\n"
+"   --pretty  -- Pretty-print the time limits.\n"
+"   --compact -- Print the limits in a single line.\n"
+"\n"
+));
+
+}
+
+static const cmdinfo_t	timelimit_cmd = {
+	.name		= "timelimit",
+	.cfunc		= timelimit_f,
+	.argmin		= 0,
+	.argmax		= -1,
+	.canpush	= 0,
+	.args		= N_("[--classic|--bigtime] [--pretty]"),
+	.oneline	= N_("display timestamp limits"),
+	.help		= timelimit_help,
+};
+
+void
+timelimit_init(void)
+{
+	add_command(&timelimit_cmd);
+}
diff --git a/man/man8/xfs_db.8 b/man/man8/xfs_db.8
index fefe862b7564..f2520e9ad1ac 100644
--- a/man/man8/xfs_db.8
+++ b/man/man8/xfs_db.8
@@ -905,6 +905,29 @@  The possible data types are:
 .BR rtsummary ", " sb ", " symlink " and " text .
 See the TYPES section below for more information on these data types.
 .TP
+.BI "timelimit [" OPTIONS ]
+Print the minimum and maximum supported values for inode timestamps,
+quota expiration timers, and quota grace periods supported by this
+filesystem.
+Options include:
+.RS 1.0i
+.TP 0.4i
+.B \--bigtime
+Print the time limits of an XFS filesystem with the
+.B bigtime
+feature enabled.
+.TP 0.4i
+.B \--classic
+Print the time limits of a classic XFS filesystem.
+.TP 0.4i
+.B \--compact
+Print all limits as raw values on a single line.
+.TP 0.4i
+.B \--pretty
+Print the timestamps in the current locale's date and time format instead of
+raw seconds since the Unix epoch.
+.RE
+.TP
 .BI "uuid [" uuid " | " generate " | " rewrite " | " restore ]
 Set the filesystem universally unique identifier (UUID).
 The filesystem UUID can be used by