From: Darrick J. Wong <darrick.wong@xxxxxxxxxx> Support printing the minimum and maxium timestamp limits on this filesystem. Signed-off-by: Darrick J. Wong <darrick.wong@xxxxxxxxxx> --- 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 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@xxxxxxxxxx> + */ +#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