From d9edd5e0c86c36e005d8ee2f76df062fa15d46fb Mon Sep 17 00:00:00 2001
From: Srinath Reddy Sadipiralla <srinath2133@gmail.com>
Date: Sun, 26 Jan 2025 19:46:15 +0530
Subject: [PATCH 1/1] 	Handle local buffer cases properly in
 BufferIsExclusiveLocked and BufferIsDirty

---
 src/backend/access/transam/xloginsert.c |  4 ++-
 src/backend/storage/buffer/bufmgr.c     | 38 +++++++++----------------
 src/include/storage/bufmgr.h            |  6 ++--
 3 files changed, 21 insertions(+), 27 deletions(-)

diff --git a/src/backend/access/transam/xloginsert.c b/src/backend/access/transam/xloginsert.c
index 9047601534..7d58d73976 100644
--- a/src/backend/access/transam/xloginsert.c
+++ b/src/backend/access/transam/xloginsert.c
@@ -39,6 +39,7 @@
 #include "storage/bufmgr.h"
 #include "storage/proc.h"
 #include "utils/memutils.h"
+#include "storage/buf_internals.h"
 
 /*
  * Guess the maximum buffer size required to store a compressed version of
@@ -257,8 +258,9 @@ XLogRegisterBuffer(uint8 block_id, Buffer buffer, uint8 flags)
 	 * bypass these checks.
 	 */
 #ifdef USE_ASSERT_CHECKING
+	BufferDesc *bufHdr;
 	if (!(flags & REGBUF_NO_CHANGE))
-		Assert(BufferIsExclusiveLocked(buffer) && BufferIsDirty(buffer));
+		Assert(BufferIsExclusiveLocked(buffer,&bufHdr) && BufferIsDirty(buffer));
 #endif
 
 	if (block_id >= max_registered_block_id)
diff --git a/src/backend/storage/buffer/bufmgr.c b/src/backend/storage/buffer/bufmgr.c
index 6181673095..a5f232113e 100644
--- a/src/backend/storage/buffer/bufmgr.c
+++ b/src/backend/storage/buffer/bufmgr.c
@@ -2451,29 +2451,33 @@ ExtendBufferedRelShared(BufferManagerRelation bmr,
 /*
  * BufferIsExclusiveLocked
  *
- *      Checks if buffer is exclusive-locked.
+ *      Checks if buffer is exclusive-locked,For local buffers we act as exclusive lock is always
+ * held,because we don't initialize content locks for local buffers.
  *
  * Buffer must be pinned.
  */
 bool
-BufferIsExclusiveLocked(Buffer buffer)
+BufferIsExclusiveLocked(Buffer buffer,BufferDesc **bufHdr)
 {
-	BufferDesc *bufHdr;
+	bool bufferIsExclusiveLocked = false;
+
+	Assert(BufferIsPinned(buffer));
 
 	if (BufferIsLocal(buffer))
 	{
 		int			bufid = -buffer - 1;
 
-		bufHdr = GetLocalBufferDescriptor(bufid);
+		*bufHdr = GetLocalBufferDescriptor(bufid);
+		bufferIsExclusiveLocked = true;
 	}
 	else
 	{
-		bufHdr = GetBufferDescriptor(buffer - 1);
-	}
-
-	Assert(BufferIsPinned(buffer));
-	return LWLockHeldByMeInMode(BufferDescriptorGetContentLock(bufHdr),
+		*bufHdr = GetBufferDescriptor(buffer - 1);
+		bufferIsExclusiveLocked = LWLockHeldByMeInMode(BufferDescriptorGetContentLock(*bufHdr),
 								LW_EXCLUSIVE);
+	}
+	
+	return bufferIsExclusiveLocked;
 }
 
 /*
@@ -2488,21 +2492,7 @@ bool
 BufferIsDirty(Buffer buffer)
 {
 	BufferDesc *bufHdr;
-
-	if (BufferIsLocal(buffer))
-	{
-		int			bufid = -buffer - 1;
-
-		bufHdr = GetLocalBufferDescriptor(bufid);
-	}
-	else
-	{
-		bufHdr = GetBufferDescriptor(buffer - 1);
-	}
-
-	Assert(BufferIsPinned(buffer));
-	Assert(LWLockHeldByMeInMode(BufferDescriptorGetContentLock(bufHdr),
-								LW_EXCLUSIVE));
+	Assert(BufferIsExclusiveLocked(buffer,&bufHdr));
 
 	return pg_atomic_read_u32(&bufHdr->state) & BM_DIRTY;
 }
diff --git a/src/include/storage/bufmgr.h b/src/include/storage/bufmgr.h
index a1e71013d3..f2cbba6034 100644
--- a/src/include/storage/bufmgr.h
+++ b/src/include/storage/bufmgr.h
@@ -23,7 +23,9 @@
 #include "utils/snapmgr.h"
 
 typedef void *Block;
-
+/* Forward declaration, to avoid including buf_internals.h here */
+struct BufferDesc;
+typedef struct BufferDesc BufferDesc;
 /*
  * Possible arguments for GetAccessStrategy().
  *
@@ -227,7 +229,7 @@ extern void WaitReadBuffers(ReadBuffersOperation *operation);
 
 extern void ReleaseBuffer(Buffer buffer);
 extern void UnlockReleaseBuffer(Buffer buffer);
-extern bool BufferIsExclusiveLocked(Buffer buffer);
+extern bool BufferIsExclusiveLocked(Buffer buffer,BufferDesc **bufHdr);
 extern bool BufferIsDirty(Buffer buffer);
 extern void MarkBufferDirty(Buffer buffer);
 extern void IncrBufferRefCount(Buffer buffer);
-- 
2.43.0

