diff --git a/contrib/pg_visibility/pg_visibility.c b/contrib/pg_visibility/pg_visibility.c index adeb9512a70..ad0f2a109a6 100644 --- a/contrib/pg_visibility/pg_visibility.c +++ b/contrib/pg_visibility/pg_visibility.c @@ -421,7 +421,7 @@ pg_truncate_visibility_map(PG_FUNCTION_ARGS) } if (BlockNumberIsValid(block)) - smgrtruncate(RelationGetSmgr(rel), &fork, 1, &old_block, &block); + smgrtruncate2(RelationGetSmgr(rel), &fork, 1, &old_block, &block); END_CRIT_SECTION(); MyProc->delayChkptFlags &= ~(DELAY_CHKPT_START | DELAY_CHKPT_COMPLETE); diff --git a/src/backend/catalog/storage.c b/src/backend/catalog/storage.c index e42c79f05b9..53ebf093285 100644 --- a/src/backend/catalog/storage.c +++ b/src/backend/catalog/storage.c @@ -418,7 +418,7 @@ RelationTruncate(Relation rel, BlockNumber nblocks) * longer exist after truncation is complete, and then truncate the * corresponding files on disk. */ - smgrtruncate(RelationGetSmgr(rel), forks, nforks, old_blocks, blocks); + smgrtruncate2(RelationGetSmgr(rel), forks, nforks, old_blocks, blocks); END_CRIT_SECTION(); @@ -1059,7 +1059,7 @@ smgr_redo(XLogReaderState *record) if (nforks > 0) { START_CRIT_SECTION(); - smgrtruncate(reln, forks, nforks, old_blocks, blocks); + smgrtruncate2(reln, forks, nforks, old_blocks, blocks); END_CRIT_SECTION(); } diff --git a/src/backend/storage/smgr/smgr.c b/src/backend/storage/smgr/smgr.c index e6cc0f1a224..67ec3b55983 100644 --- a/src/backend/storage/smgr/smgr.c +++ b/src/backend/storage/smgr/smgr.c @@ -692,6 +692,26 @@ smgrnblocks_cached(SMgrRelation reln, ForkNumber forknum) * smgrtruncate() -- Truncate the given forks of supplied relation to * each specified numbers of blocks * + * Backward-compatible version of smgrtruncate2() for the benefit of external + * callers. This version isn't used in PostgreSQL core code, and can't be + * used in a critical section. + */ +void +smgrtruncate(SMgrRelation reln, ForkNumber *forknum, int nforks, + BlockNumber *nblocks) +{ + BlockNumber old_nblocks[MAX_FORKNUM + 1]; + + for (int i = 0; i < nforks; ++i) + old_nblocks[i] = smgrnblocks(reln, forknum[i]); + + return smgrtruncate2(reln, forknum, nforks, old_nblocks, nblocks); +} + +/* + * smgrtruncate2() -- Truncate the given forks of supplied relation to + * each specified numbers of blocks + * * The truncation is done immediately, so this can't be rolled back. * * The caller must hold AccessExclusiveLock on the relation, to ensure that @@ -703,8 +723,8 @@ smgrnblocks_cached(SMgrRelation reln, ForkNumber forknum) * to this relation should be called in between. */ void -smgrtruncate(SMgrRelation reln, ForkNumber *forknum, int nforks, - BlockNumber *old_nblocks, BlockNumber *nblocks) +smgrtruncate2(SMgrRelation reln, ForkNumber *forknum, int nforks, + BlockNumber *old_nblocks, BlockNumber *nblocks) { int i; diff --git a/src/include/storage/smgr.h b/src/include/storage/smgr.h index 3f07099201d..55fce3fa04a 100644 --- a/src/include/storage/smgr.h +++ b/src/include/storage/smgr.h @@ -151,8 +151,10 @@ extern void smgrwriteback(SMgrRelation reln, ForkNumber forknum, extern BlockNumber smgrnblocks(SMgrRelation reln, ForkNumber forknum); extern BlockNumber smgrnblocks_cached(SMgrRelation reln, ForkNumber forknum); extern void smgrtruncate(SMgrRelation reln, ForkNumber *forknum, int nforks, - BlockNumber *old_nblocks, BlockNumber *nblocks); +extern void smgrtruncate2(SMgrRelation reln, ForkNumber *forknum, int nforks, + BlockNumber *old_nblocks, + BlockNumber *nblocks); extern void smgrimmedsync(SMgrRelation reln, ForkNumber forknum); extern void smgrregistersync(SMgrRelation reln, ForkNumber forknum); extern void AtEOXact_SMgr(void);