Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 9c14d60

Browse files
committed
Fix buffile.c error handling.
Convert buffile.c error handling to use ereport. This fixes cases where I/O errors were indistinguishable from EOF or not reported. Also remove "%m" from error messages where errno would be bogus. While we're modifying those strings, add block numbers and short read byte counts where appropriate. Back-patch to all supported releases. Reported-by: Amit Khandekar <[email protected]> Reviewed-by: Melanie Plageman <[email protected]> Reviewed-by: Alvaro Herrera <[email protected]> Reviewed-by: Robert Haas <[email protected]> Reviewed-by: Ibrar Ahmed <[email protected]> Reviewed-by: Michael Paquier <[email protected]> Discussion: https://postgr.es/m/CA%2BhUKGJE04G%3D8TLK0DLypT_27D9dR8F1RQgNp0jK6qR0tZGWOw%40mail.gmail.com
1 parent aeb785c commit 9c14d60

File tree

6 files changed

+95
-105
lines changed

6 files changed

+95
-105
lines changed

src/backend/access/gist/gistbuildbuffers.c

Lines changed: 9 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -757,26 +757,20 @@ gistRelocateBuildBuffersOnSplit(GISTBuildBuffers *gfbb, GISTSTATE *giststate,
757757
static void
758758
ReadTempFileBlock(BufFile *file, long blknum, void *ptr)
759759
{
760+
size_t nread;
761+
760762
if (BufFileSeekBlock(file, blknum) != 0)
761-
elog(ERROR, "could not seek temporary file: %m");
762-
if (BufFileRead(file, ptr, BLCKSZ) != BLCKSZ)
763-
elog(ERROR, "could not read temporary file: %m");
763+
elog(ERROR, "could not seek to block %ld in temporary file", blknum);
764+
nread = BufFileRead(file, ptr, BLCKSZ);
765+
if (nread != BLCKSZ)
766+
elog(ERROR, "could not read temporary file: read only %zu of %zu bytes",
767+
nread, (size_t) BLCKSZ);
764768
}
765769

766770
static void
767771
WriteTempFileBlock(BufFile *file, long blknum, void *ptr)
768772
{
769773
if (BufFileSeekBlock(file, blknum) != 0)
770-
elog(ERROR, "could not seek temporary file: %m");
771-
if (BufFileWrite(file, ptr, BLCKSZ) != BLCKSZ)
772-
{
773-
/*
774-
* the other errors in Read/WriteTempFileBlock shouldn't happen, but
775-
* an error at write can easily happen if you run out of disk space.
776-
*/
777-
ereport(ERROR,
778-
(errcode_for_file_access(),
779-
errmsg("could not write block %ld of temporary file: %m",
780-
blknum)));
781-
}
774+
elog(ERROR, "could not seek to block %ld in temporary file", blknum);
775+
BufFileWrite(file, ptr, BLCKSZ);
782776
}

src/backend/executor/nodeHashjoin.c

Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1056,7 +1056,7 @@ ExecHashJoinNewBatch(HashJoinState *hjstate)
10561056
if (BufFileSeek(innerFile, 0, 0L, SEEK_SET))
10571057
ereport(ERROR,
10581058
(errcode_for_file_access(),
1059-
errmsg("could not rewind hash-join temporary file: %m")));
1059+
errmsg("could not rewind hash-join temporary file")));
10601060

10611061
while ((slot = ExecHashJoinGetSavedTuple(hjstate,
10621062
innerFile,
@@ -1086,7 +1086,7 @@ ExecHashJoinNewBatch(HashJoinState *hjstate)
10861086
if (BufFileSeek(hashtable->outerBatchFile[curbatch], 0, 0L, SEEK_SET))
10871087
ereport(ERROR,
10881088
(errcode_for_file_access(),
1089-
errmsg("could not rewind hash-join temporary file: %m")));
1089+
errmsg("could not rewind hash-join temporary file")));
10901090
}
10911091

