truncate and open(O_TRUNC) times.

Bruce Evans brde at optusnet.com.au
Mon Jul 29 15:35:05 UTC 2013


On Mon, 29 Jul 2013, Konstantin Belousov wrote:

> On Mon, Jul 29, 2013 at 07:56:34PM +1000, Bruce Evans wrote:
>> ...
>> POSIX is weirdly different for truncate().  It only requires truncate()
>> to change the times if it changed the size (this is not weird, but unusual),
>> while it requires ftruncate() to change the times if it succeeded.
>> ...
>> FreeBSD can't possibly do this as weirdly as POSIX specifies, since
>> it uses the same VOP_SETATTR() API to set the size for ftruncate() and
>> truncate(), and this API doesn't say who made the call.  Most file
>> systems seem to force the setting of the times if successful.  E.g.,
>> ffs_truncate() does nothing much except set the times if the size
>> didn't change.
>
> vaattr.va_vaflags could grow a flag to indicate that VOP_SETATTR()
> should only change times when size was changed.

Indeed.

I just checked some details for another bug involving [f]truncate() and
the file size limit.  They are specified to act the same (SIGFXSZ with
no change in the file) above the limit, but for most file systems including
ffs, neither checks.  So the flag isn't needed to fix this bug.  It is
write() that acts differently.  It is specified to write up to the limit
and then return a short write with no SIGXFXSZ if the file pointer is
initially before the limit; otherwise SIGFXSZ with no change to the file
(or file times?).  But for most file systems including ffs, write() fails
with SIGFXSZ and no change in the file if the result of a full successful
write would be above the limit.  This is mostly a bug in POSIX.  It makes
short write()s possible for any write(), where users can easily arrange
for foot shooting using their soft rlimit, but almost no applications
understand short writes.  Most file systems including ffs never produce
short writes -- they back out of failing i/o's if possible, including for
the similar ENOSPC error; when backing out is not possible, which is
mainly for failing writes into the middle of files, they return -1 with
no backing out; applications must assume that the region of the file
written to by a failing write is indeterminate, but for writes at EOF
this region is null after the backout.

Bruce


More information about the freebsd-standards mailing list