From 54cd0e6f63f5e7e757d9d1e636507fa782ac8a4f Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@gmail.com>
Date: Sat, 21 Dec 2024 11:40:09 +1300
Subject: [PATCH] Restore smgrtruncate() prototype in back-branches.

It's possible that external code is calling smgrtruncate().  Any
external callers that copied core code might like to consider the recent
changes to RelationTruncate(), but commit 38c579b0 should not have
changed the function prototype in the back-branches, per ABI stability
policy.

Restore smgrtruncate()'s traditional argument list in the back-branches,
but make it a wrapper for a new function smgrtruncate2().  The three
callers in core can use smgrtruncate2() directly.  In master (18-to-be),
smgrtruncate2() is effectively renamed to smgrtruncate().

Discussion: https://postgr.es/m/CA%2BhUKG%2BThae6x6%2BjmQiuALQBT2Ae1ChjMh1%3DkMvJ8y_SBJZrvA%40mail.gmail.com
---
 contrib/pg_visibility/pg_visibility.c |  2 +-
 src/backend/catalog/storage.c         |  4 ++--
 src/backend/storage/smgr/smgr.c       | 24 ++++++++++++++++++++++--
 src/include/storage/smgr.h            |  4 +++-
 4 files changed, 28 insertions(+), 6 deletions(-)

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 5b22cf10990..11b3ea40200 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 b3fb8bc3ea8..89d62d1dee8 100644
--- a/src/backend/storage/smgr/smgr.c
+++ b/src/backend/storage/smgr/smgr.c
@@ -693,6 +693,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
@@ -704,8 +724,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 98fabe9935c..3856d1d4f8b 100644
--- a/src/include/storage/smgr.h
+++ b/src/include/storage/smgr.h
@@ -104,8 +104,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);
-- 
2.47.1

