Skip to content

Commit 445e31b

Browse files
committed
Fix some sloppiness in the new BufFileSize() and BufFileAppend() functions.
There were three related issues: * BufFileAppend() incorrectly reset the seek position on the 'source' file. As a result, if you had called BufFileRead() on the file before calling BufFileAppend(), it got confused, and subsequent calls would read/write at wrong position. * BufFileSize() did not work with files opened with BufFileOpenShared(). * FileGetSize() only worked on temporary files. To fix, change the way BufFileSize() works so that it works on shared files. Remove FileGetSize() altogether, as it's no longer needed. Remove buffilesize from TapeShare struct, as the leader process can simply call BufFileSize() to get the tape's size, there's no need to pass it through shared memory anymore. Discussion: https://www.postgresql.org/message-id/CAH2-WznEDYe_NZXxmnOfsoV54oFkTdMy7YLE2NPBLuttO96vTQ@mail.gmail.com
1 parent 7f6570b commit 445e31b

File tree

6 files changed

+24
-24
lines changed

6 files changed

+24
-24
lines changed

src/backend/storage/file/buffile.c

+14-4
Original file line numberDiff line numberDiff line change
@@ -802,14 +802,24 @@ BufFileTellBlock(BufFile *file)
802802
#endif
803803

804804
/*
805-
* Return the current file size. Counts any holes left behind by
806-
* BufFileViewAppend as part of the size.
805+
* Return the current file size.
806+
*
807+
* Counts any holes left behind by BufFileAppend as part of the size.
808+
* Returns -1 on error.
807809
*/
808810
off_t
809811
BufFileSize(BufFile *file)
810812
{
813+
off_t lastFileSize;
814+
815+
/* Get the size of the last physical file by seeking to end. */
816+
lastFileSize = FileSeek(file->files[file->numFiles - 1], 0, SEEK_END);
817+
if (lastFileSize < 0)
818+
return -1;
819+
file->offsets[file->numFiles - 1] = lastFileSize;
820+
811821
return ((file->numFiles - 1) * (off_t) MAX_PHYSICAL_FILESIZE) +
812-
FileGetSize(file->files[file->numFiles - 1]);
822+
lastFileSize;
813823
}
814824

815825
/*
@@ -853,7 +863,7 @@ BufFileAppend(BufFile *target, BufFile *source)
853863
for (i = target->numFiles; i < newNumFiles; i++)
854864
{
855865
target->files[i] = source->files[i - target->numFiles];
856-
target->offsets[i] = 0L;
866+
target->offsets[i] = source->offsets[i - target->numFiles];
857867
}
858868
target->numFiles = newNumFiles;
859869

src/backend/storage/file/fd.c

-10
Original file line numberDiff line numberDiff line change
@@ -2255,16 +2255,6 @@ FileGetRawMode(File file)
22552255
return VfdCache[file].fileMode;
22562256
}
22572257

2258-
/*
2259-
* FileGetSize - returns the size of file
2260-
*/
2261-
off_t
2262-
FileGetSize(File file)
2263-
{
2264-
Assert(FileIsValid(file));
2265-
return VfdCache[file].fileSize;
2266-
}
2267-
22682258
/*
22692259
* Make room for another allocatedDescs[] array entry if needed and possible.
22702260
* Returns true if an array element is available.

src/backend/utils/sort/logtape.c

+8-3
Original file line numberDiff line numberDiff line change
@@ -426,11 +426,17 @@ ltsConcatWorkerTapes(LogicalTapeSet *lts, TapeShare *shared,
426426
{
427427
char filename[MAXPGPATH];
428428
BufFile *file;
429+
off_t filesize;
429430

430431
lt = &lts->tapes[i];
431432

432433
pg_itoa(i, filename);
433434
file = BufFileOpenShared(fileset, filename);
435+
filesize = BufFileSize(file);
436+
if (filesize < 0)
437+
ereport(ERROR,
438+
(errcode_for_file_access(),
439+
errmsg("could not determine size of temporary file \"%s\"", filename)));
434440

435441
/*
436442
* Stash first BufFile, and concatenate subsequent BufFiles to that.
@@ -447,8 +453,8 @@ ltsConcatWorkerTapes(LogicalTapeSet *lts, TapeShare *shared,
447453
lt->offsetBlockNumber = BufFileAppend(lts->pfile, file);
448454
}
449455
/* Don't allocate more for read buffer than could possibly help */
450-
lt->max_size = Min(MaxAllocSize, shared[i].buffilesize);
451-
tapeblocks = shared[i].buffilesize / BLCKSZ;
456+
lt->max_size = Min(MaxAllocSize, filesize);
457+
tapeblocks = filesize / BLCKSZ;
452458
nphysicalblocks += tapeblocks;
453459
}
454460

@@ -938,7 +944,6 @@ LogicalTapeFreeze(LogicalTapeSet *lts, int tapenum, TapeShare *share)
938944
{
939945
BufFileExportShared(lts->pfile);
940946
share->firstblocknumber = lt->firstBlockNumber;
941-
share->buffilesize = BufFileSize(lts->pfile);
942947
}
943948
}
944949

src/backend/utils/sort/tuplesort.c

-1
Original file line numberDiff line numberDiff line change
@@ -4395,7 +4395,6 @@ tuplesort_initialize_shared(Sharedsort *shared, int nWorkers, dsm_segment *seg)
43954395
for (i = 0; i < nWorkers; i++)
43964396
{
43974397
shared->tapes[i].firstblocknumber = 0L;
4398-
shared->tapes[i].buffilesize = 0;
43994398
}
44004399
}
44014400

src/include/storage/fd.h

-1
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,6 @@ extern char *FilePathName(File file);
7878
extern int FileGetRawDesc(File file);
7979
extern int FileGetRawFlags(File file);
8080
extern mode_t FileGetRawMode(File file);
81-
extern off_t FileGetSize(File file);
8281

8382
/* Operations used for sharing named temporary files */
8483
extern File PathNameCreateTemporaryFile(const char *name, bool error_on_failure);

src/include/utils/logtape.h

+2-5
Original file line numberDiff line numberDiff line change
@@ -44,13 +44,10 @@ typedef struct LogicalTapeSet LogicalTapeSet;
4444
typedef struct TapeShare
4545
{
4646
/*
47-
* firstblocknumber is first block that should be read from materialized
48-
* tape.
49-
*
50-
* buffilesize is the size of associated BufFile following freezing.
47+
* Currently, all the leader process needs is the location of the
48+
* materialized tape's first block.
5149
*/
5250
long firstblocknumber;
53-
off_t buffilesize;
5451
} TapeShare;
5552

5653
/*

0 commit comments

Comments
 (0)