linux-xfs.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v6 00/26] xfsprogs: widen timestamps to deal with y2038
@ 2020-10-26 23:34 Darrick J. Wong
  2020-10-26 23:34 ` [PATCH 01/26] libxfs: create a real struct timespec64 Darrick J. Wong
                   ` (25 more replies)
  0 siblings, 26 replies; 58+ messages in thread
From: Darrick J. Wong @ 2020-10-26 23:34 UTC (permalink / raw)
  To: sandeen, darrick.wong
  Cc: Christoph Hellwig, Amir Goldstein, Allison Collins, Gao Xiang,
	Dave Chinner, linux-xfs

Hi all,

This series performs some refactoring of our timestamp and inode
encoding functions, then retrofits the timestamp union to handle
timestamps as a 64-bit nanosecond counter.  Next, it adds bit shifting
to the non-root dquot timer fields to boost their effective size to 34
bits.  These two changes enable correct time handling on XFS through the
year 2486.

On a current V5 filesystem, inodes timestamps are a signed 32-bit
seconds counter, with 0 being the Unix epoch.  Quota timers are an
unsigned 32-bit seconds counter, with 0 also being the Unix epoch.

This means that inode timestamps can range from:
-(2^31-1) (13 Dec 1901) through (2^31-1) (19 Jan 2038).

And quota timers can range from:
0 (1 Jan 1970) through (2^32-1) (7 Feb 2106).

With the bigtime encoding turned on, inode timestamps are an unsigned
64-bit nanoseconds counter, with 0 being the 1901 epoch.  Quota timers
are a 34-bit unsigned second counter right shifted two bits, with 0
being the Unix epoch, and capped at the maximum inode timestamp value.

This means that inode timestamps can range from:
0 (13 Dec 1901) through (2^64-1 / 1e9) (2 Jul 2486)

Quota timers could theoretically range from:
0 (1 Jan 1970) through (((2^34-1) + (2^31-1)) & ~3) (16 Jun 2582).

But with the capping in place, the quota timers maximum is:
max((2^64-1 / 1e9) - (2^31-1), (((2^34-1) + (2^31-1)) & ~3) (2 Jul 2486).

v2: rebase to 5.9, having landed the quota refactoring
v3: various suggestions by Amir and Dave
v4: drop the timestamp unions, add "is bigtime?" predicates everywhere
v5: reintroduce timestamp unions as *legacy* timestamp unions
v6: minor stylistic changes

If you're going to start using this mess, you probably ought to just
pull from my git trees, which are linked below.

This is an extraordinary way to destroy everything.  Enjoy!
Comments and questions are, as always, welcome.

--D

kernel git tree:
https://git.kernel.org/cgit/linux/kernel/git/djwong/xfs-linux.git/log/?h=bigtime

xfsprogs git tree:
https://git.kernel.org/cgit/linux/kernel/git/djwong/xfsprogs-dev.git/log/?h=bigtime

fstests git tree:
https://git.kernel.org/cgit/linux/kernel/git/djwong/xfstests-dev.git/log/?h=bigtime
---
 db/Makefile                |    3 -
 db/command.c               |    1 
 db/command.h               |    1 
 db/dquot.c                 |    6 +
 db/field.c                 |   10 +-
 db/field.h                 |    1 
 db/fprint.c                |  133 +++++++++++++++++++++++++++----
 db/fprint.h                |    4 +
 db/inode.c                 |    9 +-
 db/sb.c                    |   17 ++++
 db/timelimit.c             |  160 +++++++++++++++++++++++++++++++++++++
 include/libxfs.h           |    1 
 include/platform_defs.h.in |    3 +
 include/xfs.h              |    2 
 include/xfs_fs_compat.h    |   12 +++
 include/xfs_inode.h        |   27 ++++--
 include/xfs_mount.h        |    5 +
 include/xqm.h              |   20 ++++-
 libfrog/bulkstat.h         |    4 +
 libfrog/convert.c          |    6 +
 libfrog/convert.h          |    2 
 libfrog/fsgeom.c           |    6 +
 libxfs/libxfs_api_defs.h   |    2 
 libxfs/libxfs_priv.h       |    2 
 libxfs/util.c              |    7 +-
 libxfs/xfs_dquot_buf.c     |   35 ++++++++
 libxfs/xfs_format.h        |  190 +++++++++++++++++++++++++++++++++++++++++++-
 libxfs/xfs_fs.h            |    1 
 libxfs/xfs_ialloc.c        |    4 +
 libxfs/xfs_inode_buf.c     |  130 ++++++++++++++----------------
 libxfs/xfs_inode_buf.h     |   15 +++
 libxfs/xfs_log_format.h    |    7 +-
 libxfs/xfs_quota_defs.h    |    8 ++
 libxfs/xfs_sb.c            |    2 
 libxfs/xfs_shared.h        |    3 +
 libxfs/xfs_trans_inode.c   |   11 +++
 logprint/log_misc.c        |   29 ++++++-
 logprint/log_print_all.c   |    3 -
 logprint/logprint.h        |    2 
 man/man8/mkfs.xfs.8        |   16 ++++
 man/man8/xfs_admin.8       |    5 +
 man/man8/xfs_db.8          |   23 +++++
 mkfs/xfs_mkfs.c            |   24 +++++-
 quota/edit.c               |   79 +++++++++++++++---
 quota/quota.c              |   16 ++--
 quota/quota.h              |    9 ++
 quota/report.c             |   16 ++--
 quota/util.c               |    5 +
 repair/dinode.c            |   40 ++++++++-
 repair/quotacheck.c        |   11 ++-
 scrub/common.c             |    2 
 scrub/fscounters.c         |    1 
 scrub/inodes.c             |    5 -
 scrub/progress.c           |    1 
 54 files changed, 959 insertions(+), 178 deletions(-)
 create mode 100644 db/timelimit.c


^ permalink raw reply	[flat|nested] 58+ messages in thread

* [PATCH 01/26] libxfs: create a real struct timespec64
  2020-10-26 23:34 [PATCH v6 00/26] xfsprogs: widen timestamps to deal with y2038 Darrick J. Wong
@ 2020-10-26 23:34 ` Darrick J. Wong
  2020-10-29  9:44   ` Christoph Hellwig
  2020-10-26 23:34 ` [PATCH 02/26] libxfs: refactor NSEC_PER_SEC Darrick J. Wong
                   ` (24 subsequent siblings)
  25 siblings, 1 reply; 58+ messages in thread
From: Darrick J. Wong @ 2020-10-26 23:34 UTC (permalink / raw)
  To: sandeen, darrick.wong; +Cc: Amir Goldstein, linux-xfs

From: Darrick J. Wong <darrick.wong@oracle.com>

Create a real struct timespec64 that supports 64-bit seconds counts.
The C library struct timespec doesn't support this on 32-bit
architectures and we cannot lose the upper bits in the incore inode.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Amir Goldstein <amir73il@gmail.com>
---
 include/libxfs.h        |    1 -
 include/xfs_fs_compat.h |    8 ++++++++
 include/xfs_inode.h     |   22 +++++++++++-----------
 libxfs/libxfs_priv.h    |    2 --
 4 files changed, 19 insertions(+), 14 deletions(-)


diff --git a/include/libxfs.h b/include/libxfs.h
index b9370139becc..2667d3b77084 100644
--- a/include/libxfs.h
+++ b/include/libxfs.h
@@ -41,7 +41,6 @@ struct iomap;
 #define __round_mask(x, y) ((__typeof__(x))((y)-1))
 #define round_up(x, y) ((((x)-1) | __round_mask(x, y))+1)
 #define unlikely(x) (x)
-#define timespec64 timespec
 
 /*
  * This mirrors the kernel include for xfs_buf.h - it's implicitly included in
diff --git a/include/xfs_fs_compat.h b/include/xfs_fs_compat.h
index 154a802d9aed..d0ffc9775875 100644
--- a/include/xfs_fs_compat.h
+++ b/include/xfs_fs_compat.h
@@ -85,4 +85,12 @@ struct xfs_extent_data {
 #define XFS_IOC_CLONE_RANGE	 _IOW (0x94, 13, struct xfs_clone_args)
 #define XFS_IOC_FILE_EXTENT_SAME _IOWR(0x94, 54, struct xfs_extent_data)
 
+/* 64-bit seconds counter that works independently of the C library time_t. */
+typedef long long int time64_t;
+
+struct timespec64 {
+	time64_t	tv_sec;			/* seconds */
+	long		tv_nsec;		/* nanoseconds */
+};
+
 #endif	/* __XFS_FS_COMPAT_H__ */
diff --git a/include/xfs_inode.h b/include/xfs_inode.h
index 588d8c7258f4..12676cb30bf2 100644
--- a/include/xfs_inode.h
+++ b/include/xfs_inode.h
@@ -31,17 +31,17 @@ struct xfs_inode_log_item;
  * metadata.
  */
 struct inode {
-	mode_t		i_mode;
-	uint32_t	i_uid;
-	uint32_t	i_gid;
-	uint32_t	i_nlink;
-	xfs_dev_t	i_rdev;		/* This actually holds xfs_dev_t */
-	unsigned long	i_state;	/* Not actually used in userspace */
-	uint32_t	i_generation;
-	uint64_t	i_version;
-	struct timespec	i_atime;
-	struct timespec	i_mtime;
-	struct timespec	i_ctime;
+	mode_t			i_mode;
+	uint32_t		i_uid;
+	uint32_t		i_gid;
+	uint32_t		i_nlink;
+	xfs_dev_t		i_rdev;	 /* This actually holds xfs_dev_t */
+	unsigned long		i_state; /* Not actually used in userspace */
+	uint32_t		i_generation;
+	uint64_t		i_version;
+	struct timespec64	i_atime;
+	struct timespec64	i_mtime;
+	struct timespec64	i_ctime;
 };
 
 static inline uint32_t i_uid_read(struct inode *inode)
diff --git a/libxfs/libxfs_priv.h b/libxfs/libxfs_priv.h
index bd724c32c263..e92269f0bdae 100644
--- a/libxfs/libxfs_priv.h
+++ b/libxfs/libxfs_priv.h
@@ -64,8 +64,6 @@ extern kmem_zone_t *xfs_buf_zone;
 extern kmem_zone_t *xfs_inode_zone;
 extern kmem_zone_t *xfs_trans_zone;
 
-#define timespec64 timespec
-
 /* fake up iomap, (not) used in xfs_bmap.[ch] */
 #define IOMAP_F_SHARED			0x04
 #define xfs_bmbt_to_iomap(a, b, c, d)	((void) 0)


^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH 02/26] libxfs: refactor NSEC_PER_SEC
  2020-10-26 23:34 [PATCH v6 00/26] xfsprogs: widen timestamps to deal with y2038 Darrick J. Wong
  2020-10-26 23:34 ` [PATCH 01/26] libxfs: create a real struct timespec64 Darrick J. Wong
@ 2020-10-26 23:34 ` Darrick J. Wong
  2020-10-29  9:44   ` Christoph Hellwig
  2020-10-26 23:34 ` [PATCH 03/26] libfrog: define LIBFROG_BULKSTAT_CHUNKSIZE to remove dependence on XFS_INODES_PER_CHUNK Darrick J. Wong
                   ` (23 subsequent siblings)
  25 siblings, 1 reply; 58+ messages in thread
From: Darrick J. Wong @ 2020-10-26 23:34 UTC (permalink / raw)
  To: sandeen, darrick.wong; +Cc: Amir Goldstein, linux-xfs

From: Darrick J. Wong <darrick.wong@oracle.com>

Clean up all the open-coded and duplicate definitions of time unit
conversion factors.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Amir Goldstein <amir73il@gmail.com>
---
 include/platform_defs.h.in |    3 +++
 repair/dinode.c            |    2 +-
 scrub/common.c             |    2 --
 scrub/progress.c           |    1 -
 4 files changed, 4 insertions(+), 4 deletions(-)


diff --git a/include/platform_defs.h.in b/include/platform_defs.h.in
index 1f7ceafb1fbc..a11b58719380 100644
--- a/include/platform_defs.h.in
+++ b/include/platform_defs.h.in
@@ -80,4 +80,7 @@ typedef unsigned short umode_t;
 
 extern int	platform_nproc(void);
 
+#define NSEC_PER_SEC	(1000000000ULL)
+#define NSEC_PER_USEC	(1000ULL)
+
 #endif	/* __XFS_PLATFORM_DEFS_H__ */
diff --git a/repair/dinode.c b/repair/dinode.c
index 028a23cd5c8c..95e57b5318b5 100644
--- a/repair/dinode.c
+++ b/repair/dinode.c
@@ -2170,7 +2170,7 @@ check_nsec(
 	struct xfs_timestamp	*t,
 	int			*dirty)
 {
-	if (be32_to_cpu(t->t_nsec) < 1000000000)
+	if (be32_to_cpu(t->t_nsec) < NSEC_PER_SEC)
 		return;
 
 	do_warn(
diff --git a/scrub/common.c b/scrub/common.c
index c4699b6ad1e3..49a87f412c4d 100644
--- a/scrub/common.c
+++ b/scrub/common.c
@@ -288,8 +288,6 @@ scrub_nproc_workqueue(
  * Sleep for 100us * however many -b we got past the initial one.
  * This is an (albeit clumsy) way to throttle scrub activity.
  */
-#define NSEC_PER_SEC	1000000000ULL
-#define NSEC_PER_USEC	1000ULL
 void
 background_sleep(void)
 {
diff --git a/scrub/progress.c b/scrub/progress.c
index d8130ca5f93c..15247b7c6d1b 100644
--- a/scrub/progress.c
+++ b/scrub/progress.c
@@ -110,7 +110,6 @@ progress_report(
 	fflush(pt.fp);
 }
 
-#define NSEC_PER_SEC	(1000000000)
 static void *
 progress_report_thread(void *arg)
 {


^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH 03/26] libfrog: define LIBFROG_BULKSTAT_CHUNKSIZE to remove dependence on XFS_INODES_PER_CHUNK
  2020-10-26 23:34 [PATCH v6 00/26] xfsprogs: widen timestamps to deal with y2038 Darrick J. Wong
  2020-10-26 23:34 ` [PATCH 01/26] libxfs: create a real struct timespec64 Darrick J. Wong
  2020-10-26 23:34 ` [PATCH 02/26] libxfs: refactor NSEC_PER_SEC Darrick J. Wong
@ 2020-10-26 23:34 ` Darrick J. Wong
  2020-10-29  9:45   ` Christoph Hellwig
  2020-10-26 23:34 ` [PATCH 04/26] libfrog: convert cvttime to return time64_t Darrick J. Wong
                   ` (22 subsequent siblings)
  25 siblings, 1 reply; 58+ messages in thread
From: Darrick J. Wong @ 2020-10-26 23:34 UTC (permalink / raw)
  To: sandeen, darrick.wong; +Cc: linux-xfs

From: Darrick J. Wong <darrick.wong@oracle.com>

"Online" XFS programs like scrub have no business importing the internal
disk format headers to discover things like the optimum number of inodes
to request through a bulkstat request.  That number can be derived from
the ioctl definition, so define a new constant in terms of that instead
of pulling in the ondisk format unnecessarily.

Note: This patch will be needed to work around new definitions in the
bigtime patchset that will break scrub builds, so clean this up instead
of adding more #includes to the two scrub source files.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 include/xfs.h      |    2 ++
 libfrog/bulkstat.h |    4 ++++
 scrub/fscounters.c |    1 -
 scrub/inodes.c     |    5 ++---
 4 files changed, 8 insertions(+), 4 deletions(-)


diff --git a/include/xfs.h b/include/xfs.h
index af0d36cef361..e97158c8d223 100644
--- a/include/xfs.h
+++ b/include/xfs.h
@@ -38,6 +38,8 @@ extern int xfs_assert_largefile[sizeof(off_t)-8];
 #define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)]))
 #endif
 
+#define sizeof_field(TYPE, MEMBER) sizeof((((TYPE *)0)->MEMBER))
+
 #include <xfs/xfs_types.h>
 /* Include deprecated/compat pre-vfs xfs-specific symbols */
 #include <xfs/xfs_fs_compat.h>
diff --git a/libfrog/bulkstat.h b/libfrog/bulkstat.h
index 56ef7f9a8237..2f440b14f93d 100644
--- a/libfrog/bulkstat.h
+++ b/libfrog/bulkstat.h
@@ -6,6 +6,10 @@
 #ifndef __LIBFROG_BULKSTAT_H__
 #define __LIBFROG_BULKSTAT_H__
 
+/* This is the minimum reasonable size of a bulkstat request. */
+#define LIBFROG_BULKSTAT_CHUNKSIZE \
+		(NBBY * sizeof_field(struct xfs_inumbers, xi_allocmask))
+
 /* Bulkstat wrappers */
 struct xfs_bstat;
 int xfrog_bulkstat_single(struct xfs_fd *xfd, uint64_t ino, unsigned int flags,
diff --git a/scrub/fscounters.c b/scrub/fscounters.c
index 9a240d49477b..f21b24e0935c 100644
--- a/scrub/fscounters.c
+++ b/scrub/fscounters.c
@@ -9,7 +9,6 @@
 #include <sys/statvfs.h>
 #include "platform_defs.h"
 #include "xfs_arch.h"
-#include "xfs_format.h"
 #include "libfrog/paths.h"
 #include "libfrog/workqueue.h"
 #include "xfs_scrub.h"
diff --git a/scrub/inodes.c b/scrub/inodes.c
index 5ef752fe39d3..bdc12df31479 100644
--- a/scrub/inodes.c
+++ b/scrub/inodes.c
@@ -10,7 +10,6 @@
 #include <sys/statvfs.h>
 #include "platform_defs.h"
 #include "xfs_arch.h"
-#include "xfs_format.h"
 #include "handle.h"
 #include "libfrog/paths.h"
 #include "libfrog/workqueue.h"
@@ -74,7 +73,7 @@ bulkstat_for_inumbers(
 	 * Check each of the stats we got back to make sure we got the inodes
 	 * we asked for.
 	 */
-	for (i = 0, bs = bstat; i < XFS_INODES_PER_CHUNK; i++) {
+	for (i = 0, bs = bstat; i < LIBFROG_BULKSTAT_CHUNKSIZE; i++) {
 		if (!(inumbers->xi_allocmask & (1ULL << i)))
 			continue;
 		if (bs->bs_ino == inumbers->xi_startino + i) {
@@ -134,7 +133,7 @@ scan_ag_inodes(
 			sizeof(handle.ha_fid.fid_len);
 	handle.ha_fid.fid_pad = 0;
 
-	error = -xfrog_bulkstat_alloc_req(XFS_INODES_PER_CHUNK, 0, &breq);
+	error = -xfrog_bulkstat_alloc_req(LIBFROG_BULKSTAT_CHUNKSIZE, 0, &breq);
 	if (error) {
 		str_liberror(ctx, error, descr);
 		si->aborted = true;


^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH 04/26] libfrog: convert cvttime to return time64_t
  2020-10-26 23:34 [PATCH v6 00/26] xfsprogs: widen timestamps to deal with y2038 Darrick J. Wong
                   ` (2 preceding siblings ...)
  2020-10-26 23:34 ` [PATCH 03/26] libfrog: define LIBFROG_BULKSTAT_CHUNKSIZE to remove dependence on XFS_INODES_PER_CHUNK Darrick J. Wong
@ 2020-10-26 23:34 ` Darrick J. Wong
  2020-10-29  9:45   ` Christoph Hellwig
  2020-10-26 23:34 ` [PATCH 05/26] xfs_quota: convert time_to_string to use time64_t Darrick J. Wong
                   ` (21 subsequent siblings)
  25 siblings, 1 reply; 58+ messages in thread
From: Darrick J. Wong @ 2020-10-26 23:34 UTC (permalink / raw)
  To: sandeen, darrick.wong; +Cc: linux-xfs

From: Darrick J. Wong <darrick.wong@oracle.com>

Change the cvttime function to return 64-bit time values so that we can
put them to use with the bigtime feature.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 libfrog/convert.c |    6 +++---
 libfrog/convert.h |    2 +-
 quota/edit.c      |   14 +++++++-------
 3 files changed, 11 insertions(+), 11 deletions(-)


diff --git a/libfrog/convert.c b/libfrog/convert.c
index 6b8ff30de24a..0ceeb389682a 100644
--- a/libfrog/convert.c
+++ b/libfrog/convert.c
@@ -271,14 +271,14 @@ cvtstr(
 #define DAYS_TO_SECONDS(d)	((d) * HOURS_TO_SECONDS(24))
 #define WEEKS_TO_SECONDS(w)	((w) * DAYS_TO_SECONDS(7))
 
-unsigned long
+time64_t
 cvttime(
 	char		*s)
 {
-	unsigned long	i;
+	time64_t	i;
 	char		*sp;
 
-	i = strtoul(s, &sp, 0);
+	i = strtoll(s, &sp, 0);
 	if (i == 0 && sp == s)
 		return 0;
 	if (*sp == '\0')
diff --git a/libfrog/convert.h b/libfrog/convert.h
index b307d31ce955..3e5fbe055986 100644
--- a/libfrog/convert.h
+++ b/libfrog/convert.h
@@ -16,7 +16,7 @@ extern uint16_t	cvt_u16(char *s, int base);
 
 extern long long cvtnum(size_t blocksize, size_t sectorsize, const char *s);
 extern void cvtstr(double value, char *str, size_t sz);
-extern unsigned long cvttime(char *s);
+extern time64_t cvttime(char *s);
 
 extern uid_t	uid_from_string(char *user);
 extern gid_t	gid_from_string(char *group);
diff --git a/quota/edit.c b/quota/edit.c
index 01d358f740c8..b3cad024b1f1 100644
--- a/quota/edit.c
+++ b/quota/edit.c
@@ -419,13 +419,13 @@ restore_f(
 
 static void
 set_timer(
-	uint32_t	id,
-	uint		type,
-	uint		mask,
-	char		*dev,
-	uint		value)
+	uint32_t		id,
+	uint			type,
+	uint			mask,
+	char			*dev,
+	time64_t		value)
 {
-	fs_disk_quota_t	d;
+	struct fs_disk_quota	d;
 
 	memset(&d, 0, sizeof(d));
 
@@ -476,7 +476,7 @@ timer_f(
 	int		argc,
 	char		**argv)
 {
-	uint		value;
+	time64_t	value;
 	char		*name = NULL;
 	uint32_t	id = 0;
 	int		c, flags = 0, type = 0, mask = 0;


^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH 05/26] xfs_quota: convert time_to_string to use time64_t
  2020-10-26 23:34 [PATCH v6 00/26] xfsprogs: widen timestamps to deal with y2038 Darrick J. Wong
                   ` (3 preceding siblings ...)
  2020-10-26 23:34 ` [PATCH 04/26] libfrog: convert cvttime to return time64_t Darrick J. Wong
@ 2020-10-26 23:34 ` Darrick J. Wong
  2020-10-29  9:47   ` Christoph Hellwig
  2020-11-16 20:45   ` Eric Sandeen
  2020-10-26 23:34 ` [PATCH 06/26] xfs_db: refactor timestamp printing Darrick J. Wong
                   ` (20 subsequent siblings)
  25 siblings, 2 replies; 58+ messages in thread
From: Darrick J. Wong @ 2020-10-26 23:34 UTC (permalink / raw)
  To: sandeen, darrick.wong; +Cc: linux-xfs

From: Darrick J. Wong <darrick.wong@oracle.com>

Rework the time_to_string helper to be capable of dealing with 64-bit
timestamps.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 quota/quota.c  |   16 ++++++++++------
 quota/quota.h  |    2 +-
 quota/report.c |   16 ++++++++++------
 quota/util.c   |    5 +++--
 4 files changed, 24 insertions(+), 15 deletions(-)