10921092
return true;
@@ -1231,7 +1231,6 @@ ExecHashJoinSaveTuple(MinimalTuple tuple, uint32 hashvalue,
12311231
BufFile **fileptr)
12321232
{
12331233
BufFile *file = *fileptr;
1234-
size_t written;
12351234

12361235
if (file == NULL)
12371236
{
@@ -1240,17 +1239,8 @@ ExecHashJoinSaveTuple(MinimalTuple tuple, uint32 hashvalue,
12401239
*fileptr = file;
12411240
}
12421241

1243-
written = BufFileWrite(file, (void *) &hashvalue, sizeof(uint32));
1244-
if (written != sizeof(uint32))
1245-
ereport(ERROR,
1246-
(errcode_for_file_access(),
1247-
errmsg("could not write to hash-join temporary file: %m")));
1248-
1249-
written = BufFileWrite(file, (void *) tuple, tuple->t_len);
1250-
if (written != tuple->t_len)
1251-
ereport(ERROR,
1252-
(errcode_for_file_access(),
1253-
errmsg("could not write to hash-join temporary file: %m")));
1242+
BufFileWrite(file, (void *) &hashvalue, sizeof(uint32));
1243+
BufFileWrite(file, (void *) tuple, tuple->t_len);
12541244
}
12551245

12561246
/*
@@ -1291,7 +1281,8 @@ ExecHashJoinGetSavedTuple(HashJoinState *hjstate,
12911281
if (nread != sizeof(header))
12921282
ereport(ERROR,
12931283
(errcode_for_file_access(),
1294-
errmsg("could not read from hash-join temporary file: %m")));
1284+
errmsg("could not read from hash-join temporary file: read only %zu of %zu bytes",
1285+
nread, sizeof(header))));
12951286
*hashvalue = header[0];
12961287
tuple = (MinimalTuple) palloc(header[1]);
12971288
tuple->t_len = header[1];
@@ -1301,7 +1292,8 @@ ExecHashJoinGetSavedTuple(HashJoinState *hjstate,
13011292
if (nread != header[1] - sizeof(uint32))
13021293
ereport(ERROR,
13031294
(errcode_for_file_access(),
1304-
errmsg("could not read from hash-join temporary file: %m")));
1295+
errmsg("could not read from hash-join temporary file: read only %zu of %zu bytes",
1296+
nread, header[1] - sizeof(uint32))));
13051297
return ExecStoreMinimalTuple(tuple, tupleSlot, true);
13061298
}
13071299

src/backend/storage/file/buffile.c

Lines changed: 31 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ static BufFile *makeBufFile(File firstfile);
104104
static void extendBufFile(BufFile *file);
105105
static void BufFileLoadBuffer(BufFile *file);
106106
static void BufFileDumpBuffer(BufFile *file);
107-
static int BufFileFlush(BufFile *file);
107+
static void BufFileFlush(BufFile *file);
108108
static File MakeNewSharedSegment(BufFile *file, int segment);
109109

110110
/*
@@ -430,7 +430,10 @@ BufFileLoadBuffer(BufFile *file)
430430
if (file->curOffset != file->offsets[file->curFile])
431431
{
432432
if (FileSeek(thisfile, file->curOffset, SEEK_SET) != file->curOffset)
433-
return; /* seek failed, read nothing */
433+
ereport(ERROR,
434+
(errcode_for_file_access(),
435+
errmsg("could not seek in file \"%s\": %m",
436+
FilePathName(thisfile))));
434437
file->offsets[file->curFile] = file->curOffset;
435438
}
436439

@@ -442,7 +445,14 @@ BufFileLoadBuffer(BufFile *file)
442445
sizeof(file->buffer),
443446
WAIT_EVENT_BUFFILE_READ);
444447
if (file->nbytes < 0)
448+
{
445449
file->nbytes = 0;
450+
ereport(ERROR,
451+
(errcode_for_file_access(),
452+
errmsg("could not read file \"%s\": %m",
453+
FilePathName(thisfile))));
454+
}
455+
446456
file->offsets[file->curFile] += file->nbytes;
447457
/* we choose not to advance curOffset here */
448458

