[Top][All Lists]
[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 14:01:08 +0200 |
Jim Meyering wrote:
...
> 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.
FYI, here's the program I used to print the above table:
#define _GNU_SOURCE 1
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <time.h>
#include <fcntl.h>
#define BASE "test-utimens.t"
#define ASSERT(expr) \
do \
{ \
if (!(expr)) \
{ \
fprintf (stderr, "%s:%d: assertion failed\n", __FILE__, __LINE__); \
fflush (stderr); \
abort (); \
} \
} \
while (0)
#define func(a,b) utimensat(AT_FDCWD,a,b,0)
int
main (int argc, char **argv)
{
if (argc < 2)
abort ();
int signed_n = atoi (argv[1]);
if (signed_n < 0)
abort ();
unsigned int n = signed_n;
ASSERT (close (creat (BASE "file", 0600)) == 0);
unsigned long prev_now_ns = 0;
printf ("ds %8s %3s %12s %11s\n", "d.ns", "", "stat.ns", "now.ns");
printf ("==========================================\n");
unsigned int i;
for (i = 0; i < n; i++)
{
struct stat st3;
struct timespec ts[2] = { {0, UTIME_OMIT}, {0, UTIME_NOW} };
struct timespec now;
clock_gettime (CLOCK_REALTIME, &now);
ASSERT (func (BASE "file", ts) == 0);
ASSERT (stat (BASE "file", &st3) == 0);
long s_diff = st3.st_mtime - now.tv_sec;
long ns_diff = st3.st_mtim.tv_nsec - now.tv_nsec;
long delta_now = (i == 0 ? 0 : now.tv_nsec - prev_now_ns);
printf ("%ld %8ld %3s %12ld %12ld (%ld)\n", s_diff, ns_diff,
s_diff || 0 < ns_diff ? "!!!" : "",
st3.st_mtim.tv_nsec, now.tv_nsec, delta_now);
prev_now_ns = now.tv_nsec;
}
/* Cleanup. */
ASSERT (unlink (BASE "file") == 0);
return 0;
}
------------------------------------------------------
I compiled and ran it like this:
gcc -W -Wall -Wformat -Wextra utimens.c -lrt && ./a.out 100
Note: not intended to be portable.
- utimensat round 1, Eric Blake, 2009/10/08
- Re: utimensat round 2, Eric Blake, 2009/10/10
- Re: utimensat round 2, Eric Blake, 2009/10/10
- Re: utimensat round 3, Eric Blake, 2009/10/15
- Re: utimensat round 3, Jim Meyering, 2009/10/16
- Re: utimensat round 3,
Jim Meyering <=
- Re: utimensat round 3, Eric Blake, 2009/10/16
- Re: utimensat round 3, Jim Meyering, 2009/10/16
- Re: utimensat round 3, Eric Blake, 2009/10/16
- Re: utimensat round 3, Jim Meyering, 2009/10/16
- Re: utimensat round 4, Eric Blake, 2009/10/20
- Re: utimensat round 4, Jim Meyering, 2009/10/21