Date: Mon, 6 Aug 2018 10:46:42 +1000 (EST) From: Bruce Evans <brde@optusnet.com.au> To: Bruce Evans <brde@optusnet.com.au> Cc: Ian Lepore <ian@freebsd.org>, Warner Losh <imp@bsdimp.com>, "Rodney W. Grimes" <rgrimes@freebsd.org>, Conrad Meyer <cem@freebsd.org>, src-committers <src-committers@freebsd.org>, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: Re: svn commit: r337334 - head/lib/libc/sys Message-ID: <20180806095604.J860@besplex.bde.org> In-Reply-To: <20180806074507.E920@besplex.bde.org> References: <201808042208.w74M8OmD057603@repo.freebsd.org> <201808042224.w74MOgLi095274@pdx.rh.CN85.dnsmgr.net> <CANCZdfpWh25X%2BkKsbrdNY697Ex%2BxG95crVRgKqVQpfrqZO_CoA@mail.gmail.com> <1533478958.9860.18.camel@freebsd.org> <20180806074507.E920@besplex.bde.org>
next in thread | previous in thread | raw e-mail | index | archive | help
On Mon, 6 Aug 2018, Bruce Evans wrote: > ... > I forgot about FAT times, and only remembered that utc_offset() was used > for RTC drivers. I thought that utc_offset() is 0 unless something sets > the timezone to nonzero or the RTC is on local time (wall_cmos_clock case). > However, since the kernel needs the timezone for FAT times, it must be > known even if the RTC is on UTC time. Now I don't see how FAT times can > even work unless the wall_cmos_clock. They are just the UTC minus > utc_offset(), where utc_offset() is > > (tz_minuteswest * 60 + (wall_cmos_clock ? adjkerntz : 0)) > > Here wall_cmos_clock is only for managing the RTC offset. It must be 0 > unless the RTC is on local time. But then either FAT times or RTC times > must be broken except in the Greenwich meridian. Otherwise, tz_minuteswest > must be nonzero to ajust FAT times right, but this makes utc_offset() > unusable for the RTC offset. I verified the brokenness: - adjkerntz() normally leaves tz_minuteswest as 0. I verified that it does this when there is a nonzero dst adjustment. dst adjustments are folded into machdep.adjkerntz. - when wall_cmos_clock == 0, adjkerntz(8) does little or nothing, so all adjustments are 0, so utc_offset() is 0, so FAT times are broken except in the Greenwich meridian. The broken FAT times are not completely obvious, since getting and setting them use the same wrong offset of 0, so the times appear to be correct when displayed on FreeBSD. The are only obviously wrong when displayed on another system with non-broken FAT times, perhaps by rebooting to the other system or by moving removable media to such a system. FAT times are used by other file systems. I checked this in FreeBSD-9 so as to find axed file systems. The were used by smbfs, nwfs and msdosfs. Now they are only used by msdosfs. I never liked de-deduplicating their implementation into an over-engineered version with especially excessive handling for leap years. Leap year handling is unimportant compared with offset handling. tz_minuteswest is used by compatibility code. It cannot usefully be removed from the native version, since non-native syscalls use it and non-native applications might use it. Of course, it must have a correct value to work in compatibility. Its normal value of 0 breaks compatibility code much like the bugs in utc_offset() breaks FAT time. It is used in the following compatibility code: - amd64 linux32 linux_gettimeofday(). Like native gettimeofday(). It also reconstructs the dstflag part of the timezone struct. If linux drops this, then strict compatiility requires the support to depend on the linux version. - amd64 linux32 linux_settimeofday(). Like native settimeofday(). Has invisible reference to tz_minuteswest hidden in assignment of timezones. I only grepped for tz_minuteswest and only checked this indirect reference. - freebsd32 freebsd32_gettimeofday(). Similarly, except we control it, so can avoid needing version checks by not dropping support. - dev/tws/tws_services.h. This uses utc_offset() for FreeBSD-7 and later, and its reference to tz_minuteswest is only explicit for older versions where it open-codes utc_offset() with bug for bug compatibility except for adding style bugs. - smbfs. This uses FAT times, and in nearby code it uses tzoff for the offset and has commented-out code with an open-coded fully-buggy utc_offset(). - ibcs2 xenix_ftime(). This is similar to gettimeofday(). Bruce
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20180806095604.J860>