@@ -499,15 +509,22 @@ BufFileDumpBuffer(BufFile *file)
499509
if (file->curOffset != file->offsets[file->curFile])
500510
{
501511
if (FileSeek(thisfile, file->curOffset, SEEK_SET) != file->curOffset)
502-
return; /* seek failed, give up */
512+
ereport(ERROR,
513+
(errcode_for_file_access(),
514+
errmsg("could not seek in file \"%s\": %m",
515+
FilePathName(thisfile))));
503516
file->offsets[file->curFile] = file->curOffset;
504517
}
505518
bytestowrite = FileWrite(thisfile,
506519
file->buffer.data + wpos,
507520
bytestowrite,
508521
WAIT_EVENT_BUFFILE_WRITE);
509522
if (bytestowrite <= 0)
510-
return; /* failed to write */
523+
ereport(ERROR,
524+
(errcode_for_file_access(),
525+
errmsg("could not write to file \"%s\" : %m",
526+
FilePathName(thisfile))));
527+
511528
file->offsets[file->curFile] += bytestowrite;
512529
file->curOffset += bytestowrite;
513530
wpos += bytestowrite;
@@ -540,20 +557,16 @@ BufFileDumpBuffer(BufFile *file)
540557
/*
541558
* BufFileRead
542559
*
543-
* Like fread() except we assume 1-byte element size.
560+
* Like fread() except we assume 1-byte element size and report I/O errors via
561+
* ereport().
544562
*/
545563
size_t
546564
BufFileRead(BufFile *file, void *ptr, size_t size)
547565
{
548566
size_t nread = 0;
549567
size_t nthistime;
550568

551-
if (file->dirty)
552-
{
553-
if (BufFileFlush(file) != 0)
554-
return 0; /* could not flush... */
555-
Assert(!file->dirty);
556-
}
569+
BufFileFlush(file);
557570

558571
while (size > 0)
559572
{
@@ -587,7 +600,8 @@ BufFileRead(BufFile *file, void *ptr, size_t size)
587600
/*
588601
* BufFileWrite
589602
*
590-
* Like fwrite() except we assume 1-byte element size.
603+
* Like fwrite() except we assume 1-byte element size and report errors via
604+
* ereport().
591605
*/
592606
size_t
593607
BufFileWrite(BufFile *file, void *ptr, size_t size)
@@ -603,11 +617,7 @@ BufFileWrite(BufFile *file, void *ptr, size_t size)
603617
{
604618
/* Buffer full, dump it out */
605619
if (file->dirty)
606-
{
607620
BufFileDumpBuffer(file);
608-
if (file->dirty)
609-
break; /* I/O error */
610-
}
611621
else
612622
{
613623
/* Hmm, went directly from reading to writing? */
@@ -639,19 +649,15 @@ BufFileWrite(BufFile *file, void *ptr, size_t size)
639649
/*
640650
* BufFileFlush
641651
*
642-
* Like fflush()
652+
* Like fflush(), except that I/O errors are reported with ereport().
643653
*/
644-
static int
654+
static void
645655
BufFileFlush(BufFile *file)
646656
{
647657
if (file->dirty)
648-
{
649658
BufFileDumpBuffer(file);
650-
if (file->dirty)
651-
return EOF;
652-
}
653659

654-
return 0;
660+
Assert(!file->dirty);
655661
}
656662

657663
/*
@@ -660,6 +666,7 @@ BufFileFlush(BufFile *file)
660666
* Like fseek(), except that target position needs two values in order to
661667
* work when logical filesize exceeds maximum value representable by off_t.
662668
* We do not support relative seeks across more than that, however.
669+
* I/O errors are reported by ereport().
663670
*
664671
* Result is 0 if OK, EOF if not. Logical position is not moved if an
665672
* impossible seek is attempted.
@@ -717,8 +724,7 @@ BufFileSeek(BufFile *file, int fileno, off_t offset, int whence)
717724
return 0;
718725
}
719726
/* Otherwise, must reposition buffer, so flush any dirty data */
720-
if (BufFileFlush(file) != 0)
721-
return EOF;
727+
BufFileFlush(file);
722728

723729
/*
724730
* At this point and no sooner, check for seek past last segment. The

src/backend/utils/sort/logtape.c

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -248,12 +248,12 @@ ltsWriteBlock(LogicalTapeSet *lts, long blocknum, void *buffer)
248248
}
249249

250250
/* Write the requested block */
251-
if (BufFileSeekBlock(lts->pfile, blocknum) != 0 ||
252-
BufFileWrite(lts->pfile, buffer, BLCKSZ) != BLCKSZ)
251+
if (BufFileSeekBlock(lts->pfile, blocknum) != 0)
253252
ereport(ERROR,
254253
(errcode_for_file_access(),
255-
errmsg("could not write block %ld of temporary file: %m",
254+
errmsg("could not seek to block %ld of temporary file",
256255
blocknum)));
256+
BufFileWrite(lts->pfile, buffer, BLCKSZ);
257257

258258
/* Update nBlocksWritten, if we extended the file */
259259
if (blocknum == lts->nBlocksWritten)
@@ -269,12 +269,19 @@ ltsWriteBlock(LogicalTapeSet *lts, long blocknum, void *buffer)
269269
static void
270270
ltsReadBlock(LogicalTapeSet *lts, long blocknum, void *buffer)
271271
{
272-
if (BufFileSeekBlock(lts->pfile, blocknum) != 0 ||
273-
BufFileRead(lts->pfile, buffer, BLCKSZ) != BLCKSZ)
272+
size_t nread;
273+
274+
if (BufFileSeekBlock(lts->pfile, blocknum) != 0)
274275
ereport(ERROR,
275276
(errcode_for_file_access(),
276-
errmsg("could not read block %ld of temporary file: %m",
277+
errmsg("could not seek to block %ld of temporary file",
277278
blocknum)));
279+
nread = BufFileRead(lts->pfile, buffer, BLCKSZ);
280+
if (nread != BLCKSZ)
281+
ereport(ERROR,
282+
(errcode_for_file_access(),
283+
errmsg("could not read block %ld of temporary file: read only %zu of %zu bytes",
284+
blocknum, nread, (size_t) BLCKSZ)));
278285
}
279286

280287
/*

src/backend/utils/sort/sharedtuplestore.c

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -198,14 +198,9 @@ static void
198198
sts_flush_chunk(SharedTuplestoreAccessor *accessor)
199199
{
200200
size_t size;
201-
size_t written;
202201

203202
size = STS_CHUNK_PAGES * BLCKSZ;
204-
written = BufFileWrite(accessor->write_file, accessor->write_chunk, size);
205-
if (written != size)
206-
ereport(ERROR,
207-
(errcode_for_file_access(),
208-
errmsg("could not write to temporary file: %m")));
203+
BufFileWrite(accessor->write_file, accessor->write_chunk, size);
209204
memset(accessor->write_chunk, 0, size);
210205
accessor->write_pointer = &accessor->write_chunk->data[0];
211206
accessor->sts->participants[accessor->participant].npages +=
@@ -557,6 +552,7 @@ sts_parallel_scan_next(SharedTuplestoreAccessor *accessor, void *meta_data)
557552
if (!eof)
558553
{
559554
SharedTuplestoreChunk chunk_header;
555+
size_t nread;
560556

561557
/* Make sure we have the file open. */
562558
if (accessor->read_file == NULL)
@@ -572,14 +568,15 @@ sts_parallel_scan_next(SharedTuplestoreAccessor *accessor, void *meta_data)
572568
if (BufFileSeekBlock(accessor->read_file, read_page) != 0)
573569
ereport(ERROR,
574570
(errcode_for_file_access(),
575-
errmsg("could not read from shared tuplestore temporary file"),
576-
errdetail_internal("Could not seek to next block.")));
577-
if (BufFileRead(accessor->read_file, &chunk_header,
578-
STS_CHUNK_HEADER_SIZE) != STS_CHUNK_HEADER_SIZE)
571+
errmsg("could not seek block %u in shared tuplestore temporary file",
572+
read_page)));
573+
nread = BufFileRead(accessor->read_file, &chunk_header,
574+
STS_CHUNK_HEADER_SIZE);
575+
if (nread != STS_CHUNK_HEADER_SIZE)
579576
ereport(ERROR,
580577
(errcode_for_file_access(),
581-
errmsg("could not read from shared tuplestore temporary file"),
582-
errdetail_internal("Short read while reading chunk header.")));
578+
errmsg("could not read from shared tuplestore temporary file: read only %zu of %zu bytes",
579+
nread, STS_CHUNK_HEADER_SIZE)));
583580

584581
/*
585582
* If this is an overflow chunk, we skip it and any following

0 commit comments

Comments
 (0)