diff --git a/quota/quota.c b/quota/quota.c
index 9545cc430a93..8ba0995d9174 100644
--- a/quota/quota.c
+++ b/quota/quota.c
@@ -48,6 +48,7 @@ quota_mount(
 	uint		flags)
 {
 	fs_disk_quota_t	d;
+	time64_t	timer;
 	char		*dev = mount->fs_name;
 	char		c[8], h[8], s[8];
 	uint		qflags;
@@ -100,6 +101,7 @@ quota_mount(
 	}
 
 	if (form & XFS_BLOCK_QUOTA) {
+		timer = d.d_btimer;
 		qflags = (flags & HUMAN_FLAG);
 		if (d.d_blk_hardlimit && d.d_bcount > d.d_blk_hardlimit)
 			qflags |= LIMIT_FLAG;
@@ -111,16 +113,17 @@ quota_mount(
 				bbs_to_string(d.d_blk_softlimit, s, sizeof(s)),
 				bbs_to_string(d.d_blk_hardlimit, h, sizeof(h)),
 				d.d_bwarns,
-				time_to_string(d.d_btimer, qflags));
+				time_to_string(timer, qflags));
 		else
 			fprintf(fp, " %10llu %10llu %10llu   %02d %9s ",
 				(unsigned long long)d.d_bcount >> 1,
 				(unsigned long long)d.d_blk_softlimit >> 1,
 				(unsigned long long)d.d_blk_hardlimit >> 1,
 				d.d_bwarns,
-				time_to_string(d.d_btimer, qflags));
+				time_to_string(timer, qflags));
 	}
 	if (form & XFS_INODE_QUOTA) {
+		timer = d.d_itimer;
 		qflags = (flags & HUMAN_FLAG);
 		if (d.d_ino_hardlimit && d.d_icount > d.d_ino_hardlimit)
 			qflags |= LIMIT_FLAG;
@@ -132,16 +135,17 @@ quota_mount(
 				num_to_string(d.d_ino_softlimit, s, sizeof(s)),
 				num_to_string(d.d_ino_hardlimit, h, sizeof(h)),
 				d.d_iwarns,
-				time_to_string(d.d_itimer, qflags));
+				time_to_string(timer, qflags));
 		else
 			fprintf(fp, " %10llu %10llu %10llu   %02d %9s ",
 				(unsigned long long)d.d_icount,
 				(unsigned long long)d.d_ino_softlimit,
 				(unsigned long long)d.d_ino_hardlimit,
 				d.d_iwarns,
-				time_to_string(d.d_itimer, qflags));
+				time_to_string(timer, qflags));
 	}
 	if (form & XFS_RTBLOCK_QUOTA) {
+		timer = d.d_rtbtimer;
 		qflags = (flags & HUMAN_FLAG);
 		if (d.d_rtb_hardlimit && d.d_rtbcount > d.d_rtb_hardlimit)
 			qflags |= LIMIT_FLAG;
@@ -153,14 +157,14 @@ quota_mount(
 				bbs_to_string(d.d_rtb_softlimit, s, sizeof(s)),
 				bbs_to_string(d.d_rtb_hardlimit, h, sizeof(h)),
 				d.d_rtbwarns,
-				time_to_string(d.d_rtbtimer, qflags));
+				time_to_string(timer, qflags));
 		else
 			fprintf(fp, " %10llu %10llu %10llu   %02d %9s ",
 				(unsigned long long)d.d_rtbcount >> 1,
 				(unsigned long long)d.d_rtb_softlimit >> 1,
 				(unsigned long long)d.d_rtb_hardlimit >> 1,
 				d.d_rtbwarns,
-				time_to_string(d.d_rtbtimer, qflags));
+				time_to_string(timer, qflags));
 	}
 	fprintf(fp, "%s\n", mount->fs_dir);
 	return 1;
diff --git a/quota/quota.h b/quota/quota.h
index 025d887726d8..11f62b208e6a 100644
--- a/quota/quota.h
+++ b/quota/quota.h
@@ -40,7 +40,7 @@ enum {
  */
 extern char *type_to_string(uint __type);
 extern char *form_to_string(uint __form);
-extern char *time_to_string(time_t __time, uint __flags);
+extern char *time_to_string(time64_t __time, uint __flags);
 extern char *bbs_to_string(uint64_t __v, char *__c, uint __size);
 extern char *num_to_string(uint64_t __v, char *__c, uint __size);
 extern char *pct_to_string(uint64_t __v, uint64_t __t, char *__c, uint __s);
diff --git a/quota/report.c b/quota/report.c
index e6def916b827..2d5024e95177 100644
--- a/quota/report.c
+++ b/quota/report.c
@@ -330,6 +330,7 @@ report_mount(
 	uint		flags)
 {
 	fs_disk_quota_t	d;
+	time64_t	timer;
 	char		*dev = mount->fs_name;
 	char		c[8], h[8], s[8];
 	uint		qflags;
@@ -397,6 +398,7 @@ report_mount(
 	}
 
 	if (form & XFS_BLOCK_QUOTA) {
+		timer = d.d_btimer;
 		qflags = (flags & HUMAN_FLAG);
 		if (d.d_blk_hardlimit && d.d_bcount > d.d_blk_hardlimit)
 			qflags |= LIMIT_FLAG;
@@ -408,16 +410,17 @@ report_mount(
 				bbs_to_string(d.d_blk_softlimit, s, sizeof(s)),
 				bbs_to_string(d.d_blk_hardlimit, h, sizeof(h)),
 				d.d_bwarns,
-				time_to_string(d.d_btimer, qflags));
+				time_to_string(timer, qflags));
 		else
 			fprintf(fp, " %10llu %10llu %10llu     %02d %9s",
 				(unsigned long long)d.d_bcount >> 1,
 				(unsigned long long)d.d_blk_softlimit >> 1,
 				(unsigned long long)d.d_blk_hardlimit >> 1,
 				d.d_bwarns,
-				time_to_string(d.d_btimer, qflags));
+				time_to_string(timer, qflags));
 	}
 	if (form & XFS_INODE_QUOTA) {
+		timer = d.d_itimer;
 		qflags = (flags & HUMAN_FLAG);
 		if (d.d_ino_hardlimit && d.d_icount > d.d_ino_hardlimit)
 			qflags |= LIMIT_FLAG;
@@ -429,16 +432,17 @@ report_mount(
 				num_to_string(d.d_ino_softlimit, s, sizeof(s)),
 				num_to_string(d.d_ino_hardlimit, h, sizeof(h)),
 				d.d_iwarns,
-				time_to_string(d.d_itimer, qflags));
+				time_to_string(timer, qflags));
 		else
 			fprintf(fp, " %10llu %10llu %10llu     %02d %9s",
 				(unsigned long long)d.d_icount,
 				(unsigned long long)d.d_ino_softlimit,
 				(unsigned long long)d.d_ino_hardlimit,
 				d.d_iwarns,
-				time_to_string(d.d_itimer, qflags));
+				time_to_string(timer, qflags));
 	}
 	if (form & XFS_RTBLOCK_QUOTA) {
+		timer = d.d_rtbtimer;
 		qflags = (flags & HUMAN_FLAG);
 		if (d.d_rtb_hardlimit && d.d_rtbcount > d.d_rtb_hardlimit)
 			qflags |= LIMIT_FLAG;
@@ -450,14 +454,14 @@ report_mount(
 				bbs_to_string(d.d_rtb_softlimit, s, sizeof(s)),
 				bbs_to_string(d.d_rtb_hardlimit, h, sizeof(h)),
 				d.d_rtbwarns,
-				time_to_string(d.d_rtbtimer, qflags));
+				time_to_string(timer, qflags));
 		else
 			fprintf(fp, " %10llu %10llu %10llu     %02d %9s",
 				(unsigned long long)d.d_rtbcount >> 1,
 				(unsigned long long)d.d_rtb_softlimit >> 1,
 				(unsigned long long)d.d_rtb_hardlimit >> 1,
 				d.d_rtbwarns,
-				time_to_string(d.d_rtbtimer, qflags));
+				time_to_string(timer, qflags));
 	}
 	fputc('\n', fp);
 	return 1;
