From 58828b0230e7cd668f65039c56a3bc11e52aeffd Mon Sep 17 00:00:00 2001
From: Yura Sokolov <y.sokolov@postgrespro.ru>
Date: Fri, 27 Mar 2026 21:19:41 +0300
Subject: [PATCH v2 3/3] bufmgr: print flag names in DebugPrintBufferRefcount

---
 src/backend/storage/buffer/bufmgr.c    | 42 +++++++++++++++++++++-----
 src/test/modules/test_aio/t/001_aio.pl |  6 ++--
 2 files changed, 36 insertions(+), 12 deletions(-)

diff --git a/src/backend/storage/buffer/bufmgr.c b/src/backend/storage/buffer/bufmgr.c
index fd12566e674..5e9820ccc78 100644
--- a/src/backend/storage/buffer/bufmgr.c
+++ b/src/backend/storage/buffer/bufmgr.c
@@ -48,6 +48,7 @@
 #include "common/hashfn.h"
 #include "executor/instrument.h"
 #include "lib/binaryheap.h"
+#include "lib/stringinfo.h"
 #include "miscadmin.h"
 #include "pg_trace.h"
 #include "pgstat.h"
@@ -4371,9 +4372,10 @@ DebugPrintBufferRefcount(Buffer buffer)
 {
 	BufferDesc *buf;
 	int32		loccount;
-	char	   *result;
 	ProcNumber	backend;
 	uint64		buf_state;
+	StringInfoData str;
+	char		flag_prefix = '=';
 
 	Assert(BufferIsValid(buffer));
 	if (BufferIsLocal(buffer))
@@ -4389,16 +4391,39 @@ DebugPrintBufferRefcount(Buffer buffer)
 		backend = INVALID_PROC_NUMBER;
 	}
 
+	initStringInfoExt(&str, 256);
+
 	/* theoretically we should lock the bufHdr here */
 	buf_state = pg_atomic_read_u64(&buf->state);
 
-	result = psprintf("[%03d] (rel=%s, blockNum=%u, flags=0x%" PRIx64 ", refcount=%u %d)",
-					  buffer,
-					  relpathbackend(BufTagGetRelFileLocator(&buf->tag), backend,
-									 BufTagGetForkNum(&buf->tag)).str,
-					  buf->tag.blockNum, buf_state & BUF_FLAG_MASK,
-					  BUF_STATE_GET_REFCOUNT(buf_state), loccount);
-	return result;
+	appendStringInfo(&str, "[%03d] (rel=%s, blockNum=%u, flags",
+					 buffer,
+					 relpathbackend(BufTagGetRelFileLocator(&buf->tag), backend,
+									BufTagGetForkNum(&buf->tag)).str,
+					 buf->tag.blockNum);
+#define appendFlag(flag) do { \
+	if (buf_state & flag) { \
+		appendStringInfoChar(&str, flag_prefix); \
+		appendStringInfoString(&str, #flag); \
+		flag_prefix = '|'; \
+	} \
+} while(0)
+	appendFlag(BM_LOCKED);
+	appendFlag(BM_DIRTY);
+	appendFlag(BM_VALID);
+	appendFlag(BM_TAG_VALID);
+	appendFlag(BM_IO_IN_PROGRESS);
+	appendFlag(BM_IO_ERROR);
+	appendFlag(BM_PIN_COUNT_WAITER);
+	appendFlag(BM_CHECKPOINT_NEEDED);
+	appendFlag(BM_PERMANENT);
+	appendFlag(BM_LOCK_HAS_WAITERS);
+	appendFlag(BM_LOCK_WAKE_IN_PROGRESS);
+#undef appendFlag
+
+	appendStringInfo(&str, ", refcount=%u %d)",
+					 BUF_STATE_GET_REFCOUNT(buf_state), loccount);
+	return str.data;
 }
 
 /*
@@ -4562,6 +4587,7 @@ FlushBuffer(BufferDesc *buf, SMgrRelation reln, IOObject io_object,
 			  false);
 
 	INJECTION_POINT("flush-buffer-after-smgr-write", buf);
+
 	/*
 	 * When a strategy is in use, only flushes of dirty buffers already in the
 	 * strategy ring are counted as strategy writes (IOCONTEXT
diff --git a/src/test/modules/test_aio/t/001_aio.pl b/src/test/modules/test_aio/t/001_aio.pl
index 54061e0425b..35d42cfdfca 100644
--- a/src/test/modules/test_aio/t/001_aio.pl
+++ b/src/test/modules/test_aio/t/001_aio.pl
@@ -344,8 +344,7 @@ SELECT modify_rel_block('tmp_corr', 1, corrupt_header=>true);
 		  $tblname eq 'tbl_corr'
 		  ? qr/invalid page in block 1 of relation "base\/\d+\/\d+/
 		  : qr/invalid page in block 1 of relation "base\/\d+\/t\d+_\d+/;
-		# BM_IO_ERROR and BM_TAG_VALID should be set
-		my $debug_print_re = qr/blockNum=1, flags=0x.?a000000, refcount=0/;
+		my $debug_print_re = qr/blockNum=1, flags=BM_TAG_VALID\|BM_IO_ERROR\S*, refcount=0/;
 
 		# verify the error is reported in custom C code
 		psql_like(
@@ -828,12 +827,11 @@ SELECT invalidate_rel_block('tbl_ok', 2);
 		qr/^$/,
 		qr/ERROR:.*injection point triggering failure to flush buffer/
 	);
-	# BM_IO_ERROR, BM_VALID and BM_TAG_VALID should be set
 	psql_like(
 		$io_method, $psql,
 		"validate flags of 'tbl_ok' page after read_rel_block_ll()",
 		qq(SELECT debug_print_rel_block('tbl_ok', 2)),
-		qr/blockNum=2, flags=0x.?b.00000, refcount=0/, qr/^$/);
+		qr/blockNum=2, flags=BM_DIRTY\|BM_VALID\|BM_TAG_VALID\|BM_IO_ERROR\S*, refcount=0/, qr/^$/);
 	# Validate second attempt leads to "Multiple failures" message
 	psql_like(
 		$io_method, $psql,
-- 
2.51.0

