From owner-dev-commits-src-main@freebsd.org Fri May 7 07:49:19 2021 Return-Path: Delivered-To: dev-commits-src-main@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id 997C55FB028; Fri, 7 May 2021 07:49:19 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4Fc2dq3x8tz3pJR; Fri, 7 May 2021 07:49:19 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 75A312772A; Fri, 7 May 2021 07:49:19 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 1477nJvg011723; Fri, 7 May 2021 07:49:19 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 1477nJaH011722; Fri, 7 May 2021 07:49:19 GMT (envelope-from git) Date: Fri, 7 May 2021 07:49:19 GMT Message-Id: <202105070749.1477nJaH011722@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Fedor Uporov Subject: git: c40a160fd0aa - main - Make inode extra time fields updating logic more closer to linux. MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: fsu X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: c40a160fd0aa48ceb6e243c72cb8b9b59dc4e13d Auto-Submitted: auto-generated X-BeenThere: dev-commits-src-main@freebsd.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Commit messages for the main branch of the src repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 07 May 2021 07:49:19 -0000 The branch main has been updated by fsu: URL: https://cgit.FreeBSD.org/src/commit/?id=c40a160fd0aa48ceb6e243c72cb8b9b59dc4e13d commit c40a160fd0aa48ceb6e243c72cb8b9b59dc4e13d Author: Fedor Uporov AuthorDate: 2021-05-07 07:46:55 +0000 Commit: Fedor Uporov CommitDate: 2021-05-07 07:46:55 +0000 Make inode extra time fields updating logic more closer to linux. Found using pjdfstest: pjdfstest/tests/utimensat/09.t Reviewed by: pfg MFC after: 2 weeks Differential Revision: https://reviews.freebsd.org/D29933 --- sys/fs/ext2fs/ext2_inode_cnv.c | 53 ++++++++++++++++++++++++++++++------------ sys/fs/ext2fs/inode.h | 9 +++---- 2 files changed, 43 insertions(+), 19 deletions(-) diff --git a/sys/fs/ext2fs/ext2_inode_cnv.c b/sys/fs/ext2fs/ext2_inode_cnv.c index 3c79e1162896..5ca00f3be050 100644 --- a/sys/fs/ext2fs/ext2_inode_cnv.c +++ b/sys/fs/ext2fs/ext2_inode_cnv.c @@ -94,8 +94,6 @@ ext2_print_inode(struct inode *in) } #endif /* EXT2FS_PRINT_EXTENTS */ -#define XTIME_TO_NSEC(x) ((le32toh(x) & EXT3_NSEC_MASK) >> 2) - static inline bool ext2_old_valid_dev(dev_t dev) { @@ -132,6 +130,15 @@ ext2_new_decode_dev(uint32_t dev) return (makedev(maj, min)); } +static void +ext2_decode_extra_time(ext_time_t *sec, int32_t *nsec, uint32_t extra) +{ + if (extra & htole32(EXT3_EPOCH_MASK)) + *sec += (uint64_t)(le32toh(extra) & EXT3_EPOCH_MASK) << 32; + + *nsec = (le32toh(extra) & EXT3_NSEC_MASK) >> EXT3_EPOCH_BITS; +} + /* * raw ext2 inode LE to host inode conversion */ @@ -177,15 +184,19 @@ ext2_ei2i(struct ext2fs_dinode *ei, struct inode *ip) ip->i_size = le32toh(ei->e2di_size); if (S_ISREG(ip->i_mode)) ip->i_size |= (uint64_t)le32toh(ei->e2di_size_high) << 32; - ip->i_atime = le32toh(ei->e2di_atime); - ip->i_mtime = le32toh(ei->e2di_mtime); - ip->i_ctime = le32toh(ei->e2di_ctime); + ip->i_atime = (signed)le32toh(ei->e2di_atime); + ip->i_mtime = (signed)le32toh(ei->e2di_mtime); + ip->i_ctime = (signed)le32toh(ei->e2di_ctime); if (E2DI_HAS_XTIME(ip)) { - ip->i_atimensec = XTIME_TO_NSEC(ei->e2di_atime_extra); - ip->i_mtimensec = XTIME_TO_NSEC(ei->e2di_mtime_extra); - ip->i_ctimensec = XTIME_TO_NSEC(ei->e2di_ctime_extra); - ip->i_birthtime = le32toh(ei->e2di_crtime); - ip->i_birthnsec = XTIME_TO_NSEC(ei->e2di_crtime_extra); + ext2_decode_extra_time(&ip->i_atime, &ip->i_atimensec, + ei->e2di_atime_extra); + ext2_decode_extra_time(&ip->i_mtime, &ip->i_mtimensec, + ei->e2di_mtime_extra); + ext2_decode_extra_time(&ip->i_ctime, &ip->i_ctimensec, + ei->e2di_ctime_extra); + ip->i_birthtime = (signed)le32toh(ei->e2di_crtime); + ext2_decode_extra_time(&ip->i_birthtime, &ip->i_birthnsec, + ei->e2di_crtime_extra); } ip->i_flags = 0; ei_flags_host = le32toh(ei->e2di_flags); @@ -226,7 +237,15 @@ ext2_ei2i(struct ext2fs_dinode *ei, struct inode *ip) return (ext2_ei_csum_verify(ip, ei)); } -#define NSEC_TO_XTIME(t) (htole32((t << 2) & EXT3_NSEC_MASK)) +static uint32_t +ext2_encode_extra_time(int64_t sec, int32_t nsec) +{ + uint32_t extra; + + extra = ((sec - (int32_t)sec) >> 32) & EXT3_EPOCH_MASK; + + return (htole32(extra | (nsec << EXT3_EPOCH_BITS))); +} /* * inode to raw ext2 LE inode conversion @@ -253,11 +272,15 @@ ext2_i2ei(struct inode *ip, struct ext2fs_dinode *ei) ei->e2di_dtime = htole32(le16toh(ei->e2di_nlink) ? 0 : le32toh(ei->e2di_mtime)); if (E2DI_HAS_XTIME(ip)) { - ei->e2di_ctime_extra = NSEC_TO_XTIME(ip->i_ctimensec); - ei->e2di_mtime_extra = NSEC_TO_XTIME(ip->i_mtimensec); - ei->e2di_atime_extra = NSEC_TO_XTIME(ip->i_atimensec); + ei->e2di_ctime_extra = ext2_encode_extra_time(ip->i_ctime, + ip->i_ctimensec); + ei->e2di_mtime_extra = ext2_encode_extra_time(ip->i_mtime, + ip->i_mtimensec); + ei->e2di_atime_extra = ext2_encode_extra_time(ip->i_atime, + ip->i_atimensec); ei->e2di_crtime = htole32(ip->i_birthtime); - ei->e2di_crtime_extra = NSEC_TO_XTIME(ip->i_birthnsec); + ei->e2di_crtime_extra = ext2_encode_extra_time(ip->i_birthtime, + ip->i_birthnsec); } /* Keep these in host endian for a while since they change a lot */ ei->e2di_flags = 0; diff --git a/sys/fs/ext2fs/inode.h b/sys/fs/ext2fs/inode.h index e6af6ef8d5b6..25e77acc3a9d 100644 --- a/sys/fs/ext2fs/inode.h +++ b/sys/fs/ext2fs/inode.h @@ -62,6 +62,7 @@ typedef uint32_t e2fs_daddr_t; typedef int64_t e2fs_lbn_t; typedef int64_t e4fs_daddr_t; +typedef int64_t ext_time_t; /* * The inode is used to describe each active (or recently active) file in the @@ -99,10 +100,10 @@ struct inode { uint32_t i_gid; /* File group. */ uint64_t i_size; /* File byte count. */ uint64_t i_blocks; /* Blocks actually held. */ - int32_t i_atime; /* Last access time. */ - int32_t i_mtime; /* Last modified time. */ - int32_t i_ctime; /* Last inode change time. */ - int32_t i_birthtime; /* Inode creation time. */ + ext_time_t i_atime; /* Last access time. */ + ext_time_t i_mtime; /* Last modified time. */ + ext_time_t i_ctime; /* Last inode change time. */ + ext_time_t i_birthtime; /* Inode creation time. */ int32_t i_mtimensec; /* Last modified time. */ int32_t i_atimensec; /* Last access time. */ int32_t i_ctimensec; /* Last inode change time. */