diff --git a/quota/util.c b/quota/util.c
index 50470aba7b05..361d2a8ef5c6 100644
--- a/quota/util.c
+++ b/quota/util.c
@@ -18,11 +18,12 @@
 
 char *
 time_to_string(
-	time_t		origin,
+	time64_t	origin,
 	uint		flags)
 {
 	static char	timestamp[32];
-	time_t		now, timer;
+	time64_t	timer;
+	time_t		now;
 	uint		days, hours, minutes, seconds;
 
 	if (flags & ABSOLUTE_FLAG) {


^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH 06/26] xfs_db: refactor timestamp printing
  2020-10-26 23:34 [PATCH v6 00/26] xfsprogs: widen timestamps to deal with y2038 Darrick J. Wong
                   ` (4 preceding siblings ...)
  2020-10-26 23:34 ` [PATCH 05/26] xfs_quota: convert time_to_string to use time64_t Darrick J. Wong
@ 2020-10-26 23:34 ` Darrick J. Wong
  2020-10-29  9:47   ` Christoph Hellwig
  2020-10-26 23:34 ` [PATCH 07/26] xfs_db: refactor quota timer printing Darrick J. Wong
                   ` (19 subsequent siblings)
  25 siblings, 1 reply; 58+ messages in thread
From: Darrick J. Wong @ 2020-10-26 23:34 UTC (permalink / raw)
  To: sandeen, darrick.wong; +Cc: linux-xfs

From: Darrick J. Wong <darrick.wong@oracle.com>

Introduce type-specific printing functions to xfs_db to print an
xfs_timestamp instead of open-coding the timestamp decoding.  This is
needed to stay ahead of changes that we're going to make to
xfs_timestamp_t in the following patches.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 db/field.c  |    8 ++++---
 db/fprint.c |   67 ++++++++++++++++++++++++++++++++++++++++++++++-------------
 db/fprint.h |    2 ++
 db/inode.c  |    5 ++--
 4 files changed, 60 insertions(+), 22 deletions(-)


diff --git a/db/field.c b/db/field.c
index aa0154d82eb7..f0316aeb4a86 100644
--- a/db/field.c
+++ b/db/field.c
@@ -334,8 +334,8 @@ const ftattr_t	ftattrtab[] = {
 	  FTARG_SIGNED, NULL, NULL },
 	{ FLDT_INT8D, "int8d", fp_num, "%d", SI(bitsz(int8_t)), FTARG_SIGNED,
 	  NULL, NULL },
-	{ FLDT_NSEC, "nsec", fp_num, "%09d", SI(bitsz(int32_t)), FTARG_SIGNED,
-	  NULL, NULL },
+	{ FLDT_NSEC, "nsec", fp_nsec, NULL, SI(bitsz(xfs_timestamp_t)),
+	  FTARG_SIGNED, NULL, NULL },
 	{ FLDT_QCNT, "qcnt", fp_num, "%llu", SI(bitsz(xfs_qcnt_t)), 0, NULL,
 	  NULL },
 	{ FLDT_QWARNCNT, "qwarncnt", fp_num, "%u", SI(bitsz(xfs_qwarncnt_t)), 0,
@@ -347,8 +347,8 @@ const ftattr_t	ftattrtab[] = {
 	{ FLDT_SYMLINK_CRC, "symlink", NULL, (char *)symlink_crc_flds,
 	  symlink_size, FTARG_SIZE, NULL, symlink_crc_flds },
 
-	{ FLDT_TIME, "time", fp_time, NULL, SI(bitsz(int32_t)), FTARG_SIGNED,
-	  NULL, NULL },
+	{ FLDT_TIME, "time", fp_time, NULL, SI(bitsz(xfs_timestamp_t)),
+	  FTARG_SIGNED, NULL, NULL },
 	{ FLDT_TIMESTAMP, "timestamp", NULL, (char *)timestamp_flds,
 	  SI(bitsz(xfs_timestamp_t)), 0, NULL, timestamp_flds },
 	{ FLDT_UINT1, "uint1", fp_num, "%u", SI(1), 0, NULL, NULL },
diff --git a/db/fprint.c b/db/fprint.c
index c9d07e1bca7e..feec02c5de99 100644
--- a/db/fprint.c
+++ b/db/fprint.c
@@ -112,22 +112,22 @@ fp_sarray(
 	return 1;
 }
 
-/*ARGSUSED*/
 int
 fp_time(
-	void	*obj,
-	int	bit,
-	int	count,
-	char	*fmtstr,
-	int	size,
-	int	arg,
-	int	base,
-	int	array)
+	void			*obj,
+	int			bit,
+	int			count,
+	char			*fmtstr,
+	int			size,
+	int			arg,
+	int			base,
+	int			array)
 {
-	int	bitpos;
-	char	*c;
-	int	i;
-	time_t  t;
+	xfs_timestamp_t		*ts;
+	int			bitpos;
+	char			*c;
+	int			i;
+	time_t			t;
 
 	ASSERT(bitoffs(bit) == 0);
 	for (i = 0, bitpos = bit;
@@ -135,10 +135,47 @@ fp_time(
 	     i++, bitpos += size) {
 		if (array)
 			dbprintf("%d:", i + base);
-		t = (time_t)getbitval((char *)obj + byteize(bitpos), 0,
-				sizeof(int32_t) * 8, BVSIGNED);
+
+		ts = obj + byteize(bitpos);
+		t = (int)be32_to_cpu(ts->t_sec);
+
 		c = ctime(&t);
 		dbprintf("%24.24s", c);
+
+		if (i < count - 1)
+			dbprintf(" ");
+	}
+	return 1;
+}
+
+int
+fp_nsec(
+	void			*obj,
+	int			bit,
+	int			count,
+	char			*fmtstr,
+	int			size,
+	int			arg,
+	int			base,
+	int			array)
+{
+	xfs_timestamp_t		*ts;
+	unsigned int		nsec;
+	int			bitpos;
+	int			i;
+
+	ASSERT(bitoffs(bit) == 0);
+	for (i = 0, bitpos = bit;
+	     i < count && !seenint();
+	     i++, bitpos += size) {
+		if (array)
+			dbprintf("%d:", i + base);
+
+		ts = obj + byteize(bitpos);
+		nsec = (int)be32_to_cpu(ts->t_nsec);
+
+		dbprintf("%u", nsec);
+
 		if (i < count - 1)
 			dbprintf(" ");
 	}
diff --git a/db/fprint.h b/db/fprint.h
index c958dca0ed92..bfeed15ca7c4 100644
--- a/db/fprint.h
+++ b/db/fprint.h
@@ -15,6 +15,8 @@ extern int	fp_sarray(void *obj, int bit, int count, char *fmtstr, int size,
 			  int arg, int base, int array);
 extern int	fp_time(void *obj, int bit, int count, char *fmtstr, int size,
 			int arg, int base, int array);
+extern int	fp_nsec(void *obj, int bit, int count, char *fmtstr, int size,
+			int arg, int base, int array);
 extern int	fp_uuid(void *obj, int bit, int count, char *fmtstr, int size,
 			int arg, int base, int array);
 extern int	fp_crc(void *obj, int bit, int count, char *fmtstr, int size,
diff --git a/db/inode.c b/db/inode.c
index f13150c96aa9..cc0e680aadea 100644
--- a/db/inode.c
+++ b/db/inode.c
@@ -179,10 +179,9 @@ const field_t	inode_v3_flds[] = {
 };
 
 
-#define	TOFF(f)	bitize(offsetof(xfs_timestamp_t, t_ ## f))
 const field_t	timestamp_flds[] = {
-	{ "sec", FLDT_TIME, OI(TOFF(sec)), C1, 0, TYP_NONE },
-	{ "nsec", FLDT_NSEC, OI(TOFF(nsec)), C1, 0, TYP_NONE },
+	{ "sec", FLDT_TIME, OI(0), C1, 0, TYP_NONE },
+	{ "nsec", FLDT_NSEC, OI(0), C1, 0, TYP_NONE },
 	{ NULL }
 };
 


^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH 07/26] xfs_db: refactor quota timer printing
  2020-10-26 23:34 [PATCH v6 00/26] xfsprogs: widen timestamps to deal with y2038 Darrick J. Wong
                   ` (5 preceding siblings ...)
  2020-10-26 23:34 ` [PATCH 06/26] xfs_db: refactor timestamp printing Darrick J. Wong
@ 2020-10-26 23:34 ` Darrick J. Wong
  2020-10-29  9:48   ` Christoph Hellwig
  2020-10-26 23:34 ` [PATCH 08/26] xfs_logprint: refactor timestamp printing Darrick J. Wong
                   ` (18 subsequent siblings)
  25 siblings, 1 reply; 58+ messages in thread
From: Darrick J. Wong @ 2020-10-26 23:34 UTC (permalink / raw)
  To: sandeen, darrick.wong; +Cc: linux-xfs

From: Darrick J. Wong <darrick.wong@oracle.com>

Introduce type-specific printing functions to xfs_db to print a quota
timer instead of printing a raw int32 value.  This is needed to stay
ahead of changes that we're going to make to the quota timer format in
the following patches.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 db/dquot.c  |    6 +++---
 db/field.c  |    2 ++
 db/field.h  |    1 +
 db/fprint.c |   34 ++++++++++++++++++++++++++++++++++
 db/fprint.h |    2 ++
 5 files changed, 42 insertions(+), 3 deletions(-)


diff --git a/db/dquot.c b/db/dquot.c
index 1392aa1673ae..e52000f2e6ee 100644
--- a/db/dquot.c
+++ b/db/dquot.c
@@ -60,8 +60,8 @@ const field_t	disk_dquot_flds[] = {
 	  TYP_NONE },
 	{ "bcount", FLDT_QCNT, OI(DOFF(bcount)), C1, 0, TYP_NONE },
 	{ "icount", FLDT_QCNT, OI(DOFF(icount)), C1, 0, TYP_NONE },
-	{ "itimer", FLDT_INT32D, OI(DOFF(itimer)), C1, 0, TYP_NONE },
-	{ "btimer", FLDT_INT32D, OI(DOFF(btimer)), C1, 0, TYP_NONE },
+	{ "itimer", FLDT_QTIMER, OI(DOFF(itimer)), C1, 0, TYP_NONE },
+	{ "btimer", FLDT_QTIMER, OI(DOFF(btimer)), C1, 0, TYP_NONE },
 	{ "iwarns", FLDT_QWARNCNT, OI(DOFF(iwarns)), C1, 0, TYP_NONE },
 	{ "bwarns", FLDT_QWARNCNT, OI(DOFF(bwarns)), C1, 0, TYP_NONE },
 	{ "pad0", FLDT_UINT32X, OI(DOFF(pad0)), C1, FLD_SKIPALL, TYP_NONE },
@@ -70,7 +70,7 @@ const field_t	disk_dquot_flds[] = {
 	{ "rtb_softlimit", FLDT_QCNT, OI(DOFF(rtb_softlimit)), C1, 0,
 	  TYP_NONE },
 	{ "rtbcount", FLDT_QCNT, OI(DOFF(rtbcount)), C1, 0, TYP_NONE },
-	{ "rtbtimer", FLDT_INT32D, OI(DOFF(rtbtimer)), C1, 0, TYP_NONE },
+	{ "rtbtimer", FLDT_QTIMER, OI(DOFF(rtbtimer)), C1, 0, TYP_NONE },
 	{ "rtbwarns", FLDT_QWARNCNT, OI(DOFF(rtbwarns)), C1, 0, TYP_NONE },
 	{ "pad", FLDT_UINT16X, OI(DOFF(pad)), C1, FLD_SKIPALL, TYP_NONE },
 	{ NULL }
diff --git a/db/field.c b/db/field.c
index f0316aeb4a86..51268938a9d3 100644
--- a/db/field.c
+++ b/db/field.c
@@ -351,6 +351,8 @@ const ftattr_t	ftattrtab[] = {
 	  FTARG_SIGNED, NULL, NULL },
 	{ FLDT_TIMESTAMP, "timestamp", NULL, (char *)timestamp_flds,
 	  SI(bitsz(xfs_timestamp_t)), 0, NULL, timestamp_flds },
+	{ FLDT_QTIMER, "qtimer", fp_qtimer, NULL, SI(bitsz(uint32_t)), 0,
+	  NULL, NULL },
 	{ FLDT_UINT1, "uint1", fp_num, "%u", SI(1), 0, NULL, NULL },
 	{ FLDT_UINT16D, "uint16d", fp_num, "%u", SI(bitsz(uint16_t)), 0, NULL,
 	  NULL },
diff --git a/db/field.h b/db/field.h
index 15065373de39..387c189ec87a 100644
--- a/db/field.h
+++ b/db/field.h
@@ -170,6 +170,7 @@ typedef enum fldt	{
 
 	FLDT_TIME,
 	FLDT_TIMESTAMP,
+	FLDT_QTIMER,
 	FLDT_UINT1,
 	FLDT_UINT16D,
 	FLDT_UINT16O,
diff --git a/db/fprint.c b/db/fprint.c
index feec02c5de99..996e9325ddcc 100644
--- a/db/fprint.c
+++ b/db/fprint.c
@@ -182,6 +182,40 @@ fp_nsec(
 	return 1;
 }
 
+int
+fp_qtimer(
+	void			*obj,
+	int			bit,
+	int			count,
+	char			*fmtstr,
+	int			size,
+	int			arg,
+	int			base,
+	int			array)
+{
+	uint32_t		sec;
+	__be32			*t;
+	int			bitpos;
+	int			i;
+
+	ASSERT(bitoffs(bit) == 0);
+	for (i = 0, bitpos = bit;
+	     i < count && !seenint();
+	     i++, bitpos += size) {
+		if (array)
+			dbprintf("%d:", i + base);
+
+		t = obj + byteize(bitpos);
+		sec = be32_to_cpu(*t);
+
+		dbprintf("%u", sec);
+
+		if (i < count - 1)
+			dbprintf(" ");
+	}
+	return 1;
+}
+
 /*ARGSUSED*/
 int
 fp_uuid(
diff --git a/db/fprint.h b/db/fprint.h
index bfeed15ca7c4..a1ea935ca531 100644
--- a/db/fprint.h
+++ b/db/fprint.h
@@ -17,6 +17,8 @@ extern int	fp_time(void *obj, int bit, int count, char *fmtstr, int size,
 			int arg, int base, int array);
 extern int	fp_nsec(void *obj, int bit, int count, char *fmtstr, int size,
 			int arg, int base, int array);
+extern int	fp_qtimer(void *obj, int bit, int count, char *fmtstr, int size,
+			int arg, int base, int array);
 extern int	fp_uuid(void *obj, int bit, int count, char *fmtstr, int size,
 			int arg, int base, int array);
 extern int	fp_crc(void *obj, int bit, int count, char *fmtstr, int size,


^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH 08/26] xfs_logprint: refactor timestamp printing
  2020-10-26 23:34 [PATCH v6 00/26] xfsprogs: widen timestamps to deal with y2038 Darrick J. Wong
                   ` (6 preceding siblings ...)
  2020-10-26 23:34 ` [PATCH 07/26] xfs_db: refactor quota timer printing Darrick J. Wong
@ 2020-10-26 23:34 ` Darrick J. Wong
  2020-10-29  9:48   ` Christoph Hellwig
  2020-11-23 20:14   ` Eric Sandeen
  2020-10-26 23:35 ` [PATCH 09/26] xfs: explicitly define inode timestamp range Darrick J. Wong
                   ` (17 subsequent siblings)
  25 siblings, 2 replies; 58+ messages in thread
From: Darrick J. Wong @ 2020-10-26 23:34 UTC (permalink / raw)
  To: sandeen, darrick.wong; +Cc: linux-xfs

From: Darrick J. Wong <darrick.wong@oracle.com>

Introduce type-specific printing functions to xfs_logprint to print an
xfs_timestamp instead of open-coding the timestamp decoding.  This is
needed to stay ahead of changes that we're going to make to
xfs_timestamp_t in the following patches.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 logprint/log_misc.c      |   18 ++++++++++++++++--
 logprint/log_print_all.c |    3 +--
 logprint/logprint.h      |    2 ++
 3 files changed, 19 insertions(+), 4 deletions(-)


diff --git a/logprint/log_misc.c b/logprint/log_misc.c
index af927cbfa792..a747cbd360af 100644
--- a/logprint/log_misc.c
+++ b/logprint/log_misc.c
@@ -435,6 +435,21 @@ xlog_print_trans_qoff(char **ptr, uint len)
     }
 }	/* xlog_print_trans_qoff */
 
+void
+xlog_print_dinode_ts(
+	struct xfs_log_dinode	*ldip,
+	bool			compact)
+{
+	const char		*fmt;
+
+	if (compact)
+		fmt = _("atime 0x%x mtime 0x%x ctime 0x%x\n");
+	else
+		fmt = _("		atime:%d  mtime:%d  ctime:%d\n");
+
+	printf(fmt, ldip->di_atime.t_sec, ldip->di_mtime.t_sec,
+			ldip->di_ctime.t_sec);
+}
 
 static void
 xlog_print_trans_inode_core(
@@ -446,8 +461,7 @@ xlog_print_trans_inode_core(
 	   (int)ip->di_format);
     printf(_("nlink %hd uid %d gid %d\n"),
 	   ip->di_nlink, ip->di_uid, ip->di_gid);
-    printf(_("atime 0x%x mtime 0x%x ctime 0x%x\n"),
-	   ip->di_atime.t_sec, ip->di_mtime.t_sec, ip->di_ctime.t_sec);
+    xlog_print_dinode_ts(ip, true);
     printf(_("size 0x%llx nblocks 0x%llx extsize 0x%x nextents 0x%x\n"),
 	   (unsigned long long)ip->di_size, (unsigned long long)ip->di_nblocks,
 	   ip->di_extsize, ip->di_nextents);
diff --git a/logprint/log_print_all.c b/logprint/log_print_all.c
index 1924a0af70b6..fae531d3e030 100644
--- a/logprint/log_print_all.c
+++ b/logprint/log_print_all.c
@@ -249,8 +249,7 @@ xlog_recover_print_inode_core(
 	printf(_("		uid:%d  gid:%d  nlink:%d projid:0x%04x%04x\n"),
 	       di->di_uid, di->di_gid, di->di_nlink,
 	       di->di_projid_hi, di->di_projid_lo);
-	printf(_("		atime:%d  mtime:%d  ctime:%d\n"),
-	       di->di_atime.t_sec, di->di_mtime.t_sec, di->di_ctime.t_sec);
+	xlog_print_dinode_ts(di, false);
 	printf(_("		flushiter:%d\n"), di->di_flushiter);
 	printf(_("		size:0x%llx  nblks:0x%llx  exsize:%d  "
 	     "nextents:%d  anextents:%d\n"), (unsigned long long)
diff --git a/logprint/logprint.h b/logprint/logprint.h
index ee85bfe5f21f..6639e1cf5862 100644
--- a/logprint/logprint.h
+++ b/logprint/logprint.h
@@ -29,6 +29,8 @@ extern void print_xlog_record_line(void);
 extern void print_xlog_op_line(void);
 extern void print_stars(void);
 
+void xlog_print_dinode_ts(struct xfs_log_dinode *ldip, bool compact);
+
 extern struct xfs_inode_log_format *
 	xfs_inode_item_format_convert(char *, uint, struct xfs_inode_log_format *);
 


^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH 09/26] xfs: explicitly define inode timestamp range
  2020-10-26 23:34 [PATCH v6 00/26] xfsprogs: widen timestamps to deal with y2038 Darrick J. Wong
                   ` (7 preceding siblings ...)
  2020-10-26 23:34 ` [PATCH 08/26] xfs_logprint: refactor timestamp printing Darrick J. Wong
@ 2020-10-26 23:35 ` Darrick J. Wong
  2020-10-26 23:35 ` [PATCH 10/26] xfs: refactor quota expiration timer modification Darrick J. Wong
                   ` (16 subsequent siblings)
  25 siblings, 0 replies; 58+ messages in thread
From: Darrick J. Wong @ 2020-10-26 23:35 UTC (permalink / raw)
  To: sandeen, darrick.wong
  Cc: Amir Goldstein, Christoph Hellwig, Allison Collins, Gao Xiang,
	Dave Chinner, linux-xfs

From: Darrick J. Wong <darrick.wong@oracle.com>

Source kernel commit: 876fdc7c4f366a709ac272ef3336ae7dce58f2af

Formally define the inode timestamp ranges that existing filesystems
support, and switch the vfs timetamp ranges to use it.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Amir Goldstein <amir73il@gmail.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Allison Collins <allison.henderson@oracle.com>
Reviewed-by: Gao Xiang <hsiangkao@redhat.com>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 include/xfs_fs_compat.h |    4 ++++
 libxfs/xfs_format.h     |   22 ++++++++++++++++++++++
 2 files changed, 26 insertions(+)


diff --git a/include/xfs_fs_compat.h b/include/xfs_fs_compat.h
index d0ffc9775875..0077f00cb949 100644
--- a/include/xfs_fs_compat.h
+++ b/include/xfs_fs_compat.h
@@ -93,4 +93,8 @@ struct timespec64 {
 	long		tv_nsec;		/* nanoseconds */
 };
 
+#define U32_MAX		((uint32_t)~0U)
+#define S32_MAX		((int32_t)(U32_MAX >> 1))
+#define S32_MIN		((int32_t)(-S32_MAX - 1))
+
 #endif	/* __XFS_FS_COMPAT_H__ */
diff --git a/libxfs/xfs_format.h b/libxfs/xfs_format.h
index 5a183b6658e6..4a106b6713ad 100644
--- a/libxfs/xfs_format.h
+++ b/libxfs/xfs_format.h
@@ -848,11 +848,33 @@ struct xfs_agfl {
 	    ASSERT(xfs_daddr_to_agno(mp, d) == \
 		   xfs_daddr_to_agno(mp, (d) + (len) - 1)))
 
+/*
+ * XFS Timestamps
+ * ==============
+ *
+ * Traditional ondisk inode timestamps consist of signed 32-bit counters for
+ * seconds and nanoseconds; time zero is the Unix epoch, Jan  1 00:00:00 UTC
+ * 1970, which means that the timestamp epoch is the same as the Unix epoch.
+ * Therefore, the ondisk min and max defined here can be used directly to
+ * constrain the incore timestamps on a Unix system.
+ */
 typedef struct xfs_timestamp {
 	__be32		t_sec;		/* timestamp seconds */
 	__be32		t_nsec;		/* timestamp nanoseconds */
 } xfs_timestamp_t;
 
+/*
+ * Smallest possible ondisk seconds value with traditional timestamps.  This
+ * corresponds exactly with the incore timestamp Dec 13 20:45:52 UTC 1901.
+ */
+#define XFS_LEGACY_TIME_MIN	((int64_t)S32_MIN)
+
+/*
+ * Largest possible ondisk seconds value with traditional timestamps.  This
+ * corresponds exactly with the incore timestamp Jan 19 03:14:07 UTC 2038.
+ */
+#define XFS_LEGACY_TIME_MAX	((int64_t)S32_MAX)
+
 /*
  * On-disk inode structure.
  *


^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH 10/26] xfs: refactor quota expiration timer modification
  2020-10-26 23:34 [PATCH v6 00/26] xfsprogs: widen timestamps to deal with y2038 Darrick J. Wong
                   ` (8 preceding siblings ...)
  2020-10-26 23:35 ` [PATCH 09/26] xfs: explicitly define inode timestamp range Darrick J. Wong
@ 2020-10-26 23:35 ` Darrick J. Wong
  2020-10-26 23:35 ` [PATCH 11/26] xfs: refactor default quota grace period setting code Darrick J. Wong
                   ` (15 subsequent siblings)
  25 siblings, 0 replies; 58+ messages in thread
From: Darrick J. Wong @ 2020-10-26 23:35 UTC (permalink / raw)
  To: sandeen, darrick.wong
  Cc: Christoph Hellwig, Allison Collins, Dave Chinner, linux-xfs

From: Darrick J. Wong <darrick.wong@oracle.com>

Source kernel commit: 11d8a9190275855f79d62093d789e962cc7228fb

Define explicit limits on the range of quota grace period expiration
timeouts and refactor the code that modifies the timeouts into helpers
that clamp the values appropriately.  Note that we'll refactor the
default grace period timer separately.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Allison Collins <allison.henderson@oracle.com>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 libxfs/xfs_format.h |   24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)


diff --git a/libxfs/xfs_format.h b/libxfs/xfs_format.h
index 4a106b6713ad..afc068944be9 100644
--- a/libxfs/xfs_format.h
+++ b/libxfs/xfs_format.h
@@ -1199,6 +1199,30 @@ static inline void xfs_dinode_put_rdev(struct xfs_dinode *dip, xfs_dev_t rdev)
 
 #define XFS_DQTYPE_ANY		(XFS_DQTYPE_REC_MASK)
 
+/*
+ * XFS Quota Timers
+ * ================
+ *
+ * Traditional quota grace period expiration timers are an unsigned 32-bit
+ * seconds counter; time zero is the Unix epoch, Jan  1 00:00:01 UTC 1970.
+ * Note that an expiration value of zero means that the quota limit has not
+ * been reached, and therefore no expiration has been set.  Therefore, the
+ * ondisk min and max defined here can be used directly to constrain the incore
+ * quota expiration timestamps on a Unix system.
+ */
+
+/*
+ * Smallest possible ondisk quota expiration value with traditional timestamps.
+ * This corresponds exactly with the incore expiration Jan  1 00:00:01 UTC 1970.
+ */
+#define XFS_DQ_LEGACY_EXPIRY_MIN	((int64_t)1)
+
+/*
+ * Largest possible ondisk quota expiration value with traditional timestamps.
+ * This corresponds exactly with the incore expiration Feb  7 06:28:15 UTC 2106.
+ */
+#define XFS_DQ_LEGACY_EXPIRY_MAX	((int64_t)U32_MAX)
+
 /*
  * This is the main portion of the on-disk representation of quota information
  * for a user.  We pad this with some more expansion room to construct the on


^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH 11/26] xfs: refactor default quota grace period setting code
  2020-10-26 23:34 [PATCH v6 00/26] xfsprogs: widen timestamps to deal with y2038 Darrick J. Wong
                   ` (9 preceding siblings ...)
  2020-10-26 23:35 ` [PATCH 10/26] xfs: refactor quota expiration timer modification Darrick J. Wong
@ 2020-10-26 23:35 ` Darrick J. Wong
  2020-10-26 23:35 ` [PATCH 12/26] xfs: refactor quota timestamp coding Darrick J. Wong
                   ` (14 subsequent siblings)
  25 siblings, 0 replies; 58+ messages in thread
From: Darrick J. Wong @ 2020-10-26 23:35 UTC (permalink / raw)
  To: sandeen, darrick.wong
  Cc: Amir Goldstein, Christoph Hellwig, Allison Collins, Dave Chinner,
	linux-xfs

From: Darrick J. Wong <darrick.wong@oracle.com>

Source kernel commit: ccc8e771aa7a80eb047fc263780816ca76dd02a6

Refactor the code that sets the default quota grace period into a helper
function so that we can override the ondisk behavior later.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Amir Goldstein <amir73il@gmail.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Allison Collins <allison.henderson@oracle.com>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 libxfs/xfs_format.h |   13 +++++++++++++
 1 file changed, 13 insertions(+)


diff --git a/libxfs/xfs_format.h b/libxfs/xfs_format.h
index afc068944be9..a5bf27afdd44 100644
--- a/libxfs/xfs_format.h
+++ b/libxfs/xfs_format.h
@@ -1209,6 +1209,11 @@ static inline void xfs_dinode_put_rdev(struct xfs_dinode *dip, xfs_dev_t rdev)
  * been reached, and therefore no expiration has been set.  Therefore, the
  * ondisk min and max defined here can be used directly to constrain the incore
  * quota expiration timestamps on a Unix system.
+ *
+ * The grace period for each quota type is stored in the root dquot (id = 0)
+ * and is applied to a non-root dquot when it exceeds the soft or hard limits.
+ * The length of quota grace periods are unsigned 32-bit quantities measured in
+ * units of seconds.  A value of zero means to use the default period.
  */
 
 /*
@@ -1223,6 +1228,14 @@ static inline void xfs_dinode_put_rdev(struct xfs_dinode *dip, xfs_dev_t rdev)
  */
 #define XFS_DQ_LEGACY_EXPIRY_MAX	((int64_t)U32_MAX)
 
+/*
+ * Default quota grace periods, ranging from zero (use the compiled defaults)
+ * to ~136 years.  These are applied to a non-root dquot that has exceeded
+ * either limit.
+ */
+#define XFS_DQ_GRACE_MIN		((int64_t)0)
+#define XFS_DQ_GRACE_MAX		((int64_t)U32_MAX)
+
 /*
  * This is the main portion of the on-disk representation of quota information
  * for a user.  We pad this with some more expansion room to construct the on


^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH 12/26] xfs: refactor quota timestamp coding
  2020-10-26 23:34 [PATCH v6 00/26] xfsprogs: widen timestamps to deal with y2038 Darrick J. Wong
                   ` (10 preceding siblings ...)
  2020-10-26 23:35 ` [PATCH 11/26] xfs: refactor default quota grace period setting code Darrick J. Wong
@ 2020-10-26 23:35 ` Darrick J. Wong
  2020-10-26 23:35 ` [PATCH 13/26] xfs: move xfs_log_dinode_to_disk to the log recovery code Darrick J. Wong
                   ` (13 subsequent siblings)
  25 siblings, 0 replies; 58+ messages in thread
From: Darrick J. Wong @ 2020-10-26 23:35 UTC (permalink / raw)
  To: sandeen, darrick.wong
  Cc: Amir Goldstein, Christoph Hellwig, Allison Collins, Dave Chinner,
	linux-xfs

From: Darrick J. Wong <darrick.wong@oracle.com>

Source kernel commit: 9f99c8fe551a056c0929dff13cbce62b6b150156

Refactor quota timestamp encoding and decoding into helper functions so
that we can add extra behavior in the next patch.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Amir Goldstein <amir73il@gmail.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Allison Collins <allison.henderson@oracle.com>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 libxfs/xfs_dquot_buf.c  |   18 ++++++++++++++++++
 libxfs/xfs_quota_defs.h |    5 +++++
 2 files changed, 23 insertions(+)


diff --git a/libxfs/xfs_dquot_buf.c b/libxfs/xfs_dquot_buf.c
index b5adb840d015..04f62e31019d 100644
--- a/libxfs/xfs_dquot_buf.c
+++ b/libxfs/xfs_dquot_buf.c
@@ -286,3 +286,21 @@ const struct xfs_buf_ops xfs_dquot_buf_ra_ops = {
 	.verify_read = xfs_dquot_buf_readahead_verify,
 	.verify_write = xfs_dquot_buf_write_verify,
 };
+
+/* Convert an on-disk timer value into an incore timer value. */
+time64_t
+xfs_dquot_from_disk_ts(
+	struct xfs_disk_dquot	*ddq,
+	__be32			dtimer)
+{
+	return be32_to_cpu(dtimer);
+}
+
+/* Convert an incore timer value into an on-disk timer value. */
+__be32
+xfs_dquot_to_disk_ts(
+	struct xfs_dquot	*dqp,
+	time64_t		timer)
+{
+	return cpu_to_be32(timer);
+}
diff --git a/libxfs/xfs_quota_defs.h b/libxfs/xfs_quota_defs.h
index 076bdc7037ee..9a99910d857e 100644
--- a/libxfs/xfs_quota_defs.h
+++ b/libxfs/xfs_quota_defs.h
@@ -143,4 +143,9 @@ extern int xfs_calc_dquots_per_chunk(unsigned int nbblks);
 extern void xfs_dqblk_repair(struct xfs_mount *mp, struct xfs_dqblk *dqb,
 		xfs_dqid_t id, xfs_dqtype_t type);
 
+struct xfs_dquot;
+time64_t xfs_dquot_from_disk_ts(struct xfs_disk_dquot *ddq,
+		__be32 dtimer);
+__be32 xfs_dquot_to_disk_ts(struct xfs_dquot *ddq, time64_t timer);
+
 #endif	/* __XFS_QUOTA_H__ */


^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH 13/26] xfs: move xfs_log_dinode_to_disk to the log recovery code
  2020-10-26 23:34 [PATCH v6 00/26] xfsprogs: widen timestamps to deal with y2038 Darrick J. Wong
                   ` (11 preceding siblings ...)
  2020-10-26 23:35 ` [PATCH 12/26] xfs: refactor quota timestamp coding Darrick J. Wong
@ 2020-10-26 23:35 ` Darrick J. Wong
  2020-10-26 23:35 ` [PATCH 14/26] xfs: redefine xfs_timestamp_t Darrick J. Wong
                   ` (12 subsequent siblings)
  25 siblings, 0 replies; 58+ messages in thread
From: Darrick J. Wong @ 2020-10-26 23:35 UTC (permalink / raw)
  To: sandeen, darrick.wong
  Cc: Christoph Hellwig, Allison Collins, Gao Xiang, Dave Chinner, linux-xfs

From: Darrick J. Wong <darrick.wong@oracle.com>

Source kernel commit: 88947ea0ba713c9b74b212755b3b58242f0e7a56

Move this function to xfs_inode_item_recover.c since there's only one
caller of it.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Allison Collins <allison.henderson@oracle.com>
Reviewed-by: Gao Xiang <hsiangkao@redhat.com>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 libxfs/xfs_inode_buf.c |   52 ------------------------------------------------
 libxfs/xfs_inode_buf.h |    2 --
 2 files changed, 54 deletions(-)


diff --git a/libxfs/xfs_inode_buf.c b/libxfs/xfs_inode_buf.c
index a1732e509640..e3fdd71a0c63 100644
--- a/libxfs/xfs_inode_buf.c
+++ b/libxfs/xfs_inode_buf.c
@@ -307,58 +307,6 @@ xfs_inode_to_disk(
 	}
 }
 
-void
-xfs_log_dinode_to_disk(
-	struct xfs_log_dinode	*from,
-	struct xfs_dinode	*to)
-{
-	to->di_magic = cpu_to_be16(from->di_magic);
-	to->di_mode = cpu_to_be16(from->di_mode);
-	to->di_version = from->di_version;
-	to->di_format = from->di_format;
-	to->di_onlink = 0;
-	to->di_uid = cpu_to_be32(from->di_uid);
-	to->di_gid = cpu_to_be32(from->di_gid);
-	to->di_nlink = cpu_to_be32(from->di_nlink);
-	to->di_projid_lo = cpu_to_be16(from->di_projid_lo);
-	to->di_projid_hi = cpu_to_be16(from->di_projid_hi);
-	memcpy(to->di_pad, from->di_pad, sizeof(to->di_pad));
-
-	to->di_atime.t_sec = cpu_to_be32(from->di_atime.t_sec);
-	to->di_atime.t_nsec = cpu_to_be32(from->di_atime.t_nsec);
-	to->di_mtime.t_sec = cpu_to_be32(from->di_mtime.t_sec);
-	to->di_mtime.t_nsec = cpu_to_be32(from->di_mtime.t_nsec);
-	to->di_ctime.t_sec = cpu_to_be32(from->di_ctime.t_sec);
-	to->di_ctime.t_nsec = cpu_to_be32(from->di_ctime.t_nsec);
-
-	to->di_size = cpu_to_be64(from->di_size);
-	to->di_nblocks = cpu_to_be64(from->di_nblocks);
-	to->di_extsize = cpu_to_be32(from->di_extsize);
-	to->di_nextents = cpu_to_be32(from->di_nextents);
-	to->di_anextents = cpu_to_be16(from->di_anextents);
-	to->di_forkoff = from->di_forkoff;
-	to->di_aformat = from->di_aformat;
-	to->di_dmevmask = cpu_to_be32(from->di_dmevmask);
-	to->di_dmstate = cpu_to_be16(from->di_dmstate);
-	to->di_flags = cpu_to_be16(from->di_flags);
-	to->di_gen = cpu_to_be32(from->di_gen);
-
-	if (from->di_version == 3) {
-		to->di_changecount = cpu_to_be64(from->di_changecount);
-		to->di_crtime.t_sec = cpu_to_be32(from->di_crtime.t_sec);
-		to->di_crtime.t_nsec = cpu_to_be32(from->di_crtime.t_nsec);
-		to->di_flags2 = cpu_to_be64(from->di_flags2);
-		to->di_cowextsize = cpu_to_be32(from->di_cowextsize);
-		to->di_ino = cpu_to_be64(from->di_ino);
-		to->di_lsn = cpu_to_be64(from->di_lsn);
-		memcpy(to->di_pad2, from->di_pad2, sizeof(to->di_pad2));
-		uuid_copy(&to->di_uuid, &from->di_uuid);
-		to->di_flushiter = 0;
-	} else {
-		to->di_flushiter = cpu_to_be16(from->di_flushiter);
-	}
-}
-
 static xfs_failaddr_t
 xfs_dinode_verify_fork(
 	struct xfs_dinode	*dip,
diff --git a/libxfs/xfs_inode_buf.h b/libxfs/xfs_inode_buf.h
index 6b08b9d060c2..89f7bea8efd6 100644
--- a/libxfs/xfs_inode_buf.h
+++ b/libxfs/xfs_inode_buf.h
@@ -49,8 +49,6 @@ void	xfs_dinode_calc_crc(struct xfs_mount *, struct xfs_dinode *);
 void	xfs_inode_to_disk(struct xfs_inode *ip, struct xfs_dinode *to,
 			  xfs_lsn_t lsn);
 int	xfs_inode_from_disk(struct xfs_inode *ip, struct xfs_dinode *from);
-void	xfs_log_dinode_to_disk(struct xfs_log_dinode *from,
-			       struct xfs_dinode *to);
 
 xfs_failaddr_t xfs_dinode_verify(struct xfs_mount *mp, xfs_ino_t ino,
 			   struct xfs_dinode *dip);


^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH 14/26] xfs: redefine xfs_timestamp_t
  2020-10-26 23:34 [PATCH v6 00/26] xfsprogs: widen timestamps to deal with y2038 Darrick J. Wong
                   ` (12 preceding siblings ...)
  2020-10-26 23:35 ` [PATCH 13/26] xfs: move xfs_log_dinode_to_disk to the log recovery code Darrick J. Wong
@ 2020-10-26 23:35 ` Darrick J. Wong
  2020-10-26 23:35 ` [PATCH 15/26] xfs: redefine xfs_ictimestamp_t Darrick J. Wong
                   ` (11 subsequent siblings)
  25 siblings, 0 replies; 58+ messages in thread
From: Darrick J. Wong @ 2020-10-26 23:35 UTC (permalink / raw)
  To: sandeen, darrick.wong
  Cc: Christoph Hellwig, Gao Xiang, Dave Chinner, linux-xfs

From: Darrick J. Wong <darrick.wong@oracle.com>

Source kernel commit: 5a0bb066f60fa02f453d7721844eae59f505c06e

Redefine xfs_timestamp_t as a __be64 typedef in preparation for the
bigtime functionality.  Preserve the legacy structure format so that we
can let the compiler take care of masking and shifting.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Gao Xiang <hsiangkao@redhat.com>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 db/fprint.c              |   10 +++++----
 libxfs/libxfs_api_defs.h |    1 +
 libxfs/xfs_format.h      |   10 ++++++---
 libxfs/xfs_inode_buf.c   |   54 ++++++++++++++++++++++++++++++++--------------
 libxfs/xfs_inode_buf.h   |    2 ++
 repair/dinode.c          |    5 +++-
 6 files changed, 58 insertions(+), 24 deletions(-)


diff --git a/db/fprint.c b/db/fprint.c
index 996e9325ddcc..1e8a7b49efe6 100644
--- a/db/fprint.c
+++ b/db/fprint.c
@@ -123,6 +123,7 @@ fp_time(
 	int			base,
 	int			array)
 {
+	struct timespec64	tv;
 	xfs_timestamp_t		*ts;
 	int			bitpos;
 	char			*c;
@@ -137,7 +138,8 @@ fp_time(
 			dbprintf("%d:", i + base);
 
 		ts = obj + byteize(bitpos);
-		t = (int)be32_to_cpu(ts->t_sec);
+		tv = libxfs_inode_from_disk_ts(*ts);
+		t = tv.tv_sec;
 
 		c = ctime(&t);
 		dbprintf("%24.24s", c);
@@ -159,8 +161,8 @@ fp_nsec(
 	int			base,
 	int			array)
 {
+	struct timespec64	tv;
 	xfs_timestamp_t		*ts;
-	unsigned int		nsec;
 	int			bitpos;
 	int			i;
 
@@ -172,9 +174,9 @@ fp_nsec(
 			dbprintf("%d:", i + base);
 
 		ts = obj + byteize(bitpos);
-		nsec = (int)be32_to_cpu(ts->t_nsec);
+		tv = libxfs_inode_from_disk_ts(*ts);
 
-		dbprintf("%u", nsec);
+		dbprintf("%u", tv.tv_nsec);
 
 		if (i < count - 1)
 			dbprintf(" ");
diff --git a/libxfs/libxfs_api_defs.h b/libxfs/libxfs_api_defs.h
index 7029d0e7daf7..40da71ab3163 100644
--- a/libxfs/libxfs_api_defs.h
+++ b/libxfs/libxfs_api_defs.h
@@ -116,6 +116,7 @@
 #define xfs_inobt_maxrecs		libxfs_inobt_maxrecs
 #define xfs_inobt_stage_cursor		libxfs_inobt_stage_cursor
 #define xfs_inode_from_disk		libxfs_inode_from_disk
+#define xfs_inode_from_disk_ts		libxfs_inode_from_disk_ts
 #define xfs_inode_to_disk		libxfs_inode_to_disk
 #define xfs_inode_validate_cowextsize	libxfs_inode_validate_cowextsize
 #define xfs_inode_validate_extsize	libxfs_inode_validate_extsize
diff --git a/libxfs/xfs_format.h b/libxfs/xfs_format.h
index a5bf27afdd44..ca11a3eb56dd 100644
--- a/libxfs/xfs_format.h
+++ b/libxfs/xfs_format.h
@@ -856,12 +856,16 @@ struct xfs_agfl {
  * seconds and nanoseconds; time zero is the Unix epoch, Jan  1 00:00:00 UTC
  * 1970, which means that the timestamp epoch is the same as the Unix epoch.
  * Therefore, the ondisk min and max defined here can be used directly to
- * constrain the incore timestamps on a Unix system.
+ * constrain the incore timestamps on a Unix system.  Note that we actually
+ * encode a __be64 value on disk.
  */
-typedef struct xfs_timestamp {
+typedef __be64 xfs_timestamp_t;
+
+/* Legacy timestamp encoding format. */
+struct xfs_legacy_timestamp {
 	__be32		t_sec;		/* timestamp seconds */
 	__be32		t_nsec;		/* timestamp nanoseconds */
-} xfs_timestamp_t;
+};
 
 /*
  * Smallest possible ondisk seconds value with traditional timestamps.  This
diff --git a/libxfs/xfs_inode_buf.c b/libxfs/xfs_inode_buf.c
index e3fdd71a0c63..1b9f63ebe9f9 100644
--- a/libxfs/xfs_inode_buf.c
+++ b/libxfs/xfs_inode_buf.c
@@ -154,6 +154,21 @@ xfs_imap_to_bp(
 	return 0;
 }
 
+/* Convert an ondisk timestamp to an incore timestamp. */
+struct timespec64
+xfs_inode_from_disk_ts(
+	const xfs_timestamp_t		ts)
+{
+	struct timespec64		tv;
+	struct xfs_legacy_timestamp	*lts;
+
+	lts = (struct xfs_legacy_timestamp *)&ts;
+	tv.tv_sec = (int)be32_to_cpu(lts->t_sec);
+	tv.tv_nsec = (int)be32_to_cpu(lts->t_nsec);
+
+	return tv;
+}
+
 int
 xfs_inode_from_disk(
 	struct xfs_inode	*ip,
@@ -208,12 +223,9 @@ xfs_inode_from_disk(
 	 * a time before epoch is converted to a time long after epoch
 	 * on 64 bit systems.
 	 */
-	inode->i_atime.tv_sec = (int)be32_to_cpu(from->di_atime.t_sec);
-	inode->i_atime.tv_nsec = (int)be32_to_cpu(from->di_atime.t_nsec);
-	inode->i_mtime.tv_sec = (int)be32_to_cpu(from->di_mtime.t_sec);
-	inode->i_mtime.tv_nsec = (int)be32_to_cpu(from->di_mtime.t_nsec);
-	inode->i_ctime.tv_sec = (int)be32_to_cpu(from->di_ctime.t_sec);
-	inode->i_ctime.tv_nsec = (int)be32_to_cpu(from->di_ctime.t_nsec);
+	inode->i_atime = xfs_inode_from_disk_ts(from->di_atime);
+	inode->i_mtime = xfs_inode_from_disk_ts(from->di_mtime);
+	inode->i_ctime = xfs_inode_from_disk_ts(from->di_ctime);
 
 	to->di_size = be64_to_cpu(from->di_size);
 	to->di_nblocks = be64_to_cpu(from->di_nblocks);
@@ -226,8 +238,7 @@ xfs_inode_from_disk(
 	if (xfs_sb_version_has_v3inode(&ip->i_mount->m_sb)) {
 		inode_set_iversion_queried(inode,
 					   be64_to_cpu(from->di_changecount));
-		to->di_crtime.tv_sec = be32_to_cpu(from->di_crtime.t_sec);
-		to->di_crtime.tv_nsec = be32_to_cpu(from->di_crtime.t_nsec);
+		to->di_crtime = xfs_inode_from_disk_ts(from->di_crtime);
 		to->di_flags2 = be64_to_cpu(from->di_flags2);
 		to->di_cowextsize = be32_to_cpu(from->di_cowextsize);
 	}
@@ -249,6 +260,21 @@ xfs_inode_from_disk(
 	return error;
 }
 
+/* Convert an incore timestamp to an ondisk timestamp. */
+static inline xfs_timestamp_t
+xfs_inode_to_disk_ts(
+	const struct timespec64		tv)
+{
+	struct xfs_legacy_timestamp	*lts;
+	xfs_timestamp_t			ts;
+
+	lts = (struct xfs_legacy_timestamp *)&ts;
+	lts->t_sec = cpu_to_be32(tv.tv_sec);
+	lts->t_nsec = cpu_to_be32(tv.tv_nsec);
+
+	return ts;
+}
+
 void
 xfs_inode_to_disk(
 	struct xfs_inode	*ip,
@@ -268,12 +294,9 @@ xfs_inode_to_disk(
 	to->di_projid_hi = cpu_to_be16(from->di_projid >> 16);
 
 	memset(to->di_pad, 0, sizeof(to->di_pad));
-	to->di_atime.t_sec = cpu_to_be32(inode->i_atime.tv_sec);
-	to->di_atime.t_nsec = cpu_to_be32(inode->i_atime.tv_nsec);
-	to->di_mtime.t_sec = cpu_to_be32(inode->i_mtime.tv_sec);
-	to->di_mtime.t_nsec = cpu_to_be32(inode->i_mtime.tv_nsec);
-	to->di_ctime.t_sec = cpu_to_be32(inode->i_ctime.tv_sec);
-	to->di_ctime.t_nsec = cpu_to_be32(inode->i_ctime.tv_nsec);
+	to->di_atime = xfs_inode_to_disk_ts(inode->i_atime);
+	to->di_mtime = xfs_inode_to_disk_ts(inode->i_mtime);
+	to->di_ctime = xfs_inode_to_disk_ts(inode->i_ctime);
 	to->di_nlink = cpu_to_be32(inode->i_nlink);
 	to->di_gen = cpu_to_be32(inode->i_generation);
 	to->di_mode = cpu_to_be16(inode->i_mode);
@@ -292,8 +315,7 @@ xfs_inode_to_disk(
 	if (xfs_sb_version_has_v3inode(&ip->i_mount->m_sb)) {
 		to->di_version = 3;
 		to->di_changecount = cpu_to_be64(inode_peek_iversion(inode));
-		to->di_crtime.t_sec = cpu_to_be32(from->di_crtime.tv_sec);
-		to->di_crtime.t_nsec = cpu_to_be32(from->di_crtime.tv_nsec);
+		to->di_crtime = xfs_inode_to_disk_ts(from->di_crtime);
 		to->di_flags2 = cpu_to_be64(from->di_flags2);
 		to->di_cowextsize = cpu_to_be32(from->di_cowextsize);
 		to->di_ino = cpu_to_be64(ip->i_ino);
diff --git a/libxfs/xfs_inode_buf.h b/libxfs/xfs_inode_buf.h
index 89f7bea8efd6..3060ecd24a2e 100644
--- a/libxfs/xfs_inode_buf.h
+++ b/libxfs/xfs_inode_buf.h
@@ -58,4 +58,6 @@ xfs_failaddr_t xfs_inode_validate_cowextsize(struct xfs_mount *mp,
 		uint32_t cowextsize, uint16_t mode, uint16_t flags,
 		uint64_t flags2);
 
+struct timespec64 xfs_inode_from_disk_ts(const xfs_timestamp_t ts);
+
 #endif	/* __XFS_INODE_BUF_H__ */
diff --git a/repair/dinode.c b/repair/dinode.c
index 95e57b5318b5..c1d9d9727d62 100644
--- a/repair/dinode.c
+++ b/repair/dinode.c
@@ -2167,9 +2167,12 @@ static void
 check_nsec(
 	const char		*name,
 	xfs_ino_t		lino,
-	struct xfs_timestamp	*t,
+	xfs_timestamp_t		*ts,
 	int			*dirty)
 {
+	struct xfs_legacy_timestamp *t;
+
+	t = (struct xfs_legacy_timestamp *)ts;
 	if (be32_to_cpu(t->t_nsec) < NSEC_PER_SEC)
 		return;
 


^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH 15/26] xfs: redefine xfs_ictimestamp_t
  2020-10-26 23:34 [PATCH v6 00/26] xfsprogs: widen timestamps to deal with y2038 Darrick J. Wong
                   ` (13 preceding siblings ...)
  2020-10-26 23:35 ` [PATCH 14/26] xfs: redefine xfs_timestamp_t Darrick J. Wong
@ 2020-10-26 23:35 ` Darrick J. Wong
  2020-10-26 23:35 ` [PATCH 16/26] xfs: widen ondisk inode timestamps to deal with y2038+ Darrick J. Wong
                   ` (10 subsequent siblings)
  25 siblings, 0 replies; 58+ messages in thread
From: Darrick J. Wong @ 2020-10-26 23:35 UTC (permalink / raw)
  To: sandeen, darrick.wong
  Cc: Christoph Hellwig, Gao Xiang, Dave Chinner, linux-xfs

From: Darrick J. Wong <darrick.wong@oracle.com>

Source kernel commit: 30e05599219f3c15bd5f24190af0e33cdb4a00e5

Redefine xfs_ictimestamp_t as a uint64_t typedef in preparation for the
bigtime functionality.  Preserve the legacy structure format so that we
can let the compiler take care of the masking and shifting.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Gao Xiang <hsiangkao@redhat.com>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 libxfs/xfs_log_format.h |    7 +++++--
 logprint/log_misc.c     |   19 +++++++++++++++----
 2 files changed, 20 insertions(+), 6 deletions(-)


diff --git a/libxfs/xfs_log_format.h b/libxfs/xfs_log_format.h
index e3400c9c71cd..8bd00da6d2a4 100644
--- a/libxfs/xfs_log_format.h
+++ b/libxfs/xfs_log_format.h
@@ -368,10 +368,13 @@ static inline int xfs_ilog_fdata(int w)
  * directly mirrors the xfs_dinode structure as it must contain all the same
  * information.
  */
-typedef struct xfs_ictimestamp {
+typedef uint64_t xfs_ictimestamp_t;
+
+/* Legacy timestamp encoding format. */
+struct xfs_legacy_ictimestamp {
 	int32_t		t_sec;		/* timestamp seconds */
 	int32_t		t_nsec;		/* timestamp nanoseconds */
-} xfs_ictimestamp_t;
+};
 
 /*
  * Define the format of the inode core that is logged. This structure must be
diff --git a/logprint/log_misc.c b/logprint/log_misc.c
index a747cbd360af..47976cdf328a 100644
--- a/logprint/log_misc.c
+++ b/logprint/log_misc.c
@@ -435,6 +435,16 @@ xlog_print_trans_qoff(char **ptr, uint len)
     }
 }	/* xlog_print_trans_qoff */
 
+static inline time64_t
+xlog_extract_dinode_ts(
+	const xfs_ictimestamp_t		its)
+{
+	struct xfs_legacy_ictimestamp	*lits;
+
+	lits = (struct xfs_legacy_ictimestamp *)&its;
+	return (time64_t)lits->t_sec;
+}
+
 void
 xlog_print_dinode_ts(
 	struct xfs_log_dinode	*ldip,
@@ -443,12 +453,13 @@ xlog_print_dinode_ts(
 	const char		*fmt;
 
 	if (compact)
-		fmt = _("atime 0x%x mtime 0x%x ctime 0x%x\n");
+		fmt = _("atime 0x%llx mtime 0x%llx ctime 0x%llx\n");
 	else
-		fmt = _("		atime:%d  mtime:%d  ctime:%d\n");
+		fmt = _("		atime:%lld  mtime:%lld  ctime:%lld\n");
 
-	printf(fmt, ldip->di_atime.t_sec, ldip->di_mtime.t_sec,
-			ldip->di_ctime.t_sec);
+	printf(fmt, xlog_extract_dinode_ts(ldip->di_atime),
+		    xlog_extract_dinode_ts(ldip->di_mtime),
+		    xlog_extract_dinode_ts(ldip->di_ctime));
 }
 
 static void


^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH 16/26] xfs: widen ondisk inode timestamps to deal with y2038+
  2020-10-26 23:34 [PATCH v6 00/26] xfsprogs: widen timestamps to deal with y2038 Darrick J. Wong
                   ` (14 preceding siblings ...)
  2020-10-26 23:35 ` [PATCH 15/26] xfs: redefine xfs_ictimestamp_t Darrick J. Wong
@ 2020-10-26 23:35 ` Darrick J. Wong
  2020-10-26 23:35 ` [PATCH 17/26] xfs: widen ondisk quota expiration timestamps to handle y2038+ Darrick J. Wong
                   ` (9 subsequent siblings)
  25 siblings, 0 replies; 58+ messages in thread
From: Darrick J. Wong @ 2020-10-26 23:35 UTC (permalink / raw)
  To: sandeen, darrick.wong
  Cc: Christoph Hellwig, Gao Xiang, Dave Chinner, linux-xfs

From: Darrick J. Wong <darrick.wong@oracle.com>

Source kernel commit: f93e5436f0ee5a85eaa3a86d2614d215873fb18b

Redesign the ondisk inode timestamps to be a simple unsigned 64-bit
counter of nanoseconds since 14 Dec 1901 (i.e. the minimum time in the
32-bit unix time epoch).  This enables us to handle dates up to 2486,
which solves the y2038 problem.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Gao Xiang <hsiangkao@redhat.com>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 db/fprint.c              |    4 +--
 include/xfs_inode.h      |    5 +++
 libxfs/xfs_format.h      |   70 +++++++++++++++++++++++++++++++++++++++++++++-
 libxfs/xfs_fs.h          |    1 +
 libxfs/xfs_ialloc.c      |    4 +++
 libxfs/xfs_inode_buf.c   |   40 +++++++++++++++++++++-----
 libxfs/xfs_inode_buf.h   |   13 ++++++++-
 libxfs/xfs_sb.c          |    2 +
 libxfs/xfs_shared.h      |    3 ++
 libxfs/xfs_trans_inode.c |   11 +++++++
 10 files changed, 141 insertions(+), 12 deletions(-)


diff --git a/db/fprint.c b/db/fprint.c
index 1e8a7b49efe6..7ceab29cc608 100644
--- a/db/fprint.c
+++ b/db/fprint.c
@@ -138,7 +138,7 @@ fp_time(
 			dbprintf("%d:", i + base);
 
 		ts = obj + byteize(bitpos);
-		tv = libxfs_inode_from_disk_ts(*ts);
+		tv = libxfs_inode_from_disk_ts(obj, *ts);
 		t = tv.tv_sec;
 
 		c = ctime(&t);
@@ -174,7 +174,7 @@ fp_nsec(
 			dbprintf("%d:", i + base);
 
 		ts = obj + byteize(bitpos);
-		tv = libxfs_inode_from_disk_ts(*ts);
+		tv = libxfs_inode_from_disk_ts(obj, *ts);
 
 		dbprintf("%u", tv.tv_nsec);
 
diff --git a/include/xfs_inode.h b/include/xfs_inode.h
index 12676cb30bf2..40310df6a785 100644
--- a/include/xfs_inode.h
+++ b/include/xfs_inode.h
@@ -140,6 +140,11 @@ static inline bool xfs_is_reflink_inode(struct xfs_inode *ip)
 	return ip->i_d.di_flags2 & XFS_DIFLAG2_REFLINK;
 }
 
+static inline bool xfs_inode_has_bigtime(struct xfs_inode *ip)
+{
+	return ip->i_d.di_flags2 & XFS_DIFLAG2_BIGTIME;
+}
+
 typedef struct cred {
 	uid_t	cr_uid;
 	gid_t	cr_gid;
diff --git a/libxfs/xfs_format.h b/libxfs/xfs_format.h
index ca11a3eb56dd..dbc7008e4498 100644
--- a/libxfs/xfs_format.h
+++ b/libxfs/xfs_format.h
@@ -467,6 +467,7 @@ xfs_sb_has_ro_compat_feature(
 #define XFS_SB_FEAT_INCOMPAT_FTYPE	(1 << 0)	/* filetype in dirent */
 #define XFS_SB_FEAT_INCOMPAT_SPINODES	(1 << 1)	/* sparse inode chunks */
 #define XFS_SB_FEAT_INCOMPAT_META_UUID	(1 << 2)	/* metadata UUID */
+#define XFS_SB_FEAT_INCOMPAT_BIGTIME	(1 << 3)	/* large timestamps */
 #define XFS_SB_FEAT_INCOMPAT_ALL \
 		(XFS_SB_FEAT_INCOMPAT_FTYPE|	\
 		 XFS_SB_FEAT_INCOMPAT_SPINODES|	\
@@ -565,6 +566,12 @@ static inline bool xfs_sb_version_hasreflink(struct xfs_sb *sbp)
 		(sbp->sb_features_ro_compat & XFS_SB_FEAT_RO_COMPAT_REFLINK);
 }
 
+static inline bool xfs_sb_version_hasbigtime(struct xfs_sb *sbp)
+{
+	return XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5 &&
+		(sbp->sb_features_incompat & XFS_SB_FEAT_INCOMPAT_BIGTIME);
+}
+
 /*
  * Inode btree block counter.  We record the number of inobt and finobt blocks
  * in the AGI header so that we can skip the finobt walk at mount time when
@@ -858,6 +865,13 @@ struct xfs_agfl {
  * Therefore, the ondisk min and max defined here can be used directly to
  * constrain the incore timestamps on a Unix system.  Note that we actually
  * encode a __be64 value on disk.
+ *
+ * When the bigtime feature is enabled, ondisk inode timestamps become an
+ * unsigned 64-bit nanoseconds counter.  This means that the bigtime inode
+ * timestamp epoch is the start of the classic timestamp range, which is
+ * Dec 31 20:45:52 UTC 1901.  Because the epochs are not the same, callers
+ * /must/ use the bigtime conversion functions when encoding and decoding raw
+ * timestamps.
  */
 typedef __be64 xfs_timestamp_t;
 
@@ -879,6 +893,50 @@ struct xfs_legacy_timestamp {
  */
 #define XFS_LEGACY_TIME_MAX	((int64_t)S32_MAX)
 
+/*
+ * Smallest possible ondisk seconds value with bigtime timestamps.  This
+ * corresponds (after conversion to a Unix timestamp) with the traditional
+ * minimum timestamp of Dec 13 20:45:52 UTC 1901.
+ */
+#define XFS_BIGTIME_TIME_MIN	((int64_t)0)
+
+/*
+ * Largest supported ondisk seconds value with bigtime timestamps.  This
+ * corresponds (after conversion to a Unix timestamp) with an incore timestamp
+ * of Jul  2 20:20:24 UTC 2486.
+ *
+ * We round down the ondisk limit so that the bigtime quota and inode max
+ * timestamps will be the same.
+ */
+#define XFS_BIGTIME_TIME_MAX	((int64_t)((-1ULL / NSEC_PER_SEC) & ~0x3ULL))
+
+/*
+ * Bigtime epoch is set exactly to the minimum time value that a traditional
+ * 32-bit timestamp can represent when using the Unix epoch as a reference.
+ * Hence the Unix epoch is at a fixed offset into the supported bigtime
+ * timestamp range.
+ *
+ * The bigtime epoch also matches the minimum value an on-disk 32-bit XFS
+ * timestamp can represent so we will not lose any fidelity in converting
+ * to/from unix and bigtime timestamps.
+ *
+ * The following conversion factor converts a seconds counter from the Unix
+ * epoch to the bigtime epoch.
+ */
+#define XFS_BIGTIME_EPOCH_OFFSET	(-(int64_t)S32_MIN)
+
+/* Convert a timestamp from the Unix epoch to the bigtime epoch. */
+static inline uint64_t xfs_unix_to_bigtime(time64_t unix_seconds)
+{
+	return (uint64_t)unix_seconds + XFS_BIGTIME_EPOCH_OFFSET;
+}
+
+/* Convert a timestamp from the bigtime epoch to the Unix epoch. */
+static inline time64_t xfs_bigtime_to_unix(uint64_t ondisk_seconds)
+{
+	return (time64_t)ondisk_seconds - XFS_BIGTIME_EPOCH_OFFSET;
+}
+
 /*
  * On-disk inode structure.
  *
@@ -1104,12 +1162,22 @@ static inline void xfs_dinode_put_rdev(struct xfs_dinode *dip, xfs_dev_t rdev)
 #define XFS_DIFLAG2_DAX_BIT	0	/* use DAX for this inode */
 #define XFS_DIFLAG2_REFLINK_BIT	1	/* file's blocks may be shared */
 #define XFS_DIFLAG2_COWEXTSIZE_BIT   2  /* copy on write extent size hint */
+#define XFS_DIFLAG2_BIGTIME_BIT	3	/* big timestamps */
+
 #define XFS_DIFLAG2_DAX		(1 << XFS_DIFLAG2_DAX_BIT)
 #define XFS_DIFLAG2_REFLINK     (1 << XFS_DIFLAG2_REFLINK_BIT)
 #define XFS_DIFLAG2_COWEXTSIZE  (1 << XFS_DIFLAG2_COWEXTSIZE_BIT)
+#define XFS_DIFLAG2_BIGTIME	(1 << XFS_DIFLAG2_BIGTIME_BIT)
 
 #define XFS_DIFLAG2_ANY \
-	(XFS_DIFLAG2_DAX | XFS_DIFLAG2_REFLINK | XFS_DIFLAG2_COWEXTSIZE)
+	(XFS_DIFLAG2_DAX | XFS_DIFLAG2_REFLINK | XFS_DIFLAG2_COWEXTSIZE | \
+	 XFS_DIFLAG2_BIGTIME)
+
+static inline bool xfs_dinode_has_bigtime(const struct xfs_dinode *dip)
+{
+	return dip->di_version >= 3 &&
+	       (dip->di_flags2 & cpu_to_be64(XFS_DIFLAG2_BIGTIME));
+}
 
 /*
  * Inode number format:
diff --git a/libxfs/xfs_fs.h b/libxfs/xfs_fs.h
index 84bcffa87753..2a2e3cfd94f0 100644
--- a/libxfs/xfs_fs.h
+++ b/libxfs/xfs_fs.h
@@ -249,6 +249,7 @@ typedef struct xfs_fsop_resblks {
 #define XFS_FSOP_GEOM_FLAGS_SPINODES	(1 << 18) /* sparse inode chunks   */
 #define XFS_FSOP_GEOM_FLAGS_RMAPBT	(1 << 19) /* reverse mapping btree */
 #define XFS_FSOP_GEOM_FLAGS_REFLINK	(1 << 20) /* files can share blocks */
+#define XFS_FSOP_GEOM_FLAGS_BIGTIME	(1 << 21) /* 64-bit nsec timestamps */
 
 /*
  * Minimum and maximum sizes need for growth checks.
diff --git a/libxfs/xfs_ialloc.c b/libxfs/xfs_ialloc.c
index 8adeb10e5d2e..d78f960c6d44 100644
--- a/libxfs/xfs_ialloc.c
+++ b/libxfs/xfs_ialloc.c
@@ -2802,6 +2802,10 @@ xfs_ialloc_setup_geometry(
 	uint64_t		icount;
 	uint			inodes;
 
+	igeo->new_diflags2 = 0;
+	if (xfs_sb_version_hasbigtime(&mp->m_sb))
+		igeo->new_diflags2 |= XFS_DIFLAG2_BIGTIME;
+
 	/* Compute inode btree geometry. */
 	igeo->agino_log = sbp->sb_inopblog + sbp->sb_agblklog;
 	igeo->inobt_mxr[0] = xfs_inobt_maxrecs(mp, sbp->sb_blocksize, 1);
diff --git a/libxfs/xfs_inode_buf.c b/libxfs/xfs_inode_buf.c
index 1b9f63ebe9f9..6722d5afddac 100644
--- a/libxfs/xfs_inode_buf.c
+++ b/libxfs/xfs_inode_buf.c
@@ -154,14 +154,29 @@ xfs_imap_to_bp(
 	return 0;
 }
 
+static inline struct timespec64 xfs_inode_decode_bigtime(uint64_t ts)
+{
+	struct timespec64	tv;
+	uint32_t		n;
+
+	tv.tv_sec = xfs_bigtime_to_unix(div_u64_rem(ts, NSEC_PER_SEC, &n));
+	tv.tv_nsec = n;
+
+	return tv;
+}
+
 /* Convert an ondisk timestamp to an incore timestamp. */
 struct timespec64
 xfs_inode_from_disk_ts(
+	struct xfs_dinode		*dip,
 	const xfs_timestamp_t		ts)
 {
 	struct timespec64		tv;
 	struct xfs_legacy_timestamp	*lts;
 
+	if (xfs_dinode_has_bigtime(dip))
+		return xfs_inode_decode_bigtime(be64_to_cpu(ts));
+
 	lts = (struct xfs_legacy_timestamp *)&ts;
 	tv.tv_sec = (int)be32_to_cpu(lts->t_sec);
 	tv.tv_nsec = (int)be32_to_cpu(lts->t_nsec);
@@ -223,9 +238,9 @@ xfs_inode_from_disk(
 	 * a time before epoch is converted to a time long after epoch
 	 * on 64 bit systems.
 	 */
-	inode->i_atime = xfs_inode_from_disk_ts(from->di_atime);
-	inode->i_mtime = xfs_inode_from_disk_ts(from->di_mtime);
-	inode->i_ctime = xfs_inode_from_disk_ts(from->di_ctime);
+	inode->i_atime = xfs_inode_from_disk_ts(from, from->di_atime);
+	inode->i_mtime = xfs_inode_from_disk_ts(from, from->di_mtime);
+	inode->i_ctime = xfs_inode_from_disk_ts(from, from->di_ctime);
 
 	to->di_size = be64_to_cpu(from->di_size);
 	to->di_nblocks = be64_to_cpu(from->di_nblocks);
@@ -238,7 +253,7 @@ xfs_inode_from_disk(
 	if (xfs_sb_version_has_v3inode(&ip->i_mount->m_sb)) {
 		inode_set_iversion_queried(inode,
 					   be64_to_cpu(from->di_changecount));
-		to->di_crtime = xfs_inode_from_disk_ts(from->di_crtime);
+		to->di_crtime = xfs_inode_from_disk_ts(from, from->di_crtime);
 		to->di_flags2 = be64_to_cpu(from->di_flags2);
 		to->di_cowextsize = be32_to_cpu(from->di_cowextsize);
 	}
@@ -263,11 +278,15 @@ xfs_inode_from_disk(
 /* Convert an incore timestamp to an ondisk timestamp. */
 static inline xfs_timestamp_t
 xfs_inode_to_disk_ts(
+	struct xfs_inode		*ip,
 	const struct timespec64		tv)
 {
 	struct xfs_legacy_timestamp	*lts;
 	xfs_timestamp_t			ts;
 
+	if (xfs_inode_has_bigtime(ip))
+		return cpu_to_be64(xfs_inode_encode_bigtime(tv));
+
 	lts = (struct xfs_legacy_timestamp *)&ts;
 	lts->t_sec = cpu_to_be32(tv.tv_sec);
 	lts->t_nsec = cpu_to_be32(tv.tv_nsec);
@@ -294,9 +313,9 @@ xfs_inode_to_disk(
 	to->di_projid_hi = cpu_to_be16(from->di_projid >> 16);
 
 	memset(to->di_pad, 0, sizeof(to->di_pad));
-	to->di_atime = xfs_inode_to_disk_ts(inode->i_atime);
-	to->di_mtime = xfs_inode_to_disk_ts(inode->i_mtime);
-	to->di_ctime = xfs_inode_to_disk_ts(inode->i_ctime);
+	to->di_atime = xfs_inode_to_disk_ts(ip, inode->i_atime);
+	to->di_mtime = xfs_inode_to_disk_ts(ip, inode->i_mtime);
+	to->di_ctime = xfs_inode_to_disk_ts(ip, inode->i_ctime);
 	to->di_nlink = cpu_to_be32(inode->i_nlink);
 	to->di_gen = cpu_to_be32(inode->i_generation);
 	to->di_mode = cpu_to_be16(inode->i_mode);
@@ -315,7 +334,7 @@ xfs_inode_to_disk(
 	if (xfs_sb_version_has_v3inode(&ip->i_mount->m_sb)) {
 		to->di_version = 3;
 		to->di_changecount = cpu_to_be64(inode_peek_iversion(inode));
-		to->di_crtime = xfs_inode_to_disk_ts(from->di_crtime);
+		to->di_crtime = xfs_inode_to_disk_ts(ip, from->di_crtime);
 		to->di_flags2 = cpu_to_be64(from->di_flags2);
 		to->di_cowextsize = cpu_to_be32(from->di_cowextsize);
 		to->di_ino = cpu_to_be64(ip->i_ino);
@@ -535,6 +554,11 @@ xfs_dinode_verify(
 	if (fa)
 		return fa;
 
+	/* bigtime iflag can only happen on bigtime filesystems */
+	if (xfs_dinode_has_bigtime(dip) &&
+	    !xfs_sb_version_hasbigtime(&mp->m_sb))
+		return __this_address;
+
 	return NULL;
 }
 
diff --git a/libxfs/xfs_inode_buf.h b/libxfs/xfs_inode_buf.h
index 3060ecd24a2e..536666143fe7 100644
--- a/libxfs/xfs_inode_buf.h
+++ b/libxfs/xfs_inode_buf.h
@@ -32,6 +32,11 @@ struct xfs_icdinode {
 	struct timespec64 di_crtime;	/* time created */
 };
 
+static inline bool xfs_icdinode_has_bigtime(const struct xfs_icdinode *icd)
+{
+	return icd->di_flags2 & XFS_DIFLAG2_BIGTIME;
+}
+
 /*
  * Inode location information.  Stored in the inode and passed to
  * xfs_imap_to_bp() to get a buffer and dinode for a given inode.
@@ -58,6 +63,12 @@ xfs_failaddr_t xfs_inode_validate_cowextsize(struct xfs_mount *mp,
 		uint32_t cowextsize, uint16_t mode, uint16_t flags,
 		uint64_t flags2);
 
-struct timespec64 xfs_inode_from_disk_ts(const xfs_timestamp_t ts);
+static inline uint64_t xfs_inode_encode_bigtime(struct timespec64 tv)
+{
+	return xfs_unix_to_bigtime(tv.tv_sec) * NSEC_PER_SEC + tv.tv_nsec;
+}
+
+struct timespec64 xfs_inode_from_disk_ts(struct xfs_dinode *dip,
+		const xfs_timestamp_t ts);
 
 #endif	/* __XFS_INODE_BUF_H__ */
diff --git a/libxfs/xfs_sb.c b/libxfs/xfs_sb.c
index 7c7e56a8979c..fb2212b89912 100644
--- a/libxfs/xfs_sb.c
+++ b/libxfs/xfs_sb.c
@@ -1143,6 +1143,8 @@ xfs_fs_geometry(
 		geo->flags |= XFS_FSOP_GEOM_FLAGS_RMAPBT;
 	if (xfs_sb_version_hasreflink(sbp))
 		geo->flags |= XFS_FSOP_GEOM_FLAGS_REFLINK;
+	if (xfs_sb_version_hasbigtime(sbp))
+		geo->flags |= XFS_FSOP_GEOM_FLAGS_BIGTIME;
 	if (xfs_sb_version_hassector(sbp))
 		geo->logsectsize = sbp->sb_logsectsize;
 	else
diff --git a/libxfs/xfs_shared.h b/libxfs/xfs_shared.h
index 708feb8eac76..c795ae47b3c9 100644
--- a/libxfs/xfs_shared.h
+++ b/libxfs/xfs_shared.h
@@ -176,6 +176,9 @@ struct xfs_ino_geometry {
 	unsigned int	ialloc_align;
 
 	unsigned int	agino_log;	/* #bits for agino in inum */
+
+	/* precomputed value for di_flags2 */
+	uint64_t	new_diflags2;
 };
 
 #endif /* __XFS_SHARED_H__ */
diff --git a/libxfs/xfs_trans_inode.c b/libxfs/xfs_trans_inode.c
index a392fd293d25..66dadd8716ee 100644
--- a/libxfs/xfs_trans_inode.c
+++ b/libxfs/xfs_trans_inode.c
@@ -128,6 +128,17 @@ xfs_trans_log_inode(
 			iversion_flags = XFS_ILOG_CORE;
 	}
 
+	/*
+	 * If we're updating the inode core or the timestamps and it's possible
+	 * to upgrade this inode to bigtime format, do so now.
+	 */
+	if ((flags & (XFS_ILOG_CORE | XFS_ILOG_TIMESTAMP)) &&
+	    xfs_sb_version_hasbigtime(&ip->i_mount->m_sb) &&
+	    !xfs_inode_has_bigtime(ip)) {
+		ip->i_d.di_flags2 |= XFS_DIFLAG2_BIGTIME;
+		flags |= XFS_ILOG_CORE;
+	}
+
 	/*
 	 * Record the specific change for fdatasync optimisation. This allows
 	 * fdatasync to skip log forces for inodes that are only timestamp


^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH 17/26] xfs: widen ondisk quota expiration timestamps to handle y2038+
  2020-10-26 23:34 [PATCH v6 00/26] xfsprogs: widen timestamps to deal with y2038 Darrick J. Wong
                   ` (15 preceding siblings ...)
  2020-10-26 23:35 ` [PATCH 16/26] xfs: widen ondisk inode timestamps to deal with y2038+ Darrick J. Wong
@ 2020-10-26 23:35 ` Darrick J. Wong
  2020-10-26 23:36 ` [PATCH 18/26] libxfs: propagate bigtime inode flag when allocating Darrick J. Wong
                   ` (8 subsequent siblings)
  25 siblings, 0 replies; 58+ messages in thread
From: Darrick J. Wong @ 2020-10-26 23:35 UTC (permalink / raw)
  To: sandeen, darrick.wong
  Cc: Christoph Hellwig, Allison Collins, Dave Chinner, linux-xfs

From: Darrick J. Wong <darrick.wong@oracle.com>

Source kernel commit: 4ea1ff3b49681af45a4a8c14baf7f0b3d11aa74a

Enable the bigtime feature for quota timers.  We decrease the accuracy
of the timers to ~4s in exchange for being able to set timers up to the
bigtime maximum.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Allison Collins <allison.henderson@oracle.com>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 include/xfs_mount.h     |    5 +++++
 libxfs/xfs_dquot_buf.c  |   21 ++++++++++++++++++--
 libxfs/xfs_format.h     |   50 ++++++++++++++++++++++++++++++++++++++++++++++-
 libxfs/xfs_quota_defs.h |    3 ++-
 4 files changed, 75 insertions(+), 4 deletions(-)


diff --git a/include/xfs_mount.h b/include/xfs_mount.h
index 20c8bfaf4fa8..be74a922b7a1 100644
--- a/include/xfs_mount.h
+++ b/include/xfs_mount.h
@@ -184,4 +184,9 @@ extern xfs_mount_t	*libxfs_mount (xfs_mount_t *, xfs_sb_t *,
 int		libxfs_umount(struct xfs_mount *mp);
 extern void	libxfs_rtmount_destroy (xfs_mount_t *);
 
+/* Dummy xfs_dquot so that libxfs compiles. */
+struct xfs_dquot {
+	int		q_type;
+};
+
 #endif	/* __XFS_MOUNT_H__ */
diff --git a/libxfs/xfs_dquot_buf.c b/libxfs/xfs_dquot_buf.c
index 04f62e31019d..0a5a237d2236 100644
--- a/libxfs/xfs_dquot_buf.c
+++ b/libxfs/xfs_dquot_buf.c
@@ -67,6 +67,13 @@ xfs_dquot_verify(
 	    ddq_type != XFS_DQTYPE_GROUP)
 		return __this_address;
 
+	if ((ddq->d_type & XFS_DQTYPE_BIGTIME) &&
+	    !xfs_sb_version_hasbigtime(&mp->m_sb))
+		return __this_address;
+
+	if ((ddq->d_type & XFS_DQTYPE_BIGTIME) && !ddq->d_id)
+		return __this_address;
+
 	if (id != -1 && id != be32_to_cpu(ddq->d_id))
 		return __this_address;
 
@@ -293,7 +300,12 @@ xfs_dquot_from_disk_ts(
 	struct xfs_disk_dquot	*ddq,
 	__be32			dtimer)
 {
-	return be32_to_cpu(dtimer);
+	uint32_t		t = be32_to_cpu(dtimer);
+
+	if (t != 0 && (ddq->d_type & XFS_DQTYPE_BIGTIME))
+		return xfs_dq_bigtime_to_unix(t);
+
+	return t;
 }
 
 /* Convert an incore timer value into an on-disk timer value. */
@@ -302,5 +314,10 @@ xfs_dquot_to_disk_ts(
 	struct xfs_dquot	*dqp,
 	time64_t		timer)
 {
-	return cpu_to_be32(timer);
+	uint32_t		t = timer;
+
+	if (timer != 0 && (dqp->q_type & XFS_DQTYPE_BIGTIME))
+		t = xfs_dq_unix_to_bigtime(timer);
+
+	return cpu_to_be32(t);
 }
diff --git a/libxfs/xfs_format.h b/libxfs/xfs_format.h
index dbc7008e4498..0ab424cc25ca 100644
--- a/libxfs/xfs_format.h
+++ b/libxfs/xfs_format.h
@@ -1263,13 +1263,15 @@ static inline bool xfs_dinode_has_bigtime(const struct xfs_dinode *dip)
 #define XFS_DQTYPE_USER		0x01		/* user dquot record */
 #define XFS_DQTYPE_PROJ		0x02		/* project dquot record */
 #define XFS_DQTYPE_GROUP	0x04		/* group dquot record */
+#define XFS_DQTYPE_BIGTIME	0x80		/* large expiry timestamps */
 
 /* bitmask to determine if this is a user/group/project dquot */
 #define XFS_DQTYPE_REC_MASK	(XFS_DQTYPE_USER | \
 				 XFS_DQTYPE_PROJ | \
 				 XFS_DQTYPE_GROUP)
 
-#define XFS_DQTYPE_ANY		(XFS_DQTYPE_REC_MASK)
+#define XFS_DQTYPE_ANY		(XFS_DQTYPE_REC_MASK | \
+				 XFS_DQTYPE_BIGTIME)
 
 /*
  * XFS Quota Timers
@@ -1282,6 +1284,10 @@ static inline bool xfs_dinode_has_bigtime(const struct xfs_dinode *dip)
  * ondisk min and max defined here can be used directly to constrain the incore
  * quota expiration timestamps on a Unix system.
  *
+ * When bigtime is enabled, we trade two bits of precision to expand the
+ * expiration timeout range to match that of big inode timestamps.  The min and
+ * max recorded here are the on-disk limits, not a Unix timestamp.
+ *
  * The grace period for each quota type is stored in the root dquot (id = 0)
  * and is applied to a non-root dquot when it exceeds the soft or hard limits.
  * The length of quota grace periods are unsigned 32-bit quantities measured in
@@ -1300,6 +1306,48 @@ static inline bool xfs_dinode_has_bigtime(const struct xfs_dinode *dip)
  */
 #define XFS_DQ_LEGACY_EXPIRY_MAX	((int64_t)U32_MAX)
 
+/*
+ * Smallest possible ondisk quota expiration value with bigtime timestamps.
+ * This corresponds (after conversion to a Unix timestamp) with the incore
+ * expiration of Jan  1 00:00:04 UTC 1970.
+ */
+#define XFS_DQ_BIGTIME_EXPIRY_MIN	(XFS_DQ_LEGACY_EXPIRY_MIN)
+
+/*
+ * Largest supported ondisk quota expiration value with bigtime timestamps.
+ * This corresponds (after conversion to a Unix timestamp) with an incore
+ * expiration of Jul  2 20:20:24 UTC 2486.
+ *
+ * The ondisk field supports values up to -1U, which corresponds to an incore
+ * expiration in 2514.  This is beyond the maximum the bigtime inode timestamp,
+ * so we cap the maximum bigtime quota expiration to the max inode timestamp.
+ */
+#define XFS_DQ_BIGTIME_EXPIRY_MAX	((int64_t)4074815106U)
+
+/*
+ * The following conversion factors assist in converting a quota expiration
+ * timestamp between the incore and ondisk formats.
+ */
+#define XFS_DQ_BIGTIME_SHIFT	(2)
+#define XFS_DQ_BIGTIME_SLACK	((int64_t)(1ULL << XFS_DQ_BIGTIME_SHIFT) - 1)
+
+/* Convert an incore quota expiration timestamp to an ondisk bigtime value. */
+static inline uint32_t xfs_dq_unix_to_bigtime(time64_t unix_seconds)
+{
+	/*
+	 * Round the expiration timestamp up to the nearest bigtime timestamp
+	 * that we can store, to give users the most time to fix problems.
+	 */
+	return ((uint64_t)unix_seconds + XFS_DQ_BIGTIME_SLACK) >>
+			XFS_DQ_BIGTIME_SHIFT;
+}
+
+/* Convert an ondisk bigtime quota expiration value to an incore timestamp. */
+static inline time64_t xfs_dq_bigtime_to_unix(uint32_t ondisk_seconds)
+{
+	return (time64_t)ondisk_seconds << XFS_DQ_BIGTIME_SHIFT;
+}
+
 /*
  * Default quota grace periods, ranging from zero (use the compiled defaults)
  * to ~136 years.  These are applied to a non-root dquot that has exceeded
diff --git a/libxfs/xfs_quota_defs.h b/libxfs/xfs_quota_defs.h
index 9a99910d857e..0f0af4e35032 100644
--- a/libxfs/xfs_quota_defs.h
+++ b/libxfs/xfs_quota_defs.h
@@ -23,7 +23,8 @@ typedef uint8_t		xfs_dqtype_t;
 #define XFS_DQTYPE_STRINGS \
 	{ XFS_DQTYPE_USER,	"USER" }, \
 	{ XFS_DQTYPE_PROJ,	"PROJ" }, \
-	{ XFS_DQTYPE_GROUP,	"GROUP" }
+	{ XFS_DQTYPE_GROUP,	"GROUP" }, \
+	{ XFS_DQTYPE_BIGTIME,	"BIGTIME" }
 
 /*
  * flags for q_flags field in the dquot.


^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH 18/26] libxfs: propagate bigtime inode flag when allocating
  2020-10-26 23:34 [PATCH v6 00/26] xfsprogs: widen timestamps to deal with y2038 Darrick J. Wong
                   ` (16 preceding siblings ...)
  2020-10-26 23:35 ` [PATCH 17/26] xfs: widen ondisk quota expiration timestamps to handle y2038+ Darrick J. Wong
@ 2020-10-26 23:36 ` Darrick J. Wong
  2020-10-29  9:48   ` Christoph Hellwig
  2020-10-26 23:36 ` [PATCH 19/26] libfrog: list the bigtime feature when reporting geometry Darrick J. Wong
                   ` (7 subsequent siblings)
  25 siblings, 1 reply; 58+ messages in thread
From: Darrick J. Wong @ 2020-10-26 23:36 UTC (permalink / raw)
  To: sandeen, darrick.wong; +Cc: linux-xfs

From: Darrick J. Wong <darrick.wong@oracle.com>

Ensure that we propagate the bigtime inode flag correctly when creating
new inodes.  There critical part here is to use the new_diflags2 field
in the incore geometry just like we do in the kernel.

We also modify xfs_flags2diflags2 to have the same behavior as the
kernel.  This isn't strictly needed here, but we aim to avoid letting
userspace diverge from the kernel function when we can.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 libxfs/util.c |    7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)


diff --git a/libxfs/util.c b/libxfs/util.c
index c78074a01dab..252cf91e851b 100644
--- a/libxfs/util.c
+++ b/libxfs/util.c
@@ -197,7 +197,8 @@ xfs_flags2diflags2(
 	unsigned int		xflags)
 {
 	uint64_t		di_flags2 =
-		(ip->i_d.di_flags2 & XFS_DIFLAG2_REFLINK);
+		(ip->i_d.di_flags2 & (XFS_DIFLAG2_REFLINK |
+				      XFS_DIFLAG2_BIGTIME));
 
 	if (xflags & FS_XFLAG_DAX)
 		di_flags2 |= XFS_DIFLAG2_DAX;
@@ -307,8 +308,8 @@ libxfs_ialloc(
 		ASSERT(ip->i_d.di_ino == ino);
 		ASSERT(uuid_equal(&ip->i_d.di_uuid, &mp->m_sb.sb_meta_uuid));
 		VFS_I(ip)->i_version = 1;
-		ip->i_d.di_flags2 = pip ? 0 : xfs_flags2diflags2(ip,
-				fsx->fsx_xflags);
+		ip->i_d.di_flags2 = pip ? ip->i_mount->m_ino_geo.new_diflags2 :
+				xfs_flags2diflags2(ip, fsx->fsx_xflags);
 		ip->i_d.di_crtime.tv_sec = (int32_t)VFS_I(ip)->i_mtime.tv_sec;
 		ip->i_d.di_crtime.tv_nsec = (int32_t)VFS_I(ip)->i_mtime.tv_nsec;
 		ip->i_d.di_cowextsize = pip ? 0 : fsx->fsx_cowextsize;


^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH 19/26] libfrog: list the bigtime feature when reporting geometry
  2020-10-26 23:34 [PATCH v6 00/26] xfsprogs: widen timestamps to deal with y2038 Darrick J. Wong
                   ` (17 preceding siblings ...)
  2020-10-26 23:36 ` [PATCH 18/26] libxfs: propagate bigtime inode flag when allocating Darrick J. Wong
@ 2020-10-26 23:36 ` Darrick J. Wong
  2020-10-29  9:49   ` Christoph Hellwig
  2020-10-26 23:36 ` [PATCH 20/26] xfs_db: report bigtime format timestamps Darrick J. Wong
                   ` (6 subsequent siblings)
  25 siblings, 1 reply; 58+ messages in thread
From: Darrick J. Wong @ 2020-10-26 23:36 UTC (permalink / raw)
  To: sandeen, darrick.wong; +Cc: linux-xfs

From: Darrick J. Wong <darrick.wong@oracle.com>

When we're reporting on a filesystem's geometry, report if the bigtime
feature is enabled on this filesystem.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 libfrog/fsgeom.c |    6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)


diff --git a/libfrog/fsgeom.c b/libfrog/fsgeom.c
index bd93924ea795..14507668e41b 100644
--- a/libfrog/fsgeom.c
+++ b/libfrog/fsgeom.c
@@ -28,6 +28,7 @@ xfs_report_geom(
 	int			spinodes;
 	int			rmapbt_enabled;
 	int			reflink_enabled;
+	int			bigtime_enabled;
 
 	isint = geo->logstart > 0;
 	lazycount = geo->flags & XFS_FSOP_GEOM_FLAGS_LAZYSB ? 1 : 0;
@@ -43,12 +44,13 @@ xfs_report_geom(
 	spinodes = geo->flags & XFS_FSOP_GEOM_FLAGS_SPINODES ? 1 : 0;
 	rmapbt_enabled = geo->flags & XFS_FSOP_GEOM_FLAGS_RMAPBT ? 1 : 0;
 	reflink_enabled = geo->flags & XFS_FSOP_GEOM_FLAGS_REFLINK ? 1 : 0;
+	bigtime_enabled = geo->flags & XFS_FSOP_GEOM_FLAGS_BIGTIME ? 1 : 0;
 
 	printf(_(
 "meta-data=%-22s isize=%-6d agcount=%u, agsize=%u blks\n"
 "         =%-22s sectsz=%-5u attr=%u, projid32bit=%u\n"
 "         =%-22s crc=%-8u finobt=%u, sparse=%u, rmapbt=%u\n"
-"         =%-22s reflink=%u\n"
+"         =%-22s reflink=%-4u bigtime=%u\n"
 "data     =%-22s bsize=%-6u blocks=%llu, imaxpct=%u\n"
 "         =%-22s sunit=%-6u swidth=%u blks\n"
 "naming   =version %-14u bsize=%-6u ascii-ci=%d, ftype=%d\n"
@@ -58,7 +60,7 @@ xfs_report_geom(
 		mntpoint, geo->inodesize, geo->agcount, geo->agblocks,
 		"", geo->sectsize, attrversion, projid32bit,
 		"", crcs_enabled, finobt_enabled, spinodes, rmapbt_enabled,
-		"", reflink_enabled,
+		"", reflink_enabled, bigtime_enabled,
 		"", geo->blocksize, (unsigned long long)geo->datablocks,
 			geo->imaxpct,
 		"", geo->sunit, geo->swidth,


^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH 20/26] xfs_db: report bigtime format timestamps
  2020-10-26 23:34 [PATCH v6 00/26] xfsprogs: widen timestamps to deal with y2038 Darrick J. Wong
                   ` (18 preceding siblings ...)
  2020-10-26 23:36 ` [PATCH 19/26] libfrog: list the bigtime feature when reporting geometry Darrick J. Wong
@ 2020-10-26 23:36 ` Darrick J. Wong
  2020-10-29  9:50   ` Christoph Hellwig
                     ` (2 more replies)
  2020-10-26 23:36 ` [PATCH 21/26] xfs_db: support printing time limits Darrick J. Wong
                   ` (5 subsequent siblings)
  25 siblings, 3 replies; 58+ messages in thread
From: Darrick J. Wong @ 2020-10-26 23:36 UTC (permalink / raw)
  To: sandeen, darrick.wong; +Cc: linux-xfs

From: Darrick J. Wong <darrick.wong@oracle.com>

Report the large format timestamps.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 db/fprint.c              |   66 ++++++++++++++++++++++++++++++++--------------
 db/inode.c               |    4 ++-
 db/sb.c                  |    2 +
 libxfs/libxfs_api_defs.h |    1 +
 4 files changed, 52 insertions(+), 21 deletions(-)


diff --git a/db/fprint.c b/db/fprint.c
index 7ceab29cc608..48562f0c9518 100644
--- a/db/fprint.c
+++ b/db/fprint.c
@@ -112,23 +112,43 @@ fp_sarray(
 	return 1;
 }
 
-int
-fp_time(
-	void			*obj,
-	int			bit,
-	int			count,
-	char			*fmtstr,
-	int			size,
-	int			arg,
-	int			base,
-	int			array)
+static void
+fp_time64(
+	time64_t		sec)
 {
-	struct timespec64	tv;
-	xfs_timestamp_t		*ts;
-	int			bitpos;
+	time_t			tt = sec;
 	char			*c;
+
+	BUILD_BUG_ON(sizeof(long) != sizeof(time_t));
+
+	if (sec > LONG_MAX || sec < LONG_MIN)
+		goto raw;
+
+	c = ctime(&tt);
+	if (!c)
+		goto raw;
+
+	dbprintf("%24.24s", c);
+	return;
+raw:
+	dbprintf("%lld", sec);
+}
+
+int
+fp_time(
+	void			*obj,
+	int			bit,
+	int			count,
+	char			*fmtstr,
+	int			size,
+	int			arg,
+	int			base,
+	int			array)
+{
+	struct timespec64	tv;
+	xfs_timestamp_t		*ts;
+	int			bitpos;
 	int			i;
-	time_t			t;
 
 	ASSERT(bitoffs(bit) == 0);
 	for (i = 0, bitpos = bit;
@@ -139,10 +159,8 @@ fp_time(
 
 		ts = obj + byteize(bitpos);
 		tv = libxfs_inode_from_disk_ts(obj, *ts);
-		t = tv.tv_sec;
 
-		c = ctime(&t);
-		dbprintf("%24.24s", c);
+		fp_time64(tv.tv_sec);
 
 		if (i < count - 1)
 			dbprintf(" ");
@@ -195,7 +213,8 @@ fp_qtimer(
 	int			base,
 	int			array)
 {
-	uint32_t		sec;
+	struct xfs_disk_dquot	*ddq = obj;
+	time64_t		sec;
 	__be32			*t;
 	int			bitpos;
 	int			i;
@@ -208,9 +227,16 @@ fp_qtimer(
 			dbprintf("%d:", i + base);
 
 		t = obj + byteize(bitpos);
-		sec = be32_to_cpu(*t);
+		sec = libxfs_dquot_from_disk_ts(ddq, *t);
 
-		dbprintf("%u", sec);
+		/*
+		 * Display the raw value if it's the default grace expiration
+		 * period (root dquot) or if the quota has not expired.
+		 */
+		if (ddq->d_id == 0 || sec == 0)
+			dbprintf("%lld", sec);
+		else
+			fp_time64(sec);
 
 		if (i < count - 1)
 			dbprintf(" ");
diff --git a/db/inode.c b/db/inode.c
index cc0e680aadea..f0e08ebf5ad9 100644
--- a/db/inode.c
+++ b/db/inode.c
@@ -175,10 +175,12 @@ const field_t	inode_v3_flds[] = {
 	{ "dax", FLDT_UINT1,
 	  OI(COFF(flags2) + bitsz(uint64_t) - XFS_DIFLAG2_DAX_BIT - 1), C1,
 	  0, TYP_NONE },
+	{ "bigtime", FLDT_UINT1,
+	  OI(COFF(flags2) + bitsz(uint64_t) - XFS_DIFLAG2_BIGTIME_BIT - 1), C1,
+	  0, TYP_NONE },
 	{ NULL }
 };
 
-
 const field_t	timestamp_flds[] = {
 	{ "sec", FLDT_TIME, OI(0), C1, 0, TYP_NONE },
 	{ "nsec", FLDT_NSEC, OI(0), C1, 0, TYP_NONE },
diff --git a/db/sb.c b/db/sb.c
index b1033e5ef7f0..a04f36c73255 100644
--- a/db/sb.c
+++ b/db/sb.c
@@ -727,6 +727,8 @@ version_string(
 		strcat(s, ",REFLINK");
 	if (xfs_sb_version_hasinobtcounts(sbp))
 		strcat(s, ",INOBTCNT");
+	if (xfs_sb_version_hasbigtime(sbp))
+		strcat(s, ",BIGTIME");
 	return s;
 }
 
diff --git a/libxfs/libxfs_api_defs.h b/libxfs/libxfs_api_defs.h
index 40da71ab3163..419e6d9888cf 100644
--- a/libxfs/libxfs_api_defs.h
+++ b/libxfs/libxfs_api_defs.h
@@ -99,6 +99,7 @@
 #define xfs_dir_replace			libxfs_dir_replace
 
 #define xfs_dqblk_repair		libxfs_dqblk_repair
+#define xfs_dquot_from_disk_ts		libxfs_dquot_from_disk_ts
 #define xfs_dquot_verify		libxfs_dquot_verify
 
 #define xfs_finobt_calc_reserves	libxfs_finobt_calc_reserves


^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH 21/26] xfs_db: support printing time limits
  2020-10-26 23:34 [PATCH v6 00/26] xfsprogs: widen timestamps to deal with y2038 Darrick J. Wong
                   ` (19 preceding siblings ...)
  2020-10-26 23:36 ` [PATCH 20/26] xfs_db: report bigtime format timestamps Darrick J. Wong
@ 2020-10-26 23:36 ` Darrick J. Wong
  2020-10-29  9:50   ` Christoph Hellwig
  2020-10-26 23:36 ` [PATCH 22/26] xfs_db: add bigtime upgrade path Darrick J. Wong
                   ` (4 subsequent siblings)
  25 siblings, 1 reply; 58+ messages in thread
From: Darrick J. Wong @ 2020-10-26 23:36 UTC (permalink / raw)
  To: sandeen, darrick.wong; +Cc: linux-xfs

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


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


^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH 22/26] xfs_db: add bigtime upgrade path
  2020-10-26 23:34 [PATCH v6 00/26] xfsprogs: widen timestamps to deal with y2038 Darrick J. Wong
                   ` (20 preceding siblings ...)
  2020-10-26 23:36 ` [PATCH 21/26] xfs_db: support printing time limits Darrick J. Wong
@ 2020-10-26 23:36 ` Darrick J. Wong
  2020-10-29  9:51   ` Christoph Hellwig
  2020-11-16 21:15   ` [PATCH v2 " Darrick J. Wong
  2020-10-26 23:36 ` [PATCH 23/26] xfs_quota: support editing and reporting quotas with bigtime Darrick J. Wong
                   ` (3 subsequent siblings)
  25 siblings, 2 replies; 58+ messages in thread
From: Darrick J. Wong @ 2020-10-26 23:36 UTC (permalink / raw)
  To: sandeen, darrick.wong; +Cc: linux-xfs

From: Darrick J. Wong <darrick.wong@oracle.com>

Enable users to upgrade their filesystems to bigtime support.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 db/sb.c              |   15 +++++++++++++++
 man/man8/xfs_admin.8 |    5 +++++
 2 files changed, 20 insertions(+)


diff --git a/db/sb.c b/db/sb.c
index a04f36c73255..c77d7f038de2 100644
--- a/db/sb.c
+++ b/db/sb.c
@@ -781,6 +781,21 @@ version_f(
 			}
 
 			upgrade_ro_compat |= XFS_SB_FEAT_RO_COMPAT_INOBTCNT;
+		} else if (!strcasecmp(argv[1], "bigtime")) {
+			if (xfs_sb_version_hasbigtime(&mp->m_sb)) {
+				dbprintf(
+		_("bigtime feature is already enabled\n"));
+				exitcode = 1;
+				return 1;
+			}
+			if (!xfs_sb_version_hascrc(&mp->m_sb)) {
+				dbprintf(
+		_("bigtime feature cannot be enabled on pre-V5 filesystems\n"));
+				exitcode = 1;
+				return 1;
+			}
+
+			upgrade_incompat |= XFS_SB_FEAT_INCOMPAT_BIGTIME;
 		} else if (!strcasecmp(argv[1], "extflg")) {
 			switch (XFS_SB_VERSION_NUM(&mp->m_sb)) {
 			case XFS_SB_VERSION_1:
diff --git a/man/man8/xfs_admin.8 b/man/man8/xfs_admin.8
index 65ca6afc1e12..c09fe62b6827 100644
--- a/man/man8/xfs_admin.8
+++ b/man/man8/xfs_admin.8
@@ -117,6 +117,11 @@ This reduces mount time by caching the size of the inode btrees in the
 allocation group metadata.
 Once enabled, the filesystem will not be writable by older kernels.
 The filesystem cannot be downgraded after this feature is enabled.
+.TP
+.B bigtime
+Upgrade the filesystem to support larger timestamps up to the year 2486.
+Once enabled, the filesystem will not be readable by older kernels.
+The filesystem cannot be downgraded.
 .RE
 .TP
 .BI \-U " uuid"


^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH 23/26] xfs_quota: support editing and reporting quotas with bigtime
  2020-10-26 23:34 [PATCH v6 00/26] xfsprogs: widen timestamps to deal with y2038 Darrick J. Wong
                   ` (21 preceding siblings ...)
  2020-10-26 23:36 ` [PATCH 22/26] xfs_db: add bigtime upgrade path Darrick J. Wong
@ 2020-10-26 23:36 ` Darrick J. Wong
  2020-10-29  9:51   ` Christoph Hellwig
  2020-10-26 23:36 ` [PATCH 24/26] xfs_repair: support bigtime timestamp checking Darrick J. Wong
                   ` (2 subsequent siblings)
  25 siblings, 1 reply; 58+ messages in thread
From: Darrick J. Wong @ 2020-10-26 23:36 UTC (permalink / raw)
  To: sandeen, darrick.wong; +Cc: linux-xfs

From: Darrick J. Wong <darrick.wong@oracle.com>

Enhance xfs_quota to detect and report grace period expirations past
2038.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 include/xqm.h  |   20 ++++++++++++++++-
 quota/edit.c   |   65 +++++++++++++++++++++++++++++++++++++++++++++++++++-----
 quota/quota.c  |    6 +++--
 quota/quota.h  |    7 ++++++
 quota/report.c |    6 +++--
 5 files changed, 91 insertions(+), 13 deletions(-)


diff --git a/include/xqm.h b/include/xqm.h
index 8ab19072656e..573441db9860 100644
--- a/include/xqm.h
+++ b/include/xqm.h
@@ -47,7 +47,10 @@ typedef struct fs_disk_quota {
 	__s32		d_btimer;	/* similar to above; for disk blocks */
 	__u16		d_iwarns;	/* # warnings issued wrt num inodes */
 	__u16		d_bwarns;	/* # warnings issued wrt disk blocks */
-	__s32		d_padding2;	/* padding2 - for future use */
+	__s8		d_itimer_hi;	/* upper 8 bits of timer values */
+	__s8		d_btimer_hi;
+	__s8		d_rtbtimer_hi;
+	__s8		d_padding2;	/* padding2 - for future use */
 	__u64		d_rtb_hardlimit;/* absolute limit on realtime blks */
 	__u64		d_rtb_softlimit;/* preferred limit on RT disk blks */
 	__u64		d_rtbcount;	/* # realtime blocks owned */
@@ -93,6 +96,21 @@ typedef struct fs_disk_quota {
 #define FS_DQ_RTBWARNS	(1<<11)
 #define FS_DQ_WARNS_MASK	(FS_DQ_BWARNS | FS_DQ_IWARNS | FS_DQ_RTBWARNS)
 
+/*
+ * Accounting values.  These can only be set for filesystem with
+ * non-transactional quotas that require quotacheck(8) in userspace.
+ */
+#define FS_DQ_BCOUNT		(1<<12)
+#define FS_DQ_ICOUNT		(1<<13)
+#define FS_DQ_RTBCOUNT		(1<<14)
+#define FS_DQ_ACCT_MASK		(FS_DQ_BCOUNT | FS_DQ_ICOUNT | FS_DQ_RTBCOUNT)
+
+/*
+ * Quota expiration timestamps are 40-bit signed integers, with the upper 8
+ * bits encoded in the _hi fields.
+ */
+#define FS_DQ_BIGTIME		(1<<15)
+
 /*
  * Various flags related to quotactl(2).  Only relevant to XFS filesystems.
  */
diff --git a/quota/edit.c b/quota/edit.c
index b3cad024b1f1..1a3b2d9f959b 100644
--- a/quota/edit.c
+++ b/quota/edit.c
@@ -417,6 +417,53 @@ restore_f(
 	return 0;
 }
 
+time64_t
+decode_timer(
+	const struct fs_disk_quota *d,
+	__s32			timer_lo,
+	__s8			timer_hi)
+{
+	if (d->d_fieldmask & FS_DQ_BIGTIME)
+		return (uint32_t)timer_lo | (int64_t)timer_hi << 32;
+	return timer_lo;
+}
+
+static inline void
+encode_timer(
+	const struct fs_disk_quota *d,
+	__s32			*timer_lo,
+	__s8			*timer_hi,
+	time64_t		timer)
+{
+	*timer_lo = timer;
+	if (d->d_fieldmask & FS_DQ_BIGTIME)
+		*timer_hi = timer >> 32;
+	else
+		*timer_hi = 0;
+}
+
+static inline bool want_bigtime(time64_t timer)
+{
+	return timer > INT32_MAX || timer < INT32_MIN;
+}
+
+static void
+encode_timers(
+	struct fs_disk_quota	*d,
+	time64_t		btimer,
+	time64_t		itimer,
+	time64_t		rtbtimer)
+{
+	d->d_fieldmask &= ~FS_DQ_BIGTIME;
+	if (want_bigtime(btimer) || want_bigtime(itimer) ||
+	    want_bigtime(rtbtimer))
+		d->d_fieldmask |= FS_DQ_BIGTIME;
+
+	encode_timer(d, &d->d_btimer, &d->d_btimer_hi, btimer);
+	encode_timer(d, &d->d_itimer, &d->d_itimer_hi, itimer);
+	encode_timer(d, &d->d_rtbtimer, &d->d_rtbtimer_hi, rtbtimer);
+}
+
 static void
 set_timer(
 	uint32_t		id,
@@ -426,6 +473,7 @@ set_timer(
 	time64_t		value)
 {
 	struct fs_disk_quota	d;
+	time64_t		btimer, itimer, rtbtimer;
 
 	memset(&d, 0, sizeof(d));
 
@@ -446,23 +494,28 @@ set_timer(
 
 		time(&now);
 
+		btimer = decode_timer(&d, d.d_btimer, d.d_btimer_hi);
+		itimer = decode_timer(&d, d.d_itimer, d.d_itimer_hi);
+		rtbtimer = decode_timer(&d, d.d_rtbtimer, d.d_rtbtimer_hi);
+
 		/* Only set grace time if user is already past soft limit */
 		if (d.d_blk_softlimit && d.d_bcount > d.d_blk_softlimit)
-			d.d_btimer = now + value;
+			btimer = now + value;
 		if (d.d_ino_softlimit && d.d_icount > d.d_ino_softlimit)
-			d.d_itimer = now + value;
+			itimer = now + value;
 		if (d.d_rtb_softlimit && d.d_rtbcount > d.d_rtb_softlimit)
-			d.d_rtbtimer = now + value;
+			rtbtimer = now + value;
 	} else {
-		d.d_btimer = value;
-		d.d_itimer = value;
-		d.d_rtbtimer = value;
+		btimer = value;
+		itimer = value;
+		rtbtimer = value;
 	}
 
 	d.d_version = FS_DQUOT_VERSION;
 	d.d_flags = type;
 	d.d_fieldmask = mask;
 	d.d_id = id;
+	encode_timers(&d, btimer, itimer, rtbtimer);
 
 	if (xfsquotactl(XFS_SETQLIM, dev, type, id, (void *)&d) < 0) {
 		exitcode = 1;
diff --git a/quota/quota.c b/quota/quota.c
index 8ba0995d9174..0747cedcb8c2 100644
--- a/quota/quota.c
+++ b/quota/quota.c
@@ -101,7 +101,7 @@ quota_mount(
 	}
 
 	if (form & XFS_BLOCK_QUOTA) {
-		timer = d.d_btimer;
+		timer = decode_timer(&d, d.d_btimer, d.d_btimer_hi);
 		qflags = (flags & HUMAN_FLAG);
 		if (d.d_blk_hardlimit && d.d_bcount > d.d_blk_hardlimit)
 			qflags |= LIMIT_FLAG;
@@ -123,7 +123,7 @@ quota_mount(
 				time_to_string(timer, qflags));
 	}
 	if (form & XFS_INODE_QUOTA) {
-		timer = d.d_itimer;
+		timer = decode_timer(&d, d.d_itimer, d.d_itimer_hi);
 		qflags = (flags & HUMAN_FLAG);
 		if (d.d_ino_hardlimit && d.d_icount > d.d_ino_hardlimit)
 			qflags |= LIMIT_FLAG;
@@ -145,7 +145,7 @@ quota_mount(
 				time_to_string(timer, qflags));
 	}
 	if (form & XFS_RTBLOCK_QUOTA) {
-		timer = d.d_rtbtimer;
+		timer = decode_timer(&d, d.d_rtbtimer, d.d_rtbtimer_hi);
 		qflags = (flags & HUMAN_FLAG);
 		if (d.d_rtb_hardlimit && d.d_rtbcount > d.d_rtb_hardlimit)
 			qflags |= LIMIT_FLAG;
diff --git a/quota/quota.h b/quota/quota.h
index 11f62b208e6a..78b0d66d2a4f 100644
--- a/quota/quota.h
+++ b/quota/quota.h
@@ -3,6 +3,8 @@
  * Copyright (c) 2005 Silicon Graphics, Inc.
  * All Rights Reserved.
  */
+#ifndef XFS_QUOTA_QUOTA_H_
+#define XFS_QUOTA_QUOTA_H_
 
 #include "xqm.h"
 #include "libfrog/paths.h"
@@ -73,3 +75,8 @@ extern char *uid_to_name(uint32_t __uid);
 extern char *gid_to_name(uint32_t __gid);
 extern char *prid_to_name(uint32_t __prid);
 extern bool isdigits_only(const char *);
+
+time64_t decode_timer(const struct fs_disk_quota *d, __s32 timer_lo,
+		__s8 timer_hi);
+
+#endif /* XFS_QUOTA_QUOTA_H_ */
diff --git a/quota/report.c b/quota/report.c
index 2d5024e95177..6ac5549097b7 100644
--- a/quota/report.c
+++ b/quota/report.c
@@ -398,7 +398,7 @@ report_mount(
 	}
 
 	if (form & XFS_BLOCK_QUOTA) {
-		timer = d.d_btimer;
+		timer = decode_timer(&d, d.d_btimer, d.d_btimer_hi);
 		qflags = (flags & HUMAN_FLAG);
 		if (d.d_blk_hardlimit && d.d_bcount > d.d_blk_hardlimit)
 			qflags |= LIMIT_FLAG;
@@ -420,7 +420,7 @@ report_mount(
 				time_to_string(timer, qflags));
 	}
 	if (form & XFS_INODE_QUOTA) {
-		timer = d.d_itimer;
+		timer = decode_timer(&d, d.d_itimer, d.d_itimer_hi);
 		qflags = (flags & HUMAN_FLAG);
 		if (d.d_ino_hardlimit && d.d_icount > d.d_ino_hardlimit)
 			qflags |= LIMIT_FLAG;
@@ -442,7 +442,7 @@ report_mount(
 				time_to_string(timer, qflags));
 	}
 	if (form & XFS_RTBLOCK_QUOTA) {
-		timer = d.d_rtbtimer;
+		timer = decode_timer(&d, d.d_rtbtimer, d.d_rtbtimer_hi);
 		qflags = (flags & HUMAN_FLAG);
 		if (d.d_rtb_hardlimit && d.d_rtbcount > d.d_rtb_hardlimit)
 			qflags |= LIMIT_FLAG;


^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH 24/26] xfs_repair: support bigtime timestamp checking
  2020-10-26 23:34 [PATCH v6 00/26] xfsprogs: widen timestamps to deal with y2038 Darrick J. Wong
                   ` (22 preceding siblings ...)
  2020-10-26 23:36 ` [PATCH 23/26] xfs_quota: support editing and reporting quotas with bigtime Darrick J. Wong
@ 2020-10-26 23:36 ` Darrick J. Wong
  2020-10-29  9:52   ` Christoph Hellwig
  2020-10-26 23:36 ` [PATCH 25/26] mkfs: format bigtime filesystems Darrick J. Wong
  2020-10-26 23:36 ` [PATCH 26/26] xfs: enable big timestamps Darrick J. Wong
  25 siblings, 1 reply; 58+ messages in thread
From: Darrick J. Wong @ 2020-10-26 23:36 UTC (permalink / raw)
  To: sandeen, darrick.wong; +Cc: linux-xfs

From: Darrick J. Wong <darrick.wong@oracle.com>

Make sure that inodes don't have the bigtime flag set when the feature
is disabled, and don't check for overflows in the nanoseconds when
bigtime is enabled because that is no longer possible.  Also make sure
that quotas don't have bigtime set erroneously.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 repair/dinode.c     |   33 +++++++++++++++++++++++++++++----
 repair/quotacheck.c |   11 ++++++++++-
 2 files changed, 39 insertions(+), 5 deletions(-)


diff --git a/repair/dinode.c b/repair/dinode.c
index c1d9d9727d62..16f52c38a43a 100644
--- a/repair/dinode.c
+++ b/repair/dinode.c
@@ -2167,11 +2167,15 @@ static void
 check_nsec(
 	const char		*name,
 	xfs_ino_t		lino,
+	struct xfs_dinode	*dip,
 	xfs_timestamp_t		*ts,
 	int			*dirty)
 {
 	struct xfs_legacy_timestamp *t;
 
+	if (xfs_dinode_has_bigtime(dip))
+		return;
+
 	t = (struct xfs_legacy_timestamp *)ts;
 	if (be32_to_cpu(t->t_nsec) < NSEC_PER_SEC)
 		return;
@@ -2594,6 +2598,27 @@ _("bad (negative) size %" PRId64 " on inode %" PRIu64 "\n"),
 			flags2 &= ~XFS_DIFLAG2_COWEXTSIZE;
 		}
 
+		if (xfs_dinode_has_bigtime(dino) &&
+		    !xfs_sb_version_hasbigtime(&mp->m_sb)) {
+			if (!uncertain) {
+				do_warn(
+	_("inode %" PRIu64 " is marked bigtime but file system does not support large timestamps\n"),
+					lino);
+			}
+			flags2 &= ~XFS_DIFLAG2_BIGTIME;
+
+			if (no_modify) {
+				do_warn(_("would zero timestamps.\n"));
+			} else {
+				do_warn(_("zeroing timestamps.\n"));
+				dino->di_atime = 0;
+				dino->di_mtime = 0;
+				dino->di_ctime = 0;
+				dino->di_crtime = 0;
+				*dirty = 1;
+			}
+		}
+
 		if (!verify_mode && flags2 != be64_to_cpu(dino->di_flags2)) {
 			if (!no_modify) {
 				do_warn(_("fixing bad flags2.\n"));
@@ -2721,11 +2746,11 @@ _("Bad CoW extent size %u on inode %" PRIu64 ", "),
 	}
 
 	/* nsec fields cannot be larger than 1 billion */
-	check_nsec("atime", lino, &dino->di_atime, dirty);
-	check_nsec("mtime", lino, &dino->di_mtime, dirty);
-	check_nsec("ctime", lino, &dino->di_ctime, dirty);
+	check_nsec("atime", lino, dino, &dino->di_atime, dirty);
+	check_nsec("mtime", lino, dino, &dino->di_mtime, dirty);
+	check_nsec("ctime", lino, dino, &dino->di_ctime, dirty);
 	if (dino->di_version >= 3)
-		check_nsec("crtime", lino, &dino->di_crtime, dirty);
+		check_nsec("crtime", lino, dino, &dino->di_crtime, dirty);
 
 	/*
 	 * general size/consistency checks:
diff --git a/repair/quotacheck.c b/repair/quotacheck.c
index 8cbbfa2e6978..55bcc048517d 100644
--- a/repair/quotacheck.c
+++ b/repair/quotacheck.c
@@ -237,6 +237,7 @@ quotacheck_adjust(
 /* Compare this on-disk dquot against whatever we observed. */
 static void
 qc_check_dquot(
+	struct xfs_mount	*mp,
 	struct xfs_disk_dquot	*ddq,
 	struct qc_dquots	*dquots)
 {
@@ -273,6 +274,14 @@ qc_check_dquot(
 		chkd_flags = 0;
 	}
 
+	if ((ddq->d_type & XFS_DQTYPE_BIGTIME) &&
+	    !xfs_sb_version_hasbigtime(&mp->m_sb)) {
+		do_warn(
+	_("%s id %u is marked bigtime but file system does not support large timestamps\n"),
+				qflags_typestr(dquots->type), id);
+		chkd_flags = 0;
+	}
+
 	/*
 	 * Mark that we found the record on disk.  Skip locking here because
 	 * we're checking the dquots serially.
@@ -322,7 +331,7 @@ _("cannot read %s inode %"PRIu64", block %"PRIu64", disk block %"PRIu64", err=%d
 		for (dqnr = 0;
 		     dqnr < dqperchunk && dqid <= UINT_MAX;
 		     dqnr++, dqb++, dqid++)
-			qc_check_dquot(&dqb->dd_diskdq, dquots);
+			qc_check_dquot(mp, &dqb->dd_diskdq, dquots);
 		libxfs_buf_relse(bp);
 	}
 


^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH 25/26] mkfs: format bigtime filesystems
  2020-10-26 23:34 [PATCH v6 00/26] xfsprogs: widen timestamps to deal with y2038 Darrick J. Wong
                   ` (23 preceding siblings ...)
  2020-10-26 23:36 ` [PATCH 24/26] xfs_repair: support bigtime timestamp checking Darrick J. Wong
@ 2020-10-26 23:36 ` Darrick J. Wong
  2020-10-29  9:52   ` Christoph Hellwig
  2020-10-26 23:36 ` [PATCH 26/26] xfs: enable big timestamps Darrick J. Wong
  25 siblings, 1 reply; 58+ messages in thread
From: Darrick J. Wong @ 2020-10-26 23:36 UTC (permalink / raw)
  To: sandeen, darrick.wong; +Cc: linux-xfs

From: Darrick J. Wong <darrick.wong@oracle.com>

Allow formatting with large timestamps.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 man/man8/mkfs.xfs.8 |   16 ++++++++++++++++
 mkfs/xfs_mkfs.c     |   24 +++++++++++++++++++++++-
 2 files changed, 39 insertions(+), 1 deletion(-)


diff --git a/man/man8/mkfs.xfs.8 b/man/man8/mkfs.xfs.8
index 1a6a5f93f0ea..9e72a841f868 100644
--- a/man/man8/mkfs.xfs.8
+++ b/man/man8/mkfs.xfs.8
@@ -150,6 +150,22 @@ valid
 are:
 .RS 1.2i
 .TP
+.BI bigtime= value
+This option enables filesystems that can handle inode timestamps from December
+1901 to July 2486, and quota timer expirations from January 1970 to July 2486.
+The value is either 0 to disable the feature, or 1 to enable large timestamps.
+.IP
+If this feature is not enabled, the filesystem can only handle timestamps from
+December 1901 to January 2038, and quota timers from January 1970 to February
+2106.
+.IP
+By default,
+.B mkfs.xfs
+will not enable this feature.
+If the option
+.B \-m crc=0
+is used, the large timestamp feature is not supported and is disabled.
+.TP
 .BI crc= value
 This is used to create a filesystem which maintains and checks CRC information
 in all metadata objects on disk. The value is either 0 to disable the feature,
diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
index 23e3077e0174..4cb79b695921 100644
--- a/mkfs/xfs_mkfs.c
+++ b/mkfs/xfs_mkfs.c
@@ -120,6 +120,7 @@ enum {
 	M_RMAPBT,
 	M_REFLINK,
 	M_INOBTCNT,
+	M_BIGTIME,
 	M_MAX_OPTS,
 };
 
@@ -662,6 +663,7 @@ static struct opt_params mopts = {
 		[M_RMAPBT] = "rmapbt",
 		[M_REFLINK] = "reflink",
 		[M_INOBTCNT] = "inobtcount",
+		[M_BIGTIME] = "bigtime",
 	},
 	.subopt_params = {
 		{ .index = M_CRC,
@@ -698,6 +700,12 @@ static struct opt_params mopts = {
 		  .maxval = 1,
 		  .defaultval = 1,
 		},
+		{ .index = M_BIGTIME,
+		  .conflicts = { { NULL, LAST_CONFLICT } },
+		  .minval = 0,
+		  .maxval = 1,
+		  .defaultval = 1,
+		},
 	},
 };
 
@@ -749,6 +757,7 @@ struct sb_feat_args {
 	bool	rmapbt;			/* XFS_SB_FEAT_RO_COMPAT_RMAPBT */
 	bool	reflink;		/* XFS_SB_FEAT_RO_COMPAT_REFLINK */
 	bool	inobtcnt;		/* XFS_SB_FEAT_RO_COMPAT_INOBTCNT */
+	bool	bigtime;		/* XFS_SB_FEAT_INCOMPAT_BIGTIME */
 	bool	nodalign;
 	bool	nortalign;
 };
@@ -872,7 +881,7 @@ usage( void )
 	fprintf(stderr, _("Usage: %s\n\
 /* blocksize */		[-b size=num]\n\
 /* metadata */		[-m crc=0|1,finobt=0|1,uuid=xxx,rmapbt=0|1,reflink=0|1,\n\
-			    inobtcnt=0|1]\n\
+			    inobtcnt=0|1,bigtime=0|1]\n\
 /* data subvol */	[-d agcount=n,agsize=n,file,name=xxx,size=num,\n\
 			    (sunit=value,swidth=value|su=num,sw=num|noalign),\n\
 			    sectsize=num\n\
@@ -1578,6 +1587,9 @@ meta_opts_parser(
 	case M_INOBTCNT:
 		cli->sb_feat.inobtcnt = getnum(value, opts, subopt);
 		break;
+	case M_BIGTIME:
+		cli->sb_feat.bigtime = getnum(value, opts, subopt);
+		break;
 	default:
 		return -EINVAL;
 	}
@@ -2008,6 +2020,13 @@ _("inode btree counters not supported without CRC support\n"));
 			usage();
 		}
 		cli->sb_feat.inobtcnt = false;
+
+		if (cli->sb_feat.bigtime && cli_opt_set(&mopts, M_BIGTIME)) {
+			fprintf(stderr,
+_("timestamps later than 2038 not supported without CRC support\n"));
+			usage();
+		}
+		cli->sb_feat.bigtime = false;
 	}
 
 	if (!cli->sb_feat.finobt) {
@@ -2986,6 +3005,8 @@ sb_set_features(
 		sbp->sb_features_ro_compat |= XFS_SB_FEAT_RO_COMPAT_REFLINK;
 	if (fp->inobtcnt)
 		sbp->sb_features_ro_compat |= XFS_SB_FEAT_RO_COMPAT_INOBTCNT;
+	if (fp->bigtime)
+		sbp->sb_features_incompat |= XFS_SB_FEAT_INCOMPAT_BIGTIME;
 
 	/*
 	 * Sparse inode chunk support has two main inode alignment requirements.
@@ -3652,6 +3673,7 @@ main(
 			.parent_pointers = false,
 			.nodalign = false,
 			.nortalign = false,
+			.bigtime = false,
 		},
 	};
 


^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH 26/26] xfs: enable big timestamps
  2020-10-26 23:34 [PATCH v6 00/26] xfsprogs: widen timestamps to deal with y2038 Darrick J. Wong
                   ` (24 preceding siblings ...)
  2020-10-26 23:36 ` [PATCH 25/26] mkfs: format bigtime filesystems Darrick J. Wong
@ 2020-10-26 23:36 ` Darrick J. Wong
  25 siblings, 0 replies; 58+ messages in thread
From: Darrick J. Wong @ 2020-10-26 23:36 UTC (permalink / raw)
  To: sandeen, darrick.wong
  Cc: Amir Goldstein, Allison Collins, Christoph Hellwig, Gao Xiang,
	Dave Chinner, linux-xfs

From: Darrick J. Wong <darrick.wong@oracle.com>

Source kernel commit: 29887a22713192509cfc6068ea3b200cdb8856da

Enable the big timestamp feature.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Amir Goldstein <amir73il@gmail.com>
Reviewed-by: Allison Collins <allison.henderson@oracle.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Gao Xiang <hsiangkao@redhat.com>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 libxfs/xfs_format.h |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)


diff --git a/libxfs/xfs_format.h b/libxfs/xfs_format.h
index 0ab424cc25ca..e8e7e63455c6 100644
--- a/libxfs/xfs_format.h
+++ b/libxfs/xfs_format.h
@@ -471,7 +471,8 @@ xfs_sb_has_ro_compat_feature(
 #define XFS_SB_FEAT_INCOMPAT_ALL \
 		(XFS_SB_FEAT_INCOMPAT_FTYPE|	\
 		 XFS_SB_FEAT_INCOMPAT_SPINODES|	\
-		 XFS_SB_FEAT_INCOMPAT_META_UUID)
+		 XFS_SB_FEAT_INCOMPAT_META_UUID| \
+		 XFS_SB_FEAT_INCOMPAT_BIGTIME)
 
 #define XFS_SB_FEAT_INCOMPAT_UNKNOWN	~XFS_SB_FEAT_INCOMPAT_ALL
 static inline bool


^ permalink raw reply related	[flat|nested] 58+ messages in thread

* Re: [PATCH 01/26] libxfs: create a real struct timespec64
  2020-10-26 23:34 ` [PATCH 01/26] libxfs: create a real struct timespec64 Darrick J. Wong
@ 2020-10-29  9:44   ` Christoph Hellwig
  0 siblings, 0 replies; 58+ messages in thread
From: Christoph Hellwig @ 2020-10-29  9:44 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: sandeen, Amir Goldstein, linux-xfs

On Mon, Oct 26, 2020 at 04:34:13PM -0700, Darrick J. Wong wrote:
> From: Darrick J. Wong <darrick.wong@oracle.com>
> 
> Create a real struct timespec64 that supports 64-bit seconds counts.
> The C library struct timespec doesn't support this on 32-bit
> architectures and we cannot lose the upper bits in the incore inode.
> 
> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
> Reviewed-by: Amir Goldstein <amir73il@gmail.com>

Looks good,

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

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 02/26] libxfs: refactor NSEC_PER_SEC
  2020-10-26 23:34 ` [PATCH 02/26] libxfs: refactor NSEC_PER_SEC Darrick J. Wong
@ 2020-10-29  9:44   ` Christoph Hellwig
  0 siblings, 0 replies; 58+ messages in thread
From: Christoph Hellwig @ 2020-10-29  9:44 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: sandeen, Amir Goldstein, linux-xfs

Looks good,

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

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 03/26] libfrog: define LIBFROG_BULKSTAT_CHUNKSIZE to remove dependence on XFS_INODES_PER_CHUNK
  2020-10-26 23:34 ` [PATCH 03/26] libfrog: define LIBFROG_BULKSTAT_CHUNKSIZE to remove dependence on XFS_INODES_PER_CHUNK Darrick J. Wong
@ 2020-10-29  9:45   ` Christoph Hellwig
  2020-10-29  9:45     ` Christoph Hellwig
  0 siblings, 1 reply; 58+ messages in thread
From: Christoph Hellwig @ 2020-10-29  9:45 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: sandeen, linux-xfs

Looks good,

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

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 04/26] libfrog: convert cvttime to return time64_t
  2020-10-26 23:34 ` [PATCH 04/26] libfrog: convert cvttime to return time64_t Darrick J. Wong
@ 2020-10-29  9:45   ` Christoph Hellwig
  0 siblings, 0 replies; 58+ messages in thread
From: Christoph Hellwig @ 2020-10-29  9:45 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: sandeen, linux-xfs

On Mon, Oct 26, 2020 at 04:34:31PM -0700, Darrick J. Wong wrote:
> From: Darrick J. Wong <darrick.wong@oracle.com>
> 
> Change the cvttime function to return 64-bit time values so that we can
> put them to use with the bigtime feature.

Looks good,

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

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 03/26] libfrog: define LIBFROG_BULKSTAT_CHUNKSIZE to remove dependence on XFS_INODES_PER_CHUNK
  2020-10-29  9:45   ` Christoph Hellwig
@ 2020-10-29  9:45     ` Christoph Hellwig
  2020-10-29 17:25       ` Darrick J. Wong
  0 siblings, 1 reply; 58+ messages in thread
From: Christoph Hellwig @ 2020-10-29  9:45 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: sandeen, linux-xfs

On Thu, Oct 29, 2020 at 09:45:04AM +0000, Christoph Hellwig wrote:
> Looks good,
> 
> Reviewed-by: Christoph Hellwig <hch@lst.de>

And no good reason to use struct timespec64 here, right?

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 05/26] xfs_quota: convert time_to_string to use time64_t
  2020-10-26 23:34 ` [PATCH 05/26] xfs_quota: convert time_to_string to use time64_t Darrick J. Wong
@ 2020-10-29  9:47   ` Christoph Hellwig
  2020-10-29 17:32     ` Darrick J. Wong
  2020-11-16 20:45   ` Eric Sandeen
  1 sibling, 1 reply; 58+ messages in thread
From: Christoph Hellwig @ 2020-10-29  9:47 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: sandeen, linux-xfs

On Mon, Oct 26, 2020 at 04:34:38PM -0700, Darrick J. Wong wrote:
> From: Darrick J. Wong <darrick.wong@oracle.com>
> 
> Rework the time_to_string helper to be capable of dealing with 64-bit
> timestamps.
> 
> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
> ---
>  quota/quota.c  |   16 ++++++++++------
>  quota/quota.h  |    2 +-
>  quota/report.c |   16 ++++++++++------
>  quota/util.c   |    5 +++--
>  4 files changed, 24 insertions(+), 15 deletions(-)
> 
> 
> diff --git a/quota/quota.c b/quota/quota.c
> index 9545cc430a93..8ba0995d9174 100644
> --- a/quota/quota.c
> +++ b/quota/quota.c
> @@ -48,6 +48,7 @@ quota_mount(
>  	uint		flags)
>  {
>  	fs_disk_quota_t	d;
> +	time64_t	timer;
>  	char		*dev = mount->fs_name;
>  	char		c[8], h[8], s[8];
>  	uint		qflags;
> @@ -100,6 +101,7 @@ quota_mount(
>  	}
>  
>  	if (form & XFS_BLOCK_QUOTA) {
> +		timer = d.d_btimer;
>  		qflags = (flags & HUMAN_FLAG);
>  		if (d.d_blk_hardlimit && d.d_bcount > d.d_blk_hardlimit)
>  			qflags |= LIMIT_FLAG;
> @@ -111,16 +113,17 @@ quota_mount(
>  				bbs_to_string(d.d_blk_softlimit, s, sizeof(s)),
>  				bbs_to_string(d.d_blk_hardlimit, h, sizeof(h)),
>  				d.d_bwarns,
> -				time_to_string(d.d_btimer, qflags));
> +				time_to_string(timer, qflags));

What do the local variables buy us over just relying on the implicit cast
to a larger integer type?

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 06/26] xfs_db: refactor timestamp printing
  2020-10-26 23:34 ` [PATCH 06/26] xfs_db: refactor timestamp printing Darrick J. Wong
@ 2020-10-29  9:47   ` Christoph Hellwig
  0 siblings, 0 replies; 58+ messages in thread
From: Christoph Hellwig @ 2020-10-29  9:47 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: sandeen, linux-xfs

On Mon, Oct 26, 2020 at 04:34:44PM -0700, Darrick J. Wong wrote:
> From: Darrick J. Wong <darrick.wong@oracle.com>
> 
> Introduce type-specific printing functions to xfs_db to print an
> xfs_timestamp instead of open-coding the timestamp decoding.  This is
> needed to stay ahead of changes that we're going to make to
> xfs_timestamp_t in the following patches.
> 
> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>

Looks good,

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

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 07/26] xfs_db: refactor quota timer printing
  2020-10-26 23:34 ` [PATCH 07/26] xfs_db: refactor quota timer printing Darrick J. Wong
@ 2020-10-29  9:48   ` Christoph Hellwig
  0 siblings, 0 replies; 58+ messages in thread
From: Christoph Hellwig @ 2020-10-29  9:48 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: sandeen, linux-xfs

Looks as good as the xfs_db filed printing mess can..

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

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 08/26] xfs_logprint: refactor timestamp printing
  2020-10-26 23:34 ` [PATCH 08/26] xfs_logprint: refactor timestamp printing Darrick J. Wong
@ 2020-10-29  9:48   ` Christoph Hellwig
  2020-11-23 20:14   ` Eric Sandeen
  1 sibling, 0 replies; 58+ messages in thread
From: Christoph Hellwig @ 2020-10-29  9:48 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: sandeen, linux-xfs

On Mon, Oct 26, 2020 at 04:34:56PM -0700, Darrick J. Wong wrote:
> From: Darrick J. Wong <darrick.wong@oracle.com>
> 
> Introduce type-specific printing functions to xfs_logprint to print an
> xfs_timestamp instead of open-coding the timestamp decoding.  This is
> needed to stay ahead of changes that we're going to make to
> xfs_timestamp_t in the following patches.
> 
> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>

Looks good,

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

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 18/26] libxfs: propagate bigtime inode flag when allocating
  2020-10-26 23:36 ` [PATCH 18/26] libxfs: propagate bigtime inode flag when allocating Darrick J. Wong
@ 2020-10-29  9:48   ` Christoph Hellwig
  0 siblings, 0 replies; 58+ messages in thread
From: Christoph Hellwig @ 2020-10-29  9:48 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: sandeen, linux-xfs

On Mon, Oct 26, 2020 at 04:36:03PM -0700, Darrick J. Wong wrote:
> From: Darrick J. Wong <darrick.wong@oracle.com>
> 
> Ensure that we propagate the bigtime inode flag correctly when creating
> new inodes.  There critical part here is to use the new_diflags2 field
> in the incore geometry just like we do in the kernel.
> 
> We also modify xfs_flags2diflags2 to have the same behavior as the
> kernel.  This isn't strictly needed here, but we aim to avoid letting
> userspace diverge from the kernel function when we can.
> 
> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>

Looks good,

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

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 19/26] libfrog: list the bigtime feature when reporting geometry
  2020-10-26 23:36 ` [PATCH 19/26] libfrog: list the bigtime feature when reporting geometry Darrick J. Wong
@ 2020-10-29  9:49   ` Christoph Hellwig
  0 siblings, 0 replies; 58+ messages in thread
From: Christoph Hellwig @ 2020-10-29  9:49 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: sandeen, linux-xfs

On Mon, Oct 26, 2020 at 04:36:10PM -0700, Darrick J. Wong wrote:
> From: Darrick J. Wong <darrick.wong@oracle.com>
> 
> When we're reporting on a filesystem's geometry, report if the bigtime
> feature is enabled on this filesystem.
> 
> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>

Looks good,

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

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 20/26] xfs_db: report bigtime format timestamps
  2020-10-26 23:36 ` [PATCH 20/26] xfs_db: report bigtime format timestamps Darrick J. Wong
@ 2020-10-29  9:50   ` Christoph Hellwig
  2020-10-29 17:45     ` Darrick J. Wong
  2020-11-16 21:16   ` Eric Sandeen
  2020-11-17 17:45   ` [PATCH v2 " Darrick J. Wong
  2 siblings, 1 reply; 58+ messages in thread
From: Christoph Hellwig @ 2020-10-29  9:50 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: sandeen, linux-xfs

> +static void
> +fp_time64(
> +	time64_t		sec)
>  {
> +	time_t			tt = sec;
>  	char			*c;
> +
> +	BUILD_BUG_ON(sizeof(long) != sizeof(time_t));

Why?

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 21/26] xfs_db: support printing time limits
  2020-10-26 23:36 ` [PATCH 21/26] xfs_db: support printing time limits Darrick J. Wong
@ 2020-10-29  9:50   ` Christoph Hellwig
  0 siblings, 0 replies; 58+ messages in thread
From: Christoph Hellwig @ 2020-10-29  9:50 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: sandeen, linux-xfs

Looks good,

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

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 22/26] xfs_db: add bigtime upgrade path
  2020-10-26 23:36 ` [PATCH 22/26] xfs_db: add bigtime upgrade path Darrick J. Wong
@ 2020-10-29  9:51   ` Christoph Hellwig
  2020-11-16 21:15   ` [PATCH v2 " Darrick J. Wong
  1 sibling, 0 replies; 58+ messages in thread
From: Christoph Hellwig @ 2020-10-29  9:51 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: sandeen, linux-xfs

Looks good,

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

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 23/26] xfs_quota: support editing and reporting quotas with bigtime
  2020-10-26 23:36 ` [PATCH 23/26] xfs_quota: support editing and reporting quotas with bigtime Darrick J. Wong
@ 2020-10-29  9:51   ` Christoph Hellwig
  0 siblings, 0 replies; 58+ messages in thread
From: Christoph Hellwig @ 2020-10-29  9:51 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: sandeen, linux-xfs

Looks good,

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

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 24/26] xfs_repair: support bigtime timestamp checking
  2020-10-26 23:36 ` [PATCH 24/26] xfs_repair: support bigtime timestamp checking Darrick J. Wong
@ 2020-10-29  9:52   ` Christoph Hellwig
  0 siblings, 0 replies; 58+ messages in thread
From: Christoph Hellwig @ 2020-10-29  9:52 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: sandeen, linux-xfs

Looks good,

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

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 25/26] mkfs: format bigtime filesystems
  2020-10-26 23:36 ` [PATCH 25/26] mkfs: format bigtime filesystems Darrick J. Wong
@ 2020-10-29  9:52   ` Christoph Hellwig
  0 siblings, 0 replies; 58+ messages in thread
From: Christoph Hellwig @ 2020-10-29  9:52 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: sandeen, linux-xfs

Looks good,

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

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 03/26] libfrog: define LIBFROG_BULKSTAT_CHUNKSIZE to remove dependence on XFS_INODES_PER_CHUNK
  2020-10-29  9:45     ` Christoph Hellwig
@ 2020-10-29 17:25       ` Darrick J. Wong
  2020-10-30  8:20         ` Christoph Hellwig
  0 siblings, 1 reply; 58+ messages in thread
From: Darrick J. Wong @ 2020-10-29 17:25 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: sandeen, linux-xfs

On Thu, Oct 29, 2020 at 09:45:49AM +0000, Christoph Hellwig wrote:
> On Thu, Oct 29, 2020 at 09:45:04AM +0000, Christoph Hellwig wrote:
> > Looks good,
> > 
> > Reviewed-by: Christoph Hellwig <hch@lst.de>
> 
> And no good reason to use struct timespec64 here, right?

Huh?  There's no mention of a timespec in this patch at all...?

<confused>

--D

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 05/26] xfs_quota: convert time_to_string to use time64_t
  2020-10-29  9:47   ` Christoph Hellwig
@ 2020-10-29 17:32     ` Darrick J. Wong
  2020-10-30  8:21       ` Christoph Hellwig
  0 siblings, 1 reply; 58+ messages in thread
From: Darrick J. Wong @ 2020-10-29 17:32 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: sandeen, linux-xfs

On Thu, Oct 29, 2020 at 09:47:12AM +0000, Christoph Hellwig wrote:
> On Mon, Oct 26, 2020 at 04:34:38PM -0700, Darrick J. Wong wrote:
> > From: Darrick J. Wong <darrick.wong@oracle.com>
> > 
> > Rework the time_to_string helper to be capable of dealing with 64-bit
> > timestamps.
> > 
> > Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
> > ---
> >  quota/quota.c  |   16 ++++++++++------
> >  quota/quota.h  |    2 +-
> >  quota/report.c |   16 ++++++++++------
> >  quota/util.c   |    5 +++--
> >  4 files changed, 24 insertions(+), 15 deletions(-)
> > 
> > 
> > diff --git a/quota/quota.c b/quota/quota.c
> > index 9545cc430a93..8ba0995d9174 100644
> > --- a/quota/quota.c
> > +++ b/quota/quota.c
> > @@ -48,6 +48,7 @@ quota_mount(
> >  	uint		flags)
> >  {
> >  	fs_disk_quota_t	d;
> > +	time64_t	timer;
> >  	char		*dev = mount->fs_name;
> >  	char		c[8], h[8], s[8];
> >  	uint		qflags;
> > @@ -100,6 +101,7 @@ quota_mount(
> >  	}
> >  
> >  	if (form & XFS_BLOCK_QUOTA) {
> > +		timer = d.d_btimer;
> >  		qflags = (flags & HUMAN_FLAG);
> >  		if (d.d_blk_hardlimit && d.d_bcount > d.d_blk_hardlimit)
> >  			qflags |= LIMIT_FLAG;
> > @@ -111,16 +113,17 @@ quota_mount(
> >  				bbs_to_string(d.d_blk_softlimit, s, sizeof(s)),
> >  				bbs_to_string(d.d_blk_hardlimit, h, sizeof(h)),
> >  				d.d_bwarns,
> > -				time_to_string(d.d_btimer, qflags));
> > +				time_to_string(timer, qflags));
> 
> What do the local variables buy us over just relying on the implicit cast
> to a larger integer type?

It's a setup to avoid long lines of nested function call crud once we
get to patch 23.  Without the local variable, the fprintf turns into
this ugliness:

			fprintf(fp, " %6s %6s %6s  %02d %8s ",
				bbs_to_string(d.d_bcount, c, sizeof(c)),
				bbs_to_string(d.d_blk_softlimit, s, sizeof(s)),
				bbs_to_string(d.d_blk_hardlimit, h, sizeof(h)),
				d.d_bwarns,
				time_to_string(decode_timer(&d, d.d_itimer,
								d.d_itimer_hi),
						qflags));

Which I guess is also fine but I kind of hate function call inside
function call inside function call combined with high indent levels.

--D

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 20/26] xfs_db: report bigtime format timestamps
  2020-10-29  9:50   ` Christoph Hellwig
@ 2020-10-29 17:45     ` Darrick J. Wong
  2020-10-30  8:23       ` Christoph Hellwig
  0 siblings, 1 reply; 58+ messages in thread
From: Darrick J. Wong @ 2020-10-29 17:45 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: sandeen, linux-xfs

On Thu, Oct 29, 2020 at 09:50:10AM +0000, Christoph Hellwig wrote:
> > +static void
> > +fp_time64(
> > +	time64_t		sec)
> >  {
> > +	time_t			tt = sec;
> >  	char			*c;
> > +
> > +	BUILD_BUG_ON(sizeof(long) != sizeof(time_t));
> 
> Why?

Trying to make the best of a braindead situation.  IIRC C99/11/18 don't
provide a specific definition of what time_t is supposed to be.  POSIX
2017 seems to hint that it should be an integer seconds counter, but
doesn't provide any further clarity.  (And then says it defers to ISO C,
having made that allusion to integerness.)

Since I'd rather print a raw s64 value than risk truncating a time and
printing a totally garbage prettyprinted timestamp, I added the
LONG_{MIN,MAX} checks, but that assumes that time_t is a long.

Hence adding a trap so that if xfsprogs ever does encounter C library
where time_t isn't a long int, we'd get to hear about it.  Granted that
further assumes that time_t isn't a float, but ... ugh.

I guess this could have assigned sec to a time_t value and then compared
it back to the original value to see if we ripped off any upper bits.

--D

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 03/26] libfrog: define LIBFROG_BULKSTAT_CHUNKSIZE to remove dependence on XFS_INODES_PER_CHUNK
  2020-10-29 17:25       ` Darrick J. Wong
@ 2020-10-30  8:20         ` Christoph Hellwig
  0 siblings, 0 replies; 58+ messages in thread
From: Christoph Hellwig @ 2020-10-30  8:20 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: Christoph Hellwig, sandeen, linux-xfs

On Thu, Oct 29, 2020 at 10:25:57AM -0700, Darrick J. Wong wrote:
> On Thu, Oct 29, 2020 at 09:45:49AM +0000, Christoph Hellwig wrote:
> > On Thu, Oct 29, 2020 at 09:45:04AM +0000, Christoph Hellwig wrote:
> > > Looks good,
> > > 
> > > Reviewed-by: Christoph Hellwig <hch@lst.de>
> > 
> > And no good reason to use struct timespec64 here, right?
> 
> Huh?  There's no mention of a timespec in this patch at all...?

No, but a few patches earlier timespec64 is added with the rationale
that we can't rely on a 64-bit time type otherwise, while we use time64_t
here.

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 05/26] xfs_quota: convert time_to_string to use time64_t
  2020-10-29 17:32     ` Darrick J. Wong
@ 2020-10-30  8:21       ` Christoph Hellwig
  0 siblings, 0 replies; 58+ messages in thread
From: Christoph Hellwig @ 2020-10-30  8:21 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: Christoph Hellwig, sandeen, linux-xfs

On Thu, Oct 29, 2020 at 10:32:34AM -0700, Darrick J. Wong wrote:
> It's a setup to avoid long lines of nested function call crud once we
> get to patch 23.  Without the local variable, the fprintf turns into
> this ugliness:

Ok.

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 20/26] xfs_db: report bigtime format timestamps
  2020-10-29 17:45     ` Darrick J. Wong
@ 2020-10-30  8:23       ` Christoph Hellwig
  0 siblings, 0 replies; 58+ messages in thread
From: Christoph Hellwig @ 2020-10-30  8:23 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: Christoph Hellwig, sandeen, linux-xfs

On Thu, Oct 29, 2020 at 10:45:44AM -0700, Darrick J. Wong wrote:
> On Thu, Oct 29, 2020 at 09:50:10AM +0000, Christoph Hellwig wrote:
> > > +static void
> > > +fp_time64(
> > > +	time64_t		sec)
> > >  {
> > > +	time_t			tt = sec;
> > >  	char			*c;
> > > +
> > > +	BUILD_BUG_ON(sizeof(long) != sizeof(time_t));
> > 
> > Why?
> 
> Trying to make the best of a braindead situation.  IIRC C99/11/18 don't
> provide a specific definition of what time_t is supposed to be.  POSIX
> 2017 seems to hint that it should be an integer seconds counter, but
> doesn't provide any further clarity.  (And then says it defers to ISO C,
> having made that allusion to integerness.)

I'm pretty sure the x32 ABI has a time_t that is bigger than long,
which broken POSIX semantics.

> Hence adding a trap so that if xfsprogs ever does encounter C library
> where time_t isn't a long int, we'd get to hear about it.  Granted that
> further assumes that time_t isn't a float, but ... ugh.
> 
> I guess this could have assigned sec to a time_t value and then compared
> it back to the original value to see if we ripped off any upper bits.

I think the standard way would be an intmax_t local variable that the
value is assigned to.

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 05/26] xfs_quota: convert time_to_string to use time64_t
  2020-10-26 23:34 ` [PATCH 05/26] xfs_quota: convert time_to_string to use time64_t Darrick J. Wong
  2020-10-29  9:47   ` Christoph Hellwig
@ 2020-11-16 20:45   ` Eric Sandeen
  1 sibling, 0 replies; 58+ messages in thread
From: Eric Sandeen @ 2020-11-16 20:45 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: linux-xfs

On 10/26/20 6:34 PM, Darrick J. Wong wrote:
> From: Darrick J. Wong <darrick.wong@oracle.com>
> 
> Rework the time_to_string helper to be capable of dealing with 64-bit
> timestamps.
> 
> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>

Looks ok to me, seems like hch's concern was resolved too.

Reviewed-by: Eric Sandeen <sandeen@redhat.com>


^ permalink raw reply	[flat|nested] 58+ messages in thread

* [PATCH v2 22/26] xfs_db: add bigtime upgrade path
  2020-10-26 23:36 ` [PATCH 22/26] xfs_db: add bigtime upgrade path Darrick J. Wong
  2020-10-29  9:51   ` Christoph Hellwig
@ 2020-11-16 21:15   ` Darrick J. Wong
  1 sibling, 0 replies; 58+ messages in thread
From: Darrick J. Wong @ 2020-11-16 21:15 UTC (permalink / raw)
  To: sandeen; +Cc: linux-xfs, hch

From: Darrick J. Wong <darrick.wong@oracle.com>

Enable users to upgrade their filesystems to bigtime support.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
v2: rebase patch since the main feature upgrade patch got changed
slightly
---
 db/sb.c              |   15 +++++++++++++++
 man/man8/xfs_admin.8 |    5 +++++
 2 files changed, 20 insertions(+)

diff --git a/db/sb.c b/db/sb.c
index 3608508a7eb8..f66907e69da6 100644
--- a/db/sb.c
+++ b/db/sb.c
@@ -848,6 +848,21 @@ version_f(
 			}
 
 			v5features.ro_compat |= XFS_SB_FEAT_RO_COMPAT_INOBTCNT;
+		} else if (!strcasecmp(argv[1], "bigtime")) {
+			if (xfs_sb_version_hasbigtime(&mp->m_sb)) {
+				dbprintf(
+		_("bigtime feature is already enabled\n"));
+				exitcode = 1;
+				return 1;
+			}
+			if (!xfs_sb_version_hascrc(&mp->m_sb)) {
+				dbprintf(
+		_("bigtime feature cannot be enabled on pre-V5 filesystems\n"));
+				exitcode = 1;
+				return 1;
+			}
+
+			v5features.incompat |= XFS_SB_FEAT_INCOMPAT_BIGTIME;
 		} else if (!strcasecmp(argv[1], "extflg")) {
 			switch (XFS_SB_VERSION_NUM(&mp->m_sb)) {
 			case XFS_SB_VERSION_1:
diff --git a/man/man8/xfs_admin.8 b/man/man8/xfs_admin.8
index 65ca6afc1e12..c09fe62b6827 100644
--- a/man/man8/xfs_admin.8
+++ b/man/man8/xfs_admin.8
@@ -117,6 +117,11 @@ This reduces mount time by caching the size of the inode btrees in the
 allocation group metadata.
 Once enabled, the filesystem will not be writable by older kernels.
 The filesystem cannot be downgraded after this feature is enabled.
+.TP
+.B bigtime
+Upgrade the filesystem to support larger timestamps up to the year 2486.
+Once enabled, the filesystem will not be readable by older kernels.
+The filesystem cannot be downgraded.
 .RE
 .TP
 .BI \-U " uuid"

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* Re: [PATCH 20/26] xfs_db: report bigtime format timestamps
  2020-10-26 23:36 ` [PATCH 20/26] xfs_db: report bigtime format timestamps Darrick J. Wong
  2020-10-29  9:50   ` Christoph Hellwig
@ 2020-11-16 21:16   ` Eric Sandeen
  2020-11-16 22:41     ` Darrick J. Wong
  2020-11-17 17:45   ` [PATCH v2 " Darrick J. Wong
  2 siblings, 1 reply; 58+ messages in thread
From: Eric Sandeen @ 2020-11-16 21:16 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: linux-xfs

On 10/26/20 6:36 PM, Darrick J. Wong wrote:
> From: Darrick J. Wong <darrick.wong@oracle.com>
> 
> Report the large format timestamps.
> 
> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>

hch had some concerns about this, but we didn't seem to reach a
resolution... I'd like to get the bigtime stuff done this release
and not navel-gaze too much about weird abis etc, so I'm inclined
to just take this and we can fix it later in the release and/or
when somebody hits that BUG_ON...

Reviewed-by: Eric Sandeen <sandeen@redhat.com>


^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 20/26] xfs_db: report bigtime format timestamps
  2020-11-16 21:16   ` Eric Sandeen
@ 2020-11-16 22:41     ` Darrick J. Wong
  0 siblings, 0 replies; 58+ messages in thread
From: Darrick J. Wong @ 2020-11-16 22:41 UTC (permalink / raw)
  To: Eric Sandeen; +Cc: linux-xfs

On Mon, Nov 16, 2020 at 03:16:17PM -0600, Eric Sandeen wrote:
> On 10/26/20 6:36 PM, Darrick J. Wong wrote:
> > From: Darrick J. Wong <darrick.wong@oracle.com>
> > 
> > Report the large format timestamps.
> > 
> > Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
> 
> hch had some concerns about this, but we didn't seem to reach a
> resolution... I'd like to get the bigtime stuff done this release
> and not navel-gaze too much about weird abis etc, so I'm inclined
> to just take this and we can fix it later in the release and/or
> when somebody hits that BUG_ON...
> 
> Reviewed-by: Eric Sandeen <sandeen@redhat.com>

...and while I wasn't looking/these patches were all sitting in my dev
tree, this[1] happened.  So now that musl unconditionally defines time_t
to be an int64_t even on 32-bit platforms, I guess this is broken and
I'll try to go whip up a fix.

--D

[1] https://musl.libc.org/time64.html

^ permalink raw reply	[flat|nested] 58+ messages in thread

* [PATCH v2 20/26] xfs_db: report bigtime format timestamps
  2020-10-26 23:36 ` [PATCH 20/26] xfs_db: report bigtime format timestamps Darrick J. Wong
  2020-10-29  9:50   ` Christoph Hellwig
  2020-11-16 21:16   ` Eric Sandeen
@ 2020-11-17 17:45   ` Darrick J. Wong
  2020-11-17 18:18     ` Eric Sandeen
  2 siblings, 1 reply; 58+ messages in thread
From: Darrick J. Wong @ 2020-11-17 17:45 UTC (permalink / raw)
  To: sandeen; +Cc: linux-xfs

From: Darrick J. Wong <darrick.wong@oracle.com>

Report the large format timestamps in a human-readable manner if it is
possible to do so without loss of information.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
v2: skip the build bug stuff and check directly for information loss in
the time64_t -> time_t conversion
---
 db/fprint.c              |   73 +++++++++++++++++++++++++++++++++-------------
 db/inode.c               |    4 ++-
 db/sb.c                  |    2 +
 libxfs/libxfs_api_defs.h |    1 +
 4 files changed, 59 insertions(+), 21 deletions(-)

diff --git a/db/fprint.c b/db/fprint.c
index 7ceab29cc608..65accfda3fe4 100644
--- a/db/fprint.c
+++ b/db/fprint.c
@@ -112,23 +112,50 @@ fp_sarray(
 	return 1;
 }
 
-int
-fp_time(
-	void			*obj,
-	int			bit,
-	int			count,
-	char			*fmtstr,
-	int			size,
-	int			arg,
-	int			base,
-	int			array)
+static void
+fp_time64(
+	time64_t		sec)
 {
-	struct timespec64	tv;
-	xfs_timestamp_t		*ts;
-	int			bitpos;
+	time_t			tt = sec;
+	time64_t		tt_sec = tt;
 	char			*c;
+
+	/*
+	 * Stupid time_t shenanigans -- POSIX.1-2017 only requires that this
+	 * type represent a time in seconds.  Since we have no idea if our
+	 * time64_t filesystem timestamps can actually be represented by the C
+	 * library, we resort to converting the input value from time64_t to
+	 * time_t and back to time64_t to check for information loss.  If so,
+	 * we print the raw value; otherwise we print a human-readable value.
+	 */
+	if (tt_sec != sec)
+		goto raw;
+
+	c = ctime(&tt);
+	if (!c)
+		goto raw;
+
+	dbprintf("%24.24s", c);
+	return;
+raw:
+	dbprintf("%lld", sec);
+}
+
+int
+fp_time(
+	void			*obj,
+	int			bit,
+	int			count,
+	char			*fmtstr,
+	int			size,
+	int			arg,
+	int			base,
+	int			array)
+{
+	struct timespec64	tv;
+	xfs_timestamp_t		*ts;
+	int			bitpos;
 	int			i;
-	time_t			t;
 
 	ASSERT(bitoffs(bit) == 0);
 	for (i = 0, bitpos = bit;
@@ -139,10 +166,8 @@ fp_time(
 
 		ts = obj + byteize(bitpos);
 		tv = libxfs_inode_from_disk_ts(obj, *ts);
-		t = tv.tv_sec;
 
-		c = ctime(&t);
-		dbprintf("%24.24s", c);
+		fp_time64(tv.tv_sec);
 
 		if (i < count - 1)
 			dbprintf(" ");
@@ -195,7 +220,8 @@ fp_qtimer(
 	int			base,
 	int			array)
 {
-	uint32_t		sec;
+	struct xfs_disk_dquot	*ddq = obj;
+	time64_t		sec;
 	__be32			*t;
 	int			bitpos;
 	int			i;
@@ -208,9 +234,16 @@ fp_qtimer(
 			dbprintf("%d:", i + base);
 
 		t = obj + byteize(bitpos);
-		sec = be32_to_cpu(*t);
+		sec = libxfs_dquot_from_disk_ts(ddq, *t);
 
-		dbprintf("%u", sec);
+		/*
+		 * Display the raw value if it's the default grace expiration
+		 * period (root dquot) or if the quota has not expired.
+		 */
+		if (ddq->d_id == 0 || sec == 0)
+			dbprintf("%lld", sec);
+		else
+			fp_time64(sec);
 
 		if (i < count - 1)
 			dbprintf(" ");
diff --git a/db/inode.c b/db/inode.c
index cc0e680aadea..f0e08ebf5ad9 100644
--- a/db/inode.c
+++ b/db/inode.c
@@ -175,10 +175,12 @@ const field_t	inode_v3_flds[] = {
 	{ "dax", FLDT_UINT1,
 	  OI(COFF(flags2) + bitsz(uint64_t) - XFS_DIFLAG2_DAX_BIT - 1), C1,
 	  0, TYP_NONE },
+	{ "bigtime", FLDT_UINT1,
+	  OI(COFF(flags2) + bitsz(uint64_t) - XFS_DIFLAG2_BIGTIME_BIT - 1), C1,
+	  0, TYP_NONE },
 	{ NULL }
 };
 
-
 const field_t	timestamp_flds[] = {
 	{ "sec", FLDT_TIME, OI(0), C1, 0, TYP_NONE },
 	{ "nsec", FLDT_NSEC, OI(0), C1, 0, TYP_NONE },
diff --git a/db/sb.c b/db/sb.c
index cfc2e32023fc..3608508a7eb8 100644
--- a/db/sb.c
+++ b/db/sb.c
@@ -800,6 +800,8 @@ version_string(
 		strcat(s, ",REFLINK");
 	if (xfs_sb_version_hasinobtcounts(sbp))
 		strcat(s, ",INOBTCNT");
+	if (xfs_sb_version_hasbigtime(sbp))
+		strcat(s, ",BIGTIME");
 	return s;
 }
 
diff --git a/libxfs/libxfs_api_defs.h b/libxfs/libxfs_api_defs.h
index 40da71ab3163..419e6d9888cf 100644
--- a/libxfs/libxfs_api_defs.h
+++ b/libxfs/libxfs_api_defs.h
@@ -99,6 +99,7 @@
 #define xfs_dir_replace			libxfs_dir_replace
 
 #define xfs_dqblk_repair		libxfs_dqblk_repair
+#define xfs_dquot_from_disk_ts		libxfs_dquot_from_disk_ts
 #define xfs_dquot_verify		libxfs_dquot_verify
 
 #define xfs_finobt_calc_reserves	libxfs_finobt_calc_reserves

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* Re: [PATCH v2 20/26] xfs_db: report bigtime format timestamps
  2020-11-17 17:45   ` [PATCH v2 " Darrick J. Wong
@ 2020-11-17 18:18     ` Eric Sandeen
  0 siblings, 0 replies; 58+ messages in thread
From: Eric Sandeen @ 2020-11-17 18:18 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: linux-xfs

On 11/17/20 11:45 AM, Darrick J. Wong wrote:
> From: Darrick J. Wong <darrick.wong@oracle.com>
> 
> Report the large format timestamps in a human-readable manner if it is
> possible to do so without loss of information.
> 
> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
> ---
> v2: skip the build bug stuff and check directly for information loss in
> the time64_t -> time_t conversion

This looks reasonable to me.  Thanks for working this all out.

Reviewed-by: Eric Sandeen <sandeen@redhat.com>

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 08/26] xfs_logprint: refactor timestamp printing
  2020-10-26 23:34 ` [PATCH 08/26] xfs_logprint: refactor timestamp printing Darrick J. Wong
  2020-10-29  9:48   ` Christoph Hellwig
@ 2020-11-23 20:14   ` Eric Sandeen
  2020-11-24  0:25     ` Darrick J. Wong
  1 sibling, 1 reply; 58+ messages in thread
From: Eric Sandeen @ 2020-11-23 20:14 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: linux-xfs

On 10/26/20 6:34 PM, Darrick J. Wong wrote:
> From: Darrick J. Wong <darrick.wong@oracle.com>
> 
> Introduce type-specific printing functions to xfs_logprint to print an
> xfs_timestamp instead of open-coding the timestamp decoding.  This is
> needed to stay ahead of changes that we're going to make to
> xfs_timestamp_t in the following patches.
> 
> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
> ---
>  logprint/log_misc.c      |   18 ++++++++++++++++--
>  logprint/log_print_all.c |    3 +--
>  logprint/logprint.h      |    2 ++
>  3 files changed, 19 insertions(+), 4 deletions(-)
> 

Just for the record, I decided to not take this one; the helper function
with the somewhat vague "compact" arg at the callers doesnt' really seem
worth it, I just open-coded this at the 2 callsites when I did the merge.

Thanks,
-Eric

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 08/26] xfs_logprint: refactor timestamp printing
  2020-11-23 20:14   ` Eric Sandeen
@ 2020-11-24  0:25     ` Darrick J. Wong
  0 siblings, 0 replies; 58+ messages in thread
From: Darrick J. Wong @ 2020-11-24  0:25 UTC (permalink / raw)
  To: Eric Sandeen; +Cc: linux-xfs

On Mon, Nov 23, 2020 at 02:14:27PM -0600, Eric Sandeen wrote:
> On 10/26/20 6:34 PM, Darrick J. Wong wrote:
> > From: Darrick J. Wong <darrick.wong@oracle.com>
> > 
> > Introduce type-specific printing functions to xfs_logprint to print an
> > xfs_timestamp instead of open-coding the timestamp decoding.  This is
> > needed to stay ahead of changes that we're going to make to
> > xfs_timestamp_t in the following patches.
> > 
> > Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
> > ---
> >  logprint/log_misc.c      |   18 ++++++++++++++++--
> >  logprint/log_print_all.c |    3 +--
> >  logprint/logprint.h      |    2 ++
> >  3 files changed, 19 insertions(+), 4 deletions(-)
> > 
> 
> Just for the record, I decided to not take this one; the helper function
> with the somewhat vague "compact" arg at the callers doesnt' really seem
> worth it, I just open-coded this at the 2 callsites when I did the merge.

<nod> it was kind of questionable from the start :)

--D

> Thanks,
> -Eric

^ permalink raw reply	[flat|nested] 58+ messages in thread

end of thread, other threads:[~2020-11-24  0:35 UTC | newest]

Thread overview: 58+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-10-26 23:34 [PATCH v6 00/26] xfsprogs: widen timestamps to deal with y2038 Darrick J. Wong
2020-10-26 23:34 ` [PATCH 01/26] libxfs: create a real struct timespec64 Darrick J. Wong
2020-10-29  9:44   ` Christoph Hellwig
2020-10-26 23:34 ` [PATCH 02/26] libxfs: refactor NSEC_PER_SEC Darrick J. Wong
2020-10-29  9:44   ` Christoph Hellwig
2020-10-26 23:34 ` [PATCH 03/26] libfrog: define LIBFROG_BULKSTAT_CHUNKSIZE to remove dependence on XFS_INODES_PER_CHUNK Darrick J. Wong
2020-10-29  9:45   ` Christoph Hellwig
2020-10-29  9:45     ` Christoph Hellwig
2020-10-29 17:25       ` Darrick J. Wong
2020-10-30  8:20         ` Christoph Hellwig
2020-10-26 23:34 ` [PATCH 04/26] libfrog: convert cvttime to return time64_t Darrick J. Wong
2020-10-29  9:45   ` Christoph Hellwig
2020-10-26 23:34 ` [PATCH 05/26] xfs_quota: convert time_to_string to use time64_t Darrick J. Wong
2020-10-29  9:47   ` Christoph Hellwig
2020-10-29 17:32     ` Darrick J. Wong
2020-10-30  8:21       ` Christoph Hellwig
2020-11-16 20:45   ` Eric Sandeen
2020-10-26 23:34 ` [PATCH 06/26] xfs_db: refactor timestamp printing Darrick J. Wong
2020-10-29  9:47   ` Christoph Hellwig
2020-10-26 23:34 ` [PATCH 07/26] xfs_db: refactor quota timer printing Darrick J. Wong
2020-10-29  9:48   ` Christoph Hellwig
2020-10-26 23:34 ` [PATCH 08/26] xfs_logprint: refactor timestamp printing Darrick J. Wong
2020-10-29  9:48   ` Christoph Hellwig
2020-11-23 20:14   ` Eric Sandeen
2020-11-24  0:25     ` Darrick J. Wong
2020-10-26 23:35 ` [PATCH 09/26] xfs: explicitly define inode timestamp range Darrick J. Wong
2020-10-26 23:35 ` [PATCH 10/26] xfs: refactor quota expiration timer modification Darrick J. Wong
2020-10-26 23:35 ` [PATCH 11/26] xfs: refactor default quota grace period setting code Darrick J. Wong
2020-10-26 23:35 ` [PATCH 12/26] xfs: refactor quota timestamp coding Darrick J. Wong
2020-10-26 23:35 ` [PATCH 13/26] xfs: move xfs_log_dinode_to_disk to the log recovery code Darrick J. Wong
2020-10-26 23:35 ` [PATCH 14/26] xfs: redefine xfs_timestamp_t Darrick J. Wong
2020-10-26 23:35 ` [PATCH 15/26] xfs: redefine xfs_ictimestamp_t Darrick J. Wong
2020-10-26 23:35 ` [PATCH 16/26] xfs: widen ondisk inode timestamps to deal with y2038+ Darrick J. Wong
2020-10-26 23:35 ` [PATCH 17/26] xfs: widen ondisk quota expiration timestamps to handle y2038+ Darrick J. Wong
2020-10-26 23:36 ` [PATCH 18/26] libxfs: propagate bigtime inode flag when allocating Darrick J. Wong
2020-10-29  9:48   ` Christoph Hellwig
2020-10-26 23:36 ` [PATCH 19/26] libfrog: list the bigtime feature when reporting geometry Darrick J. Wong
2020-10-29  9:49   ` Christoph Hellwig
2020-10-26 23:36 ` [PATCH 20/26] xfs_db: report bigtime format timestamps Darrick J. Wong
2020-10-29  9:50   ` Christoph Hellwig
2020-10-29 17:45     ` Darrick J. Wong
2020-10-30  8:23       ` Christoph Hellwig
2020-11-16 21:16   ` Eric Sandeen
2020-11-16 22:41     ` Darrick J. Wong
2020-11-17 17:45   ` [PATCH v2 " Darrick J. Wong
2020-11-17 18:18     ` Eric Sandeen
2020-10-26 23:36 ` [PATCH 21/26] xfs_db: support printing time limits Darrick J. Wong
2020-10-29  9:50   ` Christoph Hellwig
2020-10-26 23:36 ` [PATCH 22/26] xfs_db: add bigtime upgrade path Darrick J. Wong
2020-10-29  9:51   ` Christoph Hellwig
2020-11-16 21:15   ` [PATCH v2 " Darrick J. Wong
2020-10-26 23:36 ` [PATCH 23/26] xfs_quota: support editing and reporting quotas with bigtime Darrick J. Wong
2020-10-29  9:51   ` Christoph Hellwig
2020-10-26 23:36 ` [PATCH 24/26] xfs_repair: support bigtime timestamp checking Darrick J. Wong
2020-10-29  9:52   ` Christoph Hellwig
2020-10-26 23:36 ` [PATCH 25/26] mkfs: format bigtime filesystems Darrick J. Wong
2020-10-29  9:52   ` Christoph Hellwig
2020-10-26 23:36 ` [PATCH 26/26] xfs: enable big timestamps Darrick J. Wong

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).