bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: utimensat round 3


From: Jim Meyering
Subject: Re: utimensat round 3
Date: Fri, 16 Oct 2009 13:56:50 +0200

Eric Blake wrote:
> Eric Blake <ebb9 <at> byu.net> writes:
>
>> The current state of the series is now pushed.  Subsequent improvements,
>> like utimensat, will come later.
>
> Here's the current state; I'll probably commit up through patch 4 within the
> next 24 hours, but spend more time hammering on cygwin with patch 5.
>
> Eric Blake (5):
>       [1/5] sys_stat: sort replacement declarations
> Matches what has been done in other headers, makes it easier to figure out
> where to declare utimensat.
>
>       [2/5] utimens: cache whether utimensat syscall works
> If we know that utimensat fails with ENOSYS, then why waste time calling it.
>
>       [3/5] utimens: let lutimens work on non-symlinks
> I'm working on adding 'touch -h' in coreutils; 'touch -h file' is much easier
> to write if I can use lutimens("file", NULL), rather than having to do lstat
> ("file"), S_ISLNK ? lutimens : utimens.  And POSIX requires utimensat with
> AT_SYMLINK_NOFOLLOW to work on non-symlinks.  So this reduces the number of
> situations where we might fail with ENOSYS, while still delaying any lstat
> calls until absolutely necessary.
>
>       [4/5] utimensat: new module
> When utimensat does not exist, this is pretty straight-forward - get to the
> right directory, then do utimens.  But when utimensat exists but might be 
> buggy
> (as is the case on Linux, due to ENOSYS and EINVAL problems within the past
> three years), it gets fun.  rpl_utimensat checks for a working native version,
> then calls local_utimensat if the native didn't work right; local_utimensat
> gets to the right directory and calls utimens; then utimens again tries the
> native utimensat, but this time with sanitized parameters to avoid EINVAL bugs
> and with caching to avoid repeated ENOSYS situations.  I've tested that it
> passes on Linux (both pre- and post-utimensat), Solaris 10, NetBSD, and mingw.
> It also passes on cygwin 1.5 (no utimensat) and 1.7 (native utimensat is good
> enough without the need of rpl_utimensat) when single stepping through a
> debugger, but not when run at speed, because of:

These all sound fine.

Note however, that test-utimens is failing for me
on an ext4 + Fedora-12-alpha-based system due to this:

    /* See comment above about this utimecmp call.  */
    ASSERT (0 <= utimecmp (BASE "file", &st2, &st1, UTIMECMP_TRUNCATE_SOURCE));

That utimecmp assertion fails almost all the time due to the
comparison of two time stamps independently down-sampled
at different resolutions.

It wasn't clear right away to me, so I wrote a program to
call clock_gettime, then utimensat-to-set-to-NOW, then stat.
Compare the clock_gettime result with st_mtime second and nanosecond values.

I see ~1-millisecond-resolution FS timestamps
and higher-resolution clock_gettime times:

d.ns: stat.ns - now.ns

ds   d.ns            stat.ns      now.ns  (now.ns[i] - now.ns[i-1])
==========================================
0  -579637         510150007    510729644 (0)
0  -656640         510150007    510806647 (77003)
0  -716861         510150007    510866868 (60221)
0  -776398         510150007    510926405 (59537)
0  -835731         510150007    510985738 (59333)
0  -934985         510150007    511084992 (99254)
0     3891 !!!     511150073    511146182 (61190)
0   -55913         511150073    511205986 (59804)
0  -115589         511150073    511265662 (59676)
0  -175220         511150073    511325293 (59631)
0  -234472         511150073    511384545 (59252)
0  -293974         511150073    511444047 (59502)
0  -353255         511150073    511503328 (59281)
0  -412612         511150073    511562685 (59357)
0  -472069         511150073    511622142 (59457)
0  -531468         511150073    511681541 (59399)
0  -591027         511150073    511741100 (59559)
0  -650239         511150073    511800312 (59212)
0  -709527         511150073    511859600 (59288)
0  -769023         511150073    511919096 (59496)
0  -828184         511150073    511978257 (59161)
0  -899541         511150073    512049614 (71357)
0  -959895         511150073    512109968 (60354)
0   -19442         512150046    512169488 (59520)
0   -78649         512150046    512228695 (59207)
0  -138054         512150046    512288100 (59405)
0  -197514         512150046    512347560 (59460)
0  -256642         512150046    512406688 (59128)
0  -315945         512150046    512465991 (59303)
0  -375208         512150046    512525254 (59263)
0  -434469         512150046    512584515 (59261)
0  -493769         512150046    512643815 (59300)
0  -553978         512150046    512704024 (60209)
0  -613284         512150046    512763330 (59306)
0  -672490         512150046    512822536 (59206)
0  -731724         512150046    512881770 (59234)
0  -790961         512150046    512941007 (59237)
0  -850143         512150046    513000189 (59182)
0  -920239         512150046    513070285 (70096)
0    20804 !!!     513150503    513129699 (59414)
0   -39840         513150503    513190343 (60644)
0   -99067         513150503    513249570 (59227)
0  -158482         513150503    513308985 (59415)
0  -217610         513150503    513368113 (59128)
...

This failure may also be due to the way utimecmp works,
but I haven't delved into that code today.




reply via email to

[Prev in Thread] Current Thread [Next in Thread]