rounding timestamps (or not)

Björn Jacke bj at SerNet.DE
Mon Sep 13 17:07:50 MDT 2010


looks like the explaination of the problem wasn't very clear :-)

Some examples to illustrate what I mean:

case 1) if we have a filesystem with 1s timestamp granularity and a client for
example sets the time of a file to 10:10:10.4 then the filestamp will be set to
10:10:10 (CORRECT IMHO) (if client later on requests the filetime it's not
newer than the one he set it to)

case 2) if we have a filesystem with 1s timestamp granularity and a client for
example sets the time of a file to 10:10:10.5 then the filestamp will be set to
10:10:11 because we round up (a PROBLEM!?) (if client later on requests
the filetime it *IS* newer than the one he set it to)

case 3) if we have a filesystem with µs timestamp granularity (or don't have
the utimensat() function) and a client for example sets the time of a file to
10:10:10.0000004 then the filestamp will be set to 10:10:10.000000 (CORRECT
IMHO) ...

case 4) if we have a filesystem with µs timestamp granularity (or don't have
the utimensat() function) and a client for example sets the time of a file to
10:10:10.0000005 then the filestamp will ALSO be set to 10:10:10.000000 because
rounding is not performed (which is CORRECT IMHO) ...


So in the end this means round_timespec() just rounds in case of 1s granularity
but we really want to truncate and not to round anyway in smb_set_file_time(),
don't we?

Björn


On 2010-09-13 at 14:21 -0700 Jeremy Allison sent off:
> On Mon, Sep 13, 2010 at 12:11:23PM +0200, Björn Jacke wrote:
> > Hi,
> > 
> > in round_timespec() from source3/lib/time.c there is rounding being done for
> > second resolution but for usec resulition therer is only being truncated.
> > Currently the only user of round_timespec() is smb_set_file_time. Even if it's
> > it looks like one microsecond more or less make no big difference here, the
> > rounding at this place should probably be made consistent.
> 
> This is a more subtle problem than it looks. It depends
> what the kernel does with a timespec where the number
> of tv_nsec is greater than 1second. Hopefully it will
> do the rounding correctly itself, so the code should
> work as is.
> 
> The current code for round_timespec_to_usec essentially
> divides the nsec value by 1000, then miltiplies by 1000,
> essentially losing any resolution less than 1usec.
> 
> So I guess the patch to do this in userspace should be
> (attached).
> 
> Jeremy.

> diff --git a/source3/lib/time.c b/source3/lib/time.c
> index fad5d97..eba358f 100644
> --- a/source3/lib/time.c
> +++ b/source3/lib/time.c
> @@ -409,6 +409,10 @@ void round_timespec_to_usec(struct timespec *ts)
>  {
>  	struct timeval tv = convert_timespec_to_timeval(*ts);
>  	*ts = convert_timeval_to_timespec(tv);
> +	while (ts->tv_nsec > 1000000000) {
> +		ts->tv_sec += 1;
> +		ts->tv_nsec -= 1000000000;
> +	}
>  }
>  
>  /****************************************************************************


-- 
SerNet GmbH, Bahnhofsallee 1b, 37081 Göttingen
phone: +49-551-370000-0, fax: +49-551-370000-9
AG Göttingen, HRB 2816, GF: Dr. Johannes Loxen


More information about the samba-technical mailing list