postgres.git / summary / log / commit / refs

commit    0fb496c704fce0daeb01cb3736a827ec009f382e
Author:   Tom Lane <tgl@sss.pgh.pa.us>
Date:     Tue Jul 01 16:08:20 2025 +0000
First released in: 13.22, 14.19, 15.14, 16.10, 17.6, 18.0

    Make safeguard against incorrect flags for fsync more portable.
    
    The existing code assumed that O_RDONLY is defined as 0, but this is
    not required by POSIX and is not true on GNU Hurd.  We can avoid
    the assumption by relying on O_ACCMODE to mask the fcntl() result.
    (Hopefully, all supported platforms define that.)
    
    Author: Michael Banck <mbanck@gmx.net>
    Co-authored-by: Samuel Thibault
    Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us>
    Discussion: https://postgr.es/m/6862e8d1.050a0220.194b8d.76fa@mx.google.com
    Discussion: https://postgr.es/m/68480868.5d0a0220.1e214d.68a6@mx.google.com
    Backpatch-through: 13


src/backend/storage/file/fd.c | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/src/backend/storage/file/fd.c b/src/backend/storage/file/fd.c index 38af6d1af3f..3c04c9dabda 100644 --- a/src/backend/storage/file/fd.c +++ b/src/backend/storage/file/fd.c @@ -373,25 +373,22 @@ pg_fsync(int fd) * portable, even if it runs ok on the current system. * * We assert here that a descriptor for a file was opened with write - * permissions (either O_RDWR or O_WRONLY) and for a directory without - * write permissions (O_RDONLY). + * permissions (i.e., not O_RDONLY) and for a directory without write + * permissions (O_RDONLY). Notice that the assertion check is made even + * if fsync() is disabled. * - * Ignore any fstat errors and let the follow-up fsync() do its work. - * Doing this sanity check here counts for the case where fsync() is - * disabled. + * If fstat() fails, ignore it and let the follow-up fsync() complain. */ if (fstat(fd, &st) == 0) { int desc_flags = fcntl(fd, F_GETFL); - /* - * O_RDONLY is historically 0, so just make sure that for directories - * no write flags are used. - */ + desc_flags &= O_ACCMODE; + if (S_ISDIR(st.st_mode)) - Assert((desc_flags & (O_RDWR | O_WRONLY)) == 0); + Assert(desc_flags == O_RDONLY); else - Assert((desc_flags & (O_RDWR | O_WRONLY)) != 0); + Assert(desc_flags != O_RDONLY); } errno = 0; #endif [parent: 8f456630ce93]