From nobody Tue Jun 9 21:27:02 2026 X-Original-To: dev-commits-src-branches@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4gZhnL6q9jz6ggg5 for ; Tue, 09 Jun 2026 21:27:02 +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 "R13" (not verified)) by mx1.freebsd.org (Postfix) with ESMTPS id 4gZhnL40t1z3C07 for ; Tue, 09 Jun 2026 21:27:02 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1781040422; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=eccsamHMzHYAN93xZPjTWkE/PiN/trYKAmI1JsRBPL0=; b=vNbMui50v20qWAAJIRMk/Op4YUHrwVqMGDef+uYuvAsPTu0KV1M7pSL2hjYPERIhOljvv/ BNJe3q3eoee4xFSjhGWlIhN6dvhHe8psJrcTCkyFDVZv2gepR2jnrsrXA/pCUokwxappQ3 q7WUYYMBJDHB2PLUqi/m+u7VGG/8gPQotzVmGcMYVp42TXxtRhTp1gqsUOf4m1t84QtNXb ZXKhQ+h34WxCY+O2JuFvjn1ycBoeEHny311MoT8M8syaFilyX+7oUY9mcHJPG7YDcZx2Dc NyuQjp7FMkmSzC2VZcvx6GKiyaGyy+NesaIi5//EDXytH43Z1yCXMDoCnqY+nA== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1781040422; a=rsa-sha256; cv=none; b=MyhM6cfOpNgEg4PEyjf9NMSQVAmMmgumP6cSAmWZzZRvuQYH7o4OxbxyOpxYu5ppZAjj3A xKfKOJc9xFvkby7V3S7TDkVKgDaJbh/NMAqjL7PRbxmHKBjRPywkGfkp7iEQJPSWDD9a0C zwkWRtNsUaJiGoAytLu8BrsmHEbp7uhRHPAMlyEGq92CCUvSpx89+rpsZ0YOLoT4r0C0kK R6eeJbcrEKf+99xytX2IMIMtW/Z0QSdpxhOGFdu+FZAT13M23++UfL1I/SySidUvwi+w17 tyDyb7aEkU1PNKOzNstlYtulRHB+IzHPN3tE6jz+NGXPwNEsAKQ8776OGj51+w== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1781040422; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=eccsamHMzHYAN93xZPjTWkE/PiN/trYKAmI1JsRBPL0=; b=IClOCFDTmvMm5sdpOEAR+fSbCjEqVtjSoYqykYMpBxExX1MfkAb1uHZuSEwZGyalI0QOda R6CUMNhsk62zVlzV7dDyz3x+gTE90VT7uZG7BpLo4ED6PTuskGC7SV/F9Lh5fzu9HlHPEF x9z8ywLRJ4ymfp4KhrVCpkrmpboLAndrXf5VW7CSr+x9+vRO277LKT77HaW3iSjsQAy3AE ndkVJnCLaOV3mZ8Nobxh7YX5b52OqFhZ5UFQ7Yd7rtWJJjN45/KkAfZ8yHccEZdszbBnzi IM789KT0Jyo0AeoutY2Kdnp4Whq3tpzBaTa+uKcUWuYC+bOn3LXtuvEvnHZCYA== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) by mxrelay.nyi.freebsd.org (Postfix) with ESMTP id 4gZhnL3QpPzs5v for ; Tue, 09 Jun 2026 21:27:02 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 24868 by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Tue, 09 Jun 2026 21:27:02 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Kirk McKusick Subject: git: a64877b140fe - stable/15 - Avoid incorrect UFS1 timestamp corrections when system clock fails at boot. List-Id: Commits to the stable branches of the FreeBSD src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-branches List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-branches@freebsd.org Sender: owner-dev-commits-src-branches@FreeBSD.org List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: mckusick X-Git-Repository: src X-Git-Refname: refs/heads/stable/15 X-Git-Reftype: branch X-Git-Commit: a64877b140fe0bf374cc96c95f374894c1627a32 Auto-Submitted: auto-generated Date: Tue, 09 Jun 2026 21:27:02 +0000 Message-Id: <6a288526.24868.173d902d@gitrepo.freebsd.org> The branch stable/15 has been updated by mckusick: URL: https://cgit.FreeBSD.org/src/commit/?id=a64877b140fe0bf374cc96c95f374894c1627a32 commit a64877b140fe0bf374cc96c95f374894c1627a32 Author: Kirk McKusick AuthorDate: 2026-06-01 23:48:21 +0000 Commit: Kirk McKusick CommitDate: 2026-06-09 21:26:51 +0000 Avoid incorrect UFS1 timestamp corrections when system clock fails at boot. Git 1111a44301da - main - Defer the January 19, 2038 date limit in UFS1 file systems to February 7, 2106 - did so by changing the UFS1 32-bit signed timestamps to unsigned. With this change, time stamps from before January 1, 1970 went from being negative numbers to large positive numbers implying times in the future. When such a time stamp is encountered when an inode is read into memory or when it is encountered by fsck, its timestamp is replaced with the kernel's current time. Andre Albsmeier reported that he had a machine reboot after a power failure and the battery that maintained its real-time clock had died. The result was that the system booted with the time set to five years earlier (absent a real-time clock value, the boot ROM used the time that the boot ROM had last been updated). The net result was that fsck reset the time stamps of all files newer than five years old to the five year old time. Andres's original request was for a flag in the file system superblock to say that there are no timestamps from before 1970 in the file system, so there shouldn't be anything to fix because of the signed to unsigned switch. But this assumes that no one every does an rsync or extracts a tar file or restores a dump that introduces an incorrect time stamp on their system. So this approach was not taken. This change compares the system's version of the current time to the last modification time in the file system superblock. If the current time is earlier than that time then use the last modification time in the superblock as the value for the current time. There should be no files in the file system with times newer than the last modification time in the superblock. The superblock time stamp is updated in the in-memory superblock every time any change is made to anything in the file system. The superblock is written to the disk every 30 seconds, so it may be off by up to 30 seconds plus the time it sits in the disk cache waiting to be written if the system has an unclean shutdown (such as a power failure). Thus, the worst case scenario with this change is that files written in the last 30 seconds plus disk cache delay time before the crash may have their times adjusted back by up to 30 seconds plus the disk cache delay time. Requested by: Andre Albsmeier Approved by: kib Reviewed by: kib, imp, Andre Albsmeier Differential Revision: https://reviews.freebsd.org/D57371 Sponsored-by: Netflix (cherry picked from commit 553ef188f7ecc23a384bd7ef1f3d5015fb8661da) --- lib/libufs/inode.c | 17 +++++++++-------- sbin/fsck_ffs/inode.c | 3 ++- sys/ufs/ffs/ffs_vfsops.c | 7 ++++--- 3 files changed, 15 insertions(+), 12 deletions(-) diff --git a/lib/libufs/inode.c b/lib/libufs/inode.c index bc4d99c66203..a93e1b085342 100644 --- a/lib/libufs/inode.c +++ b/lib/libufs/inode.c @@ -57,7 +57,8 @@ getinode(struct uufsd *disk, union dinodep *dp, ino_t inum) ino_t min, max; caddr_t inoblock; struct fs *fs; - struct timespec now; + struct timespec time; + time_t now; ERROR(disk, NULL); @@ -70,10 +71,11 @@ getinode(struct uufsd *disk, union dinodep *dp, ino_t inum) min = disk->d_inomin; max = disk->d_inomax; - if (clock_gettime(CLOCK_REALTIME_FAST, &now) != 0) { - ERROR(disk, "cannot get current time of day"); - return (-1); - } + if (clock_gettime(CLOCK_REALTIME_FAST, &time) == 0 && + time.tv_sec > fs->fs_time) + now = time.tv_sec; + else + now = fs->fs_time; if (inum >= min && inum < max) goto gotit; bread(disk, fsbtodb(fs, ino_to_fsba(fs, inum)), inoblock, @@ -83,7 +85,7 @@ getinode(struct uufsd *disk, union dinodep *dp, ino_t inum) gotit: switch (disk->d_ufs) { case 1: disk->d_dp.dp1 = &((struct ufs1_dinode *)inoblock)[inum - min]; - if (ffs_oldfscompat_inode_read(fs, disk->d_dp, now.tv_sec)) + if (ffs_oldfscompat_inode_read(fs, disk->d_dp, now)) putinode(disk); if (dp != NULL) *dp = disk->d_dp; @@ -93,8 +95,7 @@ gotit: switch (disk->d_ufs) { if (dp != NULL) *dp = disk->d_dp; if (ffs_verify_dinode_ckhash(fs, disk->d_dp.dp2) == 0) { - if (ffs_oldfscompat_inode_read(fs, disk->d_dp, - now.tv_sec)) + if (ffs_oldfscompat_inode_read(fs, disk->d_dp, now)) putinode(disk); return (0); } diff --git a/sbin/fsck_ffs/inode.c b/sbin/fsck_ffs/inode.c index b30e3aa5068b..f8e32bf4b157 100644 --- a/sbin/fsck_ffs/inode.c +++ b/sbin/fsck_ffs/inode.c @@ -647,7 +647,8 @@ setinodebuf(int cg, ino_t inosused) * If for some reason getting the time fails, we will use * the last time that the superblock was updated. */ - if (clock_gettime(CLOCK_REALTIME_FAST, &time) == 0) + if (clock_gettime(CLOCK_REALTIME_FAST, &time) == 0 && + time.tv_sec > sblock.fs_time) now = time.tv_sec; else now = sblock.fs_time; diff --git a/sys/ufs/ffs/ffs_vfsops.c b/sys/ufs/ffs/ffs_vfsops.c index 75f5fe716c31..e3f9270c2f49 100644 --- a/sys/ufs/ffs/ffs_vfsops.c +++ b/sys/ufs/ffs/ffs_vfsops.c @@ -189,8 +189,10 @@ ffs_load_inode(struct buf *bp, struct inode *ip, struct fs *fs, ino_t ino) { struct ufs1_dinode *dip1; struct ufs2_dinode *dip2; + time_t now; int error; + now = time_second > fs->fs_time ? time_second : fs->fs_time; if (I_IS_UFS1(ip)) { dip1 = ip->i_din1; *dip1 = @@ -203,7 +205,7 @@ ffs_load_inode(struct buf *bp, struct inode *ip, struct fs *fs, ino_t ino) ip->i_gen = dip1->di_gen; ip->i_uid = dip1->di_uid; ip->i_gid = dip1->di_gid; - if (ffs_oldfscompat_inode_read(fs, ip->i_dp, time_second) && + if (ffs_oldfscompat_inode_read(fs, ip->i_dp, now) && fs->fs_ronly == 0) UFS_INODE_SET_FLAG(ip, IN_MODIFIED); return (0); @@ -225,8 +227,7 @@ ffs_load_inode(struct buf *bp, struct inode *ip, struct fs *fs, ino_t ino) ip->i_gen = dip2->di_gen; ip->i_uid = dip2->di_uid; ip->i_gid = dip2->di_gid; - if (ffs_oldfscompat_inode_read(fs, ip->i_dp, time_second) && - fs->fs_ronly == 0) + if (ffs_oldfscompat_inode_read(fs, ip->i_dp, now) && fs->fs_ronly == 0) UFS_INODE_SET_FLAG(ip, IN_MODIFIED); return (0); }