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>