From 4893718570dac172f639cc5e8687e782c4f759ee Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Fri, 20 Nov 2020 17:03:28 -0500 Subject: [PATCH] xfs_db: support printing time limits Support printing the minimum and maxium timestamp limits on this filesystem. Signed-off-by: Darrick J. Wong Reviewed-by: Christoph Hellwig Signed-off-by: Eric Sandeen --- diff --git a/db/Makefile b/db/Makefile index 8fecfc1..68ab659 100644 --- a/db/Makefile +++ b/db/Makefile @@ -14,7 +14,7 @@ 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 info.c +CFILES = $(HFILES:.h=.c) btdump.c info.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 c7c5234..73b06a7 100644 --- a/db/command.c +++ b/db/command.c @@ -139,4 +139,5 @@ init_commands(void) write_init(); dquot_init(); fuzz_init(); + timelimit_init(); } diff --git a/db/command.h b/db/command.h index eacfd46..1a9b4d2 100644 --- a/db/command.h +++ b/db/command.h @@ -30,3 +30,4 @@ extern void init_commands(void); extern void btdump_init(void); extern void info_init(void); +extern void timelimit_init(void); diff --git a/db/timelimit.c b/db/timelimit.c new file mode 100644 index 0000000..53a0a39 --- /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 + */ +#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 a1ee351..f46e936 100644 --- a/man/man8/xfs_db.8 +++ b/man/man8/xfs_db.8 @@ -785,6 +785,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