Blame SOURCES/xfsprogs-5.10.0-xfs-redefine-xfs_timestamp_t.patch

5d5cbe
From a252aadfc977473e0851acf0d529c930c6e8e181 Mon Sep 17 00:00:00 2001
5d5cbe
From: "Darrick J. Wong" <darrick.wong@oracle.com>
5d5cbe
Date: Tue, 10 Nov 2020 16:29:40 -0500
5d5cbe
Subject: [PATCH] xfs: redefine xfs_timestamp_t
5d5cbe
5d5cbe
Source kernel commit: 5a0bb066f60fa02f453d7721844eae59f505c06e
5d5cbe
5d5cbe
Redefine xfs_timestamp_t as a __be64 typedef in preparation for the
5d5cbe
bigtime functionality.  Preserve the legacy structure format so that we
5d5cbe
can let the compiler take care of masking and shifting.
5d5cbe
5d5cbe
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
5d5cbe
Reviewed-by: Christoph Hellwig <hch@lst.de>
5d5cbe
Reviewed-by: Gao Xiang <hsiangkao@redhat.com>
5d5cbe
Reviewed-by: Dave Chinner <dchinner@redhat.com>
5d5cbe
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
5d5cbe
---
5d5cbe
5d5cbe
diff --git a/db/field.c b/db/field.c
5d5cbe
index 66fa37e..4a45c66 100644
5d5cbe
--- a/db/field.c
5d5cbe
+++ b/db/field.c
5d5cbe
@@ -350,7 +350,7 @@ const ftattr_t	ftattrtab[] = {
5d5cbe
 	{ FLDT_TIME, "time", fp_time, NULL, SI(bitsz(int32_t)), FTARG_SIGNED,
5d5cbe
 	  NULL, NULL },
5d5cbe
 	{ FLDT_TIMESTAMP, "timestamp", NULL, (char *)timestamp_flds,
5d5cbe
-	  SI(bitsz(xfs_timestamp_t)), 0, NULL, timestamp_flds },
5d5cbe
+	  SI(bitsz(struct xfs_legacy_timestamp)), 0, NULL, timestamp_flds },
5d5cbe
 	{ FLDT_UINT1, "uint1", fp_num, "%u", SI(1), 0, NULL, NULL },
5d5cbe
 	{ FLDT_UINT16D, "uint16d", fp_num, "%u", SI(bitsz(uint16_t)), 0, NULL,
5d5cbe
 	  NULL },
5d5cbe
diff --git a/db/inode.c b/db/inode.c
5d5cbe
index 697f7fe..b308538 100644
5d5cbe
--- a/db/inode.c
5d5cbe
+++ b/db/inode.c
5d5cbe
@@ -176,7 +176,7 @@ const field_t	inode_v3_flds[] = {
5d5cbe
 };
5d5cbe
 
5d5cbe
 
