Increase timestamp precision?

Bruce Evans brde at optusnet.com.au
Sat Feb 11 02:10:35 UTC 2012


PS:

On Sat, 11 Feb 2012, Bruce Evans wrote:

> On Fri, 10 Feb 2012, Sergey Kandaurov wrote:
>
>> On 10 February 2012 17:55, Ed Schouten <ed at 80386.nl> wrote:
>>> Hi all,
>>> 
>>> It seems the default timestamp precision sysctl
>>> (vfs.timestamp_precision) is currently set to 0 by default, meaning we
>>> don't do any sub-second timestamps on files. Looking at the code, it
>>> seems that vfs.timestamp_precision=1 will let it use a cached value with
>>> 1 / HZ precision and it looks like it should have little overhead.
>>> 
>>> Would anyone object if I were to change the default from 0 to 1?
>
> Sure.  The setting of 1 is too buggy to use in its current implementation.
> I don't know of any fixed version, so there is little experience with
> a usable version.  I also wouldn't use getnanotime() for anything.
> But I like nanotime().

[ ... the bugs are that it gives nanoseconds precision with garbage in the
low bits, and shares an old bug with a setting of 0 (TSP_SEC) ]

Other bugs near here:
- vfs.timestamp_precision is still global, so you can't change the default
   for individual mount points or even for individual vfs's.  The global
   is only good enough for a quick hack.
- touch(1) normally uses gettimeofday() and utimes().  Thus it normally
   gives microseconds precision and hopefully close to microseconds
   accuracy (if you are using ntpd).  But when utimes() fails due to
   insufficient security and the user didn't specify a time, touch(1)
   falls back to using utimes() with a null timeptr, to ask the kernel
   to use the current time.  The kernel uses vfs_timestamp() for this,
   so it sets times incompatibitly with touch(1) unless
   vfs.timestamp_precision=2 (TSP_USEC).  The kernel used to use
   microtime() for this, but it was changed in 2009 to use
   vfs_timestamp(), with no reason given in its log message except a
   cryptic pointer to a Debian PR.  The bug is mostly in touch(1).
- the recently-removed fallback to setting times by writing in touch(1)
   gave another incompatible way of setting times.

Timstamping bugs not so near here:
- POSIX.1-1988 avoided the design error and unportability of timevals
   by inventing timespecs.  It failed to invent an interfaces to set
   these.  It only has utime(), which only sets times in seconds.
- POSIX.1-2001 restored the design error of timevals, and utimes()
   to set them (but utimes() was marked as legacy).  It still failed to
   invent an interface to set its own timespecs.
- POSIX is apparently inventing futimesat().  This only sets timevals.
   POSIX is apparently still failing to invent an interface to set its
   own timespecs.  Any utime()-like interface invented after timespecs
   should support timespecs, with setting timevals only supported by
   compatibility cruft in this interface.
- FreeBSD also has birthtimes, but no way to set them.  Any utime()-like
   interface invented after birthtimes should support them.  FreeBSD's
   man page says essentially this.  futimesat() is unfortunately being
   standardized, so it can't be this syscall.
- in the man page, the times arg is declared as "*times" for everything
   except futimesat().  For the latter, it is declared as times[2].  This
   is a further regression in the spelling of the arg.  utime(2) has
   a better API (struct instead of array) and a better spelling of the
   arg (timep).  POSIX.1-2001 uses "times" for the utime() and times[2]
   for utimes().
- I also wish for a way to set ctimes.  Without this, metadata cannot
   be restored from backups.  I use a hack to restore ctimes by abusing
   utime*().

Bruce


More information about the freebsd-fs mailing list