Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 09 Nov 2015 21:55:29 -0800
From:      Kirk McKusick <mckusick@mckusick.com>
To:        Julian Elischer <julian@freebsd.org>
Cc:        John Baldwin <jhb@freebsd.org>, "freebsd-fs@freebsd.org" <freebsd-fs@freebsd.org>, "'Jilles Tjoelker'" <jilles@stack.nl>
Subject:   Re: futimens and utimensat vs birthtime (resurected)
Message-ID:  <201511100555.tAA5tTwY071029@chez.mckusick.com>
In-Reply-To: <564182D9.8000701@freebsd.org>

next in thread | previous in thread | raw e-mail | index | archive | help
> To: John Baldwin <jhb@freebsd.org>
> Subject: Re: futimens and utimensat vs birthtime (resurected)
> Cc: Kirk McKusick <mckusick@mckusick.com>,
>         "freebsd-fs@freebsd.org" <freebsd-fs@freebsd.org>,
>         "'Jilles Tjoelker'" <jilles@stack.nl>
> From: Julian Elischer <julian@freebsd.org>
> Date: Tue, 10 Nov 2015 13:38:33 +0800
> 
> On 11/10/15 3:09 AM, John Baldwin wrote:
> 
>> I think the mask is overly complex.  utimensat() already has UTIME_OMIT.
>> I think you should just have a new 'count' argument and use UTIME_OMIT
>> when you wish to leave a timestamp alone:
>>
>> futimens3(int fd, const struct timespec *times, int ntimes);
>> utimensat5(int fd, const char *path, const struct timespec *ntimes,
>>     int ntimes, int flag);
>>
>> ntimes defines how many valid timespecs are in the times[] array.  If
>> you pass in fewer entries than is required, any missing entries at the
>> end are treated as if they were set to UTIME_OMIT (so not modified).
>> The new versions would not set birthtime implicitly.  For now I would
>> simply define birthtime as times[2].  One curious idea is if you wanted
>> to permit setting the change time (right now ctime is implicitly updated
>> to "now" when you set the time).  I think you probably don't want to
>> allow that.
>>
>> The only other thing you might consider is adding constants for the
>> array indices which might help with portability if other systems adopt
>> this interface:
>>
>> #define TIMENS_ACCESS          0
>> #define TIMENS_MODIFICATION    1
>> #define TIMENS_BIRTH           2
>> #define TIMENS_MAX			TIMENS_BIRTH
>>
>> This would let you do things like in portable-ish code (if the
>> interface itself is more widely adopted) where different systems can
>> define the layout of the array while keeping the API portable.
>>
>> 	struct timespec times[TIMENS_MAX];
>>
>> 	for (i = 0; i < nitems(times); i++)
>> 		times[i].tv_usec = UTIME_OMIT;
>> #ifdef TIMENS_BIRTH
>> 	timens[TIMENS_BIRTH] = foo;
>> #endif
>> 	futimens4(fd, times, nitems(times));
>>
>
> All makes sense, but one thing I would like to think about from the 
> old one is the ability to check for bad birthtime, unless over-ridden..
> i.e. by default it keeps birthtime < modtime.  I'm not sure whether 
> this is important to anybody.

I added the semantics of setting birthtime < modtime (rather than
leaving it at the time the file was most recently created) as that
seemed more sensible. But that semantic was just a heuristic. If the
system call wants to set it to something that does not meet that
heuristic, it absolutely should be able to do so. The heuristic
should only be used when absent birthtime being given (e.g., when
the old interface is used).

	Kirk McKusick



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201511100555.tAA5tTwY071029>