5d5cbe
-#define	TOFF(f)	bitize(offsetof(xfs_timestamp_t, t_ ## f))
5d5cbe
+#define	TOFF(f)	bitize(offsetof(struct xfs_legacy_timestamp, t_ ## f))
5d5cbe
 const field_t	timestamp_flds[] = {
5d5cbe
 	{ "sec", FLDT_TIME, OI(TOFF(sec)), C1, 0, TYP_NONE },
5d5cbe
 	{ "nsec", FLDT_NSEC, OI(TOFF(nsec)), C1, 0, TYP_NONE },
5d5cbe
diff --git a/libxfs/xfs_format.h b/libxfs/xfs_format.h
5d5cbe
index 8858341..371f5cd 100644
5d5cbe
--- a/libxfs/xfs_format.h
5d5cbe
+++ b/libxfs/xfs_format.h
5d5cbe
@@ -847,12 +847,16 @@ typedef struct xfs_agfl {
5d5cbe
  * seconds and nanoseconds; time zero is the Unix epoch, Jan  1 00:00:00 UTC
5d5cbe
  * 1970, which means that the timestamp epoch is the same as the Unix epoch.
5d5cbe
  * Therefore, the ondisk min and max defined here can be used directly to
5d5cbe
- * constrain the incore timestamps on a Unix system.
5d5cbe
+ * constrain the incore timestamps on a Unix system.  Note that we actually
5d5cbe
+ * encode a __be64 value on disk.
5d5cbe
  */
5d5cbe
-typedef struct xfs_timestamp {
5d5cbe
+typedef __be64 xfs_timestamp_t;
5d5cbe
+
5d5cbe
+/* Legacy timestamp encoding format. */
5d5cbe
+struct xfs_legacy_timestamp {
5d5cbe
 	__be32		t_sec;		/* timestamp seconds */
5d5cbe
 	__be32		t_nsec;		/* timestamp nanoseconds */
5d5cbe
-} xfs_timestamp_t;
5d5cbe
+};
5d5cbe
 
5d5cbe
 /*
5d5cbe
  * Smallest possible ondisk seconds value with traditional timestamps.  This
5d5cbe
diff --git a/libxfs/xfs_inode_buf.c b/libxfs/xfs_inode_buf.c
5d5cbe
index f80ce10..d8831a1 100644
5d5cbe
--- a/libxfs/xfs_inode_buf.c
5d5cbe
+++ b/libxfs/xfs_inode_buf.c
5d5cbe
@@ -195,6 +195,21 @@ xfs_imap_to_bp(
5d5cbe
 	return 0;
5d5cbe
 }
5d5cbe
 
5d5cbe
+/* Convert an ondisk timestamp to an incore timestamp. */
5d5cbe
+struct timespec64
5d5cbe
+xfs_inode_from_disk_ts(
5d5cbe
+	const xfs_timestamp_t		ts)
5d5cbe
+{
5d5cbe
+	struct timespec64		tv;
5d5cbe
+	struct xfs_legacy_timestamp	*lts;
5d5cbe
+
5d5cbe
+	lts = (struct xfs_legacy_timestamp *)&ts;
5d5cbe
+	tv.tv_sec = (int)be32_to_cpu(lts->t_sec);
5d5cbe
+	tv.tv_nsec = (int)be32_to_cpu(lts->t_nsec);
5d5cbe
+
5d5cbe
+	return tv;
5d5cbe
+}
5d5cbe
+
5d5cbe
 void
5d5cbe
 xfs_inode_from_disk(
5d5cbe
 	struct xfs_inode	*ip,
5d5cbe
@@ -231,12 +246,10 @@ xfs_inode_from_disk(
5d5cbe
 	 * a time before epoch is converted to a time long after epoch
5d5cbe
 	 * on 64 bit systems.
5d5cbe
 	 */
5d5cbe
-	inode->i_atime.tv_sec = (int)be32_to_cpu(from->di_atime.t_sec);
5d5cbe
-	inode->i_atime.tv_nsec = (int)be32_to_cpu(from->di_atime.t_nsec);
5d5cbe
-	inode->i_mtime.tv_sec = (int)be32_to_cpu(from->di_mtime.t_sec);
5d5cbe
-	inode->i_mtime.tv_nsec = (int)be32_to_cpu(from->di_mtime.t_nsec);
5d5cbe
-	inode->i_ctime.tv_sec = (int)be32_to_cpu(from->di_ctime.t_sec);
5d5cbe
-	inode->i_ctime.tv_nsec = (int)be32_to_cpu(from->di_ctime.t_nsec);
5d5cbe
+	inode->i_atime = xfs_inode_from_disk_ts(from->di_atime);
5d5cbe
+	inode->i_mtime = xfs_inode_from_disk_ts(from->di_mtime);
5d5cbe
+	inode->i_ctime = xfs_inode_from_disk_ts(from->di_ctime);
5d5cbe
+
5d5cbe
 	inode->i_generation = be32_to_cpu(from->di_gen);
5d5cbe
 	inode->i_mode = be16_to_cpu(from->di_mode);
5d5cbe
 
5d5cbe
@@ -254,13 +267,27 @@ xfs_inode_from_disk(
5d5cbe
 	if (to->di_version == 3) {
5d5cbe
 		inode_set_iversion_queried(inode,
5d5cbe
 					   be64_to_cpu(from->di_changecount));
5d5cbe
-		to->di_crtime.tv_sec = be32_to_cpu(from->di_crtime.t_sec);
5d5cbe
-		to->di_crtime.tv_nsec = be32_to_cpu(from->di_crtime.t_nsec);
5d5cbe
+		to->di_crtime = xfs_inode_from_disk_ts(from->di_crtime);
5d5cbe
 		to->di_flags2 = be64_to_cpu(from->di_flags2);
5d5cbe
 		to->di_cowextsize = be32_to_cpu(from->di_cowextsize);
5d5cbe
 	}
5d5cbe
 }
5d5cbe
 
5d5cbe
+/* Convert an incore timestamp to an ondisk timestamp. */
5d5cbe
+static inline xfs_timestamp_t
5d5cbe
+xfs_inode_to_disk_ts(
5d5cbe
+	const struct timespec64		tv)
5d5cbe
+{
5d5cbe
+	struct xfs_legacy_timestamp	*lts;
5d5cbe
+	xfs_timestamp_t			ts;
5d5cbe
+
5d5cbe
+	lts = (struct xfs_legacy_timestamp *)&ts;
5d5cbe
+	lts->t_sec = cpu_to_be32(tv.tv_sec);
5d5cbe
+	lts->t_nsec = cpu_to_be32(tv.tv_nsec);
5d5cbe
+
5d5cbe
+	return ts;
5d5cbe
+}
5d5cbe
+
5d5cbe
 void
5d5cbe
 xfs_inode_to_disk(
5d5cbe
 	struct xfs_inode	*ip,
5d5cbe
@@ -281,12 +308,9 @@ xfs_inode_to_disk(
5d5cbe
 	to->di_projid_hi = cpu_to_be16(from->di_projid_hi);
5d5cbe
 
5d5cbe
 	memset(to->di_pad, 0, sizeof(to->di_pad));
5d5cbe
-	to->di_atime.t_sec = cpu_to_be32(inode->i_atime.tv_sec);
5d5cbe
-	to->di_atime.t_nsec = cpu_to_be32(inode->i_atime.tv_nsec);
5d5cbe
-	to->di_mtime.t_sec = cpu_to_be32(inode->i_mtime.tv_sec);
5d5cbe
-	to->di_mtime.t_nsec = cpu_to_be32(inode->i_mtime.tv_nsec);
5d5cbe
-	to->di_ctime.t_sec = cpu_to_be32(inode->i_ctime.tv_sec);
5d5cbe
-	to->di_ctime.t_nsec = cpu_to_be32(inode->i_ctime.tv_nsec);
5d5cbe
+	to->di_atime = xfs_inode_to_disk_ts(inode->i_atime);
5d5cbe
+	to->di_mtime = xfs_inode_to_disk_ts(inode->i_mtime);
5d5cbe
+	to->di_ctime = xfs_inode_to_disk_ts(inode->i_ctime);
5d5cbe
 	to->di_nlink = cpu_to_be32(inode->i_nlink);
5d5cbe
 	to->di_gen = cpu_to_be32(inode->i_generation);
5d5cbe
 	to->di_mode = cpu_to_be16(inode->i_mode);
5d5cbe
@@ -304,8 +328,7 @@ xfs_inode_to_disk(
5d5cbe
 
5d5cbe
 	if (from->di_version == 3) {
5d5cbe
 		to->di_changecount = cpu_to_be64(inode_peek_iversion(inode));
5d5cbe
-		to->di_crtime.t_sec = cpu_to_be32(from->di_crtime.tv_sec);
5d5cbe
-		to->di_crtime.t_nsec = cpu_to_be32(from->di_crtime.tv_nsec);
5d5cbe
+		to->di_crtime = xfs_inode_to_disk_ts(from->di_crtime);
5d5cbe
 		to->di_flags2 = cpu_to_be64(from->di_flags2);
5d5cbe
 		to->di_cowextsize = cpu_to_be32(from->di_cowextsize);
5d5cbe
 		to->di_ino = cpu_to_be64(ip->i_ino);
5d5cbe
diff --git a/libxfs/xfs_inode_buf.h b/libxfs/xfs_inode_buf.h
5d5cbe
index 0343368..6147f42 100644
5d5cbe
--- a/libxfs/xfs_inode_buf.h
5d5cbe
+++ b/libxfs/xfs_inode_buf.h
5d5cbe
@@ -76,4 +76,6 @@ xfs_failaddr_t xfs_inode_validate_cowextsize(struct xfs_mount *mp,
5d5cbe
 		uint32_t cowextsize, uint16_t mode, uint16_t flags,
5d5cbe
 		uint64_t flags2);
5d5cbe
 
5d5cbe
+struct timespec64 xfs_inode_from_disk_ts(const xfs_timestamp_t ts);
5d5cbe
+
5d5cbe
 #endif	/* __XFS_INODE_BUF_H__ */
5d5cbe
diff --git a/repair/dinode.c b/repair/dinode.c
5d5cbe
index 8fa5f88..0c40f2a 100644
5d5cbe
--- a/repair/dinode.c
5d5cbe
+++ b/repair/dinode.c
5d5cbe
@@ -2213,9 +2213,12 @@ static void
5d5cbe
 check_nsec(
5d5cbe
 	const char		*name,
5d5cbe
 	xfs_ino_t		lino,
5d5cbe
-	struct xfs_timestamp	*t,
5d5cbe
+	xfs_timestamp_t		*ts,
5d5cbe
 	int			*dirty)
5d5cbe
 {
5d5cbe
+	struct xfs_legacy_timestamp *t;
5d5cbe
+
5d5cbe
+	t = (struct xfs_legacy_timestamp *)ts;
5d5cbe
 	if (be32_to_cpu(t->t_nsec) < NSEC_PER_SEC)
5d5cbe
 		return;
5d5cbe