From 9c94301066775d4d08ae6820101c0fd7e80ea8bb Mon Sep 17 00:00:00 2001 From: Peter Eisentraut Date: Mon, 29 Jun 2026 13:37:54 +0200 Subject: [PATCH v1 14/15] Clean up FileWrite() return type analogous to the previous changes for write() Some callers did not have a separate error message for a short write. This is okay in practice because FileWriteV() sets ENOSPC for all non-error returns, so you'll get a reasonable error message either way. But callers handled this inconsistently, and this behavior isn't really prominently documented and commit 871fe4917e1 seems to frown upon it, so it seems better to make all callers handle this consistently by adding the separate error message. --- src/backend/access/heap/rewriteheap.c | 12 ++++++++---- src/backend/backup/basebackup_server.c | 8 ++++---- src/backend/storage/file/buffile.c | 19 ++++++++++--------- src/backend/storage/smgr/md.c | 8 ++++---- src/backend/utils/probes.d | 2 +- 5 files changed, 27 insertions(+), 22 deletions(-) diff --git a/src/backend/access/heap/rewriteheap.c b/src/backend/access/heap/rewriteheap.c index ee7d853c1b8..e24a98f4a2c 100644 --- a/src/backend/access/heap/rewriteheap.c +++ b/src/backend/access/heap/rewriteheap.c @@ -829,8 +829,8 @@ logical_heap_rewrite_flush_mappings(RewriteState state) char *waldata_start; xl_heap_rewrite_mapping xlrec; Oid dboid; - uint32 len; - int written; + size_t len; + ssize_t written; uint32 num_mappings = dclist_count(&src->mappings); /* this file hasn't got any new mappings */ @@ -882,10 +882,14 @@ logical_heap_rewrite_flush_mappings(RewriteState state) */ written = FileWrite(src->vfd, waldata_start, len, src->off, WAIT_EVENT_LOGICAL_REWRITE_WRITE); - if (written != len) + if (written < 0) ereport(ERROR, (errcode_for_file_access(), - errmsg("could not write to file \"%s\", wrote %d of %d: %m", src->path, + errmsg("could not write to file \"%s\": %m", src->path))); + else if (written != len) + ereport(ERROR, + (errcode_for_file_access(), + errmsg("could not write to file \"%s\": wrote %zd of %zu", src->path, written, len))); src->off += len; diff --git a/src/backend/backup/basebackup_server.c b/src/backend/backup/basebackup_server.c index 3d44bf71d19..b2e89f09d30 100644 --- a/src/backend/backup/basebackup_server.c +++ b/src/backend/backup/basebackup_server.c @@ -160,7 +160,7 @@ static void bbsink_server_archive_contents(bbsink *sink, size_t len) { bbsink_server *mysink = (bbsink_server *) sink; - int nbytes; + ssize_t nbytes; nbytes = FileWrite(mysink->file, mysink->base.bbs_buffer, len, mysink->filepos, WAIT_EVENT_BASEBACKUP_WRITE); @@ -176,7 +176,7 @@ bbsink_server_archive_contents(bbsink *sink, size_t len) /* short write: complain appropriately */ ereport(ERROR, (errcode(ERRCODE_DISK_FULL), - errmsg("could not write file \"%s\": wrote only %d of %zu bytes at offset %lld", + errmsg("could not write file \"%s\": wrote only %zd of %zu bytes at offset %lld", FilePathName(mysink->file), nbytes, len, (long long) mysink->filepos), errhint("Check free disk space."))); @@ -253,7 +253,7 @@ static void bbsink_server_manifest_contents(bbsink *sink, size_t len) { bbsink_server *mysink = (bbsink_server *) sink; - int nbytes; + ssize_t nbytes; nbytes = FileWrite(mysink->file, mysink->base.bbs_buffer, len, mysink->filepos, WAIT_EVENT_BASEBACKUP_WRITE); @@ -269,7 +269,7 @@ bbsink_server_manifest_contents(bbsink *sink, size_t len) /* short write: complain appropriately */ ereport(ERROR, (errcode(ERRCODE_DISK_FULL), - errmsg("could not write file \"%s\": wrote only %d of %zu bytes at offset %lld", + errmsg("could not write file \"%s\": wrote only %zd of %zu bytes at offset %lld", FilePathName(mysink->file), nbytes, len, (long long) mysink->filepos), errhint("Check free disk space."))); diff --git a/src/backend/storage/file/buffile.c b/src/backend/storage/file/buffile.c index b44d24cdbd3..5c59913646b 100644 --- a/src/backend/storage/file/buffile.c +++ b/src/backend/storage/file/buffile.c @@ -498,7 +498,6 @@ static void BufFileDumpBuffer(BufFile *file) { int64 wpos = 0; - int64 bytestowrite; File thisfile; /* @@ -510,6 +509,8 @@ BufFileDumpBuffer(BufFile *file) int64 availbytes; instr_time io_start; instr_time io_time; + size_t bytestowrite; + ssize_t rc; /* * Advance to next component file if necessary and possible. @@ -538,12 +539,12 @@ BufFileDumpBuffer(BufFile *file) else INSTR_TIME_SET_ZERO(io_start); - bytestowrite = FileWrite(thisfile, - file->buffer.data + wpos, - bytestowrite, - file->curOffset, - WAIT_EVENT_BUFFILE_WRITE); - if (bytestowrite <= 0) + rc = FileWrite(thisfile, + file->buffer.data + wpos, + bytestowrite, + file->curOffset, + WAIT_EVENT_BUFFILE_WRITE); + if (rc <= 0) ereport(ERROR, (errcode_for_file_access(), errmsg("could not write to file \"%s\": %m", @@ -555,8 +556,8 @@ BufFileDumpBuffer(BufFile *file) INSTR_TIME_ACCUM_DIFF(pgBufferUsage.temp_blk_write_time, io_time, io_start); } - file->curOffset += bytestowrite; - wpos += bytestowrite; + file->curOffset += rc; + wpos += rc; pgBufferUsage.temp_blks_written++; } diff --git a/src/backend/storage/smgr/md.c b/src/backend/storage/smgr/md.c index 5b1f6e1f4b6..e4a449ab8c5 100644 --- a/src/backend/storage/smgr/md.c +++ b/src/backend/storage/smgr/md.c @@ -489,7 +489,7 @@ mdextend(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum, const void *buffer, bool skipFsync) { pgoff_t seekpos; - int nbytes; + ssize_t nbytes; MdfdVec *v; /* If this build supports direct I/O, the buffer must be I/O aligned. */ @@ -531,9 +531,9 @@ mdextend(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum, /* short write: complain appropriately */ ereport(ERROR, (errcode(ERRCODE_DISK_FULL), - errmsg("could not extend file \"%s\": wrote only %d of %d bytes at block %u", + errmsg("could not extend file \"%s\": wrote only %zd of %zu bytes at block %u", FilePathName(v->mdfd_vfd), - nbytes, BLCKSZ, blocknum), + nbytes, (size_t) BLCKSZ, blocknum), errhint("Check free disk space."))); } @@ -1081,7 +1081,7 @@ mdwritev(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum, struct iovec iov[PG_IOV_MAX]; int iovcnt; pgoff_t seekpos; - int nbytes; + ssize_t nbytes; MdfdVec *v; BlockNumber nblocks_this_segment; size_t transferred_this_segment; diff --git a/src/backend/utils/probes.d b/src/backend/utils/probes.d index 48b269468a5..2d8f12cbe30 100644 --- a/src/backend/utils/probes.d +++ b/src/backend/utils/probes.d @@ -85,7 +85,7 @@ provider postgresql { probe smgr__md__read__start(ForkNumber, BlockNumber, Oid, Oid, Oid, int); probe smgr__md__read__done(ForkNumber, BlockNumber, Oid, Oid, Oid, int, long long int, long long int); probe smgr__md__write__start(ForkNumber, BlockNumber, Oid, Oid, Oid, int); - probe smgr__md__write__done(ForkNumber, BlockNumber, Oid, Oid, Oid, int, int, int); + probe smgr__md__write__done(ForkNumber, BlockNumber, Oid, Oid, Oid, int, long long int, long long int); probe wal__insert(unsigned char, unsigned char); probe wal__switch(); -- 2.54.0