From a252aadfc977473e0851acf0d529c930c6e8e181 Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Tue, 10 Nov 2020 16:29:40 -0500 Subject: [PATCH] xfs: redefine xfs_timestamp_t 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 Reviewed-by: Christoph Hellwig Reviewed-by: Gao Xiang Reviewed-by: Dave Chinner Signed-off-by: Eric Sandeen --- db/field.c | 2 +- db/inode.c | 2 +- libxfs/xfs_format.h | 10 +++++--- libxfs/xfs_inode_buf.c | 54 +++++++++++++++++++++++++++++------------- libxfs/xfs_inode_buf.h | 2 ++ repair/dinode.c | 5 +++- 6 files changed, 53 insertions(+), 22 deletions(-) diff --git a/db/field.c b/db/field.c index aa0154d82..7ccfbfb13 100644 --- a/db/field.c +++ b/db/field.c @@ -350,7 +350,7 @@ const ftattr_t ftattrtab[] = { { FLDT_TIME, "time", fp_time, NULL, SI(bitsz(int32_t)), FTARG_SIGNED, NULL, NULL }, { FLDT_TIMESTAMP, "timestamp", NULL, (char *)timestamp_flds, - SI(bitsz(xfs_timestamp_t)), 0, NULL, timestamp_flds }, + SI(bitsz(struct xfs_legacy_timestamp)), 0, NULL, timestamp_flds }, { 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/inode.c b/db/inode.c index f13150c96..c65a7c747 100644 --- a/db/inode.c +++ b/db/inode.c @@ -179,7 +179,7 @@ const field_t inode_v3_flds[] = { }; -#define TOFF(f) bitize(offsetof(xfs_timestamp_t, t_ ## f)) +#define TOFF(f) bitize(offsetof(struct xfs_legacy_timestamp, 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 }, diff --git a/libxfs/xfs_format.h b/libxfs/xfs_format.h index f3fcb406b..43565a171 100644 --- a/libxfs/xfs_format.h +++ b/libxfs/xfs_format.h @@ -855,12 +855,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 e3fdd71a0..1b9f63ebe 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 @@ out_destroy_data_fork: 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 89f7bea8e..3060ecd24 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 7d55fe456..77c34801f 100644 --- a/repair/dinode.c +++ b/repair/dinode.c @@ -2123,9 +2123,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; -- 2.47.2