Increase timestamp precision?

Sergey Kandaurov pluknet at gmail.com
Sat Feb 11 07:20:30 UTC 2012


On 11 February 2012 06:10, Bruce Evans <brde at optusnet.com.au> wrote:
> 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.

Agreed. :-/
That is the main obstacle in my pov why it was not changed yet.

> - 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.

In POSIX-2008 touch description mentions now that touch shall perform
actions equivalent to futimens() or utimensat() (see below) depending
on whether the specified file exists. It also introduces the concept of
finegrained timestamps - a fractional part of second like:
touch -d "2007-11-12 10:15:30.002Z"
-d is a new way to specify your own time but in ISO 8601:2000 format

> 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.[...]  futimesat() is unfortunately being
>  standardized[..]

POSIX.1-2008 invented two *utimes() syscalls since then which both operate
on timespecs.
I implemented them a year ago, but failed to commit yet for some reason,
particularity because of overcomplicated utimes(2) man page.
- futimens() is like our futimes() but works with timespec();
- utimensat() is like our futimesat(). It is "ours" because it was never
standardized. Our manpage for futimesat() only mentions that it "follows
The Open Group Extended API Set 2 specification."
Linux manpage provides somewhat better history:
 This system call is nonstandard.  It was implemented from a specification that
 was proposed for POSIX.1, but that specification was replaced by the one for
 utimensat(2).

utimensat() diverges from futimesat() by enabling usage of timespec and
addition of the optional flag with only one existing bit that follows other
*at() family convention:
     AT_SYMLINK_NOFOLLOW
             If path names a symbolic link, the symbolic link's dates are
             changed.

-- 
wbr,
pluknet


More information about the freebsd-fs mailing list