Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 10 Nov 2015 13:38:33 +0800
From:      Julian Elischer <julian@freebsd.org>
To:        John Baldwin <jhb@freebsd.org>
Cc:        Kirk McKusick <mckusick@mckusick.com>, "freebsd-fs@freebsd.org" <freebsd-fs@freebsd.org>, "'Jilles Tjoelker'" <jilles@stack.nl>
Subject:   Re: futimens and utimensat vs birthtime (resurected)
Message-ID:  <564182D9.8000701@freebsd.org>
In-Reply-To: <10503657.4i3LlcO4Z3@ralph.baldwin.cx>
References:  <201508142122.t7ELMPjR002452@chez.mckusick.com> <56401002.8020909@freebsd.org> <10503657.4i3LlcO4Z3@ralph.baldwin.cx>

next in thread | previous in thread | raw e-mail | index | archive | help
On 11/10/15 3:09 AM, John Baldwin wrote:
> On Monday, November 09, 2015 11:16:18 AM Julian Elischer wrote:
>> On 8/15/15 5:22 AM, Kirk McKusick wrote:
>>>> From: John Baldwin <jhb@freebsd.org>
>>>> To: freebsd-current@freebsd.org
>>>> Subject: Re: futimens and utimensat vs birthtime
>>>> Date: Fri, 14 Aug 2015 10:39:41 -0700
>>>> Cc: "freebsd-fs@freebsd.org" <freebsd-fs@freebsd.org>,
>>>>           "'Jilles Tjoelker'" <jilles@stack.nl>
>>>>
>>>> On Friday, August 14, 2015 10:46:10 PM Julian Elischer wrote:
>>>>> I would like to implement this call. but would like input as to it's
>>>>> nature.
>>>>> The code inside the system would already appear to support handling
>>>>> three elements, though it needs some scrutiny,
>>>>> so all that is needed is a system call with the ability to set the
>>>>> birthtime directly.
>>>>>
>>>>> Whether it should take the form of the existing calls but expecting
>>>>> three items is up for discussion.
>>>>> Maybe teh addition of a flags argument to specify which items are
>>>>> present and which to set.
>>>>>
>>>>> ideas?
>>>> I believe these should be new calls.  Only utimensat() provides a flag
>>>> argument, but it is reserved for AT_* flags.  I would be fine with
>>>> something like futimens3() and utimensat3() (where 3 means "three
>>>> timespecs").  Jilles implemented futimens() and utimensat(), so he
>>>> might have ideas as well.  I would probably stick the birth time in
>>>> the third (final) timespec slot to make it easier to update new code
>>>> (you can use an #ifdef just around ts[2] without having to #ifdef the
>>>> entire block).
>>>>
>>> I concur with John's suggestion. Add a new system call with three
>>> argument set of times specifying birthtime as the last one. I
>>> proposed doing this when I added birthtime, but did not as the
>>> sentiment at the time was that it would gratuitously make FreeBSD
>>> written applications less portable if they used this new non-standard
>>> system call.
>> time has passed and I would like to get back to this:
>> There was some feedback last time. Taking that into account:
>>
>> One problem with the '3 arg' version is that we have to reinvent it
>> again if we get a 4th.
>> We could make something like the following:
>>
>> It has been suggested that a 4th entry might be "last archive time"
>> and that
>> "time created on this filesystem" and "file created first time (ever)"
>> might also
>> be separate in some systems. (as examples of why 3 might not be enough)
>>
>> the syscall name is also not decided.
>> one suggested form is:
>> $name (int fd, int32 flags/mask, const struct timespec *arrayptr[]);
>>
>> vs the current:
>> utimensat(int fd, const char *path, const struct timespec times[2],
>>            int flag);
>>
>> where mask is:
>> ---
>> 0x01 disable_heuristic
>> 0x02 AT_SYMLINK_NOFOLLOW
>> 0x04-0x08 unused
>> --  times present---
>> 0x10 access time
>> 0x20 mod time
>> 0x40 birth time
>> 0x80 archive time
>> 0x100 conception time
>> 0x200-on reserverd for future times
>>
>> any bit not set in 0x010-on is not represented in the array.
>> no bits would be a nop (the price for orthogonality) and would
>> effectively be the same as a test for writeability.
>> "disable heuristic" would disable the forcing of birthtime back to mod
>> time or earlier (and any other 'logical fixes')
>> setting all 5 'time-present' bits would imply the array has 5 entries.
>>
>> anyone care to comment
> 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.





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