Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 6 Dec 2018 07:23:01 +1100 (EST)
From:      Bruce Evans <brde@optusnet.com.au>
To:        Alan Somers <asomers@freebsd.org>
Cc:        src-committers@freebsd.org, svn-src-all@freebsd.org,  svn-src-head@freebsd.org
Subject:   Re: svn commit: r341598 - head/lib/libc/sys
Message-ID:  <20181206062019.I3775@besplex.bde.org>
In-Reply-To: <201812051728.wB5HSes8099327@repo.freebsd.org>
References:  <201812051728.wB5HSes8099327@repo.freebsd.org>

next in thread | previous in thread | raw e-mail | index | archive | help
On Wed, 5 Dec 2018, Alan Somers wrote:

> Log:
>  stat(2): clarify which syscalls modify file timestamps
>
>  The list of syscalls that modify st_atim, st_mtim, and st_ctim was quite out
>  of date and probably not accurate to begin with.  Update it, and make it
>  clear that the list is open-ended.

These fields shouldn't exist.  They are misimplemented compatibility cruft.
They didn't exist in FreeBSD-4.  They were correctly implemented
compatibility cruft then.  The POSIX fields are still only time_t's with
names st_atime, etc., but these fields are timespecs with necessarily
different names.  In FreeBSD-4, they were named st_atimespec, etc. unless
POSIX_SOURCE is defined, which before about 2007 POSIX required struct
timespec to not be defined, so the fields were declared as 2 scalars
st_atime and st_atimensec, etc.  Padding of the scalars caused ABI problems
which I fixed in FreeBSD-5 using bit-fields.  Now the support for POSIX
before about 2007 is broken by declaring struct timespec undonditionally
and using it for st_atim, etc.  API compatibility with old versions of
FreeBSD is broken by renaming st_atimespec to st_atim, etc.

All versions that use timespecs use macro hacks of dubious standard
conformance to convert from timespecs to POSIX time_t's.  All names starting
with st_ are reserved if <sys/stat.h> is included.  This is what makes it
conforming for the implementation to use st_atim, etc.  It is less clear
if the macros conform because it would be non-conforming for a an application
to #undef st_atim or depend on st_atim not being a macro.

> Modified: head/lib/libc/sys/stat.2
> ==============================================================================
> --- head/lib/libc/sys/stat.2	Wed Dec  5 17:13:33 2018	(r341597)
> +++ head/lib/libc/sys/stat.2	Wed Dec  5 17:28:40 2018	(r341598)
> ...
> @@ -193,45 +193,53 @@ are:
> .Bl -tag -width ".Va st_birthtim"
> .It Va st_atim
> Time when file data was last accessed.
> -Changed by the
> -.Xr mknod 2 ,

Not changed by mknod, but set by it.  Still set by it.

> -.Xr utimes 2 ,

Not really changed if the change is null, where a null change may be the
result of rounding to a representable value.  Permissions are still required
for making null changes.  Similarly for most operations.

> +Changed implicitly by syscalls such as
> .Xr read 2
> and
> -.Xr readv 2
> -system calls.
> +.Xr readv 2 ,

Not changed by reads if the file system is mounted -noatime and the file
system supports this (you can't tell if the file system supports this
by examining its MNT_NOATIME flag).  Not changed if granularity makes the
change null.

> +and explicitly by
> +.Xr utimes 2 .

The lists would be even longer if they mentioned utime, lutimes, futimes,
futimesat, futimens and futimnsat.

> .It Va st_mtim
> Time when file data was last modified.
> -Changed by the
> +Changed implicitly by syscalls such as
> +.Xr truncate 2 ,
> +.Xr write 2 ,
> +and
> +.Xr writev 2 ,
> +and explicitly by
> +.Xr utimes 2 .
> +Also, any syscall which modifies directory content changes the
> +.Va st_mtim
> +for the affected directory.
> +For instance,
> +.Xr creat 2 ,

Usually spelled open with O_CREAT.

> .Xr mkdir 2 ,

creat, open with O_CREAT, link, symlink, mkdir and all of the removed mk's
also set all times.

> -.Xr mkfifo 2 ,
> -.Xr mknod 2 ,
> -.Xr utimes 2 ,
> -.Xr write 2
> +.Xr rename 2 ,
> +.Xr link 2 ,

rename to a different directory changes 2 sets of directory times.

link is unsorted in this and another list.

> ...
> +.Xr link 2 ,
> and
> -.Xr writev 2
> -system calls.
> +.Xr unlink 2 .
> .It Va st_birthtim
> Time when the inode was created.
> .El

st_birthim should be named st_btime.

st_birthtim is set by all creation operations.  It is changed by changing
st_mtim to a value before the current st_birthtim.  This is done at the vfs
level, so it should work for all file systems that support birthtimes.

Changing st_birthtime forwards is not supported by any syscall.  There
are already about 10 times too many syscalls for setting times, but
none of them supports setting birthtimes or ctimes.  I use a sysctl
hack to set ctimes, as needed to back up and restore them, but don't
do anything special for birthtimes.

Bruce



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