agora inbox for pgsql-hackers@postgresql.org  
help / color / mirror / Atom feed
[PATCH v5 10/10] Additional validation for buffer in the ring
107+ messages / 2 participants
[nested] [flat]

* [PATCH v5 10/10] Additional validation for buffer in the ring
@ 2025-06-11 12:45 Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
  0 siblings, 0 replies; 107+ messages in thread

From: Ashutosh Bapat @ 2025-06-11 12:45 UTC (permalink / raw)

If the buffer pool has been shrunk, the buffers in the buffer list may
not be valid anymore. Modify GetBufferFromRing to check if the buffer is
still valid before using it. This makes GetBufferFromRing() a bit more
expensive because of additional boolean condition. That may not be
expensive enough to affect query performance. The alternative to that is
more complex as explained below.

The strategy object is created in CurrentMemoryContext and is not
available in any global structure thus accessible when processing buffer
resizing barriers. We may modify GetAccessStrategy() to register
strategy in a global linked list and then arrange to deregister it once
it's no more in use. Looking at the places which use
GetAccessStrategy(), fixing all those may be some work.

Ashutosh Bapat
---
 src/backend/storage/buffer/freelist.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/src/backend/storage/buffer/freelist.c b/src/backend/storage/buffer/freelist.c
index 41641bb3ae6..74d070733a4 100644
--- a/src/backend/storage/buffer/freelist.c
+++ b/src/backend/storage/buffer/freelist.c
@@ -948,12 +948,13 @@ GetBufferFromRing(BufferAccessStrategy strategy, uint32 *buf_state)
 		strategy->current = 0;
 
 	/*
-	 * If the slot hasn't been filled yet, tell the caller to allocate a new
-	 * buffer with the normal allocation strategy.  He will then fill this
-	 * slot by calling AddBufferToRing with the new buffer.
+	 * If the slot hasn't been filled yet or the buffer in the slot has been
+	 * invalidated when buffer pool was shrunk, tell the caller to allocate a new
+	 * buffer with the normal allocation strategy.  He will then fill this slot
+	 * by calling AddBufferToRing with the new buffer.
 	 */
 	bufnum = strategy->buffers[strategy->current];
-	if (bufnum == InvalidBuffer)
+	if (bufnum == InvalidBuffer || bufnum > NBuffers)
 		return NULL;
 
 	/*
-- 
2.49.0


--bwrlgp6w2ubxykjq--





^ permalink  raw  reply  [nested|flat] 107+ messages in thread

* [PATCH v5 10/10] Additional validation for buffer in the ring
@ 2025-06-11 12:45 Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
  0 siblings, 0 replies; 107+ messages in thread

From: Ashutosh Bapat @ 2025-06-11 12:45 UTC (permalink / raw)

If the buffer pool has been shrunk, the buffers in the buffer list may
not be valid anymore. Modify GetBufferFromRing to check if the buffer is
still valid before using it. This makes GetBufferFromRing() a bit more
expensive because of additional boolean condition. That may not be
expensive enough to affect query performance. The alternative to that is
more complex as explained below.

The strategy object is created in CurrentMemoryContext and is not
available in any global structure thus accessible when processing buffer
resizing barriers. We may modify GetAccessStrategy() to register
strategy in a global linked list and then arrange to deregister it once
it's no more in use. Looking at the places which use
GetAccessStrategy(), fixing all those may be some work.

Ashutosh Bapat
---
 src/backend/storage/buffer/freelist.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/src/backend/storage/buffer/freelist.c b/src/backend/storage/buffer/freelist.c
index 41641bb3ae6..74d070733a4 100644
--- a/src/backend/storage/buffer/freelist.c
+++ b/src/backend/storage/buffer/freelist.c
@@ -948,12 +948,13 @@ GetBufferFromRing(BufferAccessStrategy strategy, uint32 *buf_state)
 		strategy->current = 0;
 
 	/*
-	 * If the slot hasn't been filled yet, tell the caller to allocate a new
-	 * buffer with the normal allocation strategy.  He will then fill this
-	 * slot by calling AddBufferToRing with the new buffer.
+	 * If the slot hasn't been filled yet or the buffer in the slot has been
+	 * invalidated when buffer pool was shrunk, tell the caller to allocate a new
+	 * buffer with the normal allocation strategy.  He will then fill this slot
+	 * by calling AddBufferToRing with the new buffer.
 	 */
 	bufnum = strategy->buffers[strategy->current];
-	if (bufnum == InvalidBuffer)
+	if (bufnum == InvalidBuffer || bufnum > NBuffers)
 		return NULL;
 
 	/*
-- 
2.49.0


--bwrlgp6w2ubxykjq--





^ permalink  raw  reply  [nested|flat] 107+ messages in thread

* [PATCH v5 10/10] Additional validation for buffer in the ring
@ 2025-06-11 12:45 Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
  0 siblings, 0 replies; 107+ messages in thread

From: Ashutosh Bapat @ 2025-06-11 12:45 UTC (permalink / raw)

If the buffer pool has been shrunk, the buffers in the buffer list may
not be valid anymore. Modify GetBufferFromRing to check if the buffer is
still valid before using it. This makes GetBufferFromRing() a bit more
expensive because of additional boolean condition. That may not be
expensive enough to affect query performance. The alternative to that is
more complex as explained below.

The strategy object is created in CurrentMemoryContext and is not
available in any global structure thus accessible when processing buffer
resizing barriers. We may modify GetAccessStrategy() to register
strategy in a global linked list and then arrange to deregister it once
it's no more in use. Looking at the places which use
GetAccessStrategy(), fixing all those may be some work.

Ashutosh Bapat
---
 src/backend/storage/buffer/freelist.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/src/backend/storage/buffer/freelist.c b/src/backend/storage/buffer/freelist.c
index 41641bb3ae6..74d070733a4 100644
--- a/src/backend/storage/buffer/freelist.c
+++ b/src/backend/storage/buffer/freelist.c
@@ -948,12 +948,13 @@ GetBufferFromRing(BufferAccessStrategy strategy, uint32 *buf_state)
 		strategy->current = 0;
 
 	/*
-	 * If the slot hasn't been filled yet, tell the caller to allocate a new
-	 * buffer with the normal allocation strategy.  He will then fill this
-	 * slot by calling AddBufferToRing with the new buffer.
+	 * If the slot hasn't been filled yet or the buffer in the slot has been
+	 * invalidated when buffer pool was shrunk, tell the caller to allocate a new
+	 * buffer with the normal allocation strategy.  He will then fill this slot
+	 * by calling AddBufferToRing with the new buffer.
 	 */
 	bufnum = strategy->buffers[strategy->current];
-	if (bufnum == InvalidBuffer)
+	if (bufnum == InvalidBuffer || bufnum > NBuffers)
 		return NULL;
 
 	/*
-- 
2.49.0


--bwrlgp6w2ubxykjq--





^ permalink  raw  reply  [nested|flat] 107+ messages in thread

* [PATCH v5 10/10] Additional validation for buffer in the ring
@ 2025-06-11 12:45 Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
  0 siblings, 0 replies; 107+ messages in thread

From: Ashutosh Bapat @ 2025-06-11 12:45 UTC (permalink / raw)

If the buffer pool has been shrunk, the buffers in the buffer list may
not be valid anymore. Modify GetBufferFromRing to check if the buffer is
still valid before using it. This makes GetBufferFromRing() a bit more
expensive because of additional boolean condition. That may not be
expensive enough to affect query performance. The alternative to that is
more complex as explained below.

The strategy object is created in CurrentMemoryContext and is not
available in any global structure thus accessible when processing buffer
resizing barriers. We may modify GetAccessStrategy() to register
strategy in a global linked list and then arrange to deregister it once
it's no more in use. Looking at the places which use
GetAccessStrategy(), fixing all those may be some work.

Ashutosh Bapat
---
 src/backend/storage/buffer/freelist.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/src/backend/storage/buffer/freelist.c b/src/backend/storage/buffer/freelist.c
index 41641bb3ae6..74d070733a4 100644
--- a/src/backend/storage/buffer/freelist.c
+++ b/src/backend/storage/buffer/freelist.c
@@ -948,12 +948,13 @@ GetBufferFromRing(BufferAccessStrategy strategy, uint32 *buf_state)
 		strategy->current = 0;
 
 	/*
-	 * If the slot hasn't been filled yet, tell the caller to allocate a new
-	 * buffer with the normal allocation strategy.  He will then fill this
-	 * slot by calling AddBufferToRing with the new buffer.
+	 * If the slot hasn't been filled yet or the buffer in the slot has been
+	 * invalidated when buffer pool was shrunk, tell the caller to allocate a new
+	 * buffer with the normal allocation strategy.  He will then fill this slot
+	 * by calling AddBufferToRing with the new buffer.
 	 */
 	bufnum = strategy->buffers[strategy->current];
-	if (bufnum == InvalidBuffer)
+	if (bufnum == InvalidBuffer || bufnum > NBuffers)
 		return NULL;
 
 	/*
-- 
2.49.0


--bwrlgp6w2ubxykjq--





^ permalink  raw  reply  [nested|flat] 107+ messages in thread

* [PATCH v5 10/10] Additional validation for buffer in the ring
@ 2025-06-11 12:45 Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
  0 siblings, 0 replies; 107+ messages in thread

From: Ashutosh Bapat @ 2025-06-11 12:45 UTC (permalink / raw)

If the buffer pool has been shrunk, the buffers in the buffer list may
not be valid anymore. Modify GetBufferFromRing to check if the buffer is
still valid before using it. This makes GetBufferFromRing() a bit more
expensive because of additional boolean condition. That may not be
expensive enough to affect query performance. The alternative to that is
more complex as explained below.

The strategy object is created in CurrentMemoryContext and is not
available in any global structure thus accessible when processing buffer
resizing barriers. We may modify GetAccessStrategy() to register
strategy in a global linked list and then arrange to deregister it once
it's no more in use. Looking at the places which use
GetAccessStrategy(), fixing all those may be some work.

Ashutosh Bapat
---
 src/backend/storage/buffer/freelist.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/src/backend/storage/buffer/freelist.c b/src/backend/storage/buffer/freelist.c
index 41641bb3ae6..74d070733a4 100644
--- a/src/backend/storage/buffer/freelist.c
+++ b/src/backend/storage/buffer/freelist.c
@@ -948,12 +948,13 @@ GetBufferFromRing(BufferAccessStrategy strategy, uint32 *buf_state)
 		strategy->current = 0;
 
 	/*
-	 * If the slot hasn't been filled yet, tell the caller to allocate a new
-	 * buffer with the normal allocation strategy.  He will then fill this
-	 * slot by calling AddBufferToRing with the new buffer.
+	 * If the slot hasn't been filled yet or the buffer in the slot has been
+	 * invalidated when buffer pool was shrunk, tell the caller to allocate a new
+	 * buffer with the normal allocation strategy.  He will then fill this slot
+	 * by calling AddBufferToRing with the new buffer.
 	 */
 	bufnum = strategy->buffers[strategy->current];
-	if (bufnum == InvalidBuffer)
+	if (bufnum == InvalidBuffer || bufnum > NBuffers)
 		return NULL;
 
 	/*
-- 
2.49.0


--bwrlgp6w2ubxykjq--





^ permalink  raw  reply  [nested|flat] 107+ messages in thread

* [PATCH v5 10/10] Additional validation for buffer in the ring
@ 2025-06-11 12:45 Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
  0 siblings, 0 replies; 107+ messages in thread

From: Ashutosh Bapat @ 2025-06-11 12:45 UTC (permalink / raw)

If the buffer pool has been shrunk, the buffers in the buffer list may
not be valid anymore. Modify GetBufferFromRing to check if the buffer is
still valid before using it. This makes GetBufferFromRing() a bit more
expensive because of additional boolean condition. That may not be
expensive enough to affect query performance. The alternative to that is
more complex as explained below.

The strategy object is created in CurrentMemoryContext and is not
available in any global structure thus accessible when processing buffer
resizing barriers. We may modify GetAccessStrategy() to register
strategy in a global linked list and then arrange to deregister it once
it's no more in use. Looking at the places which use
GetAccessStrategy(), fixing all those may be some work.

Ashutosh Bapat
---
 src/backend/storage/buffer/freelist.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/src/backend/storage/buffer/freelist.c b/src/backend/storage/buffer/freelist.c
index 41641bb3ae6..74d070733a4 100644
--- a/src/backend/storage/buffer/freelist.c
+++ b/src/backend/storage/buffer/freelist.c
@@ -948,12 +948,13 @@ GetBufferFromRing(BufferAccessStrategy strategy, uint32 *buf_state)
 		strategy->current = 0;
 
 	/*
-	 * If the slot hasn't been filled yet, tell the caller to allocate a new
-	 * buffer with the normal allocation strategy.  He will then fill this
-	 * slot by calling AddBufferToRing with the new buffer.
+	 * If the slot hasn't been filled yet or the buffer in the slot has been
+	 * invalidated when buffer pool was shrunk, tell the caller to allocate a new
+	 * buffer with the normal allocation strategy.  He will then fill this slot
+	 * by calling AddBufferToRing with the new buffer.
 	 */
 	bufnum = strategy->buffers[strategy->current];
-	if (bufnum == InvalidBuffer)
+	if (bufnum == InvalidBuffer || bufnum > NBuffers)
 		return NULL;
 
 	/*
-- 
2.49.0


--bwrlgp6w2ubxykjq--





^ permalink  raw  reply  [nested|flat] 107+ messages in thread

* [PATCH v5 10/10] Additional validation for buffer in the ring
@ 2025-06-11 12:45 Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
  0 siblings, 0 replies; 107+ messages in thread

From: Ashutosh Bapat @ 2025-06-11 12:45 UTC (permalink / raw)

If the buffer pool has been shrunk, the buffers in the buffer list may
not be valid anymore. Modify GetBufferFromRing to check if the buffer is
still valid before using it. This makes GetBufferFromRing() a bit more
expensive because of additional boolean condition. That may not be
expensive enough to affect query performance. The alternative to that is
more complex as explained below.

The strategy object is created in CurrentMemoryContext and is not
available in any global structure thus accessible when processing buffer
resizing barriers. We may modify GetAccessStrategy() to register
strategy in a global linked list and then arrange to deregister it once
it's no more in use. Looking at the places which use
GetAccessStrategy(), fixing all those may be some work.

Ashutosh Bapat
---
 src/backend/storage/buffer/freelist.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/src/backend/storage/buffer/freelist.c b/src/backend/storage/buffer/freelist.c
index 41641bb3ae6..74d070733a4 100644
--- a/src/backend/storage/buffer/freelist.c
+++ b/src/backend/storage/buffer/freelist.c
@@ -948,12 +948,13 @@ GetBufferFromRing(BufferAccessStrategy strategy, uint32 *buf_state)
 		strategy->current = 0;
 
 	/*
-	 * If the slot hasn't been filled yet, tell the caller to allocate a new
-	 * buffer with the normal allocation strategy.  He will then fill this
-	 * slot by calling AddBufferToRing with the new buffer.
+	 * If the slot hasn't been filled yet or the buffer in the slot has been
+	 * invalidated when buffer pool was shrunk, tell the caller to allocate a new
+	 * buffer with the normal allocation strategy.  He will then fill this slot
+	 * by calling AddBufferToRing with the new buffer.
 	 */
 	bufnum = strategy->buffers[strategy->current];
-	if (bufnum == InvalidBuffer)
+	if (bufnum == InvalidBuffer || bufnum > NBuffers)
 		return NULL;
 
 	/*
-- 
2.49.0


--bwrlgp6w2ubxykjq--





^ permalink  raw  reply  [nested|flat] 107+ messages in thread

* [PATCH v5 10/10] Additional validation for buffer in the ring
@ 2025-06-11 12:45 Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
  0 siblings, 0 replies; 107+ messages in thread

From: Ashutosh Bapat @ 2025-06-11 12:45 UTC (permalink / raw)

If the buffer pool has been shrunk, the buffers in the buffer list may
not be valid anymore. Modify GetBufferFromRing to check if the buffer is
still valid before using it. This makes GetBufferFromRing() a bit more
expensive because of additional boolean condition. That may not be
expensive enough to affect query performance. The alternative to that is
more complex as explained below.

The strategy object is created in CurrentMemoryContext and is not
available in any global structure thus accessible when processing buffer
resizing barriers. We may modify GetAccessStrategy() to register
strategy in a global linked list and then arrange to deregister it once
it's no more in use. Looking at the places which use
GetAccessStrategy(), fixing all those may be some work.

Ashutosh Bapat
---
 src/backend/storage/buffer/freelist.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/src/backend/storage/buffer/freelist.c b/src/backend/storage/buffer/freelist.c
index 41641bb3ae6..74d070733a4 100644
--- a/src/backend/storage/buffer/freelist.c
+++ b/src/backend/storage/buffer/freelist.c
@@ -948,12 +948,13 @@ GetBufferFromRing(BufferAccessStrategy strategy, uint32 *buf_state)
 		strategy->current = 0;
 
 	/*
-	 * If the slot hasn't been filled yet, tell the caller to allocate a new
-	 * buffer with the normal allocation strategy.  He will then fill this
-	 * slot by calling AddBufferToRing with the new buffer.
+	 * If the slot hasn't been filled yet or the buffer in the slot has been
+	 * invalidated when buffer pool was shrunk, tell the caller to allocate a new
+	 * buffer with the normal allocation strategy.  He will then fill this slot
+	 * by calling AddBufferToRing with the new buffer.
 	 */
 	bufnum = strategy->buffers[strategy->current];
-	if (bufnum == InvalidBuffer)
+	if (bufnum == InvalidBuffer || bufnum > NBuffers)
 		return NULL;
 
 	/*
-- 
2.49.0


--bwrlgp6w2ubxykjq--





^ permalink  raw  reply  [nested|flat] 107+ messages in thread

* [PATCH v5 10/10] Additional validation for buffer in the ring
@ 2025-06-11 12:45 Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
  0 siblings, 0 replies; 107+ messages in thread

From: Ashutosh Bapat @ 2025-06-11 12:45 UTC (permalink / raw)

If the buffer pool has been shrunk, the buffers in the buffer list may
not be valid anymore. Modify GetBufferFromRing to check if the buffer is
still valid before using it. This makes GetBufferFromRing() a bit more
expensive because of additional boolean condition. That may not be
expensive enough to affect query performance. The alternative to that is
more complex as explained below.

The strategy object is created in CurrentMemoryContext and is not
available in any global structure thus accessible when processing buffer
resizing barriers. We may modify GetAccessStrategy() to register
strategy in a global linked list and then arrange to deregister it once
it's no more in use. Looking at the places which use
GetAccessStrategy(), fixing all those may be some work.

Ashutosh Bapat
---
 src/backend/storage/buffer/freelist.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/src/backend/storage/buffer/freelist.c b/src/backend/storage/buffer/freelist.c
index 41641bb3ae6..74d070733a4 100644
--- a/src/backend/storage/buffer/freelist.c
+++ b/src/backend/storage/buffer/freelist.c
@@ -948,12 +948,13 @@ GetBufferFromRing(BufferAccessStrategy strategy, uint32 *buf_state)
 		strategy->current = 0;
 
 	/*
-	 * If the slot hasn't been filled yet, tell the caller to allocate a new
-	 * buffer with the normal allocation strategy.  He will then fill this
-	 * slot by calling AddBufferToRing with the new buffer.
+	 * If the slot hasn't been filled yet or the buffer in the slot has been
+	 * invalidated when buffer pool was shrunk, tell the caller to allocate a new
+	 * buffer with the normal allocation strategy.  He will then fill this slot
+	 * by calling AddBufferToRing with the new buffer.
 	 */
 	bufnum = strategy->buffers[strategy->current];
-	if (bufnum == InvalidBuffer)
+	if (bufnum == InvalidBuffer || bufnum > NBuffers)
 		return NULL;
 
 	/*
-- 
2.49.0


--bwrlgp6w2ubxykjq--





^ permalink  raw  reply  [nested|flat] 107+ messages in thread

* [PATCH v5 10/10] Additional validation for buffer in the ring
@ 2025-06-11 12:45 Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
  0 siblings, 0 replies; 107+ messages in thread

From: Ashutosh Bapat @ 2025-06-11 12:45 UTC (permalink / raw)

If the buffer pool has been shrunk, the buffers in the buffer list may
not be valid anymore. Modify GetBufferFromRing to check if the buffer is
still valid before using it. This makes GetBufferFromRing() a bit more
expensive because of additional boolean condition. That may not be
expensive enough to affect query performance. The alternative to that is
more complex as explained below.

The strategy object is created in CurrentMemoryContext and is not
available in any global structure thus accessible when processing buffer
resizing barriers. We may modify GetAccessStrategy() to register
strategy in a global linked list and then arrange to deregister it once
it's no more in use. Looking at the places which use
GetAccessStrategy(), fixing all those may be some work.

Ashutosh Bapat
---
 src/backend/storage/buffer/freelist.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/src/backend/storage/buffer/freelist.c b/src/backend/storage/buffer/freelist.c
index 41641bb3ae6..74d070733a4 100644
--- a/src/backend/storage/buffer/freelist.c
+++ b/src/backend/storage/buffer/freelist.c
@@ -948,12 +948,13 @@ GetBufferFromRing(BufferAccessStrategy strategy, uint32 *buf_state)
 		strategy->current = 0;
 
 	/*
-	 * If the slot hasn't been filled yet, tell the caller to allocate a new
-	 * buffer with the normal allocation strategy.  He will then fill this
-	 * slot by calling AddBufferToRing with the new buffer.
+	 * If the slot hasn't been filled yet or the buffer in the slot has been
+	 * invalidated when buffer pool was shrunk, tell the caller to allocate a new
+	 * buffer with the normal allocation strategy.  He will then fill this slot
+	 * by calling AddBufferToRing with the new buffer.
 	 */
 	bufnum = strategy->buffers[strategy->current];
-	if (bufnum == InvalidBuffer)
+	if (bufnum == InvalidBuffer || bufnum > NBuffers)
 		return NULL;
 
 	/*
-- 
2.49.0


--bwrlgp6w2ubxykjq--





^ permalink  raw  reply  [nested|flat] 107+ messages in thread

* [PATCH v5 10/10] Additional validation for buffer in the ring
@ 2025-06-11 12:45 Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
  0 siblings, 0 replies; 107+ messages in thread

From: Ashutosh Bapat @ 2025-06-11 12:45 UTC (permalink / raw)

If the buffer pool has been shrunk, the buffers in the buffer list may
not be valid anymore. Modify GetBufferFromRing to check if the buffer is
still valid before using it. This makes GetBufferFromRing() a bit more
expensive because of additional boolean condition. That may not be
expensive enough to affect query performance. The alternative to that is
more complex as explained below.

The strategy object is created in CurrentMemoryContext and is not
available in any global structure thus accessible when processing buffer
resizing barriers. We may modify GetAccessStrategy() to register
strategy in a global linked list and then arrange to deregister it once
it's no more in use. Looking at the places which use
GetAccessStrategy(), fixing all those may be some work.

Ashutosh Bapat
---
 src/backend/storage/buffer/freelist.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/src/backend/storage/buffer/freelist.c b/src/backend/storage/buffer/freelist.c
index 41641bb3ae6..74d070733a4 100644
--- a/src/backend/storage/buffer/freelist.c
+++ b/src/backend/storage/buffer/freelist.c
@@ -948,12 +948,13 @@ GetBufferFromRing(BufferAccessStrategy strategy, uint32 *buf_state)
 		strategy->current = 0;
 
 	/*
-	 * If the slot hasn't been filled yet, tell the caller to allocate a new
-	 * buffer with the normal allocation strategy.  He will then fill this
-	 * slot by calling AddBufferToRing with the new buffer.
+	 * If the slot hasn't been filled yet or the buffer in the slot has been
+	 * invalidated when buffer pool was shrunk, tell the caller to allocate a new
+	 * buffer with the normal allocation strategy.  He will then fill this slot
+	 * by calling AddBufferToRing with the new buffer.
 	 */
 	bufnum = strategy->buffers[strategy->current];
-	if (bufnum == InvalidBuffer)
+	if (bufnum == InvalidBuffer || bufnum > NBuffers)
 		return NULL;
 
 	/*
-- 
2.49.0


--bwrlgp6w2ubxykjq--





^ permalink  raw  reply  [nested|flat] 107+ messages in thread

* [PATCH v5 10/10] Additional validation for buffer in the ring
@ 2025-06-11 12:45 Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
  0 siblings, 0 replies; 107+ messages in thread

From: Ashutosh Bapat @ 2025-06-11 12:45 UTC (permalink / raw)

If the buffer pool has been shrunk, the buffers in the buffer list may
not be valid anymore. Modify GetBufferFromRing to check if the buffer is
still valid before using it. This makes GetBufferFromRing() a bit more
expensive because of additional boolean condition. That may not be
expensive enough to affect query performance. The alternative to that is
more complex as explained below.

The strategy object is created in CurrentMemoryContext and is not
available in any global structure thus accessible when processing buffer
resizing barriers. We may modify GetAccessStrategy() to register
strategy in a global linked list and then arrange to deregister it once
it's no more in use. Looking at the places which use
GetAccessStrategy(), fixing all those may be some work.

Ashutosh Bapat
---
 src/backend/storage/buffer/freelist.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/src/backend/storage/buffer/freelist.c b/src/backend/storage/buffer/freelist.c
index 41641bb3ae6..74d070733a4 100644
--- a/src/backend/storage/buffer/freelist.c
+++ b/src/backend/storage/buffer/freelist.c
@@ -948,12 +948,13 @@ GetBufferFromRing(BufferAccessStrategy strategy, uint32 *buf_state)
 		strategy->current = 0;
 
 	/*
-	 * If the slot hasn't been filled yet, tell the caller to allocate a new
-	 * buffer with the normal allocation strategy.  He will then fill this
-	 * slot by calling AddBufferToRing with the new buffer.
+	 * If the slot hasn't been filled yet or the buffer in the slot has been
+	 * invalidated when buffer pool was shrunk, tell the caller to allocate a new
+	 * buffer with the normal allocation strategy.  He will then fill this slot
+	 * by calling AddBufferToRing with the new buffer.
 	 */
 	bufnum = strategy->buffers[strategy->current];
-	if (bufnum == InvalidBuffer)
+	if (bufnum == InvalidBuffer || bufnum > NBuffers)
 		return NULL;
 
 	/*
-- 
2.49.0


--bwrlgp6w2ubxykjq--





^ permalink  raw  reply  [nested|flat] 107+ messages in thread

* [PATCH v5 10/10] Additional validation for buffer in the ring
@ 2025-06-11 12:45 Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
  0 siblings, 0 replies; 107+ messages in thread

From: Ashutosh Bapat @ 2025-06-11 12:45 UTC (permalink / raw)

If the buffer pool has been shrunk, the buffers in the buffer list may
not be valid anymore. Modify GetBufferFromRing to check if the buffer is
still valid before using it. This makes GetBufferFromRing() a bit more
expensive because of additional boolean condition. That may not be
expensive enough to affect query performance. The alternative to that is
more complex as explained below.

The strategy object is created in CurrentMemoryContext and is not
available in any global structure thus accessible when processing buffer
resizing barriers. We may modify GetAccessStrategy() to register
strategy in a global linked list and then arrange to deregister it once
it's no more in use. Looking at the places which use
GetAccessStrategy(), fixing all those may be some work.

Ashutosh Bapat
---
 src/backend/storage/buffer/freelist.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/src/backend/storage/buffer/freelist.c b/src/backend/storage/buffer/freelist.c
index 41641bb3ae6..74d070733a4 100644
--- a/src/backend/storage/buffer/freelist.c
+++ b/src/backend/storage/buffer/freelist.c
@@ -948,12 +948,13 @@ GetBufferFromRing(BufferAccessStrategy strategy, uint32 *buf_state)
 		strategy->current = 0;
 
 	/*
-	 * If the slot hasn't been filled yet, tell the caller to allocate a new
-	 * buffer with the normal allocation strategy.  He will then fill this
-	 * slot by calling AddBufferToRing with the new buffer.
+	 * If the slot hasn't been filled yet or the buffer in the slot has been
+	 * invalidated when buffer pool was shrunk, tell the caller to allocate a new
+	 * buffer with the normal allocation strategy.  He will then fill this slot
+	 * by calling AddBufferToRing with the new buffer.
 	 */
 	bufnum = strategy->buffers[strategy->current];
-	if (bufnum == InvalidBuffer)
+	if (bufnum == InvalidBuffer || bufnum > NBuffers)
 		return NULL;
 
 	/*
-- 
2.49.0


--bwrlgp6w2ubxykjq--





^ permalink  raw  reply  [nested|flat] 107+ messages in thread

* [PATCH v5 10/10] Additional validation for buffer in the ring
@ 2025-06-11 12:45 Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
  0 siblings, 0 replies; 107+ messages in thread

From: Ashutosh Bapat @ 2025-06-11 12:45 UTC (permalink / raw)

If the buffer pool has been shrunk, the buffers in the buffer list may
not be valid anymore. Modify GetBufferFromRing to check if the buffer is
still valid before using it. This makes GetBufferFromRing() a bit more
expensive because of additional boolean condition. That may not be
expensive enough to affect query performance. The alternative to that is
more complex as explained below.

The strategy object is created in CurrentMemoryContext and is not
available in any global structure thus accessible when processing buffer
resizing barriers. We may modify GetAccessStrategy() to register
strategy in a global linked list and then arrange to deregister it once
it's no more in use. Looking at the places which use
GetAccessStrategy(), fixing all those may be some work.

Ashutosh Bapat
---
 src/backend/storage/buffer/freelist.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/src/backend/storage/buffer/freelist.c b/src/backend/storage/buffer/freelist.c
index 41641bb3ae6..74d070733a4 100644
--- a/src/backend/storage/buffer/freelist.c
+++ b/src/backend/storage/buffer/freelist.c
@@ -948,12 +948,13 @@ GetBufferFromRing(BufferAccessStrategy strategy, uint32 *buf_state)
 		strategy->current = 0;
 
 	/*
-	 * If the slot hasn't been filled yet, tell the caller to allocate a new
-	 * buffer with the normal allocation strategy.  He will then fill this
-	 * slot by calling AddBufferToRing with the new buffer.
+	 * If the slot hasn't been filled yet or the buffer in the slot has been
+	 * invalidated when buffer pool was shrunk, tell the caller to allocate a new
+	 * buffer with the normal allocation strategy.  He will then fill this slot
+	 * by calling AddBufferToRing with the new buffer.
 	 */
 	bufnum = strategy->buffers[strategy->current];
-	if (bufnum == InvalidBuffer)
+	if (bufnum == InvalidBuffer || bufnum > NBuffers)
 		return NULL;
 
 	/*
-- 
2.49.0


--bwrlgp6w2ubxykjq--





^ permalink  raw  reply  [nested|flat] 107+ messages in thread

* [PATCH v5 10/10] Additional validation for buffer in the ring
@ 2025-06-11 12:45 Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
  0 siblings, 0 replies; 107+ messages in thread

From: Ashutosh Bapat @ 2025-06-11 12:45 UTC (permalink / raw)

If the buffer pool has been shrunk, the buffers in the buffer list may
not be valid anymore. Modify GetBufferFromRing to check if the buffer is
still valid before using it. This makes GetBufferFromRing() a bit more
expensive because of additional boolean condition. That may not be
expensive enough to affect query performance. The alternative to that is
more complex as explained below.

The strategy object is created in CurrentMemoryContext and is not
available in any global structure thus accessible when processing buffer
resizing barriers. We may modify GetAccessStrategy() to register
strategy in a global linked list and then arrange to deregister it once
it's no more in use. Looking at the places which use
GetAccessStrategy(), fixing all those may be some work.

Ashutosh Bapat
---
 src/backend/storage/buffer/freelist.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/src/backend/storage/buffer/freelist.c b/src/backend/storage/buffer/freelist.c
index 41641bb3ae6..74d070733a4 100644
--- a/src/backend/storage/buffer/freelist.c
+++ b/src/backend/storage/buffer/freelist.c
@@ -948,12 +948,13 @@ GetBufferFromRing(BufferAccessStrategy strategy, uint32 *buf_state)
 		strategy->current = 0;
 
 	/*
-	 * If the slot hasn't been filled yet, tell the caller to allocate a new
-	 * buffer with the normal allocation strategy.  He will then fill this
-	 * slot by calling AddBufferToRing with the new buffer.
+	 * If the slot hasn't been filled yet or the buffer in the slot has been
+	 * invalidated when buffer pool was shrunk, tell the caller to allocate a new
+	 * buffer with the normal allocation strategy.  He will then fill this slot
+	 * by calling AddBufferToRing with the new buffer.
 	 */
 	bufnum = strategy->buffers[strategy->current];
-	if (bufnum == InvalidBuffer)
+	if (bufnum == InvalidBuffer || bufnum > NBuffers)
 		return NULL;
 
 	/*
-- 
2.49.0


--bwrlgp6w2ubxykjq--





^ permalink  raw  reply  [nested|flat] 107+ messages in thread

* [PATCH v5 10/10] Additional validation for buffer in the ring
@ 2025-06-11 12:45 Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
  0 siblings, 0 replies; 107+ messages in thread

From: Ashutosh Bapat @ 2025-06-11 12:45 UTC (permalink / raw)

If the buffer pool has been shrunk, the buffers in the buffer list may
not be valid anymore. Modify GetBufferFromRing to check if the buffer is
still valid before using it. This makes GetBufferFromRing() a bit more
expensive because of additional boolean condition. That may not be
expensive enough to affect query performance. The alternative to that is
more complex as explained below.

The strategy object is created in CurrentMemoryContext and is not
available in any global structure thus accessible when processing buffer
resizing barriers. We may modify GetAccessStrategy() to register
strategy in a global linked list and then arrange to deregister it once
it's no more in use. Looking at the places which use
GetAccessStrategy(), fixing all those may be some work.

Ashutosh Bapat
---
 src/backend/storage/buffer/freelist.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/src/backend/storage/buffer/freelist.c b/src/backend/storage/buffer/freelist.c
index 41641bb3ae6..74d070733a4 100644
--- a/src/backend/storage/buffer/freelist.c
+++ b/src/backend/storage/buffer/freelist.c
@@ -948,12 +948,13 @@ GetBufferFromRing(BufferAccessStrategy strategy, uint32 *buf_state)
 		strategy->current = 0;
 
 	/*
-	 * If the slot hasn't been filled yet, tell the caller to allocate a new
-	 * buffer with the normal allocation strategy.  He will then fill this
-	 * slot by calling AddBufferToRing with the new buffer.
+	 * If the slot hasn't been filled yet or the buffer in the slot has been
+	 * invalidated when buffer pool was shrunk, tell the caller to allocate a new
+	 * buffer with the normal allocation strategy.  He will then fill this slot
+	 * by calling AddBufferToRing with the new buffer.
 	 */
 	bufnum = strategy->buffers[strategy->current];
-	if (bufnum == InvalidBuffer)
+	if (bufnum == InvalidBuffer || bufnum > NBuffers)
 		return NULL;
 
 	/*
-- 
2.49.0


--bwrlgp6w2ubxykjq--





^ permalink  raw  reply  [nested|flat] 107+ messages in thread

* [PATCH v5 10/10] Additional validation for buffer in the ring
@ 2025-06-11 12:45 Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
  0 siblings, 0 replies; 107+ messages in thread

From: Ashutosh Bapat @ 2025-06-11 12:45 UTC (permalink / raw)

If the buffer pool has been shrunk, the buffers in the buffer list may
not be valid anymore. Modify GetBufferFromRing to check if the buffer is
still valid before using it. This makes GetBufferFromRing() a bit more
expensive because of additional boolean condition. That may not be
expensive enough to affect query performance. The alternative to that is
more complex as explained below.

The strategy object is created in CurrentMemoryContext and is not
available in any global structure thus accessible when processing buffer
resizing barriers. We may modify GetAccessStrategy() to register
strategy in a global linked list and then arrange to deregister it once
it's no more in use. Looking at the places which use
GetAccessStrategy(), fixing all those may be some work.

Ashutosh Bapat
---
 src/backend/storage/buffer/freelist.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/src/backend/storage/buffer/freelist.c b/src/backend/storage/buffer/freelist.c
index 41641bb3ae6..74d070733a4 100644
--- a/src/backend/storage/buffer/freelist.c
+++ b/src/backend/storage/buffer/freelist.c
@@ -948,12 +948,13 @@ GetBufferFromRing(BufferAccessStrategy strategy, uint32 *buf_state)
 		strategy->current = 0;
 
 	/*
-	 * If the slot hasn't been filled yet, tell the caller to allocate a new
-	 * buffer with the normal allocation strategy.  He will then fill this
-	 * slot by calling AddBufferToRing with the new buffer.
+	 * If the slot hasn't been filled yet or the buffer in the slot has been
+	 * invalidated when buffer pool was shrunk, tell the caller to allocate a new
+	 * buffer with the normal allocation strategy.  He will then fill this slot
+	 * by calling AddBufferToRing with the new buffer.
 	 */
 	bufnum = strategy->buffers[strategy->current];
-	if (bufnum == InvalidBuffer)
+	if (bufnum == InvalidBuffer || bufnum > NBuffers)
 		return NULL;
 
 	/*
-- 
2.49.0


--bwrlgp6w2ubxykjq--





^ permalink  raw  reply  [nested|flat] 107+ messages in thread

* [PATCH v5 10/10] Additional validation for buffer in the ring
@ 2025-06-11 12:45 Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
  0 siblings, 0 replies; 107+ messages in thread

From: Ashutosh Bapat @ 2025-06-11 12:45 UTC (permalink / raw)

If the buffer pool has been shrunk, the buffers in the buffer list may
not be valid anymore. Modify GetBufferFromRing to check if the buffer is
still valid before using it. This makes GetBufferFromRing() a bit more
expensive because of additional boolean condition. That may not be
expensive enough to affect query performance. The alternative to that is
more complex as explained below.

The strategy object is created in CurrentMemoryContext and is not
available in any global structure thus accessible when processing buffer
resizing barriers. We may modify GetAccessStrategy() to register
strategy in a global linked list and then arrange to deregister it once
it's no more in use. Looking at the places which use
GetAccessStrategy(), fixing all those may be some work.

Ashutosh Bapat
---
 src/backend/storage/buffer/freelist.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/src/backend/storage/buffer/freelist.c b/src/backend/storage/buffer/freelist.c
index 41641bb3ae6..74d070733a4 100644
--- a/src/backend/storage/buffer/freelist.c
+++ b/src/backend/storage/buffer/freelist.c
@@ -948,12 +948,13 @@ GetBufferFromRing(BufferAccessStrategy strategy, uint32 *buf_state)
 		strategy->current = 0;
 
 	/*
-	 * If the slot hasn't been filled yet, tell the caller to allocate a new
-	 * buffer with the normal allocation strategy.  He will then fill this
-	 * slot by calling AddBufferToRing with the new buffer.
+	 * If the slot hasn't been filled yet or the buffer in the slot has been
+	 * invalidated when buffer pool was shrunk, tell the caller to allocate a new
+	 * buffer with the normal allocation strategy.  He will then fill this slot
+	 * by calling AddBufferToRing with the new buffer.
 	 */
 	bufnum = strategy->buffers[strategy->current];
-	if (bufnum == InvalidBuffer)
+	if (bufnum == InvalidBuffer || bufnum > NBuffers)
 		return NULL;
 
 	/*
-- 
2.49.0


--bwrlgp6w2ubxykjq--





^ permalink  raw  reply  [nested|flat] 107+ messages in thread

* [PATCH v5 10/10] Additional validation for buffer in the ring
@ 2025-06-11 12:45 Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
  0 siblings, 0 replies; 107+ messages in thread

From: Ashutosh Bapat @ 2025-06-11 12:45 UTC (permalink / raw)

If the buffer pool has been shrunk, the buffers in the buffer list may
not be valid anymore. Modify GetBufferFromRing to check if the buffer is
still valid before using it. This makes GetBufferFromRing() a bit more
expensive because of additional boolean condition. That may not be
expensive enough to affect query performance. The alternative to that is
more complex as explained below.

The strategy object is created in CurrentMemoryContext and is not
available in any global structure thus accessible when processing buffer
resizing barriers. We may modify GetAccessStrategy() to register
strategy in a global linked list and then arrange to deregister it once
it's no more in use. Looking at the places which use
GetAccessStrategy(), fixing all those may be some work.

Ashutosh Bapat
---
 src/backend/storage/buffer/freelist.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/src/backend/storage/buffer/freelist.c b/src/backend/storage/buffer/freelist.c
index 41641bb3ae6..74d070733a4 100644
--- a/src/backend/storage/buffer/freelist.c
+++ b/src/backend/storage/buffer/freelist.c
@@ -948,12 +948,13 @@ GetBufferFromRing(BufferAccessStrategy strategy, uint32 *buf_state)
 		strategy->current = 0;
 
 	/*
-	 * If the slot hasn't been filled yet, tell the caller to allocate a new
-	 * buffer with the normal allocation strategy.  He will then fill this
-	 * slot by calling AddBufferToRing with the new buffer.
+	 * If the slot hasn't been filled yet or the buffer in the slot has been
+	 * invalidated when buffer pool was shrunk, tell the caller to allocate a new
+	 * buffer with the normal allocation strategy.  He will then fill this slot
+	 * by calling AddBufferToRing with the new buffer.
 	 */
 	bufnum = strategy->buffers[strategy->current];
-	if (bufnum == InvalidBuffer)
+	if (bufnum == InvalidBuffer || bufnum > NBuffers)
 		return NULL;
 
 	/*
-- 
2.49.0


--bwrlgp6w2ubxykjq--





^ permalink  raw  reply  [nested|flat] 107+ messages in thread

* [PATCH v5 10/10] Additional validation for buffer in the ring
@ 2025-06-11 12:45 Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
  0 siblings, 0 replies; 107+ messages in thread

From: Ashutosh Bapat @ 2025-06-11 12:45 UTC (permalink / raw)

If the buffer pool has been shrunk, the buffers in the buffer list may
not be valid anymore. Modify GetBufferFromRing to check if the buffer is
still valid before using it. This makes GetBufferFromRing() a bit more
expensive because of additional boolean condition. That may not be
expensive enough to affect query performance. The alternative to that is
more complex as explained below.

The strategy object is created in CurrentMemoryContext and is not
available in any global structure thus accessible when processing buffer
resizing barriers. We may modify GetAccessStrategy() to register
strategy in a global linked list and then arrange to deregister it once
it's no more in use. Looking at the places which use
GetAccessStrategy(), fixing all those may be some work.

Ashutosh Bapat
---
 src/backend/storage/buffer/freelist.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/src/backend/storage/buffer/freelist.c b/src/backend/storage/buffer/freelist.c
index 41641bb3ae6..74d070733a4 100644
--- a/src/backend/storage/buffer/freelist.c
+++ b/src/backend/storage/buffer/freelist.c
@@ -948,12 +948,13 @@ GetBufferFromRing(BufferAccessStrategy strategy, uint32 *buf_state)
 		strategy->current = 0;
 
 	/*
-	 * If the slot hasn't been filled yet, tell the caller to allocate a new
-	 * buffer with the normal allocation strategy.  He will then fill this
-	 * slot by calling AddBufferToRing with the new buffer.
+	 * If the slot hasn't been filled yet or the buffer in the slot has been
+	 * invalidated when buffer pool was shrunk, tell the caller to allocate a new
+	 * buffer with the normal allocation strategy.  He will then fill this slot
+	 * by calling AddBufferToRing with the new buffer.
 	 */
 	bufnum = strategy->buffers[strategy->current];
-	if (bufnum == InvalidBuffer)
+	if (bufnum == InvalidBuffer || bufnum > NBuffers)
 		return NULL;
 
 	/*
-- 
2.49.0


--bwrlgp6w2ubxykjq--





^ permalink  raw  reply  [nested|flat] 107+ messages in thread

* [PATCH v5 10/10] Additional validation for buffer in the ring
@ 2025-06-11 12:45 Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
  0 siblings, 0 replies; 107+ messages in thread

From: Ashutosh Bapat @ 2025-06-11 12:45 UTC (permalink / raw)

If the buffer pool has been shrunk, the buffers in the buffer list may
not be valid anymore. Modify GetBufferFromRing to check if the buffer is
still valid before using it. This makes GetBufferFromRing() a bit more
expensive because of additional boolean condition. That may not be
expensive enough to affect query performance. The alternative to that is
more complex as explained below.

The strategy object is created in CurrentMemoryContext and is not
available in any global structure thus accessible when processing buffer
resizing barriers. We may modify GetAccessStrategy() to register
strategy in a global linked list and then arrange to deregister it once
it's no more in use. Looking at the places which use
GetAccessStrategy(), fixing all those may be some work.

Ashutosh Bapat
---
 src/backend/storage/buffer/freelist.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/src/backend/storage/buffer/freelist.c b/src/backend/storage/buffer/freelist.c
index 41641bb3ae6..74d070733a4 100644
--- a/src/backend/storage/buffer/freelist.c
+++ b/src/backend/storage/buffer/freelist.c
@@ -948,12 +948,13 @@ GetBufferFromRing(BufferAccessStrategy strategy, uint32 *buf_state)
 		strategy->current = 0;
 
 	/*
-	 * If the slot hasn't been filled yet, tell the caller to allocate a new
-	 * buffer with the normal allocation strategy.  He will then fill this
-	 * slot by calling AddBufferToRing with the new buffer.
+	 * If the slot hasn't been filled yet or the buffer in the slot has been
+	 * invalidated when buffer pool was shrunk, tell the caller to allocate a new
+	 * buffer with the normal allocation strategy.  He will then fill this slot
+	 * by calling AddBufferToRing with the new buffer.
 	 */
 	bufnum = strategy->buffers[strategy->current];
-	if (bufnum == InvalidBuffer)
+	if (bufnum == InvalidBuffer || bufnum > NBuffers)
 		return NULL;
 
 	/*
-- 
2.49.0


--bwrlgp6w2ubxykjq--





^ permalink  raw  reply  [nested|flat] 107+ messages in thread

* [PATCH v5 10/10] Additional validation for buffer in the ring
@ 2025-06-11 12:45 Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
  0 siblings, 0 replies; 107+ messages in thread

From: Ashutosh Bapat @ 2025-06-11 12:45 UTC (permalink / raw)

If the buffer pool has been shrunk, the buffers in the buffer list may
not be valid anymore. Modify GetBufferFromRing to check if the buffer is
still valid before using it. This makes GetBufferFromRing() a bit more
expensive because of additional boolean condition. That may not be
expensive enough to affect query performance. The alternative to that is
more complex as explained below.

The strategy object is created in CurrentMemoryContext and is not
available in any global structure thus accessible when processing buffer
resizing barriers. We may modify GetAccessStrategy() to register
strategy in a global linked list and then arrange to deregister it once
it's no more in use. Looking at the places which use
GetAccessStrategy(), fixing all those may be some work.

Ashutosh Bapat
---
 src/backend/storage/buffer/freelist.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/src/backend/storage/buffer/freelist.c b/src/backend/storage/buffer/freelist.c
index 41641bb3ae6..74d070733a4 100644
--- a/src/backend/storage/buffer/freelist.c
+++ b/src/backend/storage/buffer/freelist.c
@@ -948,12 +948,13 @@ GetBufferFromRing(BufferAccessStrategy strategy, uint32 *buf_state)
 		strategy->current = 0;
 
 	/*
-	 * If the slot hasn't been filled yet, tell the caller to allocate a new
-	 * buffer with the normal allocation strategy.  He will then fill this
-	 * slot by calling AddBufferToRing with the new buffer.
+	 * If the slot hasn't been filled yet or the buffer in the slot has been
+	 * invalidated when buffer pool was shrunk, tell the caller to allocate a new
+	 * buffer with the normal allocation strategy.  He will then fill this slot
+	 * by calling AddBufferToRing with the new buffer.
 	 */
 	bufnum = strategy->buffers[strategy->current];
-	if (bufnum == InvalidBuffer)
+	if (bufnum == InvalidBuffer || bufnum > NBuffers)
 		return NULL;
 
 	/*
-- 
2.49.0


--bwrlgp6w2ubxykjq--





^ permalink  raw  reply  [nested|flat] 107+ messages in thread

* [PATCH v5 10/10] Additional validation for buffer in the ring
@ 2025-06-11 12:45 Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
  0 siblings, 0 replies; 107+ messages in thread

From: Ashutosh Bapat @ 2025-06-11 12:45 UTC (permalink / raw)

If the buffer pool has been shrunk, the buffers in the buffer list may
not be valid anymore. Modify GetBufferFromRing to check if the buffer is
still valid before using it. This makes GetBufferFromRing() a bit more
expensive because of additional boolean condition. That may not be
expensive enough to affect query performance. The alternative to that is
more complex as explained below.

The strategy object is created in CurrentMemoryContext and is not
available in any global structure thus accessible when processing buffer
resizing barriers. We may modify GetAccessStrategy() to register
strategy in a global linked list and then arrange to deregister it once
it's no more in use. Looking at the places which use
GetAccessStrategy(), fixing all those may be some work.

Ashutosh Bapat
---
 src/backend/storage/buffer/freelist.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/src/backend/storage/buffer/freelist.c b/src/backend/storage/buffer/freelist.c
index 41641bb3ae6..74d070733a4 100644
--- a/src/backend/storage/buffer/freelist.c
+++ b/src/backend/storage/buffer/freelist.c
@@ -948,12 +948,13 @@ GetBufferFromRing(BufferAccessStrategy strategy, uint32 *buf_state)
 		strategy->current = 0;
 
 	/*
-	 * If the slot hasn't been filled yet, tell the caller to allocate a new
-	 * buffer with the normal allocation strategy.  He will then fill this
-	 * slot by calling AddBufferToRing with the new buffer.
+	 * If the slot hasn't been filled yet or the buffer in the slot has been
+	 * invalidated when buffer pool was shrunk, tell the caller to allocate a new
+	 * buffer with the normal allocation strategy.  He will then fill this slot
+	 * by calling AddBufferToRing with the new buffer.
 	 */
 	bufnum = strategy->buffers[strategy->current];
-	if (bufnum == InvalidBuffer)
+	if (bufnum == InvalidBuffer || bufnum > NBuffers)
 		return NULL;
 
 	/*
-- 
2.49.0


--bwrlgp6w2ubxykjq--





^ permalink  raw  reply  [nested|flat] 107+ messages in thread

* [PATCH v5 10/10] Additional validation for buffer in the ring
@ 2025-06-11 12:45 Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
  0 siblings, 0 replies; 107+ messages in thread

From: Ashutosh Bapat @ 2025-06-11 12:45 UTC (permalink / raw)

If the buffer pool has been shrunk, the buffers in the buffer list may
not be valid anymore. Modify GetBufferFromRing to check if the buffer is
still valid before using it. This makes GetBufferFromRing() a bit more
expensive because of additional boolean condition. That may not be
expensive enough to affect query performance. The alternative to that is
more complex as explained below.

The strategy object is created in CurrentMemoryContext and is not
available in any global structure thus accessible when processing buffer
resizing barriers. We may modify GetAccessStrategy() to register
strategy in a global linked list and then arrange to deregister it once
it's no more in use. Looking at the places which use
GetAccessStrategy(), fixing all those may be some work.

Ashutosh Bapat
---
 src/backend/storage/buffer/freelist.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/src/backend/storage/buffer/freelist.c b/src/backend/storage/buffer/freelist.c
index 41641bb3ae6..74d070733a4 100644
--- a/src/backend/storage/buffer/freelist.c
+++ b/src/backend/storage/buffer/freelist.c
@@ -948,12 +948,13 @@ GetBufferFromRing(BufferAccessStrategy strategy, uint32 *buf_state)
 		strategy->current = 0;
 
 	/*
-	 * If the slot hasn't been filled yet, tell the caller to allocate a new
-	 * buffer with the normal allocation strategy.  He will then fill this
-	 * slot by calling AddBufferToRing with the new buffer.
+	 * If the slot hasn't been filled yet or the buffer in the slot has been
+	 * invalidated when buffer pool was shrunk, tell the caller to allocate a new
+	 * buffer with the normal allocation strategy.  He will then fill this slot
+	 * by calling AddBufferToRing with the new buffer.
 	 */
 	bufnum = strategy->buffers[strategy->current];
-	if (bufnum == InvalidBuffer)
+	if (bufnum == InvalidBuffer || bufnum > NBuffers)
 		return NULL;
 
 	/*
-- 
2.49.0


--bwrlgp6w2ubxykjq--





^ permalink  raw  reply  [nested|flat] 107+ messages in thread

* [PATCH v5 10/10] Additional validation for buffer in the ring
@ 2025-06-11 12:45 Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
  0 siblings, 0 replies; 107+ messages in thread

From: Ashutosh Bapat @ 2025-06-11 12:45 UTC (permalink / raw)

If the buffer pool has been shrunk, the buffers in the buffer list may
not be valid anymore. Modify GetBufferFromRing to check if the buffer is
still valid before using it. This makes GetBufferFromRing() a bit more
expensive because of additional boolean condition. That may not be
expensive enough to affect query performance. The alternative to that is
more complex as explained below.

The strategy object is created in CurrentMemoryContext and is not
available in any global structure thus accessible when processing buffer
resizing barriers. We may modify GetAccessStrategy() to register
strategy in a global linked list and then arrange to deregister it once
it's no more in use. Looking at the places which use
GetAccessStrategy(), fixing all those may be some work.

Ashutosh Bapat
---
 src/backend/storage/buffer/freelist.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/src/backend/storage/buffer/freelist.c b/src/backend/storage/buffer/freelist.c
index 41641bb3ae6..74d070733a4 100644
--- a/src/backend/storage/buffer/freelist.c
+++ b/src/backend/storage/buffer/freelist.c
@@ -948,12 +948,13 @@ GetBufferFromRing(BufferAccessStrategy strategy, uint32 *buf_state)
 		strategy->current = 0;
 
 	/*
-	 * If the slot hasn't been filled yet, tell the caller to allocate a new
-	 * buffer with the normal allocation strategy.  He will then fill this
-	 * slot by calling AddBufferToRing with the new buffer.
+	 * If the slot hasn't been filled yet or the buffer in the slot has been
+	 * invalidated when buffer pool was shrunk, tell the caller to allocate a new
+	 * buffer with the normal allocation strategy.  He will then fill this slot
+	 * by calling AddBufferToRing with the new buffer.
 	 */
 	bufnum = strategy->buffers[strategy->current];
-	if (bufnum == InvalidBuffer)
+	if (bufnum == InvalidBuffer || bufnum > NBuffers)
 		return NULL;
 
 	/*
-- 
2.49.0


--bwrlgp6w2ubxykjq--





^ permalink  raw  reply  [nested|flat] 107+ messages in thread

* [PATCH v5 10/10] Additional validation for buffer in the ring
@ 2025-06-11 12:45 Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
  0 siblings, 0 replies; 107+ messages in thread

From: Ashutosh Bapat @ 2025-06-11 12:45 UTC (permalink / raw)

If the buffer pool has been shrunk, the buffers in the buffer list may
not be valid anymore. Modify GetBufferFromRing to check if the buffer is
still valid before using it. This makes GetBufferFromRing() a bit more
expensive because of additional boolean condition. That may not be
expensive enough to affect query performance. The alternative to that is
more complex as explained below.

The strategy object is created in CurrentMemoryContext and is not
available in any global structure thus accessible when processing buffer
resizing barriers. We may modify GetAccessStrategy() to register
strategy in a global linked list and then arrange to deregister it once
it's no more in use. Looking at the places which use
GetAccessStrategy(), fixing all those may be some work.

Ashutosh Bapat
---
 src/backend/storage/buffer/freelist.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/src/backend/storage/buffer/freelist.c b/src/backend/storage/buffer/freelist.c
index 41641bb3ae6..74d070733a4 100644
--- a/src/backend/storage/buffer/freelist.c
+++ b/src/backend/storage/buffer/freelist.c
@@ -948,12 +948,13 @@ GetBufferFromRing(BufferAccessStrategy strategy, uint32 *buf_state)
 		strategy->current = 0;
 
 	/*
-	 * If the slot hasn't been filled yet, tell the caller to allocate a new
-	 * buffer with the normal allocation strategy.  He will then fill this
-	 * slot by calling AddBufferToRing with the new buffer.
+	 * If the slot hasn't been filled yet or the buffer in the slot has been
+	 * invalidated when buffer pool was shrunk, tell the caller to allocate a new
+	 * buffer with the normal allocation strategy.  He will then fill this slot
+	 * by calling AddBufferToRing with the new buffer.
 	 */
 	bufnum = strategy->buffers[strategy->current];
-	if (bufnum == InvalidBuffer)
+	if (bufnum == InvalidBuffer || bufnum > NBuffers)
 		return NULL;
 
 	/*
-- 
2.49.0


--bwrlgp6w2ubxykjq--





^ permalink  raw  reply  [nested|flat] 107+ messages in thread

* [PATCH v5 10/10] Additional validation for buffer in the ring
@ 2025-06-11 12:45 Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
  0 siblings, 0 replies; 107+ messages in thread

From: Ashutosh Bapat @ 2025-06-11 12:45 UTC (permalink / raw)

If the buffer pool has been shrunk, the buffers in the buffer list may
not be valid anymore. Modify GetBufferFromRing to check if the buffer is
still valid before using it. This makes GetBufferFromRing() a bit more
expensive because of additional boolean condition. That may not be
expensive enough to affect query performance. The alternative to that is
more complex as explained below.

The strategy object is created in CurrentMemoryContext and is not
available in any global structure thus accessible when processing buffer
resizing barriers. We may modify GetAccessStrategy() to register
strategy in a global linked list and then arrange to deregister it once
it's no more in use. Looking at the places which use
GetAccessStrategy(), fixing all those may be some work.

Ashutosh Bapat
---
 src/backend/storage/buffer/freelist.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/src/backend/storage/buffer/freelist.c b/src/backend/storage/buffer/freelist.c
index 41641bb3ae6..74d070733a4 100644
--- a/src/backend/storage/buffer/freelist.c
+++ b/src/backend/storage/buffer/freelist.c
@@ -948,12 +948,13 @@ GetBufferFromRing(BufferAccessStrategy strategy, uint32 *buf_state)
 		strategy->current = 0;
 
 	/*
-	 * If the slot hasn't been filled yet, tell the caller to allocate a new
-	 * buffer with the normal allocation strategy.  He will then fill this
-	 * slot by calling AddBufferToRing with the new buffer.
+	 * If the slot hasn't been filled yet or the buffer in the slot has been
+	 * invalidated when buffer pool was shrunk, tell the caller to allocate a new
+	 * buffer with the normal allocation strategy.  He will then fill this slot
+	 * by calling AddBufferToRing with the new buffer.
 	 */
 	bufnum = strategy->buffers[strategy->current];
-	if (bufnum == InvalidBuffer)
+	if (bufnum == InvalidBuffer || bufnum > NBuffers)
 		return NULL;
 
 	/*
-- 
2.49.0


--bwrlgp6w2ubxykjq--





^ permalink  raw  reply  [nested|flat] 107+ messages in thread

* [PATCH v5 10/10] Additional validation for buffer in the ring
@ 2025-06-11 12:45 Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
  0 siblings, 0 replies; 107+ messages in thread

From: Ashutosh Bapat @ 2025-06-11 12:45 UTC (permalink / raw)

If the buffer pool has been shrunk, the buffers in the buffer list may
not be valid anymore. Modify GetBufferFromRing to check if the buffer is
still valid before using it. This makes GetBufferFromRing() a bit more
expensive because of additional boolean condition. That may not be
expensive enough to affect query performance. The alternative to that is
more complex as explained below.

The strategy object is created in CurrentMemoryContext and is not
available in any global structure thus accessible when processing buffer
resizing barriers. We may modify GetAccessStrategy() to register
strategy in a global linked list and then arrange to deregister it once
it's no more in use. Looking at the places which use
GetAccessStrategy(), fixing all those may be some work.

Ashutosh Bapat
---
 src/backend/storage/buffer/freelist.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/src/backend/storage/buffer/freelist.c b/src/backend/storage/buffer/freelist.c
index 41641bb3ae6..74d070733a4 100644
--- a/src/backend/storage/buffer/freelist.c
+++ b/src/backend/storage/buffer/freelist.c
@@ -948,12 +948,13 @@ GetBufferFromRing(BufferAccessStrategy strategy, uint32 *buf_state)
 		strategy->current = 0;
 
 	/*
-	 * If the slot hasn't been filled yet, tell the caller to allocate a new
-	 * buffer with the normal allocation strategy.  He will then fill this
-	 * slot by calling AddBufferToRing with the new buffer.
+	 * If the slot hasn't been filled yet or the buffer in the slot has been
+	 * invalidated when buffer pool was shrunk, tell the caller to allocate a new
+	 * buffer with the normal allocation strategy.  He will then fill this slot
+	 * by calling AddBufferToRing with the new buffer.
 	 */
 	bufnum = strategy->buffers[strategy->current];
-	if (bufnum == InvalidBuffer)
+	if (bufnum == InvalidBuffer || bufnum > NBuffers)
 		return NULL;
 
 	/*
-- 
2.49.0


--bwrlgp6w2ubxykjq--





^ permalink  raw  reply  [nested|flat] 107+ messages in thread

* [PATCH v5 10/10] Additional validation for buffer in the ring
@ 2025-06-11 12:45 Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
  0 siblings, 0 replies; 107+ messages in thread

From: Ashutosh Bapat @ 2025-06-11 12:45 UTC (permalink / raw)

If the buffer pool has been shrunk, the buffers in the buffer list may
not be valid anymore. Modify GetBufferFromRing to check if the buffer is
still valid before using it. This makes GetBufferFromRing() a bit more
expensive because of additional boolean condition. That may not be
expensive enough to affect query performance. The alternative to that is
more complex as explained below.

The strategy object is created in CurrentMemoryContext and is not
available in any global structure thus accessible when processing buffer
resizing barriers. We may modify GetAccessStrategy() to register
strategy in a global linked list and then arrange to deregister it once
it's no more in use. Looking at the places which use
GetAccessStrategy(), fixing all those may be some work.

Ashutosh Bapat
---
 src/backend/storage/buffer/freelist.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/src/backend/storage/buffer/freelist.c b/src/backend/storage/buffer/freelist.c
index 41641bb3ae6..74d070733a4 100644
--- a/src/backend/storage/buffer/freelist.c
+++ b/src/backend/storage/buffer/freelist.c
@@ -948,12 +948,13 @@ GetBufferFromRing(BufferAccessStrategy strategy, uint32 *buf_state)
 		strategy->current = 0;
 
 	/*
-	 * If the slot hasn't been filled yet, tell the caller to allocate a new
-	 * buffer with the normal allocation strategy.  He will then fill this
-	 * slot by calling AddBufferToRing with the new buffer.
+	 * If the slot hasn't been filled yet or the buffer in the slot has been
+	 * invalidated when buffer pool was shrunk, tell the caller to allocate a new
+	 * buffer with the normal allocation strategy.  He will then fill this slot
+	 * by calling AddBufferToRing with the new buffer.
 	 */
 	bufnum = strategy->buffers[strategy->current];
-	if (bufnum == InvalidBuffer)
+	if (bufnum == InvalidBuffer || bufnum > NBuffers)
 		return NULL;
 
 	/*
-- 
2.49.0


--bwrlgp6w2ubxykjq--





^ permalink  raw  reply  [nested|flat] 107+ messages in thread

* [PATCH v5 10/10] Additional validation for buffer in the ring
@ 2025-06-11 12:45 Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
  0 siblings, 0 replies; 107+ messages in thread

From: Ashutosh Bapat @ 2025-06-11 12:45 UTC (permalink / raw)

If the buffer pool has been shrunk, the buffers in the buffer list may
not be valid anymore. Modify GetBufferFromRing to check if the buffer is
still valid before using it. This makes GetBufferFromRing() a bit more
expensive because of additional boolean condition. That may not be
expensive enough to affect query performance. The alternative to that is
more complex as explained below.

The strategy object is created in CurrentMemoryContext and is not
available in any global structure thus accessible when processing buffer
resizing barriers. We may modify GetAccessStrategy() to register
strategy in a global linked list and then arrange to deregister it once
it's no more in use. Looking at the places which use
GetAccessStrategy(), fixing all those may be some work.

Ashutosh Bapat
---
 src/backend/storage/buffer/freelist.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/src/backend/storage/buffer/freelist.c b/src/backend/storage/buffer/freelist.c
index 41641bb3ae6..74d070733a4 100644
--- a/src/backend/storage/buffer/freelist.c
+++ b/src/backend/storage/buffer/freelist.c
@@ -948,12 +948,13 @@ GetBufferFromRing(BufferAccessStrategy strategy, uint32 *buf_state)
 		strategy->current = 0;
 
 	/*
-	 * If the slot hasn't been filled yet, tell the caller to allocate a new
-	 * buffer with the normal allocation strategy.  He will then fill this
-	 * slot by calling AddBufferToRing with the new buffer.
+	 * If the slot hasn't been filled yet or the buffer in the slot has been
+	 * invalidated when buffer pool was shrunk, tell the caller to allocate a new
+	 * buffer with the normal allocation strategy.  He will then fill this slot
+	 * by calling AddBufferToRing with the new buffer.
 	 */
 	bufnum = strategy->buffers[strategy->current];
-	if (bufnum == InvalidBuffer)
+	if (bufnum == InvalidBuffer || bufnum > NBuffers)
 		return NULL;
 
 	/*
-- 
2.49.0


--bwrlgp6w2ubxykjq--





^ permalink  raw  reply  [nested|flat] 107+ messages in thread

* [PATCH v5 10/10] Additional validation for buffer in the ring
@ 2025-06-11 12:45 Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
  0 siblings, 0 replies; 107+ messages in thread

From: Ashutosh Bapat @ 2025-06-11 12:45 UTC (permalink / raw)

If the buffer pool has been shrunk, the buffers in the buffer list may
not be valid anymore. Modify GetBufferFromRing to check if the buffer is
still valid before using it. This makes GetBufferFromRing() a bit more
expensive because of additional boolean condition. That may not be
expensive enough to affect query performance. The alternative to that is
more complex as explained below.

The strategy object is created in CurrentMemoryContext and is not
available in any global structure thus accessible when processing buffer
resizing barriers. We may modify GetAccessStrategy() to register
strategy in a global linked list and then arrange to deregister it once
it's no more in use. Looking at the places which use
GetAccessStrategy(), fixing all those may be some work.

Ashutosh Bapat
---
 src/backend/storage/buffer/freelist.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/src/backend/storage/buffer/freelist.c b/src/backend/storage/buffer/freelist.c
index 41641bb3ae6..74d070733a4 100644
--- a/src/backend/storage/buffer/freelist.c
+++ b/src/backend/storage/buffer/freelist.c
@@ -948,12 +948,13 @@ GetBufferFromRing(BufferAccessStrategy strategy, uint32 *buf_state)
 		strategy->current = 0;
 
 	/*
-	 * If the slot hasn't been filled yet, tell the caller to allocate a new
-	 * buffer with the normal allocation strategy.  He will then fill this
-	 * slot by calling AddBufferToRing with the new buffer.
+	 * If the slot hasn't been filled yet or the buffer in the slot has been
+	 * invalidated when buffer pool was shrunk, tell the caller to allocate a new
+	 * buffer with the normal allocation strategy.  He will then fill this slot
+	 * by calling AddBufferToRing with the new buffer.
 	 */
 	bufnum = strategy->buffers[strategy->current];
-	if (bufnum == InvalidBuffer)
+	if (bufnum == InvalidBuffer || bufnum > NBuffers)
 		return NULL;
 
 	/*
-- 
2.49.0


--bwrlgp6w2ubxykjq--





^ permalink  raw  reply  [nested|flat] 107+ messages in thread

* [PATCH v5 10/10] Additional validation for buffer in the ring
@ 2025-06-11 12:45 Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
  0 siblings, 0 replies; 107+ messages in thread

From: Ashutosh Bapat @ 2025-06-11 12:45 UTC (permalink / raw)

If the buffer pool has been shrunk, the buffers in the buffer list may
not be valid anymore. Modify GetBufferFromRing to check if the buffer is
still valid before using it. This makes GetBufferFromRing() a bit more
expensive because of additional boolean condition. That may not be
expensive enough to affect query performance. The alternative to that is
more complex as explained below.

The strategy object is created in CurrentMemoryContext and is not
available in any global structure thus accessible when processing buffer
resizing barriers. We may modify GetAccessStrategy() to register
strategy in a global linked list and then arrange to deregister it once
it's no more in use. Looking at the places which use
GetAccessStrategy(), fixing all those may be some work.

Ashutosh Bapat
---
 src/backend/storage/buffer/freelist.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/src/backend/storage/buffer/freelist.c b/src/backend/storage/buffer/freelist.c
index 41641bb3ae6..74d070733a4 100644
--- a/src/backend/storage/buffer/freelist.c
+++ b/src/backend/storage/buffer/freelist.c
@@ -948,12 +948,13 @@ GetBufferFromRing(BufferAccessStrategy strategy, uint32 *buf_state)
 		strategy->current = 0;
 
 	/*
-	 * If the slot hasn't been filled yet, tell the caller to allocate a new
-	 * buffer with the normal allocation strategy.  He will then fill this
-	 * slot by calling AddBufferToRing with the new buffer.
+	 * If the slot hasn't been filled yet or the buffer in the slot has been
+	 * invalidated when buffer pool was shrunk, tell the caller to allocate a new
+	 * buffer with the normal allocation strategy.  He will then fill this slot
+	 * by calling AddBufferToRing with the new buffer.
 	 */
 	bufnum = strategy->buffers[strategy->current];
-	if (bufnum == InvalidBuffer)
+	if (bufnum == InvalidBuffer || bufnum > NBuffers)
 		return NULL;
 
 	/*
-- 
2.49.0


--bwrlgp6w2ubxykjq--





^ permalink  raw  reply  [nested|flat] 107+ messages in thread

* [PATCH v5 10/10] Additional validation for buffer in the ring
@ 2025-06-11 12:45 Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
  0 siblings, 0 replies; 107+ messages in thread

From: Ashutosh Bapat @ 2025-06-11 12:45 UTC (permalink / raw)

If the buffer pool has been shrunk, the buffers in the buffer list may
not be valid anymore. Modify GetBufferFromRing to check if the buffer is
still valid before using it. This makes GetBufferFromRing() a bit more
expensive because of additional boolean condition. That may not be
expensive enough to affect query performance. The alternative to that is
more complex as explained below.

The strategy object is created in CurrentMemoryContext and is not
available in any global structure thus accessible when processing buffer
resizing barriers. We may modify GetAccessStrategy() to register
strategy in a global linked list and then arrange to deregister it once
it's no more in use. Looking at the places which use
GetAccessStrategy(), fixing all those may be some work.

Ashutosh Bapat
---
 src/backend/storage/buffer/freelist.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/src/backend/storage/buffer/freelist.c b/src/backend/storage/buffer/freelist.c
index 41641bb3ae6..74d070733a4 100644
--- a/src/backend/storage/buffer/freelist.c
+++ b/src/backend/storage/buffer/freelist.c
@@ -948,12 +948,13 @@ GetBufferFromRing(BufferAccessStrategy strategy, uint32 *buf_state)
 		strategy->current = 0;
 
 	/*
-	 * If the slot hasn't been filled yet, tell the caller to allocate a new
-	 * buffer with the normal allocation strategy.  He will then fill this
-	 * slot by calling AddBufferToRing with the new buffer.
+	 * If the slot hasn't been filled yet or the buffer in the slot has been
+	 * invalidated when buffer pool was shrunk, tell the caller to allocate a new
+	 * buffer with the normal allocation strategy.  He will then fill this slot
+	 * by calling AddBufferToRing with the new buffer.
 	 */
 	bufnum = strategy->buffers[strategy->current];
-	if (bufnum == InvalidBuffer)
+	if (bufnum == InvalidBuffer || bufnum > NBuffers)
 		return NULL;
 
 	/*
-- 
2.49.0


--bwrlgp6w2ubxykjq--





^ permalink  raw  reply  [nested|flat] 107+ messages in thread

* [PATCH v5 10/10] Additional validation for buffer in the ring
@ 2025-06-11 12:45 Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
  0 siblings, 0 replies; 107+ messages in thread

From: Ashutosh Bapat @ 2025-06-11 12:45 UTC (permalink / raw)

If the buffer pool has been shrunk, the buffers in the buffer list may
not be valid anymore. Modify GetBufferFromRing to check if the buffer is
still valid before using it. This makes GetBufferFromRing() a bit more
expensive because of additional boolean condition. That may not be
expensive enough to affect query performance. The alternative to that is
more complex as explained below.

The strategy object is created in CurrentMemoryContext and is not
available in any global structure thus accessible when processing buffer
resizing barriers. We may modify GetAccessStrategy() to register
strategy in a global linked list and then arrange to deregister it once
it's no more in use. Looking at the places which use
GetAccessStrategy(), fixing all those may be some work.

Ashutosh Bapat
---
 src/backend/storage/buffer/freelist.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/src/backend/storage/buffer/freelist.c b/src/backend/storage/buffer/freelist.c
index 41641bb3ae6..74d070733a4 100644
--- a/src/backend/storage/buffer/freelist.c
+++ b/src/backend/storage/buffer/freelist.c
@@ -948,12 +948,13 @@ GetBufferFromRing(BufferAccessStrategy strategy, uint32 *buf_state)
 		strategy->current = 0;
 
 	/*
-	 * If the slot hasn't been filled yet, tell the caller to allocate a new
-	 * buffer with the normal allocation strategy.  He will then fill this
-	 * slot by calling AddBufferToRing with the new buffer.
+	 * If the slot hasn't been filled yet or the buffer in the slot has been
+	 * invalidated when buffer pool was shrunk, tell the caller to allocate a new
+	 * buffer with the normal allocation strategy.  He will then fill this slot
+	 * by calling AddBufferToRing with the new buffer.
 	 */
 	bufnum = strategy->buffers[strategy->current];
-	if (bufnum == InvalidBuffer)
+	if (bufnum == InvalidBuffer || bufnum > NBuffers)
 		return NULL;
 
 	/*
-- 
2.49.0


--bwrlgp6w2ubxykjq--





^ permalink  raw  reply  [nested|flat] 107+ messages in thread

* [PATCH v5 10/10] Additional validation for buffer in the ring
@ 2025-06-11 12:45 Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
  0 siblings, 0 replies; 107+ messages in thread

From: Ashutosh Bapat @ 2025-06-11 12:45 UTC (permalink / raw)

If the buffer pool has been shrunk, the buffers in the buffer list may
not be valid anymore. Modify GetBufferFromRing to check if the buffer is
still valid before using it. This makes GetBufferFromRing() a bit more
expensive because of additional boolean condition. That may not be
expensive enough to affect query performance. The alternative to that is
more complex as explained below.

The strategy object is created in CurrentMemoryContext and is not
available in any global structure thus accessible when processing buffer
resizing barriers. We may modify GetAccessStrategy() to register
strategy in a global linked list and then arrange to deregister it once
it's no more in use. Looking at the places which use
GetAccessStrategy(), fixing all those may be some work.

Ashutosh Bapat
---
 src/backend/storage/buffer/freelist.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/src/backend/storage/buffer/freelist.c b/src/backend/storage/buffer/freelist.c
index 41641bb3ae6..74d070733a4 100644
--- a/src/backend/storage/buffer/freelist.c
+++ b/src/backend/storage/buffer/freelist.c
@@ -948,12 +948,13 @@ GetBufferFromRing(BufferAccessStrategy strategy, uint32 *buf_state)
 		strategy->current = 0;
 
 	/*
-	 * If the slot hasn't been filled yet, tell the caller to allocate a new
-	 * buffer with the normal allocation strategy.  He will then fill this
-	 * slot by calling AddBufferToRing with the new buffer.
+	 * If the slot hasn't been filled yet or the buffer in the slot has been
+	 * invalidated when buffer pool was shrunk, tell the caller to allocate a new
+	 * buffer with the normal allocation strategy.  He will then fill this slot
+	 * by calling AddBufferToRing with the new buffer.
 	 */
 	bufnum = strategy->buffers[strategy->current];
-	if (bufnum == InvalidBuffer)
+	if (bufnum == InvalidBuffer || bufnum > NBuffers)
 		return NULL;
 
 	/*
-- 
2.49.0


--bwrlgp6w2ubxykjq--





^ permalink  raw  reply  [nested|flat] 107+ messages in thread

* [PATCH v5 10/10] Additional validation for buffer in the ring
@ 2025-06-11 12:45 Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
  0 siblings, 0 replies; 107+ messages in thread

From: Ashutosh Bapat @ 2025-06-11 12:45 UTC (permalink / raw)

If the buffer pool has been shrunk, the buffers in the buffer list may
not be valid anymore. Modify GetBufferFromRing to check if the buffer is
still valid before using it. This makes GetBufferFromRing() a bit more
expensive because of additional boolean condition. That may not be
expensive enough to affect query performance. The alternative to that is
more complex as explained below.

The strategy object is created in CurrentMemoryContext and is not
available in any global structure thus accessible when processing buffer
resizing barriers. We may modify GetAccessStrategy() to register
strategy in a global linked list and then arrange to deregister it once
it's no more in use. Looking at the places which use
GetAccessStrategy(), fixing all those may be some work.

Ashutosh Bapat
---
 src/backend/storage/buffer/freelist.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/src/backend/storage/buffer/freelist.c b/src/backend/storage/buffer/freelist.c
index 41641bb3ae6..74d070733a4 100644
--- a/src/backend/storage/buffer/freelist.c
+++ b/src/backend/storage/buffer/freelist.c
@@ -948,12 +948,13 @@ GetBufferFromRing(BufferAccessStrategy strategy, uint32 *buf_state)
 		strategy->current = 0;
 
 	/*
-	 * If the slot hasn't been filled yet, tell the caller to allocate a new
-	 * buffer with the normal allocation strategy.  He will then fill this
-	 * slot by calling AddBufferToRing with the new buffer.
+	 * If the slot hasn't been filled yet or the buffer in the slot has been
+	 * invalidated when buffer pool was shrunk, tell the caller to allocate a new
+	 * buffer with the normal allocation strategy.  He will then fill this slot
+	 * by calling AddBufferToRing with the new buffer.
 	 */
 	bufnum = strategy->buffers[strategy->current];
-	if (bufnum == InvalidBuffer)
+	if (bufnum == InvalidBuffer || bufnum > NBuffers)
 		return NULL;
 
 	/*
-- 
2.49.0


--bwrlgp6w2ubxykjq--





^ permalink  raw  reply  [nested|flat] 107+ messages in thread

* [PATCH v5 10/10] Additional validation for buffer in the ring
@ 2025-06-11 12:45 Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
  0 siblings, 0 replies; 107+ messages in thread

From: Ashutosh Bapat @ 2025-06-11 12:45 UTC (permalink / raw)

If the buffer pool has been shrunk, the buffers in the buffer list may
not be valid anymore. Modify GetBufferFromRing to check if the buffer is
still valid before using it. This makes GetBufferFromRing() a bit more
expensive because of additional boolean condition. That may not be
expensive enough to affect query performance. The alternative to that is
more complex as explained below.

The strategy object is created in CurrentMemoryContext and is not
available in any global structure thus accessible when processing buffer
resizing barriers. We may modify GetAccessStrategy() to register
strategy in a global linked list and then arrange to deregister it once
it's no more in use. Looking at the places which use
GetAccessStrategy(), fixing all those may be some work.

Ashutosh Bapat
---
 src/backend/storage/buffer/freelist.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/src/backend/storage/buffer/freelist.c b/src/backend/storage/buffer/freelist.c
index 41641bb3ae6..74d070733a4 100644
--- a/src/backend/storage/buffer/freelist.c
+++ b/src/backend/storage/buffer/freelist.c
@@ -948,12 +948,13 @@ GetBufferFromRing(BufferAccessStrategy strategy, uint32 *buf_state)
 		strategy->current = 0;
 
 	/*
-	 * If the slot hasn't been filled yet, tell the caller to allocate a new
-	 * buffer with the normal allocation strategy.  He will then fill this
-	 * slot by calling AddBufferToRing with the new buffer.
+	 * If the slot hasn't been filled yet or the buffer in the slot has been
+	 * invalidated when buffer pool was shrunk, tell the caller to allocate a new
+	 * buffer with the normal allocation strategy.  He will then fill this slot
+	 * by calling AddBufferToRing with the new buffer.
 	 */
 	bufnum = strategy->buffers[strategy->current];
-	if (bufnum == InvalidBuffer)
+	if (bufnum == InvalidBuffer || bufnum > NBuffers)
 		return NULL;
 
 	/*
-- 
2.49.0


--bwrlgp6w2ubxykjq--





^ permalink  raw  reply  [nested|flat] 107+ messages in thread

* [PATCH v5 10/10] Additional validation for buffer in the ring
@ 2025-06-11 12:45 Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
  0 siblings, 0 replies; 107+ messages in thread

From: Ashutosh Bapat @ 2025-06-11 12:45 UTC (permalink / raw)

If the buffer pool has been shrunk, the buffers in the buffer list may
not be valid anymore. Modify GetBufferFromRing to check if the buffer is
still valid before using it. This makes GetBufferFromRing() a bit more
expensive because of additional boolean condition. That may not be
expensive enough to affect query performance. The alternative to that is
more complex as explained below.

The strategy object is created in CurrentMemoryContext and is not
available in any global structure thus accessible when processing buffer
resizing barriers. We may modify GetAccessStrategy() to register
strategy in a global linked list and then arrange to deregister it once
it's no more in use. Looking at the places which use
GetAccessStrategy(), fixing all those may be some work.

Ashutosh Bapat
---
 src/backend/storage/buffer/freelist.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/src/backend/storage/buffer/freelist.c b/src/backend/storage/buffer/freelist.c
index 41641bb3ae6..74d070733a4 100644
--- a/src/backend/storage/buffer/freelist.c
+++ b/src/backend/storage/buffer/freelist.c
@@ -948,12 +948,13 @@ GetBufferFromRing(BufferAccessStrategy strategy, uint32 *buf_state)
 		strategy->current = 0;
 
 	/*
-	 * If the slot hasn't been filled yet, tell the caller to allocate a new
-	 * buffer with the normal allocation strategy.  He will then fill this
-	 * slot by calling AddBufferToRing with the new buffer.
+	 * If the slot hasn't been filled yet or the buffer in the slot has been
+	 * invalidated when buffer pool was shrunk, tell the caller to allocate a new
+	 * buffer with the normal allocation strategy.  He will then fill this slot
+	 * by calling AddBufferToRing with the new buffer.
 	 */
 	bufnum = strategy->buffers[strategy->current];
-	if (bufnum == InvalidBuffer)
+	if (bufnum == InvalidBuffer || bufnum > NBuffers)
 		return NULL;
 
 	/*
-- 
2.49.0


--bwrlgp6w2ubxykjq--





^ permalink  raw  reply  [nested|flat] 107+ messages in thread

* [PATCH v5 10/10] Additional validation for buffer in the ring
@ 2025-06-11 12:45 Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
  0 siblings, 0 replies; 107+ messages in thread

From: Ashutosh Bapat @ 2025-06-11 12:45 UTC (permalink / raw)

If the buffer pool has been shrunk, the buffers in the buffer list may
not be valid anymore. Modify GetBufferFromRing to check if the buffer is
still valid before using it. This makes GetBufferFromRing() a bit more
expensive because of additional boolean condition. That may not be
expensive enough to affect query performance. The alternative to that is
more complex as explained below.

The strategy object is created in CurrentMemoryContext and is not
available in any global structure thus accessible when processing buffer
resizing barriers. We may modify GetAccessStrategy() to register
strategy in a global linked list and then arrange to deregister it once
it's no more in use. Looking at the places which use
GetAccessStrategy(), fixing all those may be some work.

Ashutosh Bapat
---
 src/backend/storage/buffer/freelist.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/src/backend/storage/buffer/freelist.c b/src/backend/storage/buffer/freelist.c
index 41641bb3ae6..74d070733a4 100644
--- a/src/backend/storage/buffer/freelist.c
+++ b/src/backend/storage/buffer/freelist.c
@@ -948,12 +948,13 @@ GetBufferFromRing(BufferAccessStrategy strategy, uint32 *buf_state)
 		strategy->current = 0;
 
 	/*
-	 * If the slot hasn't been filled yet, tell the caller to allocate a new
-	 * buffer with the normal allocation strategy.  He will then fill this
-	 * slot by calling AddBufferToRing with the new buffer.
+	 * If the slot hasn't been filled yet or the buffer in the slot has been
+	 * invalidated when buffer pool was shrunk, tell the caller to allocate a new
+	 * buffer with the normal allocation strategy.  He will then fill this slot
+	 * by calling AddBufferToRing with the new buffer.
 	 */
 	bufnum = strategy->buffers[strategy->current];
-	if (bufnum == InvalidBuffer)
+	if (bufnum == InvalidBuffer || bufnum > NBuffers)
 		return NULL;
 
 	/*
-- 
2.49.0


--bwrlgp6w2ubxykjq--





^ permalink  raw  reply  [nested|flat] 107+ messages in thread

* [PATCH v5 10/10] Additional validation for buffer in the ring
@ 2025-06-11 12:45 Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
  0 siblings, 0 replies; 107+ messages in thread

From: Ashutosh Bapat @ 2025-06-11 12:45 UTC (permalink / raw)

If the buffer pool has been shrunk, the buffers in the buffer list may
not be valid anymore. Modify GetBufferFromRing to check if the buffer is
still valid before using it. This makes GetBufferFromRing() a bit more
expensive because of additional boolean condition. That may not be
expensive enough to affect query performance. The alternative to that is
more complex as explained below.

The strategy object is created in CurrentMemoryContext and is not
available in any global structure thus accessible when processing buffer
resizing barriers. We may modify GetAccessStrategy() to register
strategy in a global linked list and then arrange to deregister it once
it's no more in use. Looking at the places which use
GetAccessStrategy(), fixing all those may be some work.

Ashutosh Bapat
---
 src/backend/storage/buffer/freelist.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/src/backend/storage/buffer/freelist.c b/src/backend/storage/buffer/freelist.c
index 41641bb3ae6..74d070733a4 100644
--- a/src/backend/storage/buffer/freelist.c
+++ b/src/backend/storage/buffer/freelist.c
@@ -948,12 +948,13 @@ GetBufferFromRing(BufferAccessStrategy strategy, uint32 *buf_state)
 		strategy->current = 0;
 
 	/*
-	 * If the slot hasn't been filled yet, tell the caller to allocate a new
-	 * buffer with the normal allocation strategy.  He will then fill this
-	 * slot by calling AddBufferToRing with the new buffer.
+	 * If the slot hasn't been filled yet or the buffer in the slot has been
+	 * invalidated when buffer pool was shrunk, tell the caller to allocate a new
+	 * buffer with the normal allocation strategy.  He will then fill this slot
+	 * by calling AddBufferToRing with the new buffer.
 	 */
 	bufnum = strategy->buffers[strategy->current];
-	if (bufnum == InvalidBuffer)
+	if (bufnum == InvalidBuffer || bufnum > NBuffers)
 		return NULL;
 
 	/*
-- 
2.49.0


--bwrlgp6w2ubxykjq--





^ permalink  raw  reply  [nested|flat] 107+ messages in thread

* [PATCH v5 10/10] Additional validation for buffer in the ring
@ 2025-06-11 12:45 Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
  0 siblings, 0 replies; 107+ messages in thread

From: Ashutosh Bapat @ 2025-06-11 12:45 UTC (permalink / raw)

If the buffer pool has been shrunk, the buffers in the buffer list may
not be valid anymore. Modify GetBufferFromRing to check if the buffer is
still valid before using it. This makes GetBufferFromRing() a bit more
expensive because of additional boolean condition. That may not be
expensive enough to affect query performance. The alternative to that is
more complex as explained below.

The strategy object is created in CurrentMemoryContext and is not
available in any global structure thus accessible when processing buffer
resizing barriers. We may modify GetAccessStrategy() to register
strategy in a global linked list and then arrange to deregister it once
it's no more in use. Looking at the places which use
GetAccessStrategy(), fixing all those may be some work.

Ashutosh Bapat
---
 src/backend/storage/buffer/freelist.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/src/backend/storage/buffer/freelist.c b/src/backend/storage/buffer/freelist.c
index 41641bb3ae6..74d070733a4 100644
--- a/src/backend/storage/buffer/freelist.c
+++ b/src/backend/storage/buffer/freelist.c
@@ -948,12 +948,13 @@ GetBufferFromRing(BufferAccessStrategy strategy, uint32 *buf_state)
 		strategy->current = 0;
 
 	/*
-	 * If the slot hasn't been filled yet, tell the caller to allocate a new
-	 * buffer with the normal allocation strategy.  He will then fill this
-	 * slot by calling AddBufferToRing with the new buffer.
+	 * If the slot hasn't been filled yet or the buffer in the slot has been
+	 * invalidated when buffer pool was shrunk, tell the caller to allocate a new
+	 * buffer with the normal allocation strategy.  He will then fill this slot
+	 * by calling AddBufferToRing with the new buffer.
 	 */
 	bufnum = strategy->buffers[strategy->current];
-	if (bufnum == InvalidBuffer)
+	if (bufnum == InvalidBuffer || bufnum > NBuffers)
 		return NULL;
 
 	/*
-- 
2.49.0


--bwrlgp6w2ubxykjq--





^ permalink  raw  reply  [nested|flat] 107+ messages in thread

* [PATCH v5 10/10] Additional validation for buffer in the ring
@ 2025-06-11 12:45 Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
  0 siblings, 0 replies; 107+ messages in thread

From: Ashutosh Bapat @ 2025-06-11 12:45 UTC (permalink / raw)

If the buffer pool has been shrunk, the buffers in the buffer list may
not be valid anymore. Modify GetBufferFromRing to check if the buffer is
still valid before using it. This makes GetBufferFromRing() a bit more
expensive because of additional boolean condition. That may not be
expensive enough to affect query performance. The alternative to that is
more complex as explained below.

The strategy object is created in CurrentMemoryContext and is not
available in any global structure thus accessible when processing buffer
resizing barriers. We may modify GetAccessStrategy() to register
strategy in a global linked list and then arrange to deregister it once
it's no more in use. Looking at the places which use
GetAccessStrategy(), fixing all those may be some work.

Ashutosh Bapat
---
 src/backend/storage/buffer/freelist.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/src/backend/storage/buffer/freelist.c b/src/backend/storage/buffer/freelist.c
index 41641bb3ae6..74d070733a4 100644
--- a/src/backend/storage/buffer/freelist.c
+++ b/src/backend/storage/buffer/freelist.c
@@ -948,12 +948,13 @@ GetBufferFromRing(BufferAccessStrategy strategy, uint32 *buf_state)
 		strategy->current = 0;
 
 	/*
-	 * If the slot hasn't been filled yet, tell the caller to allocate a new
-	 * buffer with the normal allocation strategy.  He will then fill this
-	 * slot by calling AddBufferToRing with the new buffer.
+	 * If the slot hasn't been filled yet or the buffer in the slot has been
+	 * invalidated when buffer pool was shrunk, tell the caller to allocate a new
+	 * buffer with the normal allocation strategy.  He will then fill this slot
+	 * by calling AddBufferToRing with the new buffer.
 	 */
 	bufnum = strategy->buffers[strategy->current];
-	if (bufnum == InvalidBuffer)
+	if (bufnum == InvalidBuffer || bufnum > NBuffers)
 		return NULL;
 
 	/*
-- 
2.49.0


--bwrlgp6w2ubxykjq--





^ permalink  raw  reply  [nested|flat] 107+ messages in thread

* [PATCH v5 10/10] Additional validation for buffer in the ring
@ 2025-06-11 12:45 Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
  0 siblings, 0 replies; 107+ messages in thread

From: Ashutosh Bapat @ 2025-06-11 12:45 UTC (permalink / raw)

If the buffer pool has been shrunk, the buffers in the buffer list may
not be valid anymore. Modify GetBufferFromRing to check if the buffer is
still valid before using it. This makes GetBufferFromRing() a bit more
expensive because of additional boolean condition. That may not be
expensive enough to affect query performance. The alternative to that is
more complex as explained below.

The strategy object is created in CurrentMemoryContext and is not
available in any global structure thus accessible when processing buffer
resizing barriers. We may modify GetAccessStrategy() to register
strategy in a global linked list and then arrange to deregister it once
it's no more in use. Looking at the places which use
GetAccessStrategy(), fixing all those may be some work.

Ashutosh Bapat
---
 src/backend/storage/buffer/freelist.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/src/backend/storage/buffer/freelist.c b/src/backend/storage/buffer/freelist.c
index 41641bb3ae6..74d070733a4 100644
--- a/src/backend/storage/buffer/freelist.c
+++ b/src/backend/storage/buffer/freelist.c
@@ -948,12 +948,13 @@ GetBufferFromRing(BufferAccessStrategy strategy, uint32 *buf_state)
 		strategy->current = 0;
 
 	/*
-	 * If the slot hasn't been filled yet, tell the caller to allocate a new
-	 * buffer with the normal allocation strategy.  He will then fill this
-	 * slot by calling AddBufferToRing with the new buffer.
+	 * If the slot hasn't been filled yet or the buffer in the slot has been
+	 * invalidated when buffer pool was shrunk, tell the caller to allocate a new
+	 * buffer with the normal allocation strategy.  He will then fill this slot
+	 * by calling AddBufferToRing with the new buffer.
 	 */
 	bufnum = strategy->buffers[strategy->current];
-	if (bufnum == InvalidBuffer)
+	if (bufnum == InvalidBuffer || bufnum > NBuffers)
 		return NULL;
 
 	/*
-- 
2.49.0


--bwrlgp6w2ubxykjq--





^ permalink  raw  reply  [nested|flat] 107+ messages in thread

* [PATCH v5 10/10] Additional validation for buffer in the ring
@ 2025-06-11 12:45 Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
  0 siblings, 0 replies; 107+ messages in thread

From: Ashutosh Bapat @ 2025-06-11 12:45 UTC (permalink / raw)

If the buffer pool has been shrunk, the buffers in the buffer list may
not be valid anymore. Modify GetBufferFromRing to check if the buffer is
still valid before using it. This makes GetBufferFromRing() a bit more
expensive because of additional boolean condition. That may not be
expensive enough to affect query performance. The alternative to that is
more complex as explained below.

The strategy object is created in CurrentMemoryContext and is not
available in any global structure thus accessible when processing buffer
resizing barriers. We may modify GetAccessStrategy() to register
strategy in a global linked list and then arrange to deregister it once
it's no more in use. Looking at the places which use
GetAccessStrategy(), fixing all those may be some work.

Ashutosh Bapat
---
 src/backend/storage/buffer/freelist.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/src/backend/storage/buffer/freelist.c b/src/backend/storage/buffer/freelist.c
index 41641bb3ae6..74d070733a4 100644
--- a/src/backend/storage/buffer/freelist.c
+++ b/src/backend/storage/buffer/freelist.c
@@ -948,12 +948,13 @@ GetBufferFromRing(BufferAccessStrategy strategy, uint32 *buf_state)
 		strategy->current = 0;
 
 	/*
-	 * If the slot hasn't been filled yet, tell the caller to allocate a new
-	 * buffer with the normal allocation strategy.  He will then fill this
-	 * slot by calling AddBufferToRing with the new buffer.
+	 * If the slot hasn't been filled yet or the buffer in the slot has been
+	 * invalidated when buffer pool was shrunk, tell the caller to allocate a new
+	 * buffer with the normal allocation strategy.  He will then fill this slot
+	 * by calling AddBufferToRing with the new buffer.
 	 */
 	bufnum = strategy->buffers[strategy->current];
-	if (bufnum == InvalidBuffer)
+	if (bufnum == InvalidBuffer || bufnum > NBuffers)
 		return NULL;
 
 	/*
-- 
2.49.0


--bwrlgp6w2ubxykjq--





^ permalink  raw  reply  [nested|flat] 107+ messages in thread

* [PATCH v5 10/10] Additional validation for buffer in the ring
@ 2025-06-11 12:45 Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
  0 siblings, 0 replies; 107+ messages in thread

From: Ashutosh Bapat @ 2025-06-11 12:45 UTC (permalink / raw)

If the buffer pool has been shrunk, the buffers in the buffer list may
not be valid anymore. Modify GetBufferFromRing to check if the buffer is
still valid before using it. This makes GetBufferFromRing() a bit more
expensive because of additional boolean condition. That may not be
expensive enough to affect query performance. The alternative to that is
more complex as explained below.

The strategy object is created in CurrentMemoryContext and is not
available in any global structure thus accessible when processing buffer
resizing barriers. We may modify GetAccessStrategy() to register
strategy in a global linked list and then arrange to deregister it once
it's no more in use. Looking at the places which use
GetAccessStrategy(), fixing all those may be some work.

Ashutosh Bapat
---
 src/backend/storage/buffer/freelist.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/src/backend/storage/buffer/freelist.c b/src/backend/storage/buffer/freelist.c
index 41641bb3ae6..74d070733a4 100644
--- a/src/backend/storage/buffer/freelist.c
+++ b/src/backend/storage/buffer/freelist.c
@@ -948,12 +948,13 @@ GetBufferFromRing(BufferAccessStrategy strategy, uint32 *buf_state)
 		strategy->current = 0;
 
 	/*
-	 * If the slot hasn't been filled yet, tell the caller to allocate a new
-	 * buffer with the normal allocation strategy.  He will then fill this
-	 * slot by calling AddBufferToRing with the new buffer.
+	 * If the slot hasn't been filled yet or the buffer in the slot has been
+	 * invalidated when buffer pool was shrunk, tell the caller to allocate a new
+	 * buffer with the normal allocation strategy.  He will then fill this slot
+	 * by calling AddBufferToRing with the new buffer.
 	 */
 	bufnum = strategy->buffers[strategy->current];
-	if (bufnum == InvalidBuffer)
+	if (bufnum == InvalidBuffer || bufnum > NBuffers)
 		return NULL;
 
 	/*
-- 
2.49.0


--bwrlgp6w2ubxykjq--





^ permalink  raw  reply  [nested|flat] 107+ messages in thread

* [PATCH v5 10/10] Additional validation for buffer in the ring
@ 2025-06-11 12:45 Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
  0 siblings, 0 replies; 107+ messages in thread

From: Ashutosh Bapat @ 2025-06-11 12:45 UTC (permalink / raw)

If the buffer pool has been shrunk, the buffers in the buffer list may
not be valid anymore. Modify GetBufferFromRing to check if the buffer is
still valid before using it. This makes GetBufferFromRing() a bit more
expensive because of additional boolean condition. That may not be
expensive enough to affect query performance. The alternative to that is
more complex as explained below.

The strategy object is created in CurrentMemoryContext and is not
available in any global structure thus accessible when processing buffer
resizing barriers. We may modify GetAccessStrategy() to register
strategy in a global linked list and then arrange to deregister it once
it's no more in use. Looking at the places which use
GetAccessStrategy(), fixing all those may be some work.

Ashutosh Bapat
---
 src/backend/storage/buffer/freelist.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/src/backend/storage/buffer/freelist.c b/src/backend/storage/buffer/freelist.c
index 41641bb3ae6..74d070733a4 100644
--- a/src/backend/storage/buffer/freelist.c
+++ b/src/backend/storage/buffer/freelist.c
@@ -948,12 +948,13 @@ GetBufferFromRing(BufferAccessStrategy strategy, uint32 *buf_state)
 		strategy->current = 0;
 
 	/*
-	 * If the slot hasn't been filled yet, tell the caller to allocate a new
-	 * buffer with the normal allocation strategy.  He will then fill this
-	 * slot by calling AddBufferToRing with the new buffer.
+	 * If the slot hasn't been filled yet or the buffer in the slot has been
+	 * invalidated when buffer pool was shrunk, tell the caller to allocate a new
+	 * buffer with the normal allocation strategy.  He will then fill this slot
+	 * by calling AddBufferToRing with the new buffer.
 	 */
 	bufnum = strategy->buffers[strategy->current];
-	if (bufnum == InvalidBuffer)
+	if (bufnum == InvalidBuffer || bufnum > NBuffers)
 		return NULL;
 
 	/*
-- 
2.49.0


--bwrlgp6w2ubxykjq--





^ permalink  raw  reply  [nested|flat] 107+ messages in thread

* [PATCH v5 10/10] Additional validation for buffer in the ring
@ 2025-06-11 12:45 Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
  0 siblings, 0 replies; 107+ messages in thread

From: Ashutosh Bapat @ 2025-06-11 12:45 UTC (permalink / raw)

If the buffer pool has been shrunk, the buffers in the buffer list may
not be valid anymore. Modify GetBufferFromRing to check if the buffer is
still valid before using it. This makes GetBufferFromRing() a bit more
expensive because of additional boolean condition. That may not be
expensive enough to affect query performance. The alternative to that is
more complex as explained below.

The strategy object is created in CurrentMemoryContext and is not
available in any global structure thus accessible when processing buffer
resizing barriers. We may modify GetAccessStrategy() to register
strategy in a global linked list and then arrange to deregister it once
it's no more in use. Looking at the places which use
GetAccessStrategy(), fixing all those may be some work.

Ashutosh Bapat
---
 src/backend/storage/buffer/freelist.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/src/backend/storage/buffer/freelist.c b/src/backend/storage/buffer/freelist.c
index 41641bb3ae6..74d070733a4 100644
--- a/src/backend/storage/buffer/freelist.c
+++ b/src/backend/storage/buffer/freelist.c
@@ -948,12 +948,13 @@ GetBufferFromRing(BufferAccessStrategy strategy, uint32 *buf_state)
 		strategy->current = 0;
 
 	/*
-	 * If the slot hasn't been filled yet, tell the caller to allocate a new
-	 * buffer with the normal allocation strategy.  He will then fill this
-	 * slot by calling AddBufferToRing with the new buffer.
+	 * If the slot hasn't been filled yet or the buffer in the slot has been
+	 * invalidated when buffer pool was shrunk, tell the caller to allocate a new
+	 * buffer with the normal allocation strategy.  He will then fill this slot
+	 * by calling AddBufferToRing with the new buffer.
 	 */
 	bufnum = strategy->buffers[strategy->current];
-	if (bufnum == InvalidBuffer)
+	if (bufnum == InvalidBuffer || bufnum > NBuffers)
 		return NULL;
 
 	/*
-- 
2.49.0


--bwrlgp6w2ubxykjq--





^ permalink  raw  reply  [nested|flat] 107+ messages in thread

* [PATCH v5 10/10] Additional validation for buffer in the ring
@ 2025-06-11 12:45 Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
  0 siblings, 0 replies; 107+ messages in thread

From: Ashutosh Bapat @ 2025-06-11 12:45 UTC (permalink / raw)

If the buffer pool has been shrunk, the buffers in the buffer list may
not be valid anymore. Modify GetBufferFromRing to check if the buffer is
still valid before using it. This makes GetBufferFromRing() a bit more
expensive because of additional boolean condition. That may not be
expensive enough to affect query performance. The alternative to that is
more complex as explained below.

The strategy object is created in CurrentMemoryContext and is not
available in any global structure thus accessible when processing buffer
resizing barriers. We may modify GetAccessStrategy() to register
strategy in a global linked list and then arrange to deregister it once
it's no more in use. Looking at the places which use
GetAccessStrategy(), fixing all those may be some work.

Ashutosh Bapat
---
 src/backend/storage/buffer/freelist.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/src/backend/storage/buffer/freelist.c b/src/backend/storage/buffer/freelist.c
index 41641bb3ae6..74d070733a4 100644
--- a/src/backend/storage/buffer/freelist.c
+++ b/src/backend/storage/buffer/freelist.c
@@ -948,12 +948,13 @@ GetBufferFromRing(BufferAccessStrategy strategy, uint32 *buf_state)
 		strategy->current = 0;
 
 	/*
-	 * If the slot hasn't been filled yet, tell the caller to allocate a new
-	 * buffer with the normal allocation strategy.  He will then fill this
-	 * slot by calling AddBufferToRing with the new buffer.
+	 * If the slot hasn't been filled yet or the buffer in the slot has been
+	 * invalidated when buffer pool was shrunk, tell the caller to allocate a new
+	 * buffer with the normal allocation strategy.  He will then fill this slot
+	 * by calling AddBufferToRing with the new buffer.
 	 */
 	bufnum = strategy->buffers[strategy->current];
-	if (bufnum == InvalidBuffer)
+	if (bufnum == InvalidBuffer || bufnum > NBuffers)
 		return NULL;
 
 	/*
-- 
2.49.0


--bwrlgp6w2ubxykjq--





^ permalink  raw  reply  [nested|flat] 107+ messages in thread

* [PATCH v5 10/10] Additional validation for buffer in the ring
@ 2025-06-11 12:45 Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
  0 siblings, 0 replies; 107+ messages in thread

From: Ashutosh Bapat @ 2025-06-11 12:45 UTC (permalink / raw)

If the buffer pool has been shrunk, the buffers in the buffer list may
not be valid anymore. Modify GetBufferFromRing to check if the buffer is
still valid before using it. This makes GetBufferFromRing() a bit more
expensive because of additional boolean condition. That may not be
expensive enough to affect query performance. The alternative to that is
more complex as explained below.

The strategy object is created in CurrentMemoryContext and is not
available in any global structure thus accessible when processing buffer
resizing barriers. We may modify GetAccessStrategy() to register
strategy in a global linked list and then arrange to deregister it once
it's no more in use. Looking at the places which use
GetAccessStrategy(), fixing all those may be some work.

Ashutosh Bapat
---
 src/backend/storage/buffer/freelist.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/src/backend/storage/buffer/freelist.c b/src/backend/storage/buffer/freelist.c
index 41641bb3ae6..74d070733a4 100644
--- a/src/backend/storage/buffer/freelist.c
+++ b/src/backend/storage/buffer/freelist.c
@@ -948,12 +948,13 @@ GetBufferFromRing(BufferAccessStrategy strategy, uint32 *buf_state)
 		strategy->current = 0;
 
 	/*
-	 * If the slot hasn't been filled yet, tell the caller to allocate a new
-	 * buffer with the normal allocation strategy.  He will then fill this
-	 * slot by calling AddBufferToRing with the new buffer.
+	 * If the slot hasn't been filled yet or the buffer in the slot has been
+	 * invalidated when buffer pool was shrunk, tell the caller to allocate a new
+	 * buffer with the normal allocation strategy.  He will then fill this slot
+	 * by calling AddBufferToRing with the new buffer.
 	 */
 	bufnum = strategy->buffers[strategy->current];
-	if (bufnum == InvalidBuffer)
+	if (bufnum == InvalidBuffer || bufnum > NBuffers)
 		return NULL;
 
 	/*
-- 
2.49.0


--bwrlgp6w2ubxykjq--





^ permalink  raw  reply  [nested|flat] 107+ messages in thread

* [PATCH v5 10/10] Additional validation for buffer in the ring
@ 2025-06-11 12:45 Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
  0 siblings, 0 replies; 107+ messages in thread

From: Ashutosh Bapat @ 2025-06-11 12:45 UTC (permalink / raw)

If the buffer pool has been shrunk, the buffers in the buffer list may
not be valid anymore. Modify GetBufferFromRing to check if the buffer is
still valid before using it. This makes GetBufferFromRing() a bit more
expensive because of additional boolean condition. That may not be
expensive enough to affect query performance. The alternative to that is
more complex as explained below.

The strategy object is created in CurrentMemoryContext and is not
available in any global structure thus accessible when processing buffer
resizing barriers. We may modify GetAccessStrategy() to register
strategy in a global linked list and then arrange to deregister it once
it's no more in use. Looking at the places which use
GetAccessStrategy(), fixing all those may be some work.

Ashutosh Bapat
---
 src/backend/storage/buffer/freelist.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/src/backend/storage/buffer/freelist.c b/src/backend/storage/buffer/freelist.c
index 41641bb3ae6..74d070733a4 100644
--- a/src/backend/storage/buffer/freelist.c
+++ b/src/backend/storage/buffer/freelist.c
@@ -948,12 +948,13 @@ GetBufferFromRing(BufferAccessStrategy strategy, uint32 *buf_state)
 		strategy->current = 0;
 
 	/*
-	 * If the slot hasn't been filled yet, tell the caller to allocate a new
-	 * buffer with the normal allocation strategy.  He will then fill this
-	 * slot by calling AddBufferToRing with the new buffer.
+	 * If the slot hasn't been filled yet or the buffer in the slot has been
+	 * invalidated when buffer pool was shrunk, tell the caller to allocate a new
+	 * buffer with the normal allocation strategy.  He will then fill this slot
+	 * by calling AddBufferToRing with the new buffer.
 	 */
 	bufnum = strategy->buffers[strategy->current];
-	if (bufnum == InvalidBuffer)
+	if (bufnum == InvalidBuffer || bufnum > NBuffers)
 		return NULL;
 
 	/*
-- 
2.49.0


--bwrlgp6w2ubxykjq--





^ permalink  raw  reply  [nested|flat] 107+ messages in thread

* [PATCH v5 10/10] Additional validation for buffer in the ring
@ 2025-06-11 12:45 Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
  0 siblings, 0 replies; 107+ messages in thread

From: Ashutosh Bapat @ 2025-06-11 12:45 UTC (permalink / raw)

If the buffer pool has been shrunk, the buffers in the buffer list may
not be valid anymore. Modify GetBufferFromRing to check if the buffer is
still valid before using it. This makes GetBufferFromRing() a bit more
expensive because of additional boolean condition. That may not be
expensive enough to affect query performance. The alternative to that is
more complex as explained below.

The strategy object is created in CurrentMemoryContext and is not
available in any global structure thus accessible when processing buffer
resizing barriers. We may modify GetAccessStrategy() to register
strategy in a global linked list and then arrange to deregister it once
it's no more in use. Looking at the places which use
GetAccessStrategy(), fixing all those may be some work.

Ashutosh Bapat
---
 src/backend/storage/buffer/freelist.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/src/backend/storage/buffer/freelist.c b/src/backend/storage/buffer/freelist.c
index 41641bb3ae6..74d070733a4 100644
--- a/src/backend/storage/buffer/freelist.c
+++ b/src/backend/storage/buffer/freelist.c
@@ -948,12 +948,13 @@ GetBufferFromRing(BufferAccessStrategy strategy, uint32 *buf_state)
 		strategy->current = 0;
 
 	/*
-	 * If the slot hasn't been filled yet, tell the caller to allocate a new
-	 * buffer with the normal allocation strategy.  He will then fill this
-	 * slot by calling AddBufferToRing with the new buffer.
+	 * If the slot hasn't been filled yet or the buffer in the slot has been
+	 * invalidated when buffer pool was shrunk, tell the caller to allocate a new
+	 * buffer with the normal allocation strategy.  He will then fill this slot
+	 * by calling AddBufferToRing with the new buffer.
 	 */
 	bufnum = strategy->buffers[strategy->current];
-	if (bufnum == InvalidBuffer)
+	if (bufnum == InvalidBuffer || bufnum > NBuffers)
 		return NULL;
 
 	/*
-- 
2.49.0


--bwrlgp6w2ubxykjq--





^ permalink  raw  reply  [nested|flat] 107+ messages in thread

* [PATCH v5 10/10] Additional validation for buffer in the ring
@ 2025-06-11 12:45 Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
  0 siblings, 0 replies; 107+ messages in thread

From: Ashutosh Bapat @ 2025-06-11 12:45 UTC (permalink / raw)

If the buffer pool has been shrunk, the buffers in the buffer list may
not be valid anymore. Modify GetBufferFromRing to check if the buffer is
still valid before using it. This makes GetBufferFromRing() a bit more
expensive because of additional boolean condition. That may not be
expensive enough to affect query performance. The alternative to that is
more complex as explained below.

The strategy object is created in CurrentMemoryContext and is not
available in any global structure thus accessible when processing buffer
resizing barriers. We may modify GetAccessStrategy() to register
strategy in a global linked list and then arrange to deregister it once
it's no more in use. Looking at the places which use
GetAccessStrategy(), fixing all those may be some work.

Ashutosh Bapat
---
 src/backend/storage/buffer/freelist.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/src/backend/storage/buffer/freelist.c b/src/backend/storage/buffer/freelist.c
index 41641bb3ae6..74d070733a4 100644
--- a/src/backend/storage/buffer/freelist.c
+++ b/src/backend/storage/buffer/freelist.c
@@ -948,12 +948,13 @@ GetBufferFromRing(BufferAccessStrategy strategy, uint32 *buf_state)
 		strategy->current = 0;
 
 	/*
-	 * If the slot hasn't been filled yet, tell the caller to allocate a new
-	 * buffer with the normal allocation strategy.  He will then fill this
-	 * slot by calling AddBufferToRing with the new buffer.
+	 * If the slot hasn't been filled yet or the buffer in the slot has been
+	 * invalidated when buffer pool was shrunk, tell the caller to allocate a new
+	 * buffer with the normal allocation strategy.  He will then fill this slot
+	 * by calling AddBufferToRing with the new buffer.
 	 */
 	bufnum = strategy->buffers[strategy->current];
-	if (bufnum == InvalidBuffer)
+	if (bufnum == InvalidBuffer || bufnum > NBuffers)
 		return NULL;
 
 	/*
-- 
2.49.0


--bwrlgp6w2ubxykjq--





^ permalink  raw  reply  [nested|flat] 107+ messages in thread

* [PATCH v5 10/10] Additional validation for buffer in the ring
@ 2025-06-11 12:45 Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
  0 siblings, 0 replies; 107+ messages in thread

From: Ashutosh Bapat @ 2025-06-11 12:45 UTC (permalink / raw)

If the buffer pool has been shrunk, the buffers in the buffer list may
not be valid anymore. Modify GetBufferFromRing to check if the buffer is
still valid before using it. This makes GetBufferFromRing() a bit more
expensive because of additional boolean condition. That may not be
expensive enough to affect query performance. The alternative to that is
more complex as explained below.

The strategy object is created in CurrentMemoryContext and is not
available in any global structure thus accessible when processing buffer
resizing barriers. We may modify GetAccessStrategy() to register
strategy in a global linked list and then arrange to deregister it once
it's no more in use. Looking at the places which use
GetAccessStrategy(), fixing all those may be some work.

Ashutosh Bapat
---
 src/backend/storage/buffer/freelist.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/src/backend/storage/buffer/freelist.c b/src/backend/storage/buffer/freelist.c
index 41641bb3ae6..74d070733a4 100644
--- a/src/backend/storage/buffer/freelist.c
+++ b/src/backend/storage/buffer/freelist.c
@@ -948,12 +948,13 @@ GetBufferFromRing(BufferAccessStrategy strategy, uint32 *buf_state)
 		strategy->current = 0;
 
 	/*
-	 * If the slot hasn't been filled yet, tell the caller to allocate a new
-	 * buffer with the normal allocation strategy.  He will then fill this
-	 * slot by calling AddBufferToRing with the new buffer.
+	 * If the slot hasn't been filled yet or the buffer in the slot has been
+	 * invalidated when buffer pool was shrunk, tell the caller to allocate a new
+	 * buffer with the normal allocation strategy.  He will then fill this slot
+	 * by calling AddBufferToRing with the new buffer.
 	 */
 	bufnum = strategy->buffers[strategy->current];
-	if (bufnum == InvalidBuffer)
+	if (bufnum == InvalidBuffer || bufnum > NBuffers)
 		return NULL;
 
 	/*
-- 
2.49.0


--bwrlgp6w2ubxykjq--





^ permalink  raw  reply  [nested|flat] 107+ messages in thread

* [PATCH v5 10/10] Additional validation for buffer in the ring
@ 2025-06-11 12:45 Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
  0 siblings, 0 replies; 107+ messages in thread

From: Ashutosh Bapat @ 2025-06-11 12:45 UTC (permalink / raw)

If the buffer pool has been shrunk, the buffers in the buffer list may
not be valid anymore. Modify GetBufferFromRing to check if the buffer is
still valid before using it. This makes GetBufferFromRing() a bit more
expensive because of additional boolean condition. That may not be
expensive enough to affect query performance. The alternative to that is
more complex as explained below.

The strategy object is created in CurrentMemoryContext and is not
available in any global structure thus accessible when processing buffer
resizing barriers. We may modify GetAccessStrategy() to register
strategy in a global linked list and then arrange to deregister it once
it's no more in use. Looking at the places which use
GetAccessStrategy(), fixing all those may be some work.

Ashutosh Bapat
---
 src/backend/storage/buffer/freelist.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/src/backend/storage/buffer/freelist.c b/src/backend/storage/buffer/freelist.c
index 41641bb3ae6..74d070733a4 100644
--- a/src/backend/storage/buffer/freelist.c
+++ b/src/backend/storage/buffer/freelist.c
@@ -948,12 +948,13 @@ GetBufferFromRing(BufferAccessStrategy strategy, uint32 *buf_state)
 		strategy->current = 0;
 
 	/*
-	 * If the slot hasn't been filled yet, tell the caller to allocate a new
-	 * buffer with the normal allocation strategy.  He will then fill this
-	 * slot by calling AddBufferToRing with the new buffer.
+	 * If the slot hasn't been filled yet or the buffer in the slot has been
+	 * invalidated when buffer pool was shrunk, tell the caller to allocate a new
+	 * buffer with the normal allocation strategy.  He will then fill this slot
+	 * by calling AddBufferToRing with the new buffer.
 	 */
 	bufnum = strategy->buffers[strategy->current];
-	if (bufnum == InvalidBuffer)
+	if (bufnum == InvalidBuffer || bufnum > NBuffers)
 		return NULL;
 
 	/*
-- 
2.49.0


--bwrlgp6w2ubxykjq--





^ permalink  raw  reply  [nested|flat] 107+ messages in thread

* [PATCH v5 10/10] Additional validation for buffer in the ring
@ 2025-06-11 12:45 Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
  0 siblings, 0 replies; 107+ messages in thread

From: Ashutosh Bapat @ 2025-06-11 12:45 UTC (permalink / raw)

If the buffer pool has been shrunk, the buffers in the buffer list may
not be valid anymore. Modify GetBufferFromRing to check if the buffer is
still valid before using it. This makes GetBufferFromRing() a bit more
expensive because of additional boolean condition. That may not be
expensive enough to affect query performance. The alternative to that is
more complex as explained below.

The strategy object is created in CurrentMemoryContext and is not
available in any global structure thus accessible when processing buffer
resizing barriers. We may modify GetAccessStrategy() to register
strategy in a global linked list and then arrange to deregister it once
it's no more in use. Looking at the places which use
GetAccessStrategy(), fixing all those may be some work.

Ashutosh Bapat
---
 src/backend/storage/buffer/freelist.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/src/backend/storage/buffer/freelist.c b/src/backend/storage/buffer/freelist.c
index 41641bb3ae6..74d070733a4 100644
--- a/src/backend/storage/buffer/freelist.c
+++ b/src/backend/storage/buffer/freelist.c
@@ -948,12 +948,13 @@ GetBufferFromRing(BufferAccessStrategy strategy, uint32 *buf_state)
 		strategy->current = 0;
 
 	/*
-	 * If the slot hasn't been filled yet, tell the caller to allocate a new
-	 * buffer with the normal allocation strategy.  He will then fill this
-	 * slot by calling AddBufferToRing with the new buffer.
+	 * If the slot hasn't been filled yet or the buffer in the slot has been
+	 * invalidated when buffer pool was shrunk, tell the caller to allocate a new
+	 * buffer with the normal allocation strategy.  He will then fill this slot
+	 * by calling AddBufferToRing with the new buffer.
 	 */
 	bufnum = strategy->buffers[strategy->current];
-	if (bufnum == InvalidBuffer)
+	if (bufnum == InvalidBuffer || bufnum > NBuffers)
 		return NULL;
 
 	/*
-- 
2.49.0


--bwrlgp6w2ubxykjq--





^ permalink  raw  reply  [nested|flat] 107+ messages in thread

* [PATCH v5 10/10] Additional validation for buffer in the ring
@ 2025-06-11 12:45 Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
  0 siblings, 0 replies; 107+ messages in thread

From: Ashutosh Bapat @ 2025-06-11 12:45 UTC (permalink / raw)

If the buffer pool has been shrunk, the buffers in the buffer list may
not be valid anymore. Modify GetBufferFromRing to check if the buffer is
still valid before using it. This makes GetBufferFromRing() a bit more
expensive because of additional boolean condition. That may not be
expensive enough to affect query performance. The alternative to that is
more complex as explained below.

The strategy object is created in CurrentMemoryContext and is not
available in any global structure thus accessible when processing buffer
resizing barriers. We may modify GetAccessStrategy() to register
strategy in a global linked list and then arrange to deregister it once
it's no more in use. Looking at the places which use
GetAccessStrategy(), fixing all those may be some work.

Ashutosh Bapat
---
 src/backend/storage/buffer/freelist.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/src/backend/storage/buffer/freelist.c b/src/backend/storage/buffer/freelist.c
index 41641bb3ae6..74d070733a4 100644
--- a/src/backend/storage/buffer/freelist.c
+++ b/src/backend/storage/buffer/freelist.c
@@ -948,12 +948,13 @@ GetBufferFromRing(BufferAccessStrategy strategy, uint32 *buf_state)
 		strategy->current = 0;
 
 	/*
-	 * If the slot hasn't been filled yet, tell the caller to allocate a new
-	 * buffer with the normal allocation strategy.  He will then fill this
-	 * slot by calling AddBufferToRing with the new buffer.
+	 * If the slot hasn't been filled yet or the buffer in the slot has been
+	 * invalidated when buffer pool was shrunk, tell the caller to allocate a new
+	 * buffer with the normal allocation strategy.  He will then fill this slot
+	 * by calling AddBufferToRing with the new buffer.
 	 */
 	bufnum = strategy->buffers[strategy->current];
-	if (bufnum == InvalidBuffer)
+	if (bufnum == InvalidBuffer || bufnum > NBuffers)
 		return NULL;
 
 	/*
-- 
2.49.0


--bwrlgp6w2ubxykjq--





^ permalink  raw  reply  [nested|flat] 107+ messages in thread

* [PATCH v5 10/10] Additional validation for buffer in the ring
@ 2025-06-11 12:45 Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
  0 siblings, 0 replies; 107+ messages in thread

From: Ashutosh Bapat @ 2025-06-11 12:45 UTC (permalink / raw)

If the buffer pool has been shrunk, the buffers in the buffer list may
not be valid anymore. Modify GetBufferFromRing to check if the buffer is
still valid before using it. This makes GetBufferFromRing() a bit more
expensive because of additional boolean condition. That may not be
expensive enough to affect query performance. The alternative to that is
more complex as explained below.

The strategy object is created in CurrentMemoryContext and is not
available in any global structure thus accessible when processing buffer
resizing barriers. We may modify GetAccessStrategy() to register
strategy in a global linked list and then arrange to deregister it once
it's no more in use. Looking at the places which use
GetAccessStrategy(), fixing all those may be some work.

Ashutosh Bapat
---
 src/backend/storage/buffer/freelist.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/src/backend/storage/buffer/freelist.c b/src/backend/storage/buffer/freelist.c
index 41641bb3ae6..74d070733a4 100644
--- a/src/backend/storage/buffer/freelist.c
+++ b/src/backend/storage/buffer/freelist.c
@@ -948,12 +948,13 @@ GetBufferFromRing(BufferAccessStrategy strategy, uint32 *buf_state)
 		strategy->current = 0;
 
 	/*
-	 * If the slot hasn't been filled yet, tell the caller to allocate a new
-	 * buffer with the normal allocation strategy.  He will then fill this
-	 * slot by calling AddBufferToRing with the new buffer.
+	 * If the slot hasn't been filled yet or the buffer in the slot has been
+	 * invalidated when buffer pool was shrunk, tell the caller to allocate a new
+	 * buffer with the normal allocation strategy.  He will then fill this slot
+	 * by calling AddBufferToRing with the new buffer.
 	 */
 	bufnum = strategy->buffers[strategy->current];
-	if (bufnum == InvalidBuffer)
+	if (bufnum == InvalidBuffer || bufnum > NBuffers)
 		return NULL;
 
 	/*
-- 
2.49.0


--bwrlgp6w2ubxykjq--





^ permalink  raw  reply  [nested|flat] 107+ messages in thread

* [PATCH v5 10/10] Additional validation for buffer in the ring
@ 2025-06-11 12:45 Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
  0 siblings, 0 replies; 107+ messages in thread

From: Ashutosh Bapat @ 2025-06-11 12:45 UTC (permalink / raw)

If the buffer pool has been shrunk, the buffers in the buffer list may
not be valid anymore. Modify GetBufferFromRing to check if the buffer is
still valid before using it. This makes GetBufferFromRing() a bit more
expensive because of additional boolean condition. That may not be
expensive enough to affect query performance. The alternative to that is
more complex as explained below.

The strategy object is created in CurrentMemoryContext and is not
available in any global structure thus accessible when processing buffer
resizing barriers. We may modify GetAccessStrategy() to register
strategy in a global linked list and then arrange to deregister it once
it's no more in use. Looking at the places which use
GetAccessStrategy(), fixing all those may be some work.

Ashutosh Bapat
---
 src/backend/storage/buffer/freelist.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/src/backend/storage/buffer/freelist.c b/src/backend/storage/buffer/freelist.c
index 41641bb3ae6..74d070733a4 100644
--- a/src/backend/storage/buffer/freelist.c
+++ b/src/backend/storage/buffer/freelist.c
@@ -948,12 +948,13 @@ GetBufferFromRing(BufferAccessStrategy strategy, uint32 *buf_state)
 		strategy->current = 0;
 
 	/*
-	 * If the slot hasn't been filled yet, tell the caller to allocate a new
-	 * buffer with the normal allocation strategy.  He will then fill this
-	 * slot by calling AddBufferToRing with the new buffer.
+	 * If the slot hasn't been filled yet or the buffer in the slot has been
+	 * invalidated when buffer pool was shrunk, tell the caller to allocate a new
+	 * buffer with the normal allocation strategy.  He will then fill this slot
+	 * by calling AddBufferToRing with the new buffer.
 	 */
 	bufnum = strategy->buffers[strategy->current];
-	if (bufnum == InvalidBuffer)
+	if (bufnum == InvalidBuffer || bufnum > NBuffers)
 		return NULL;
 
 	/*
-- 
2.49.0


--bwrlgp6w2ubxykjq--





^ permalink  raw  reply  [nested|flat] 107+ messages in thread

* [PATCH v5 10/10] Additional validation for buffer in the ring
@ 2025-06-11 12:45 Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
  0 siblings, 0 replies; 107+ messages in thread

From: Ashutosh Bapat @ 2025-06-11 12:45 UTC (permalink / raw)

If the buffer pool has been shrunk, the buffers in the buffer list may
not be valid anymore. Modify GetBufferFromRing to check if the buffer is
still valid before using it. This makes GetBufferFromRing() a bit more
expensive because of additional boolean condition. That may not be
expensive enough to affect query performance. The alternative to that is
more complex as explained below.

The strategy object is created in CurrentMemoryContext and is not
available in any global structure thus accessible when processing buffer
resizing barriers. We may modify GetAccessStrategy() to register
strategy in a global linked list and then arrange to deregister it once
it's no more in use. Looking at the places which use
GetAccessStrategy(), fixing all those may be some work.

Ashutosh Bapat
---
 src/backend/storage/buffer/freelist.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/src/backend/storage/buffer/freelist.c b/src/backend/storage/buffer/freelist.c
index 41641bb3ae6..74d070733a4 100644
--- a/src/backend/storage/buffer/freelist.c
+++ b/src/backend/storage/buffer/freelist.c
@@ -948,12 +948,13 @@ GetBufferFromRing(BufferAccessStrategy strategy, uint32 *buf_state)
 		strategy->current = 0;
 
 	/*
-	 * If the slot hasn't been filled yet, tell the caller to allocate a new
-	 * buffer with the normal allocation strategy.  He will then fill this
-	 * slot by calling AddBufferToRing with the new buffer.
+	 * If the slot hasn't been filled yet or the buffer in the slot has been
+	 * invalidated when buffer pool was shrunk, tell the caller to allocate a new
+	 * buffer with the normal allocation strategy.  He will then fill this slot
+	 * by calling AddBufferToRing with the new buffer.
 	 */
 	bufnum = strategy->buffers[strategy->current];
-	if (bufnum == InvalidBuffer)
+	if (bufnum == InvalidBuffer || bufnum > NBuffers)
 		return NULL;
 
 	/*
-- 
2.49.0


--bwrlgp6w2ubxykjq--





^ permalink  raw  reply  [nested|flat] 107+ messages in thread

* [PATCH v5 10/10] Additional validation for buffer in the ring
@ 2025-06-11 12:45 Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
  0 siblings, 0 replies; 107+ messages in thread

From: Ashutosh Bapat @ 2025-06-11 12:45 UTC (permalink / raw)

If the buffer pool has been shrunk, the buffers in the buffer list may
not be valid anymore. Modify GetBufferFromRing to check if the buffer is
still valid before using it. This makes GetBufferFromRing() a bit more
expensive because of additional boolean condition. That may not be
expensive enough to affect query performance. The alternative to that is
more complex as explained below.

The strategy object is created in CurrentMemoryContext and is not
available in any global structure thus accessible when processing buffer
resizing barriers. We may modify GetAccessStrategy() to register
strategy in a global linked list and then arrange to deregister it once
it's no more in use. Looking at the places which use
GetAccessStrategy(), fixing all those may be some work.

Ashutosh Bapat
---
 src/backend/storage/buffer/freelist.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/src/backend/storage/buffer/freelist.c b/src/backend/storage/buffer/freelist.c
index 41641bb3ae6..74d070733a4 100644
--- a/src/backend/storage/buffer/freelist.c
+++ b/src/backend/storage/buffer/freelist.c
@@ -948,12 +948,13 @@ GetBufferFromRing(BufferAccessStrategy strategy, uint32 *buf_state)
 		strategy->current = 0;
 
 	/*
-	 * If the slot hasn't been filled yet, tell the caller to allocate a new
-	 * buffer with the normal allocation strategy.  He will then fill this
-	 * slot by calling AddBufferToRing with the new buffer.
+	 * If the slot hasn't been filled yet or the buffer in the slot has been
+	 * invalidated when buffer pool was shrunk, tell the caller to allocate a new
+	 * buffer with the normal allocation strategy.  He will then fill this slot
+	 * by calling AddBufferToRing with the new buffer.
 	 */
 	bufnum = strategy->buffers[strategy->current];
-	if (bufnum == InvalidBuffer)
+	if (bufnum == InvalidBuffer || bufnum > NBuffers)
 		return NULL;
 
 	/*
-- 
2.49.0


--bwrlgp6w2ubxykjq--





^ permalink  raw  reply  [nested|flat] 107+ messages in thread

* [PATCH v5 10/10] Additional validation for buffer in the ring
@ 2025-06-11 12:45 Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
  0 siblings, 0 replies; 107+ messages in thread

From: Ashutosh Bapat @ 2025-06-11 12:45 UTC (permalink / raw)

If the buffer pool has been shrunk, the buffers in the buffer list may
not be valid anymore. Modify GetBufferFromRing to check if the buffer is
still valid before using it. This makes GetBufferFromRing() a bit more
expensive because of additional boolean condition. That may not be
expensive enough to affect query performance. The alternative to that is
more complex as explained below.

The strategy object is created in CurrentMemoryContext and is not
available in any global structure thus accessible when processing buffer
resizing barriers. We may modify GetAccessStrategy() to register
strategy in a global linked list and then arrange to deregister it once
it's no more in use. Looking at the places which use
GetAccessStrategy(), fixing all those may be some work.

Ashutosh Bapat
---
 src/backend/storage/buffer/freelist.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/src/backend/storage/buffer/freelist.c b/src/backend/storage/buffer/freelist.c
index 41641bb3ae6..74d070733a4 100644
--- a/src/backend/storage/buffer/freelist.c
+++ b/src/backend/storage/buffer/freelist.c
@@ -948,12 +948,13 @@ GetBufferFromRing(BufferAccessStrategy strategy, uint32 *buf_state)
 		strategy->current = 0;
 
 	/*
-	 * If the slot hasn't been filled yet, tell the caller to allocate a new
-	 * buffer with the normal allocation strategy.  He will then fill this
-	 * slot by calling AddBufferToRing with the new buffer.
+	 * If the slot hasn't been filled yet or the buffer in the slot has been
+	 * invalidated when buffer pool was shrunk, tell the caller to allocate a new
+	 * buffer with the normal allocation strategy.  He will then fill this slot
+	 * by calling AddBufferToRing with the new buffer.
 	 */
 	bufnum = strategy->buffers[strategy->current];
-	if (bufnum == InvalidBuffer)
+	if (bufnum == InvalidBuffer || bufnum > NBuffers)
 		return NULL;
 
 	/*
-- 
2.49.0


--bwrlgp6w2ubxykjq--





^ permalink  raw  reply  [nested|flat] 107+ messages in thread

* [PATCH v5 10/10] Additional validation for buffer in the ring
@ 2025-06-11 12:45 Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
  0 siblings, 0 replies; 107+ messages in thread

From: Ashutosh Bapat @ 2025-06-11 12:45 UTC (permalink / raw)

If the buffer pool has been shrunk, the buffers in the buffer list may
not be valid anymore. Modify GetBufferFromRing to check if the buffer is
still valid before using it. This makes GetBufferFromRing() a bit more
expensive because of additional boolean condition. That may not be
expensive enough to affect query performance. The alternative to that is
more complex as explained below.

The strategy object is created in CurrentMemoryContext and is not
available in any global structure thus accessible when processing buffer
resizing barriers. We may modify GetAccessStrategy() to register
strategy in a global linked list and then arrange to deregister it once
it's no more in use. Looking at the places which use
GetAccessStrategy(), fixing all those may be some work.

Ashutosh Bapat
---
 src/backend/storage/buffer/freelist.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/src/backend/storage/buffer/freelist.c b/src/backend/storage/buffer/freelist.c
index 41641bb3ae6..74d070733a4 100644
--- a/src/backend/storage/buffer/freelist.c
+++ b/src/backend/storage/buffer/freelist.c
@@ -948,12 +948,13 @@ GetBufferFromRing(BufferAccessStrategy strategy, uint32 *buf_state)
 		strategy->current = 0;
 
 	/*
-	 * If the slot hasn't been filled yet, tell the caller to allocate a new
-	 * buffer with the normal allocation strategy.  He will then fill this
-	 * slot by calling AddBufferToRing with the new buffer.
+	 * If the slot hasn't been filled yet or the buffer in the slot has been
+	 * invalidated when buffer pool was shrunk, tell the caller to allocate a new
+	 * buffer with the normal allocation strategy.  He will then fill this slot
+	 * by calling AddBufferToRing with the new buffer.
 	 */
 	bufnum = strategy->buffers[strategy->current];
-	if (bufnum == InvalidBuffer)
+	if (bufnum == InvalidBuffer || bufnum > NBuffers)
 		return NULL;
 
 	/*
-- 
2.49.0


--bwrlgp6w2ubxykjq--





^ permalink  raw  reply  [nested|flat] 107+ messages in thread

* [PATCH v5 10/10] Additional validation for buffer in the ring
@ 2025-06-11 12:45 Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
  0 siblings, 0 replies; 107+ messages in thread

From: Ashutosh Bapat @ 2025-06-11 12:45 UTC (permalink / raw)

If the buffer pool has been shrunk, the buffers in the buffer list may
not be valid anymore. Modify GetBufferFromRing to check if the buffer is
still valid before using it. This makes GetBufferFromRing() a bit more
expensive because of additional boolean condition. That may not be
expensive enough to affect query performance. The alternative to that is
more complex as explained below.

The strategy object is created in CurrentMemoryContext and is not
available in any global structure thus accessible when processing buffer
resizing barriers. We may modify GetAccessStrategy() to register
strategy in a global linked list and then arrange to deregister it once
it's no more in use. Looking at the places which use
GetAccessStrategy(), fixing all those may be some work.

Ashutosh Bapat
---
 src/backend/storage/buffer/freelist.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/src/backend/storage/buffer/freelist.c b/src/backend/storage/buffer/freelist.c
index 41641bb3ae6..74d070733a4 100644
--- a/src/backend/storage/buffer/freelist.c
+++ b/src/backend/storage/buffer/freelist.c
@@ -948,12 +948,13 @@ GetBufferFromRing(BufferAccessStrategy strategy, uint32 *buf_state)
 		strategy->current = 0;
 
 	/*
-	 * If the slot hasn't been filled yet, tell the caller to allocate a new
-	 * buffer with the normal allocation strategy.  He will then fill this
-	 * slot by calling AddBufferToRing with the new buffer.
+	 * If the slot hasn't been filled yet or the buffer in the slot has been
+	 * invalidated when buffer pool was shrunk, tell the caller to allocate a new
+	 * buffer with the normal allocation strategy.  He will then fill this slot
+	 * by calling AddBufferToRing with the new buffer.
 	 */
 	bufnum = strategy->buffers[strategy->current];
-	if (bufnum == InvalidBuffer)
+	if (bufnum == InvalidBuffer || bufnum > NBuffers)
 		return NULL;
 
 	/*
-- 
2.49.0


--bwrlgp6w2ubxykjq--





^ permalink  raw  reply  [nested|flat] 107+ messages in thread

* [PATCH v5 10/10] Additional validation for buffer in the ring
@ 2025-06-11 12:45 Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
  0 siblings, 0 replies; 107+ messages in thread

From: Ashutosh Bapat @ 2025-06-11 12:45 UTC (permalink / raw)

If the buffer pool has been shrunk, the buffers in the buffer list may
not be valid anymore. Modify GetBufferFromRing to check if the buffer is
still valid before using it. This makes GetBufferFromRing() a bit more
expensive because of additional boolean condition. That may not be
expensive enough to affect query performance. The alternative to that is
more complex as explained below.

The strategy object is created in CurrentMemoryContext and is not
available in any global structure thus accessible when processing buffer
resizing barriers. We may modify GetAccessStrategy() to register
strategy in a global linked list and then arrange to deregister it once
it's no more in use. Looking at the places which use
GetAccessStrategy(), fixing all those may be some work.

Ashutosh Bapat
---
 src/backend/storage/buffer/freelist.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/src/backend/storage/buffer/freelist.c b/src/backend/storage/buffer/freelist.c
index 41641bb3ae6..74d070733a4 100644
--- a/src/backend/storage/buffer/freelist.c
+++ b/src/backend/storage/buffer/freelist.c
@@ -948,12 +948,13 @@ GetBufferFromRing(BufferAccessStrategy strategy, uint32 *buf_state)
 		strategy->current = 0;
 
 	/*
-	 * If the slot hasn't been filled yet, tell the caller to allocate a new
-	 * buffer with the normal allocation strategy.  He will then fill this
-	 * slot by calling AddBufferToRing with the new buffer.
+	 * If the slot hasn't been filled yet or the buffer in the slot has been
+	 * invalidated when buffer pool was shrunk, tell the caller to allocate a new
+	 * buffer with the normal allocation strategy.  He will then fill this slot
+	 * by calling AddBufferToRing with the new buffer.
 	 */
 	bufnum = strategy->buffers[strategy->current];
-	if (bufnum == InvalidBuffer)
+	if (bufnum == InvalidBuffer || bufnum > NBuffers)
 		return NULL;
 
 	/*
-- 
2.49.0


--bwrlgp6w2ubxykjq--





^ permalink  raw  reply  [nested|flat] 107+ messages in thread

* [PATCH v5 10/10] Additional validation for buffer in the ring
@ 2025-06-11 12:45 Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
  0 siblings, 0 replies; 107+ messages in thread

From: Ashutosh Bapat @ 2025-06-11 12:45 UTC (permalink / raw)

If the buffer pool has been shrunk, the buffers in the buffer list may
not be valid anymore. Modify GetBufferFromRing to check if the buffer is
still valid before using it. This makes GetBufferFromRing() a bit more
expensive because of additional boolean condition. That may not be
expensive enough to affect query performance. The alternative to that is
more complex as explained below.

The strategy object is created in CurrentMemoryContext and is not
available in any global structure thus accessible when processing buffer
resizing barriers. We may modify GetAccessStrategy() to register
strategy in a global linked list and then arrange to deregister it once
it's no more in use. Looking at the places which use
GetAccessStrategy(), fixing all those may be some work.

Ashutosh Bapat
---
 src/backend/storage/buffer/freelist.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/src/backend/storage/buffer/freelist.c b/src/backend/storage/buffer/freelist.c
index 41641bb3ae6..74d070733a4 100644
--- a/src/backend/storage/buffer/freelist.c
+++ b/src/backend/storage/buffer/freelist.c
@@ -948,12 +948,13 @@ GetBufferFromRing(BufferAccessStrategy strategy, uint32 *buf_state)
 		strategy->current = 0;
 
 	/*
-	 * If the slot hasn't been filled yet, tell the caller to allocate a new
-	 * buffer with the normal allocation strategy.  He will then fill this
-	 * slot by calling AddBufferToRing with the new buffer.
+	 * If the slot hasn't been filled yet or the buffer in the slot has been
+	 * invalidated when buffer pool was shrunk, tell the caller to allocate a new
+	 * buffer with the normal allocation strategy.  He will then fill this slot
+	 * by calling AddBufferToRing with the new buffer.
 	 */
 	bufnum = strategy->buffers[strategy->current];
-	if (bufnum == InvalidBuffer)
+	if (bufnum == InvalidBuffer || bufnum > NBuffers)
 		return NULL;
 
 	/*
-- 
2.49.0


--bwrlgp6w2ubxykjq--





^ permalink  raw  reply  [nested|flat] 107+ messages in thread

* [PATCH v5 10/10] Additional validation for buffer in the ring
@ 2025-06-11 12:45 Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
  0 siblings, 0 replies; 107+ messages in thread

From: Ashutosh Bapat @ 2025-06-11 12:45 UTC (permalink / raw)

If the buffer pool has been shrunk, the buffers in the buffer list may
not be valid anymore. Modify GetBufferFromRing to check if the buffer is
still valid before using it. This makes GetBufferFromRing() a bit more
expensive because of additional boolean condition. That may not be
expensive enough to affect query performance. The alternative to that is
more complex as explained below.

The strategy object is created in CurrentMemoryContext and is not
available in any global structure thus accessible when processing buffer
resizing barriers. We may modify GetAccessStrategy() to register
strategy in a global linked list and then arrange to deregister it once
it's no more in use. Looking at the places which use
GetAccessStrategy(), fixing all those may be some work.

Ashutosh Bapat
---
 src/backend/storage/buffer/freelist.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/src/backend/storage/buffer/freelist.c b/src/backend/storage/buffer/freelist.c
index 41641bb3ae6..74d070733a4 100644
--- a/src/backend/storage/buffer/freelist.c
+++ b/src/backend/storage/buffer/freelist.c
@@ -948,12 +948,13 @@ GetBufferFromRing(BufferAccessStrategy strategy, uint32 *buf_state)
 		strategy->current = 0;
 
 	/*
-	 * If the slot hasn't been filled yet, tell the caller to allocate a new
-	 * buffer with the normal allocation strategy.  He will then fill this
-	 * slot by calling AddBufferToRing with the new buffer.
+	 * If the slot hasn't been filled yet or the buffer in the slot has been
+	 * invalidated when buffer pool was shrunk, tell the caller to allocate a new
+	 * buffer with the normal allocation strategy.  He will then fill this slot
+	 * by calling AddBufferToRing with the new buffer.
 	 */
 	bufnum = strategy->buffers[strategy->current];
-	if (bufnum == InvalidBuffer)
+	if (bufnum == InvalidBuffer || bufnum > NBuffers)
 		return NULL;
 
 	/*
-- 
2.49.0


--bwrlgp6w2ubxykjq--





^ permalink  raw  reply  [nested|flat] 107+ messages in thread

* [PATCH v5 10/10] Additional validation for buffer in the ring
@ 2025-06-11 12:45 Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
  0 siblings, 0 replies; 107+ messages in thread

From: Ashutosh Bapat @ 2025-06-11 12:45 UTC (permalink / raw)

If the buffer pool has been shrunk, the buffers in the buffer list may
not be valid anymore. Modify GetBufferFromRing to check if the buffer is
still valid before using it. This makes GetBufferFromRing() a bit more
expensive because of additional boolean condition. That may not be
expensive enough to affect query performance. The alternative to that is
more complex as explained below.

The strategy object is created in CurrentMemoryContext and is not
available in any global structure thus accessible when processing buffer
resizing barriers. We may modify GetAccessStrategy() to register
strategy in a global linked list and then arrange to deregister it once
it's no more in use. Looking at the places which use
GetAccessStrategy(), fixing all those may be some work.

Ashutosh Bapat
---
 src/backend/storage/buffer/freelist.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/src/backend/storage/buffer/freelist.c b/src/backend/storage/buffer/freelist.c
index 41641bb3ae6..74d070733a4 100644
--- a/src/backend/storage/buffer/freelist.c
+++ b/src/backend/storage/buffer/freelist.c
@@ -948,12 +948,13 @@ GetBufferFromRing(BufferAccessStrategy strategy, uint32 *buf_state)
 		strategy->current = 0;
 
 	/*
-	 * If the slot hasn't been filled yet, tell the caller to allocate a new
-	 * buffer with the normal allocation strategy.  He will then fill this
-	 * slot by calling AddBufferToRing with the new buffer.
+	 * If the slot hasn't been filled yet or the buffer in the slot has been
+	 * invalidated when buffer pool was shrunk, tell the caller to allocate a new
+	 * buffer with the normal allocation strategy.  He will then fill this slot
+	 * by calling AddBufferToRing with the new buffer.
 	 */
 	bufnum = strategy->buffers[strategy->current];
-	if (bufnum == InvalidBuffer)
+	if (bufnum == InvalidBuffer || bufnum > NBuffers)
 		return NULL;
 
 	/*
-- 
2.49.0


--bwrlgp6w2ubxykjq--





^ permalink  raw  reply  [nested|flat] 107+ messages in thread

* [PATCH v5 10/10] Additional validation for buffer in the ring
@ 2025-06-11 12:45 Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
  0 siblings, 0 replies; 107+ messages in thread

From: Ashutosh Bapat @ 2025-06-11 12:45 UTC (permalink / raw)

If the buffer pool has been shrunk, the buffers in the buffer list may
not be valid anymore. Modify GetBufferFromRing to check if the buffer is
still valid before using it. This makes GetBufferFromRing() a bit more
expensive because of additional boolean condition. That may not be
expensive enough to affect query performance. The alternative to that is
more complex as explained below.

The strategy object is created in CurrentMemoryContext and is not
available in any global structure thus accessible when processing buffer
resizing barriers. We may modify GetAccessStrategy() to register
strategy in a global linked list and then arrange to deregister it once
it's no more in use. Looking at the places which use
GetAccessStrategy(), fixing all those may be some work.

Ashutosh Bapat
---
 src/backend/storage/buffer/freelist.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/src/backend/storage/buffer/freelist.c b/src/backend/storage/buffer/freelist.c
index 41641bb3ae6..74d070733a4 100644
--- a/src/backend/storage/buffer/freelist.c
+++ b/src/backend/storage/buffer/freelist.c
@@ -948,12 +948,13 @@ GetBufferFromRing(BufferAccessStrategy strategy, uint32 *buf_state)
 		strategy->current = 0;
 
 	/*
-	 * If the slot hasn't been filled yet, tell the caller to allocate a new
-	 * buffer with the normal allocation strategy.  He will then fill this
-	 * slot by calling AddBufferToRing with the new buffer.
+	 * If the slot hasn't been filled yet or the buffer in the slot has been
+	 * invalidated when buffer pool was shrunk, tell the caller to allocate a new
+	 * buffer with the normal allocation strategy.  He will then fill this slot
+	 * by calling AddBufferToRing with the new buffer.
 	 */
 	bufnum = strategy->buffers[strategy->current];
-	if (bufnum == InvalidBuffer)
+	if (bufnum == InvalidBuffer || bufnum > NBuffers)
 		return NULL;
 
 	/*
-- 
2.49.0


--bwrlgp6w2ubxykjq--





^ permalink  raw  reply  [nested|flat] 107+ messages in thread

* [PATCH v5 10/10] Additional validation for buffer in the ring
@ 2025-06-11 12:45 Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
  0 siblings, 0 replies; 107+ messages in thread

From: Ashutosh Bapat @ 2025-06-11 12:45 UTC (permalink / raw)

If the buffer pool has been shrunk, the buffers in the buffer list may
not be valid anymore. Modify GetBufferFromRing to check if the buffer is
still valid before using it. This makes GetBufferFromRing() a bit more
expensive because of additional boolean condition. That may not be
expensive enough to affect query performance. The alternative to that is
more complex as explained below.

The strategy object is created in CurrentMemoryContext and is not
available in any global structure thus accessible when processing buffer
resizing barriers. We may modify GetAccessStrategy() to register
strategy in a global linked list and then arrange to deregister it once
it's no more in use. Looking at the places which use
GetAccessStrategy(), fixing all those may be some work.

Ashutosh Bapat
---
 src/backend/storage/buffer/freelist.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/src/backend/storage/buffer/freelist.c b/src/backend/storage/buffer/freelist.c
index 41641bb3ae6..74d070733a4 100644
--- a/src/backend/storage/buffer/freelist.c
+++ b/src/backend/storage/buffer/freelist.c
@@ -948,12 +948,13 @@ GetBufferFromRing(BufferAccessStrategy strategy, uint32 *buf_state)
 		strategy->current = 0;
 
 	/*
-	 * If the slot hasn't been filled yet, tell the caller to allocate a new
-	 * buffer with the normal allocation strategy.  He will then fill this
-	 * slot by calling AddBufferToRing with the new buffer.
+	 * If the slot hasn't been filled yet or the buffer in the slot has been
+	 * invalidated when buffer pool was shrunk, tell the caller to allocate a new
+	 * buffer with the normal allocation strategy.  He will then fill this slot
+	 * by calling AddBufferToRing with the new buffer.
 	 */
 	bufnum = strategy->buffers[strategy->current];
-	if (bufnum == InvalidBuffer)
+	if (bufnum == InvalidBuffer || bufnum > NBuffers)
 		return NULL;
 
 	/*
-- 
2.49.0


--bwrlgp6w2ubxykjq--





^ permalink  raw  reply  [nested|flat] 107+ messages in thread

* [PATCH v5 10/10] Additional validation for buffer in the ring
@ 2025-06-11 12:45 Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
  0 siblings, 0 replies; 107+ messages in thread

From: Ashutosh Bapat @ 2025-06-11 12:45 UTC (permalink / raw)

If the buffer pool has been shrunk, the buffers in the buffer list may
not be valid anymore. Modify GetBufferFromRing to check if the buffer is
still valid before using it. This makes GetBufferFromRing() a bit more
expensive because of additional boolean condition. That may not be
expensive enough to affect query performance. The alternative to that is
more complex as explained below.

The strategy object is created in CurrentMemoryContext and is not
available in any global structure thus accessible when processing buffer
resizing barriers. We may modify GetAccessStrategy() to register
strategy in a global linked list and then arrange to deregister it once
it's no more in use. Looking at the places which use
GetAccessStrategy(), fixing all those may be some work.

Ashutosh Bapat
---
 src/backend/storage/buffer/freelist.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/src/backend/storage/buffer/freelist.c b/src/backend/storage/buffer/freelist.c
index 41641bb3ae6..74d070733a4 100644
--- a/src/backend/storage/buffer/freelist.c
+++ b/src/backend/storage/buffer/freelist.c
@@ -948,12 +948,13 @@ GetBufferFromRing(BufferAccessStrategy strategy, uint32 *buf_state)
 		strategy->current = 0;
 
 	/*
-	 * If the slot hasn't been filled yet, tell the caller to allocate a new
-	 * buffer with the normal allocation strategy.  He will then fill this
-	 * slot by calling AddBufferToRing with the new buffer.
+	 * If the slot hasn't been filled yet or the buffer in the slot has been
+	 * invalidated when buffer pool was shrunk, tell the caller to allocate a new
+	 * buffer with the normal allocation strategy.  He will then fill this slot
+	 * by calling AddBufferToRing with the new buffer.
 	 */
 	bufnum = strategy->buffers[strategy->current];
-	if (bufnum == InvalidBuffer)
+	if (bufnum == InvalidBuffer || bufnum > NBuffers)
 		return NULL;
 
 	/*
-- 
2.49.0


--bwrlgp6w2ubxykjq--





^ permalink  raw  reply  [nested|flat] 107+ messages in thread

* [PATCH v5 10/10] Additional validation for buffer in the ring
@ 2025-06-11 12:45 Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
  0 siblings, 0 replies; 107+ messages in thread

From: Ashutosh Bapat @ 2025-06-11 12:45 UTC (permalink / raw)

If the buffer pool has been shrunk, the buffers in the buffer list may
not be valid anymore. Modify GetBufferFromRing to check if the buffer is
still valid before using it. This makes GetBufferFromRing() a bit more
expensive because of additional boolean condition. That may not be
expensive enough to affect query performance. The alternative to that is
more complex as explained below.

The strategy object is created in CurrentMemoryContext and is not
available in any global structure thus accessible when processing buffer
resizing barriers. We may modify GetAccessStrategy() to register
strategy in a global linked list and then arrange to deregister it once
it's no more in use. Looking at the places which use
GetAccessStrategy(), fixing all those may be some work.

Ashutosh Bapat
---
 src/backend/storage/buffer/freelist.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/src/backend/storage/buffer/freelist.c b/src/backend/storage/buffer/freelist.c
index 41641bb3ae6..74d070733a4 100644
--- a/src/backend/storage/buffer/freelist.c
+++ b/src/backend/storage/buffer/freelist.c
@@ -948,12 +948,13 @@ GetBufferFromRing(BufferAccessStrategy strategy, uint32 *buf_state)
 		strategy->current = 0;
 
 	/*
-	 * If the slot hasn't been filled yet, tell the caller to allocate a new
-	 * buffer with the normal allocation strategy.  He will then fill this
-	 * slot by calling AddBufferToRing with the new buffer.
+	 * If the slot hasn't been filled yet or the buffer in the slot has been
+	 * invalidated when buffer pool was shrunk, tell the caller to allocate a new
+	 * buffer with the normal allocation strategy.  He will then fill this slot
+	 * by calling AddBufferToRing with the new buffer.
 	 */
 	bufnum = strategy->buffers[strategy->current];
-	if (bufnum == InvalidBuffer)
+	if (bufnum == InvalidBuffer || bufnum > NBuffers)
 		return NULL;
 
 	/*
-- 
2.49.0


--bwrlgp6w2ubxykjq--





^ permalink  raw  reply  [nested|flat] 107+ messages in thread

* [PATCH v5 10/10] Additional validation for buffer in the ring
@ 2025-06-11 12:45 Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
  0 siblings, 0 replies; 107+ messages in thread

From: Ashutosh Bapat @ 2025-06-11 12:45 UTC (permalink / raw)

If the buffer pool has been shrunk, the buffers in the buffer list may
not be valid anymore. Modify GetBufferFromRing to check if the buffer is
still valid before using it. This makes GetBufferFromRing() a bit more
expensive because of additional boolean condition. That may not be
expensive enough to affect query performance. The alternative to that is
more complex as explained below.

The strategy object is created in CurrentMemoryContext and is not
available in any global structure thus accessible when processing buffer
resizing barriers. We may modify GetAccessStrategy() to register
strategy in a global linked list and then arrange to deregister it once
it's no more in use. Looking at the places which use
GetAccessStrategy(), fixing all those may be some work.

Ashutosh Bapat
---
 src/backend/storage/buffer/freelist.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/src/backend/storage/buffer/freelist.c b/src/backend/storage/buffer/freelist.c
index 41641bb3ae6..74d070733a4 100644
--- a/src/backend/storage/buffer/freelist.c
+++ b/src/backend/storage/buffer/freelist.c
@@ -948,12 +948,13 @@ GetBufferFromRing(BufferAccessStrategy strategy, uint32 *buf_state)
 		strategy->current = 0;
 
 	/*
-	 * If the slot hasn't been filled yet, tell the caller to allocate a new
-	 * buffer with the normal allocation strategy.  He will then fill this
-	 * slot by calling AddBufferToRing with the new buffer.
+	 * If the slot hasn't been filled yet or the buffer in the slot has been
+	 * invalidated when buffer pool was shrunk, tell the caller to allocate a new
+	 * buffer with the normal allocation strategy.  He will then fill this slot
+	 * by calling AddBufferToRing with the new buffer.
 	 */
 	bufnum = strategy->buffers[strategy->current];
-	if (bufnum == InvalidBuffer)
+	if (bufnum == InvalidBuffer || bufnum > NBuffers)
 		return NULL;
 
 	/*
-- 
2.49.0


--bwrlgp6w2ubxykjq--





^ permalink  raw  reply  [nested|flat] 107+ messages in thread

* [PATCH v5 10/10] Additional validation for buffer in the ring
@ 2025-06-11 12:45 Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
  0 siblings, 0 replies; 107+ messages in thread

From: Ashutosh Bapat @ 2025-06-11 12:45 UTC (permalink / raw)

If the buffer pool has been shrunk, the buffers in the buffer list may
not be valid anymore. Modify GetBufferFromRing to check if the buffer is
still valid before using it. This makes GetBufferFromRing() a bit more
expensive because of additional boolean condition. That may not be
expensive enough to affect query performance. The alternative to that is
more complex as explained below.

The strategy object is created in CurrentMemoryContext and is not
available in any global structure thus accessible when processing buffer
resizing barriers. We may modify GetAccessStrategy() to register
strategy in a global linked list and then arrange to deregister it once
it's no more in use. Looking at the places which use
GetAccessStrategy(), fixing all those may be some work.

Ashutosh Bapat
---
 src/backend/storage/buffer/freelist.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/src/backend/storage/buffer/freelist.c b/src/backend/storage/buffer/freelist.c
index 41641bb3ae6..74d070733a4 100644
--- a/src/backend/storage/buffer/freelist.c
+++ b/src/backend/storage/buffer/freelist.c
@@ -948,12 +948,13 @@ GetBufferFromRing(BufferAccessStrategy strategy, uint32 *buf_state)
 		strategy->current = 0;
 
 	/*
-	 * If the slot hasn't been filled yet, tell the caller to allocate a new
-	 * buffer with the normal allocation strategy.  He will then fill this
-	 * slot by calling AddBufferToRing with the new buffer.
+	 * If the slot hasn't been filled yet or the buffer in the slot has been
+	 * invalidated when buffer pool was shrunk, tell the caller to allocate a new
+	 * buffer with the normal allocation strategy.  He will then fill this slot
+	 * by calling AddBufferToRing with the new buffer.
 	 */
 	bufnum = strategy->buffers[strategy->current];
-	if (bufnum == InvalidBuffer)
+	if (bufnum == InvalidBuffer || bufnum > NBuffers)
 		return NULL;
 
 	/*
-- 
2.49.0


--bwrlgp6w2ubxykjq--





^ permalink  raw  reply  [nested|flat] 107+ messages in thread

* [PATCH v5 10/10] Additional validation for buffer in the ring
@ 2025-06-11 12:45 Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
  0 siblings, 0 replies; 107+ messages in thread

From: Ashutosh Bapat @ 2025-06-11 12:45 UTC (permalink / raw)

If the buffer pool has been shrunk, the buffers in the buffer list may
not be valid anymore. Modify GetBufferFromRing to check if the buffer is
still valid before using it. This makes GetBufferFromRing() a bit more
expensive because of additional boolean condition. That may not be
expensive enough to affect query performance. The alternative to that is
more complex as explained below.

The strategy object is created in CurrentMemoryContext and is not
available in any global structure thus accessible when processing buffer
resizing barriers. We may modify GetAccessStrategy() to register
strategy in a global linked list and then arrange to deregister it once
it's no more in use. Looking at the places which use
GetAccessStrategy(), fixing all those may be some work.

Ashutosh Bapat
---
 src/backend/storage/buffer/freelist.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/src/backend/storage/buffer/freelist.c b/src/backend/storage/buffer/freelist.c
index 41641bb3ae6..74d070733a4 100644
--- a/src/backend/storage/buffer/freelist.c
+++ b/src/backend/storage/buffer/freelist.c
@@ -948,12 +948,13 @@ GetBufferFromRing(BufferAccessStrategy strategy, uint32 *buf_state)
 		strategy->current = 0;
 
 	/*
-	 * If the slot hasn't been filled yet, tell the caller to allocate a new
-	 * buffer with the normal allocation strategy.  He will then fill this
-	 * slot by calling AddBufferToRing with the new buffer.
+	 * If the slot hasn't been filled yet or the buffer in the slot has been
+	 * invalidated when buffer pool was shrunk, tell the caller to allocate a new
+	 * buffer with the normal allocation strategy.  He will then fill this slot
+	 * by calling AddBufferToRing with the new buffer.
 	 */
 	bufnum = strategy->buffers[strategy->current];
-	if (bufnum == InvalidBuffer)
+	if (bufnum == InvalidBuffer || bufnum > NBuffers)
 		return NULL;
 
 	/*
-- 
2.49.0


--bwrlgp6w2ubxykjq--





^ permalink  raw  reply  [nested|flat] 107+ messages in thread

* [PATCH v5 10/10] Additional validation for buffer in the ring
@ 2025-06-11 12:45 Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
  0 siblings, 0 replies; 107+ messages in thread

From: Ashutosh Bapat @ 2025-06-11 12:45 UTC (permalink / raw)

If the buffer pool has been shrunk, the buffers in the buffer list may
not be valid anymore. Modify GetBufferFromRing to check if the buffer is
still valid before using it. This makes GetBufferFromRing() a bit more
expensive because of additional boolean condition. That may not be
expensive enough to affect query performance. The alternative to that is
more complex as explained below.

The strategy object is created in CurrentMemoryContext and is not
available in any global structure thus accessible when processing buffer
resizing barriers. We may modify GetAccessStrategy() to register
strategy in a global linked list and then arrange to deregister it once
it's no more in use. Looking at the places which use
GetAccessStrategy(), fixing all those may be some work.

Ashutosh Bapat
---
 src/backend/storage/buffer/freelist.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/src/backend/storage/buffer/freelist.c b/src/backend/storage/buffer/freelist.c
index 41641bb3ae6..74d070733a4 100644
--- a/src/backend/storage/buffer/freelist.c
+++ b/src/backend/storage/buffer/freelist.c
@@ -948,12 +948,13 @@ GetBufferFromRing(BufferAccessStrategy strategy, uint32 *buf_state)
 		strategy->current = 0;
 
 	/*
-	 * If the slot hasn't been filled yet, tell the caller to allocate a new
-	 * buffer with the normal allocation strategy.  He will then fill this
-	 * slot by calling AddBufferToRing with the new buffer.
+	 * If the slot hasn't been filled yet or the buffer in the slot has been
+	 * invalidated when buffer pool was shrunk, tell the caller to allocate a new
+	 * buffer with the normal allocation strategy.  He will then fill this slot
+	 * by calling AddBufferToRing with the new buffer.
 	 */
 	bufnum = strategy->buffers[strategy->current];
-	if (bufnum == InvalidBuffer)
+	if (bufnum == InvalidBuffer || bufnum > NBuffers)
 		return NULL;
 
 	/*
-- 
2.49.0


--bwrlgp6w2ubxykjq--





^ permalink  raw  reply  [nested|flat] 107+ messages in thread

* [PATCH v5 10/10] Additional validation for buffer in the ring
@ 2025-06-11 12:45 Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
  0 siblings, 0 replies; 107+ messages in thread

From: Ashutosh Bapat @ 2025-06-11 12:45 UTC (permalink / raw)

If the buffer pool has been shrunk, the buffers in the buffer list may
not be valid anymore. Modify GetBufferFromRing to check if the buffer is
still valid before using it. This makes GetBufferFromRing() a bit more
expensive because of additional boolean condition. That may not be
expensive enough to affect query performance. The alternative to that is
more complex as explained below.

The strategy object is created in CurrentMemoryContext and is not
available in any global structure thus accessible when processing buffer
resizing barriers. We may modify GetAccessStrategy() to register
strategy in a global linked list and then arrange to deregister it once
it's no more in use. Looking at the places which use
GetAccessStrategy(), fixing all those may be some work.

Ashutosh Bapat
---
 src/backend/storage/buffer/freelist.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/src/backend/storage/buffer/freelist.c b/src/backend/storage/buffer/freelist.c
index 41641bb3ae6..74d070733a4 100644
--- a/src/backend/storage/buffer/freelist.c
+++ b/src/backend/storage/buffer/freelist.c
@@ -948,12 +948,13 @@ GetBufferFromRing(BufferAccessStrategy strategy, uint32 *buf_state)
 		strategy->current = 0;
 
 	/*
-	 * If the slot hasn't been filled yet, tell the caller to allocate a new
-	 * buffer with the normal allocation strategy.  He will then fill this
-	 * slot by calling AddBufferToRing with the new buffer.
+	 * If the slot hasn't been filled yet or the buffer in the slot has been
+	 * invalidated when buffer pool was shrunk, tell the caller to allocate a new
+	 * buffer with the normal allocation strategy.  He will then fill this slot
+	 * by calling AddBufferToRing with the new buffer.
 	 */
 	bufnum = strategy->buffers[strategy->current];
-	if (bufnum == InvalidBuffer)
+	if (bufnum == InvalidBuffer || bufnum > NBuffers)
 		return NULL;
 
 	/*
-- 
2.49.0


--bwrlgp6w2ubxykjq--





^ permalink  raw  reply  [nested|flat] 107+ messages in thread

* [PATCH v5 10/10] Additional validation for buffer in the ring
@ 2025-06-11 12:45 Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
  0 siblings, 0 replies; 107+ messages in thread

From: Ashutosh Bapat @ 2025-06-11 12:45 UTC (permalink / raw)

If the buffer pool has been shrunk, the buffers in the buffer list may
not be valid anymore. Modify GetBufferFromRing to check if the buffer is
still valid before using it. This makes GetBufferFromRing() a bit more
expensive because of additional boolean condition. That may not be
expensive enough to affect query performance. The alternative to that is
more complex as explained below.

The strategy object is created in CurrentMemoryContext and is not
available in any global structure thus accessible when processing buffer
resizing barriers. We may modify GetAccessStrategy() to register
strategy in a global linked list and then arrange to deregister it once
it's no more in use. Looking at the places which use
GetAccessStrategy(), fixing all those may be some work.

Ashutosh Bapat
---
 src/backend/storage/buffer/freelist.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/src/backend/storage/buffer/freelist.c b/src/backend/storage/buffer/freelist.c
index 41641bb3ae6..74d070733a4 100644
--- a/src/backend/storage/buffer/freelist.c
+++ b/src/backend/storage/buffer/freelist.c
@@ -948,12 +948,13 @@ GetBufferFromRing(BufferAccessStrategy strategy, uint32 *buf_state)
 		strategy->current = 0;
 
 	/*
-	 * If the slot hasn't been filled yet, tell the caller to allocate a new
-	 * buffer with the normal allocation strategy.  He will then fill this
-	 * slot by calling AddBufferToRing with the new buffer.
+	 * If the slot hasn't been filled yet or the buffer in the slot has been
+	 * invalidated when buffer pool was shrunk, tell the caller to allocate a new
+	 * buffer with the normal allocation strategy.  He will then fill this slot
+	 * by calling AddBufferToRing with the new buffer.
 	 */
 	bufnum = strategy->buffers[strategy->current];
-	if (bufnum == InvalidBuffer)
+	if (bufnum == InvalidBuffer || bufnum > NBuffers)
 		return NULL;
 
 	/*
-- 
2.49.0


--bwrlgp6w2ubxykjq--





^ permalink  raw  reply  [nested|flat] 107+ messages in thread

* [PATCH v5 10/10] Additional validation for buffer in the ring
@ 2025-06-11 12:45 Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
  0 siblings, 0 replies; 107+ messages in thread

From: Ashutosh Bapat @ 2025-06-11 12:45 UTC (permalink / raw)

If the buffer pool has been shrunk, the buffers in the buffer list may
not be valid anymore. Modify GetBufferFromRing to check if the buffer is
still valid before using it. This makes GetBufferFromRing() a bit more
expensive because of additional boolean condition. That may not be
expensive enough to affect query performance. The alternative to that is
more complex as explained below.

The strategy object is created in CurrentMemoryContext and is not
available in any global structure thus accessible when processing buffer
resizing barriers. We may modify GetAccessStrategy() to register
strategy in a global linked list and then arrange to deregister it once
it's no more in use. Looking at the places which use
GetAccessStrategy(), fixing all those may be some work.

Ashutosh Bapat
---
 src/backend/storage/buffer/freelist.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/src/backend/storage/buffer/freelist.c b/src/backend/storage/buffer/freelist.c
index 41641bb3ae6..74d070733a4 100644
--- a/src/backend/storage/buffer/freelist.c
+++ b/src/backend/storage/buffer/freelist.c
@@ -948,12 +948,13 @@ GetBufferFromRing(BufferAccessStrategy strategy, uint32 *buf_state)
 		strategy->current = 0;
 
 	/*
-	 * If the slot hasn't been filled yet, tell the caller to allocate a new
-	 * buffer with the normal allocation strategy.  He will then fill this
-	 * slot by calling AddBufferToRing with the new buffer.
+	 * If the slot hasn't been filled yet or the buffer in the slot has been
+	 * invalidated when buffer pool was shrunk, tell the caller to allocate a new
+	 * buffer with the normal allocation strategy.  He will then fill this slot
+	 * by calling AddBufferToRing with the new buffer.
 	 */
 	bufnum = strategy->buffers[strategy->current];
-	if (bufnum == InvalidBuffer)
+	if (bufnum == InvalidBuffer || bufnum > NBuffers)
 		return NULL;
 
 	/*
-- 
2.49.0


--bwrlgp6w2ubxykjq--





^ permalink  raw  reply  [nested|flat] 107+ messages in thread

* [PATCH v5 10/10] Additional validation for buffer in the ring
@ 2025-06-11 12:45 Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
  0 siblings, 0 replies; 107+ messages in thread

From: Ashutosh Bapat @ 2025-06-11 12:45 UTC (permalink / raw)

If the buffer pool has been shrunk, the buffers in the buffer list may
not be valid anymore. Modify GetBufferFromRing to check if the buffer is
still valid before using it. This makes GetBufferFromRing() a bit more
expensive because of additional boolean condition. That may not be
expensive enough to affect query performance. The alternative to that is
more complex as explained below.

The strategy object is created in CurrentMemoryContext and is not
available in any global structure thus accessible when processing buffer
resizing barriers. We may modify GetAccessStrategy() to register
strategy in a global linked list and then arrange to deregister it once
it's no more in use. Looking at the places which use
GetAccessStrategy(), fixing all those may be some work.

Ashutosh Bapat
---
 src/backend/storage/buffer/freelist.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/src/backend/storage/buffer/freelist.c b/src/backend/storage/buffer/freelist.c
index 41641bb3ae6..74d070733a4 100644
--- a/src/backend/storage/buffer/freelist.c
+++ b/src/backend/storage/buffer/freelist.c
@@ -948,12 +948,13 @@ GetBufferFromRing(BufferAccessStrategy strategy, uint32 *buf_state)
 		strategy->current = 0;
 
 	/*
-	 * If the slot hasn't been filled yet, tell the caller to allocate a new
-	 * buffer with the normal allocation strategy.  He will then fill this
-	 * slot by calling AddBufferToRing with the new buffer.
+	 * If the slot hasn't been filled yet or the buffer in the slot has been
+	 * invalidated when buffer pool was shrunk, tell the caller to allocate a new
+	 * buffer with the normal allocation strategy.  He will then fill this slot
+	 * by calling AddBufferToRing with the new buffer.
 	 */
 	bufnum = strategy->buffers[strategy->current];
-	if (bufnum == InvalidBuffer)
+	if (bufnum == InvalidBuffer || bufnum > NBuffers)
 		return NULL;
 
 	/*
-- 
2.49.0


--bwrlgp6w2ubxykjq--





^ permalink  raw  reply  [nested|flat] 107+ messages in thread

* [PATCH v5 10/10] Additional validation for buffer in the ring
@ 2025-06-11 12:45 Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
  0 siblings, 0 replies; 107+ messages in thread

From: Ashutosh Bapat @ 2025-06-11 12:45 UTC (permalink / raw)

If the buffer pool has been shrunk, the buffers in the buffer list may
not be valid anymore. Modify GetBufferFromRing to check if the buffer is
still valid before using it. This makes GetBufferFromRing() a bit more
expensive because of additional boolean condition. That may not be
expensive enough to affect query performance. The alternative to that is
more complex as explained below.

The strategy object is created in CurrentMemoryContext and is not
available in any global structure thus accessible when processing buffer
resizing barriers. We may modify GetAccessStrategy() to register
strategy in a global linked list and then arrange to deregister it once
it's no more in use. Looking at the places which use
GetAccessStrategy(), fixing all those may be some work.

Ashutosh Bapat
---
 src/backend/storage/buffer/freelist.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/src/backend/storage/buffer/freelist.c b/src/backend/storage/buffer/freelist.c
index 41641bb3ae6..74d070733a4 100644
--- a/src/backend/storage/buffer/freelist.c
+++ b/src/backend/storage/buffer/freelist.c
@@ -948,12 +948,13 @@ GetBufferFromRing(BufferAccessStrategy strategy, uint32 *buf_state)
 		strategy->current = 0;
 
 	/*
-	 * If the slot hasn't been filled yet, tell the caller to allocate a new
-	 * buffer with the normal allocation strategy.  He will then fill this
-	 * slot by calling AddBufferToRing with the new buffer.
+	 * If the slot hasn't been filled yet or the buffer in the slot has been
+	 * invalidated when buffer pool was shrunk, tell the caller to allocate a new
+	 * buffer with the normal allocation strategy.  He will then fill this slot
+	 * by calling AddBufferToRing with the new buffer.
 	 */
 	bufnum = strategy->buffers[strategy->current];
-	if (bufnum == InvalidBuffer)
+	if (bufnum == InvalidBuffer || bufnum > NBuffers)
 		return NULL;
 
 	/*
-- 
2.49.0


--bwrlgp6w2ubxykjq--





^ permalink  raw  reply  [nested|flat] 107+ messages in thread

* [PATCH v5 10/10] Additional validation for buffer in the ring
@ 2025-06-11 12:45 Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
  0 siblings, 0 replies; 107+ messages in thread

From: Ashutosh Bapat @ 2025-06-11 12:45 UTC (permalink / raw)

If the buffer pool has been shrunk, the buffers in the buffer list may
not be valid anymore. Modify GetBufferFromRing to check if the buffer is
still valid before using it. This makes GetBufferFromRing() a bit more
expensive because of additional boolean condition. That may not be
expensive enough to affect query performance. The alternative to that is
more complex as explained below.

The strategy object is created in CurrentMemoryContext and is not
available in any global structure thus accessible when processing buffer
resizing barriers. We may modify GetAccessStrategy() to register
strategy in a global linked list and then arrange to deregister it once
it's no more in use. Looking at the places which use
GetAccessStrategy(), fixing all those may be some work.

Ashutosh Bapat
---
 src/backend/storage/buffer/freelist.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/src/backend/storage/buffer/freelist.c b/src/backend/storage/buffer/freelist.c
index 41641bb3ae6..74d070733a4 100644
--- a/src/backend/storage/buffer/freelist.c
+++ b/src/backend/storage/buffer/freelist.c
@@ -948,12 +948,13 @@ GetBufferFromRing(BufferAccessStrategy strategy, uint32 *buf_state)
 		strategy->current = 0;
 
 	/*
-	 * If the slot hasn't been filled yet, tell the caller to allocate a new
-	 * buffer with the normal allocation strategy.  He will then fill this
-	 * slot by calling AddBufferToRing with the new buffer.
+	 * If the slot hasn't been filled yet or the buffer in the slot has been
+	 * invalidated when buffer pool was shrunk, tell the caller to allocate a new
+	 * buffer with the normal allocation strategy.  He will then fill this slot
+	 * by calling AddBufferToRing with the new buffer.
 	 */
 	bufnum = strategy->buffers[strategy->current];
-	if (bufnum == InvalidBuffer)
+	if (bufnum == InvalidBuffer || bufnum > NBuffers)
 		return NULL;
 
 	/*
-- 
2.49.0


--bwrlgp6w2ubxykjq--





^ permalink  raw  reply  [nested|flat] 107+ messages in thread

* [PATCH v5 10/10] Additional validation for buffer in the ring
@ 2025-06-11 12:45 Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
  0 siblings, 0 replies; 107+ messages in thread

From: Ashutosh Bapat @ 2025-06-11 12:45 UTC (permalink / raw)

If the buffer pool has been shrunk, the buffers in the buffer list may
not be valid anymore. Modify GetBufferFromRing to check if the buffer is
still valid before using it. This makes GetBufferFromRing() a bit more
expensive because of additional boolean condition. That may not be
expensive enough to affect query performance. The alternative to that is
more complex as explained below.

The strategy object is created in CurrentMemoryContext and is not
available in any global structure thus accessible when processing buffer
resizing barriers. We may modify GetAccessStrategy() to register
strategy in a global linked list and then arrange to deregister it once
it's no more in use. Looking at the places which use
GetAccessStrategy(), fixing all those may be some work.

Ashutosh Bapat
---
 src/backend/storage/buffer/freelist.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/src/backend/storage/buffer/freelist.c b/src/backend/storage/buffer/freelist.c
index 41641bb3ae6..74d070733a4 100644
--- a/src/backend/storage/buffer/freelist.c
+++ b/src/backend/storage/buffer/freelist.c
@@ -948,12 +948,13 @@ GetBufferFromRing(BufferAccessStrategy strategy, uint32 *buf_state)
 		strategy->current = 0;
 
 	/*
-	 * If the slot hasn't been filled yet, tell the caller to allocate a new
-	 * buffer with the normal allocation strategy.  He will then fill this
-	 * slot by calling AddBufferToRing with the new buffer.
+	 * If the slot hasn't been filled yet or the buffer in the slot has been
+	 * invalidated when buffer pool was shrunk, tell the caller to allocate a new
+	 * buffer with the normal allocation strategy.  He will then fill this slot
+	 * by calling AddBufferToRing with the new buffer.
 	 */
 	bufnum = strategy->buffers[strategy->current];
-	if (bufnum == InvalidBuffer)
+	if (bufnum == InvalidBuffer || bufnum > NBuffers)
 		return NULL;
 
 	/*
-- 
2.49.0


--bwrlgp6w2ubxykjq--





^ permalink  raw  reply  [nested|flat] 107+ messages in thread

* [PATCH v5 10/10] Additional validation for buffer in the ring
@ 2025-06-11 12:45 Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
  0 siblings, 0 replies; 107+ messages in thread

From: Ashutosh Bapat @ 2025-06-11 12:45 UTC (permalink / raw)

If the buffer pool has been shrunk, the buffers in the buffer list may
not be valid anymore. Modify GetBufferFromRing to check if the buffer is
still valid before using it. This makes GetBufferFromRing() a bit more
expensive because of additional boolean condition. That may not be
expensive enough to affect query performance. The alternative to that is
more complex as explained below.

The strategy object is created in CurrentMemoryContext and is not
available in any global structure thus accessible when processing buffer
resizing barriers. We may modify GetAccessStrategy() to register
strategy in a global linked list and then arrange to deregister it once
it's no more in use. Looking at the places which use
GetAccessStrategy(), fixing all those may be some work.

Ashutosh Bapat
---
 src/backend/storage/buffer/freelist.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/src/backend/storage/buffer/freelist.c b/src/backend/storage/buffer/freelist.c
index 41641bb3ae6..74d070733a4 100644
--- a/src/backend/storage/buffer/freelist.c
+++ b/src/backend/storage/buffer/freelist.c
@@ -948,12 +948,13 @@ GetBufferFromRing(BufferAccessStrategy strategy, uint32 *buf_state)
 		strategy->current = 0;
 
 	/*
-	 * If the slot hasn't been filled yet, tell the caller to allocate a new
-	 * buffer with the normal allocation strategy.  He will then fill this
-	 * slot by calling AddBufferToRing with the new buffer.
+	 * If the slot hasn't been filled yet or the buffer in the slot has been
+	 * invalidated when buffer pool was shrunk, tell the caller to allocate a new
+	 * buffer with the normal allocation strategy.  He will then fill this slot
+	 * by calling AddBufferToRing with the new buffer.
 	 */
 	bufnum = strategy->buffers[strategy->current];
-	if (bufnum == InvalidBuffer)
+	if (bufnum == InvalidBuffer || bufnum > NBuffers)
 		return NULL;
 
 	/*
-- 
2.49.0


--bwrlgp6w2ubxykjq--





^ permalink  raw  reply  [nested|flat] 107+ messages in thread

* [PATCH v5 10/10] Additional validation for buffer in the ring
@ 2025-06-11 12:45 Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
  0 siblings, 0 replies; 107+ messages in thread

From: Ashutosh Bapat @ 2025-06-11 12:45 UTC (permalink / raw)

If the buffer pool has been shrunk, the buffers in the buffer list may
not be valid anymore. Modify GetBufferFromRing to check if the buffer is
still valid before using it. This makes GetBufferFromRing() a bit more
expensive because of additional boolean condition. That may not be
expensive enough to affect query performance. The alternative to that is
more complex as explained below.

The strategy object is created in CurrentMemoryContext and is not
available in any global structure thus accessible when processing buffer
resizing barriers. We may modify GetAccessStrategy() to register
strategy in a global linked list and then arrange to deregister it once
it's no more in use. Looking at the places which use
GetAccessStrategy(), fixing all those may be some work.

Ashutosh Bapat
---
 src/backend/storage/buffer/freelist.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/src/backend/storage/buffer/freelist.c b/src/backend/storage/buffer/freelist.c
index 41641bb3ae6..74d070733a4 100644
--- a/src/backend/storage/buffer/freelist.c
+++ b/src/backend/storage/buffer/freelist.c
@@ -948,12 +948,13 @@ GetBufferFromRing(BufferAccessStrategy strategy, uint32 *buf_state)
 		strategy->current = 0;
 
 	/*
-	 * If the slot hasn't been filled yet, tell the caller to allocate a new
-	 * buffer with the normal allocation strategy.  He will then fill this
-	 * slot by calling AddBufferToRing with the new buffer.
+	 * If the slot hasn't been filled yet or the buffer in the slot has been
+	 * invalidated when buffer pool was shrunk, tell the caller to allocate a new
+	 * buffer with the normal allocation strategy.  He will then fill this slot
+	 * by calling AddBufferToRing with the new buffer.
 	 */
 	bufnum = strategy->buffers[strategy->current];
-	if (bufnum == InvalidBuffer)
+	if (bufnum == InvalidBuffer || bufnum > NBuffers)
 		return NULL;
 
 	/*
-- 
2.49.0


--bwrlgp6w2ubxykjq--





^ permalink  raw  reply  [nested|flat] 107+ messages in thread

* [PATCH v5 10/10] Additional validation for buffer in the ring
@ 2025-06-11 12:45 Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
  0 siblings, 0 replies; 107+ messages in thread

From: Ashutosh Bapat @ 2025-06-11 12:45 UTC (permalink / raw)

If the buffer pool has been shrunk, the buffers in the buffer list may
not be valid anymore. Modify GetBufferFromRing to check if the buffer is
still valid before using it. This makes GetBufferFromRing() a bit more
expensive because of additional boolean condition. That may not be
expensive enough to affect query performance. The alternative to that is
more complex as explained below.

The strategy object is created in CurrentMemoryContext and is not
available in any global structure thus accessible when processing buffer
resizing barriers. We may modify GetAccessStrategy() to register
strategy in a global linked list and then arrange to deregister it once
it's no more in use. Looking at the places which use
GetAccessStrategy(), fixing all those may be some work.

Ashutosh Bapat
---
 src/backend/storage/buffer/freelist.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/src/backend/storage/buffer/freelist.c b/src/backend/storage/buffer/freelist.c
index 41641bb3ae6..74d070733a4 100644
--- a/src/backend/storage/buffer/freelist.c
+++ b/src/backend/storage/buffer/freelist.c
@@ -948,12 +948,13 @@ GetBufferFromRing(BufferAccessStrategy strategy, uint32 *buf_state)
 		strategy->current = 0;
 
 	/*
-	 * If the slot hasn't been filled yet, tell the caller to allocate a new
-	 * buffer with the normal allocation strategy.  He will then fill this
-	 * slot by calling AddBufferToRing with the new buffer.
+	 * If the slot hasn't been filled yet or the buffer in the slot has been
+	 * invalidated when buffer pool was shrunk, tell the caller to allocate a new
+	 * buffer with the normal allocation strategy.  He will then fill this slot
+	 * by calling AddBufferToRing with the new buffer.
 	 */
 	bufnum = strategy->buffers[strategy->current];
-	if (bufnum == InvalidBuffer)
+	if (bufnum == InvalidBuffer || bufnum > NBuffers)
 		return NULL;
 
 	/*
-- 
2.49.0


--bwrlgp6w2ubxykjq--





^ permalink  raw  reply  [nested|flat] 107+ messages in thread

* [PATCH v5 10/10] Additional validation for buffer in the ring
@ 2025-06-11 12:45 Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
  0 siblings, 0 replies; 107+ messages in thread

From: Ashutosh Bapat @ 2025-06-11 12:45 UTC (permalink / raw)

If the buffer pool has been shrunk, the buffers in the buffer list may
not be valid anymore. Modify GetBufferFromRing to check if the buffer is
still valid before using it. This makes GetBufferFromRing() a bit more
expensive because of additional boolean condition. That may not be
expensive enough to affect query performance. The alternative to that is
more complex as explained below.

The strategy object is created in CurrentMemoryContext and is not
available in any global structure thus accessible when processing buffer
resizing barriers. We may modify GetAccessStrategy() to register
strategy in a global linked list and then arrange to deregister it once
it's no more in use. Looking at the places which use
GetAccessStrategy(), fixing all those may be some work.

Ashutosh Bapat
---
 src/backend/storage/buffer/freelist.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/src/backend/storage/buffer/freelist.c b/src/backend/storage/buffer/freelist.c
index 41641bb3ae6..74d070733a4 100644
--- a/src/backend/storage/buffer/freelist.c
+++ b/src/backend/storage/buffer/freelist.c
@@ -948,12 +948,13 @@ GetBufferFromRing(BufferAccessStrategy strategy, uint32 *buf_state)
 		strategy->current = 0;
 
 	/*
-	 * If the slot hasn't been filled yet, tell the caller to allocate a new
-	 * buffer with the normal allocation strategy.  He will then fill this
-	 * slot by calling AddBufferToRing with the new buffer.
+	 * If the slot hasn't been filled yet or the buffer in the slot has been
+	 * invalidated when buffer pool was shrunk, tell the caller to allocate a new
+	 * buffer with the normal allocation strategy.  He will then fill this slot
+	 * by calling AddBufferToRing with the new buffer.
 	 */
 	bufnum = strategy->buffers[strategy->current];
-	if (bufnum == InvalidBuffer)
+	if (bufnum == InvalidBuffer || bufnum > NBuffers)
 		return NULL;
 
 	/*
-- 
2.49.0


--bwrlgp6w2ubxykjq--





^ permalink  raw  reply  [nested|flat] 107+ messages in thread

* [PATCH v5 10/10] Additional validation for buffer in the ring
@ 2025-06-11 12:45 Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
  0 siblings, 0 replies; 107+ messages in thread

From: Ashutosh Bapat @ 2025-06-11 12:45 UTC (permalink / raw)

If the buffer pool has been shrunk, the buffers in the buffer list may
not be valid anymore. Modify GetBufferFromRing to check if the buffer is
still valid before using it. This makes GetBufferFromRing() a bit more
expensive because of additional boolean condition. That may not be
expensive enough to affect query performance. The alternative to that is
more complex as explained below.

The strategy object is created in CurrentMemoryContext and is not
available in any global structure thus accessible when processing buffer
resizing barriers. We may modify GetAccessStrategy() to register
strategy in a global linked list and then arrange to deregister it once
it's no more in use. Looking at the places which use
GetAccessStrategy(), fixing all those may be some work.

Ashutosh Bapat
---
 src/backend/storage/buffer/freelist.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/src/backend/storage/buffer/freelist.c b/src/backend/storage/buffer/freelist.c
index 41641bb3ae6..74d070733a4 100644
--- a/src/backend/storage/buffer/freelist.c
+++ b/src/backend/storage/buffer/freelist.c
@@ -948,12 +948,13 @@ GetBufferFromRing(BufferAccessStrategy strategy, uint32 *buf_state)
 		strategy->current = 0;
 
 	/*
-	 * If the slot hasn't been filled yet, tell the caller to allocate a new
-	 * buffer with the normal allocation strategy.  He will then fill this
-	 * slot by calling AddBufferToRing with the new buffer.
+	 * If the slot hasn't been filled yet or the buffer in the slot has been
+	 * invalidated when buffer pool was shrunk, tell the caller to allocate a new
+	 * buffer with the normal allocation strategy.  He will then fill this slot
+	 * by calling AddBufferToRing with the new buffer.
 	 */
 	bufnum = strategy->buffers[strategy->current];
-	if (bufnum == InvalidBuffer)
+	if (bufnum == InvalidBuffer || bufnum > NBuffers)
 		return NULL;
 
 	/*
-- 
2.49.0


--bwrlgp6w2ubxykjq--





^ permalink  raw  reply  [nested|flat] 107+ messages in thread

* [PATCH v5 10/10] Additional validation for buffer in the ring
@ 2025-06-11 12:45 Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
  0 siblings, 0 replies; 107+ messages in thread

From: Ashutosh Bapat @ 2025-06-11 12:45 UTC (permalink / raw)

If the buffer pool has been shrunk, the buffers in the buffer list may
not be valid anymore. Modify GetBufferFromRing to check if the buffer is
still valid before using it. This makes GetBufferFromRing() a bit more
expensive because of additional boolean condition. That may not be
expensive enough to affect query performance. The alternative to that is
more complex as explained below.

The strategy object is created in CurrentMemoryContext and is not
available in any global structure thus accessible when processing buffer
resizing barriers. We may modify GetAccessStrategy() to register
strategy in a global linked list and then arrange to deregister it once
it's no more in use. Looking at the places which use
GetAccessStrategy(), fixing all those may be some work.

Ashutosh Bapat
---
 src/backend/storage/buffer/freelist.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/src/backend/storage/buffer/freelist.c b/src/backend/storage/buffer/freelist.c
index 41641bb3ae6..74d070733a4 100644
--- a/src/backend/storage/buffer/freelist.c
+++ b/src/backend/storage/buffer/freelist.c
@@ -948,12 +948,13 @@ GetBufferFromRing(BufferAccessStrategy strategy, uint32 *buf_state)
 		strategy->current = 0;
 
 	/*
-	 * If the slot hasn't been filled yet, tell the caller to allocate a new
-	 * buffer with the normal allocation strategy.  He will then fill this
-	 * slot by calling AddBufferToRing with the new buffer.
+	 * If the slot hasn't been filled yet or the buffer in the slot has been
+	 * invalidated when buffer pool was shrunk, tell the caller to allocate a new
+	 * buffer with the normal allocation strategy.  He will then fill this slot
+	 * by calling AddBufferToRing with the new buffer.
 	 */
 	bufnum = strategy->buffers[strategy->current];
-	if (bufnum == InvalidBuffer)
+	if (bufnum == InvalidBuffer || bufnum > NBuffers)
 		return NULL;
 
 	/*
-- 
2.49.0


--bwrlgp6w2ubxykjq--





^ permalink  raw  reply  [nested|flat] 107+ messages in thread

* [PATCH v5 10/10] Additional validation for buffer in the ring
@ 2025-06-11 12:45 Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
  0 siblings, 0 replies; 107+ messages in thread

From: Ashutosh Bapat @ 2025-06-11 12:45 UTC (permalink / raw)

If the buffer pool has been shrunk, the buffers in the buffer list may
not be valid anymore. Modify GetBufferFromRing to check if the buffer is
still valid before using it. This makes GetBufferFromRing() a bit more
expensive because of additional boolean condition. That may not be
expensive enough to affect query performance. The alternative to that is
more complex as explained below.

The strategy object is created in CurrentMemoryContext and is not
available in any global structure thus accessible when processing buffer
resizing barriers. We may modify GetAccessStrategy() to register
strategy in a global linked list and then arrange to deregister it once
it's no more in use. Looking at the places which use
GetAccessStrategy(), fixing all those may be some work.

Ashutosh Bapat
---
 src/backend/storage/buffer/freelist.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/src/backend/storage/buffer/freelist.c b/src/backend/storage/buffer/freelist.c
index 41641bb3ae6..74d070733a4 100644
--- a/src/backend/storage/buffer/freelist.c
+++ b/src/backend/storage/buffer/freelist.c
@@ -948,12 +948,13 @@ GetBufferFromRing(BufferAccessStrategy strategy, uint32 *buf_state)
 		strategy->current = 0;
 
 	/*
-	 * If the slot hasn't been filled yet, tell the caller to allocate a new
-	 * buffer with the normal allocation strategy.  He will then fill this
-	 * slot by calling AddBufferToRing with the new buffer.
+	 * If the slot hasn't been filled yet or the buffer in the slot has been
+	 * invalidated when buffer pool was shrunk, tell the caller to allocate a new
+	 * buffer with the normal allocation strategy.  He will then fill this slot
+	 * by calling AddBufferToRing with the new buffer.
 	 */
 	bufnum = strategy->buffers[strategy->current];
-	if (bufnum == InvalidBuffer)
+	if (bufnum == InvalidBuffer || bufnum > NBuffers)
 		return NULL;
 
 	/*
-- 
2.49.0


--bwrlgp6w2ubxykjq--





^ permalink  raw  reply  [nested|flat] 107+ messages in thread

* [PATCH v5 10/10] Additional validation for buffer in the ring
@ 2025-06-11 12:45 Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
  0 siblings, 0 replies; 107+ messages in thread

From: Ashutosh Bapat @ 2025-06-11 12:45 UTC (permalink / raw)

If the buffer pool has been shrunk, the buffers in the buffer list may
not be valid anymore. Modify GetBufferFromRing to check if the buffer is
still valid before using it. This makes GetBufferFromRing() a bit more
expensive because of additional boolean condition. That may not be
expensive enough to affect query performance. The alternative to that is
more complex as explained below.

The strategy object is created in CurrentMemoryContext and is not
available in any global structure thus accessible when processing buffer
resizing barriers. We may modify GetAccessStrategy() to register
strategy in a global linked list and then arrange to deregister it once
it's no more in use. Looking at the places which use
GetAccessStrategy(), fixing all those may be some work.

Ashutosh Bapat
---
 src/backend/storage/buffer/freelist.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/src/backend/storage/buffer/freelist.c b/src/backend/storage/buffer/freelist.c
index 41641bb3ae6..74d070733a4 100644
--- a/src/backend/storage/buffer/freelist.c
+++ b/src/backend/storage/buffer/freelist.c
@@ -948,12 +948,13 @@ GetBufferFromRing(BufferAccessStrategy strategy, uint32 *buf_state)
 		strategy->current = 0;
 
 	/*
-	 * If the slot hasn't been filled yet, tell the caller to allocate a new
-	 * buffer with the normal allocation strategy.  He will then fill this
-	 * slot by calling AddBufferToRing with the new buffer.
+	 * If the slot hasn't been filled yet or the buffer in the slot has been
+	 * invalidated when buffer pool was shrunk, tell the caller to allocate a new
+	 * buffer with the normal allocation strategy.  He will then fill this slot
+	 * by calling AddBufferToRing with the new buffer.
 	 */
 	bufnum = strategy->buffers[strategy->current];
-	if (bufnum == InvalidBuffer)
+	if (bufnum == InvalidBuffer || bufnum > NBuffers)
 		return NULL;
 
 	/*
-- 
2.49.0


--bwrlgp6w2ubxykjq--





^ permalink  raw  reply  [nested|flat] 107+ messages in thread

* [PATCH v5 10/10] Additional validation for buffer in the ring
@ 2025-06-11 12:45 Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
  0 siblings, 0 replies; 107+ messages in thread

From: Ashutosh Bapat @ 2025-06-11 12:45 UTC (permalink / raw)

If the buffer pool has been shrunk, the buffers in the buffer list may
not be valid anymore. Modify GetBufferFromRing to check if the buffer is
still valid before using it. This makes GetBufferFromRing() a bit more
expensive because of additional boolean condition. That may not be
expensive enough to affect query performance. The alternative to that is
more complex as explained below.

The strategy object is created in CurrentMemoryContext and is not
available in any global structure thus accessible when processing buffer
resizing barriers. We may modify GetAccessStrategy() to register
strategy in a global linked list and then arrange to deregister it once
it's no more in use. Looking at the places which use
GetAccessStrategy(), fixing all those may be some work.

Ashutosh Bapat
---
 src/backend/storage/buffer/freelist.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/src/backend/storage/buffer/freelist.c b/src/backend/storage/buffer/freelist.c
index 41641bb3ae6..74d070733a4 100644
--- a/src/backend/storage/buffer/freelist.c
+++ b/src/backend/storage/buffer/freelist.c
@@ -948,12 +948,13 @@ GetBufferFromRing(BufferAccessStrategy strategy, uint32 *buf_state)
 		strategy->current = 0;
 
 	/*
-	 * If the slot hasn't been filled yet, tell the caller to allocate a new
-	 * buffer with the normal allocation strategy.  He will then fill this
-	 * slot by calling AddBufferToRing with the new buffer.
+	 * If the slot hasn't been filled yet or the buffer in the slot has been
+	 * invalidated when buffer pool was shrunk, tell the caller to allocate a new
+	 * buffer with the normal allocation strategy.  He will then fill this slot
+	 * by calling AddBufferToRing with the new buffer.
 	 */
 	bufnum = strategy->buffers[strategy->current];
-	if (bufnum == InvalidBuffer)
+	if (bufnum == InvalidBuffer || bufnum > NBuffers)
 		return NULL;
 
 	/*
-- 
2.49.0


--bwrlgp6w2ubxykjq--





^ permalink  raw  reply  [nested|flat] 107+ messages in thread

* [PATCH v5 10/10] Additional validation for buffer in the ring
@ 2025-06-11 12:45 Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
  0 siblings, 0 replies; 107+ messages in thread

From: Ashutosh Bapat @ 2025-06-11 12:45 UTC (permalink / raw)

If the buffer pool has been shrunk, the buffers in the buffer list may
not be valid anymore. Modify GetBufferFromRing to check if the buffer is
still valid before using it. This makes GetBufferFromRing() a bit more
expensive because of additional boolean condition. That may not be
expensive enough to affect query performance. The alternative to that is
more complex as explained below.

The strategy object is created in CurrentMemoryContext and is not
available in any global structure thus accessible when processing buffer
resizing barriers. We may modify GetAccessStrategy() to register
strategy in a global linked list and then arrange to deregister it once
it's no more in use. Looking at the places which use
GetAccessStrategy(), fixing all those may be some work.

Ashutosh Bapat
---
 src/backend/storage/buffer/freelist.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/src/backend/storage/buffer/freelist.c b/src/backend/storage/buffer/freelist.c
index 41641bb3ae6..74d070733a4 100644
--- a/src/backend/storage/buffer/freelist.c
+++ b/src/backend/storage/buffer/freelist.c
@@ -948,12 +948,13 @@ GetBufferFromRing(BufferAccessStrategy strategy, uint32 *buf_state)
 		strategy->current = 0;
 
 	/*
-	 * If the slot hasn't been filled yet, tell the caller to allocate a new
-	 * buffer with the normal allocation strategy.  He will then fill this
-	 * slot by calling AddBufferToRing with the new buffer.
+	 * If the slot hasn't been filled yet or the buffer in the slot has been
+	 * invalidated when buffer pool was shrunk, tell the caller to allocate a new
+	 * buffer with the normal allocation strategy.  He will then fill this slot
+	 * by calling AddBufferToRing with the new buffer.
 	 */
 	bufnum = strategy->buffers[strategy->current];
-	if (bufnum == InvalidBuffer)
+	if (bufnum == InvalidBuffer || bufnum > NBuffers)
 		return NULL;
 
 	/*
-- 
2.49.0


--bwrlgp6w2ubxykjq--





^ permalink  raw  reply  [nested|flat] 107+ messages in thread

* [PATCH v5 10/10] Additional validation for buffer in the ring
@ 2025-06-11 12:45 Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
  0 siblings, 0 replies; 107+ messages in thread

From: Ashutosh Bapat @ 2025-06-11 12:45 UTC (permalink / raw)

If the buffer pool has been shrunk, the buffers in the buffer list may
not be valid anymore. Modify GetBufferFromRing to check if the buffer is
still valid before using it. This makes GetBufferFromRing() a bit more
expensive because of additional boolean condition. That may not be
expensive enough to affect query performance. The alternative to that is
more complex as explained below.

The strategy object is created in CurrentMemoryContext and is not
available in any global structure thus accessible when processing buffer
resizing barriers. We may modify GetAccessStrategy() to register
strategy in a global linked list and then arrange to deregister it once
it's no more in use. Looking at the places which use
GetAccessStrategy(), fixing all those may be some work.

Ashutosh Bapat
---
 src/backend/storage/buffer/freelist.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/src/backend/storage/buffer/freelist.c b/src/backend/storage/buffer/freelist.c
index 41641bb3ae6..74d070733a4 100644
--- a/src/backend/storage/buffer/freelist.c
+++ b/src/backend/storage/buffer/freelist.c
@@ -948,12 +948,13 @@ GetBufferFromRing(BufferAccessStrategy strategy, uint32 *buf_state)
 		strategy->current = 0;
 
 	/*
-	 * If the slot hasn't been filled yet, tell the caller to allocate a new
-	 * buffer with the normal allocation strategy.  He will then fill this
-	 * slot by calling AddBufferToRing with the new buffer.
+	 * If the slot hasn't been filled yet or the buffer in the slot has been
+	 * invalidated when buffer pool was shrunk, tell the caller to allocate a new
+	 * buffer with the normal allocation strategy.  He will then fill this slot
+	 * by calling AddBufferToRing with the new buffer.
 	 */
 	bufnum = strategy->buffers[strategy->current];
-	if (bufnum == InvalidBuffer)
+	if (bufnum == InvalidBuffer || bufnum > NBuffers)
 		return NULL;
 
 	/*
-- 
2.49.0


--bwrlgp6w2ubxykjq--





^ permalink  raw  reply  [nested|flat] 107+ messages in thread

* [PATCH v5 10/10] Additional validation for buffer in the ring
@ 2025-06-11 12:45 Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
  0 siblings, 0 replies; 107+ messages in thread

From: Ashutosh Bapat @ 2025-06-11 12:45 UTC (permalink / raw)

If the buffer pool has been shrunk, the buffers in the buffer list may
not be valid anymore. Modify GetBufferFromRing to check if the buffer is
still valid before using it. This makes GetBufferFromRing() a bit more
expensive because of additional boolean condition. That may not be
expensive enough to affect query performance. The alternative to that is
more complex as explained below.

The strategy object is created in CurrentMemoryContext and is not
available in any global structure thus accessible when processing buffer
resizing barriers. We may modify GetAccessStrategy() to register
strategy in a global linked list and then arrange to deregister it once
it's no more in use. Looking at the places which use
GetAccessStrategy(), fixing all those may be some work.

Ashutosh Bapat
---
 src/backend/storage/buffer/freelist.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/src/backend/storage/buffer/freelist.c b/src/backend/storage/buffer/freelist.c
index 41641bb3ae6..74d070733a4 100644
--- a/src/backend/storage/buffer/freelist.c
+++ b/src/backend/storage/buffer/freelist.c
@@ -948,12 +948,13 @@ GetBufferFromRing(BufferAccessStrategy strategy, uint32 *buf_state)
 		strategy->current = 0;
 
 	/*
-	 * If the slot hasn't been filled yet, tell the caller to allocate a new
-	 * buffer with the normal allocation strategy.  He will then fill this
-	 * slot by calling AddBufferToRing with the new buffer.
+	 * If the slot hasn't been filled yet or the buffer in the slot has been
+	 * invalidated when buffer pool was shrunk, tell the caller to allocate a new
+	 * buffer with the normal allocation strategy.  He will then fill this slot
+	 * by calling AddBufferToRing with the new buffer.
 	 */
 	bufnum = strategy->buffers[strategy->current];
-	if (bufnum == InvalidBuffer)
+	if (bufnum == InvalidBuffer || bufnum > NBuffers)
 		return NULL;
 
 	/*
-- 
2.49.0


--bwrlgp6w2ubxykjq--





^ permalink  raw  reply  [nested|flat] 107+ messages in thread

* [PATCH v5 10/10] Additional validation for buffer in the ring
@ 2025-06-11 12:45 Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
  0 siblings, 0 replies; 107+ messages in thread

From: Ashutosh Bapat @ 2025-06-11 12:45 UTC (permalink / raw)

If the buffer pool has been shrunk, the buffers in the buffer list may
not be valid anymore. Modify GetBufferFromRing to check if the buffer is
still valid before using it. This makes GetBufferFromRing() a bit more
expensive because of additional boolean condition. That may not be
expensive enough to affect query performance. The alternative to that is
more complex as explained below.

The strategy object is created in CurrentMemoryContext and is not
available in any global structure thus accessible when processing buffer
resizing barriers. We may modify GetAccessStrategy() to register
strategy in a global linked list and then arrange to deregister it once
it's no more in use. Looking at the places which use
GetAccessStrategy(), fixing all those may be some work.

Ashutosh Bapat
---
 src/backend/storage/buffer/freelist.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/src/backend/storage/buffer/freelist.c b/src/backend/storage/buffer/freelist.c
index 41641bb3ae6..74d070733a4 100644
--- a/src/backend/storage/buffer/freelist.c
+++ b/src/backend/storage/buffer/freelist.c
@@ -948,12 +948,13 @@ GetBufferFromRing(BufferAccessStrategy strategy, uint32 *buf_state)
 		strategy->current = 0;
 
 	/*
-	 * If the slot hasn't been filled yet, tell the caller to allocate a new
-	 * buffer with the normal allocation strategy.  He will then fill this
-	 * slot by calling AddBufferToRing with the new buffer.
+	 * If the slot hasn't been filled yet or the buffer in the slot has been
+	 * invalidated when buffer pool was shrunk, tell the caller to allocate a new
+	 * buffer with the normal allocation strategy.  He will then fill this slot
+	 * by calling AddBufferToRing with the new buffer.
 	 */
 	bufnum = strategy->buffers[strategy->current];
-	if (bufnum == InvalidBuffer)
+	if (bufnum == InvalidBuffer || bufnum > NBuffers)
 		return NULL;
 
 	/*
-- 
2.49.0


--bwrlgp6w2ubxykjq--





^ permalink  raw  reply  [nested|flat] 107+ messages in thread

* [PATCH v5 10/10] Additional validation for buffer in the ring
@ 2025-06-11 12:45 Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
  0 siblings, 0 replies; 107+ messages in thread

From: Ashutosh Bapat @ 2025-06-11 12:45 UTC (permalink / raw)

If the buffer pool has been shrunk, the buffers in the buffer list may
not be valid anymore. Modify GetBufferFromRing to check if the buffer is
still valid before using it. This makes GetBufferFromRing() a bit more
expensive because of additional boolean condition. That may not be
expensive enough to affect query performance. The alternative to that is
more complex as explained below.

The strategy object is created in CurrentMemoryContext and is not
available in any global structure thus accessible when processing buffer
resizing barriers. We may modify GetAccessStrategy() to register
strategy in a global linked list and then arrange to deregister it once
it's no more in use. Looking at the places which use
GetAccessStrategy(), fixing all those may be some work.

Ashutosh Bapat
---
 src/backend/storage/buffer/freelist.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/src/backend/storage/buffer/freelist.c b/src/backend/storage/buffer/freelist.c
index 41641bb3ae6..74d070733a4 100644
--- a/src/backend/storage/buffer/freelist.c
+++ b/src/backend/storage/buffer/freelist.c
@@ -948,12 +948,13 @@ GetBufferFromRing(BufferAccessStrategy strategy, uint32 *buf_state)
 		strategy->current = 0;
 
 	/*
-	 * If the slot hasn't been filled yet, tell the caller to allocate a new
-	 * buffer with the normal allocation strategy.  He will then fill this
-	 * slot by calling AddBufferToRing with the new buffer.
+	 * If the slot hasn't been filled yet or the buffer in the slot has been
+	 * invalidated when buffer pool was shrunk, tell the caller to allocate a new
+	 * buffer with the normal allocation strategy.  He will then fill this slot
+	 * by calling AddBufferToRing with the new buffer.
 	 */
 	bufnum = strategy->buffers[strategy->current];
-	if (bufnum == InvalidBuffer)
+	if (bufnum == InvalidBuffer || bufnum > NBuffers)
 		return NULL;
 
 	/*
-- 
2.49.0


--bwrlgp6w2ubxykjq--





^ permalink  raw  reply  [nested|flat] 107+ messages in thread

* [PATCH v5 10/10] Additional validation for buffer in the ring
@ 2025-06-11 12:45 Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
  0 siblings, 0 replies; 107+ messages in thread

From: Ashutosh Bapat @ 2025-06-11 12:45 UTC (permalink / raw)

If the buffer pool has been shrunk, the buffers in the buffer list may
not be valid anymore. Modify GetBufferFromRing to check if the buffer is
still valid before using it. This makes GetBufferFromRing() a bit more
expensive because of additional boolean condition. That may not be
expensive enough to affect query performance. The alternative to that is
more complex as explained below.

The strategy object is created in CurrentMemoryContext and is not
available in any global structure thus accessible when processing buffer
resizing barriers. We may modify GetAccessStrategy() to register
strategy in a global linked list and then arrange to deregister it once
it's no more in use. Looking at the places which use
GetAccessStrategy(), fixing all those may be some work.

Ashutosh Bapat
---
 src/backend/storage/buffer/freelist.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/src/backend/storage/buffer/freelist.c b/src/backend/storage/buffer/freelist.c
index 41641bb3ae6..74d070733a4 100644
--- a/src/backend/storage/buffer/freelist.c
+++ b/src/backend/storage/buffer/freelist.c
@@ -948,12 +948,13 @@ GetBufferFromRing(BufferAccessStrategy strategy, uint32 *buf_state)
 		strategy->current = 0;
 
 	/*
-	 * If the slot hasn't been filled yet, tell the caller to allocate a new
-	 * buffer with the normal allocation strategy.  He will then fill this
-	 * slot by calling AddBufferToRing with the new buffer.
+	 * If the slot hasn't been filled yet or the buffer in the slot has been
+	 * invalidated when buffer pool was shrunk, tell the caller to allocate a new
+	 * buffer with the normal allocation strategy.  He will then fill this slot
+	 * by calling AddBufferToRing with the new buffer.
 	 */
 	bufnum = strategy->buffers[strategy->current];
-	if (bufnum == InvalidBuffer)
+	if (bufnum == InvalidBuffer || bufnum > NBuffers)
 		return NULL;
 
 	/*
-- 
2.49.0


--bwrlgp6w2ubxykjq--





^ permalink  raw  reply  [nested|flat] 107+ messages in thread

* [PATCH v5 10/10] Additional validation for buffer in the ring
@ 2025-06-11 12:45 Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
  0 siblings, 0 replies; 107+ messages in thread

From: Ashutosh Bapat @ 2025-06-11 12:45 UTC (permalink / raw)

If the buffer pool has been shrunk, the buffers in the buffer list may
not be valid anymore. Modify GetBufferFromRing to check if the buffer is
still valid before using it. This makes GetBufferFromRing() a bit more
expensive because of additional boolean condition. That may not be
expensive enough to affect query performance. The alternative to that is
more complex as explained below.

The strategy object is created in CurrentMemoryContext and is not
available in any global structure thus accessible when processing buffer
resizing barriers. We may modify GetAccessStrategy() to register
strategy in a global linked list and then arrange to deregister it once
it's no more in use. Looking at the places which use
GetAccessStrategy(), fixing all those may be some work.

Ashutosh Bapat
---
 src/backend/storage/buffer/freelist.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/src/backend/storage/buffer/freelist.c b/src/backend/storage/buffer/freelist.c
index 41641bb3ae6..74d070733a4 100644
--- a/src/backend/storage/buffer/freelist.c
+++ b/src/backend/storage/buffer/freelist.c
@@ -948,12 +948,13 @@ GetBufferFromRing(BufferAccessStrategy strategy, uint32 *buf_state)
 		strategy->current = 0;
 
 	/*
-	 * If the slot hasn't been filled yet, tell the caller to allocate a new
-	 * buffer with the normal allocation strategy.  He will then fill this
-	 * slot by calling AddBufferToRing with the new buffer.
+	 * If the slot hasn't been filled yet or the buffer in the slot has been
+	 * invalidated when buffer pool was shrunk, tell the caller to allocate a new
+	 * buffer with the normal allocation strategy.  He will then fill this slot
+	 * by calling AddBufferToRing with the new buffer.
 	 */
 	bufnum = strategy->buffers[strategy->current];
-	if (bufnum == InvalidBuffer)
+	if (bufnum == InvalidBuffer || bufnum > NBuffers)
 		return NULL;
 
 	/*
-- 
2.49.0


--bwrlgp6w2ubxykjq--





^ permalink  raw  reply  [nested|flat] 107+ messages in thread

* [PATCH v5 10/10] Additional validation for buffer in the ring
@ 2025-06-11 12:45 Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
  0 siblings, 0 replies; 107+ messages in thread

From: Ashutosh Bapat @ 2025-06-11 12:45 UTC (permalink / raw)

If the buffer pool has been shrunk, the buffers in the buffer list may
not be valid anymore. Modify GetBufferFromRing to check if the buffer is
still valid before using it. This makes GetBufferFromRing() a bit more
expensive because of additional boolean condition. That may not be
expensive enough to affect query performance. The alternative to that is
more complex as explained below.

The strategy object is created in CurrentMemoryContext and is not
available in any global structure thus accessible when processing buffer
resizing barriers. We may modify GetAccessStrategy() to register
strategy in a global linked list and then arrange to deregister it once
it's no more in use. Looking at the places which use
GetAccessStrategy(), fixing all those may be some work.

Ashutosh Bapat
---
 src/backend/storage/buffer/freelist.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/src/backend/storage/buffer/freelist.c b/src/backend/storage/buffer/freelist.c
index 41641bb3ae6..74d070733a4 100644
--- a/src/backend/storage/buffer/freelist.c
+++ b/src/backend/storage/buffer/freelist.c
@@ -948,12 +948,13 @@ GetBufferFromRing(BufferAccessStrategy strategy, uint32 *buf_state)
 		strategy->current = 0;
 
 	/*
-	 * If the slot hasn't been filled yet, tell the caller to allocate a new
-	 * buffer with the normal allocation strategy.  He will then fill this
-	 * slot by calling AddBufferToRing with the new buffer.
+	 * If the slot hasn't been filled yet or the buffer in the slot has been
+	 * invalidated when buffer pool was shrunk, tell the caller to allocate a new
+	 * buffer with the normal allocation strategy.  He will then fill this slot
+	 * by calling AddBufferToRing with the new buffer.
 	 */
 	bufnum = strategy->buffers[strategy->current];
-	if (bufnum == InvalidBuffer)
+	if (bufnum == InvalidBuffer || bufnum > NBuffers)
 		return NULL;
 
 	/*
-- 
2.49.0


--bwrlgp6w2ubxykjq--





^ permalink  raw  reply  [nested|flat] 107+ messages in thread

* [PATCH v5 10/10] Additional validation for buffer in the ring
@ 2025-06-11 12:45 Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
  0 siblings, 0 replies; 107+ messages in thread

From: Ashutosh Bapat @ 2025-06-11 12:45 UTC (permalink / raw)

If the buffer pool has been shrunk, the buffers in the buffer list may
not be valid anymore. Modify GetBufferFromRing to check if the buffer is
still valid before using it. This makes GetBufferFromRing() a bit more
expensive because of additional boolean condition. That may not be
expensive enough to affect query performance. The alternative to that is
more complex as explained below.

The strategy object is created in CurrentMemoryContext and is not
available in any global structure thus accessible when processing buffer
resizing barriers. We may modify GetAccessStrategy() to register
strategy in a global linked list and then arrange to deregister it once
it's no more in use. Looking at the places which use
GetAccessStrategy(), fixing all those may be some work.

Ashutosh Bapat
---
 src/backend/storage/buffer/freelist.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/src/backend/storage/buffer/freelist.c b/src/backend/storage/buffer/freelist.c
index 41641bb3ae6..74d070733a4 100644
--- a/src/backend/storage/buffer/freelist.c
+++ b/src/backend/storage/buffer/freelist.c
@@ -948,12 +948,13 @@ GetBufferFromRing(BufferAccessStrategy strategy, uint32 *buf_state)
 		strategy->current = 0;
 
 	/*
-	 * If the slot hasn't been filled yet, tell the caller to allocate a new
-	 * buffer with the normal allocation strategy.  He will then fill this
-	 * slot by calling AddBufferToRing with the new buffer.
+	 * If the slot hasn't been filled yet or the buffer in the slot has been
+	 * invalidated when buffer pool was shrunk, tell the caller to allocate a new
+	 * buffer with the normal allocation strategy.  He will then fill this slot
+	 * by calling AddBufferToRing with the new buffer.
 	 */
 	bufnum = strategy->buffers[strategy->current];
-	if (bufnum == InvalidBuffer)
+	if (bufnum == InvalidBuffer || bufnum > NBuffers)
 		return NULL;
 
 	/*
-- 
2.49.0


--bwrlgp6w2ubxykjq--





^ permalink  raw  reply  [nested|flat] 107+ messages in thread

* [PATCH v5 10/10] Additional validation for buffer in the ring
@ 2025-06-11 12:45 Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
  0 siblings, 0 replies; 107+ messages in thread

From: Ashutosh Bapat @ 2025-06-11 12:45 UTC (permalink / raw)

If the buffer pool has been shrunk, the buffers in the buffer list may
not be valid anymore. Modify GetBufferFromRing to check if the buffer is
still valid before using it. This makes GetBufferFromRing() a bit more
expensive because of additional boolean condition. That may not be
expensive enough to affect query performance. The alternative to that is
more complex as explained below.

The strategy object is created in CurrentMemoryContext and is not
available in any global structure thus accessible when processing buffer
resizing barriers. We may modify GetAccessStrategy() to register
strategy in a global linked list and then arrange to deregister it once
it's no more in use. Looking at the places which use
GetAccessStrategy(), fixing all those may be some work.

Ashutosh Bapat
---
 src/backend/storage/buffer/freelist.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/src/backend/storage/buffer/freelist.c b/src/backend/storage/buffer/freelist.c
index 41641bb3ae6..74d070733a4 100644
--- a/src/backend/storage/buffer/freelist.c
+++ b/src/backend/storage/buffer/freelist.c
@@ -948,12 +948,13 @@ GetBufferFromRing(BufferAccessStrategy strategy, uint32 *buf_state)
 		strategy->current = 0;
 
 	/*
-	 * If the slot hasn't been filled yet, tell the caller to allocate a new
-	 * buffer with the normal allocation strategy.  He will then fill this
-	 * slot by calling AddBufferToRing with the new buffer.
+	 * If the slot hasn't been filled yet or the buffer in the slot has been
+	 * invalidated when buffer pool was shrunk, tell the caller to allocate a new
+	 * buffer with the normal allocation strategy.  He will then fill this slot
+	 * by calling AddBufferToRing with the new buffer.
 	 */
 	bufnum = strategy->buffers[strategy->current];
-	if (bufnum == InvalidBuffer)
+	if (bufnum == InvalidBuffer || bufnum > NBuffers)
 		return NULL;
 
 	/*
-- 
2.49.0


--bwrlgp6w2ubxykjq--





^ permalink  raw  reply  [nested|flat] 107+ messages in thread

* [PATCH v5 10/10] Additional validation for buffer in the ring
@ 2025-06-11 12:45 Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
  0 siblings, 0 replies; 107+ messages in thread

From: Ashutosh Bapat @ 2025-06-11 12:45 UTC (permalink / raw)

If the buffer pool has been shrunk, the buffers in the buffer list may
not be valid anymore. Modify GetBufferFromRing to check if the buffer is
still valid before using it. This makes GetBufferFromRing() a bit more
expensive because of additional boolean condition. That may not be
expensive enough to affect query performance. The alternative to that is
more complex as explained below.

The strategy object is created in CurrentMemoryContext and is not
available in any global structure thus accessible when processing buffer
resizing barriers. We may modify GetAccessStrategy() to register
strategy in a global linked list and then arrange to deregister it once
it's no more in use. Looking at the places which use
GetAccessStrategy(), fixing all those may be some work.

Ashutosh Bapat
---
 src/backend/storage/buffer/freelist.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/src/backend/storage/buffer/freelist.c b/src/backend/storage/buffer/freelist.c
index 41641bb3ae6..74d070733a4 100644
--- a/src/backend/storage/buffer/freelist.c
+++ b/src/backend/storage/buffer/freelist.c
@@ -948,12 +948,13 @@ GetBufferFromRing(BufferAccessStrategy strategy, uint32 *buf_state)
 		strategy->current = 0;
 
 	/*
-	 * If the slot hasn't been filled yet, tell the caller to allocate a new
-	 * buffer with the normal allocation strategy.  He will then fill this
-	 * slot by calling AddBufferToRing with the new buffer.
+	 * If the slot hasn't been filled yet or the buffer in the slot has been
+	 * invalidated when buffer pool was shrunk, tell the caller to allocate a new
+	 * buffer with the normal allocation strategy.  He will then fill this slot
+	 * by calling AddBufferToRing with the new buffer.
 	 */
 	bufnum = strategy->buffers[strategy->current];
-	if (bufnum == InvalidBuffer)
+	if (bufnum == InvalidBuffer || bufnum > NBuffers)
 		return NULL;
 
 	/*
-- 
2.49.0


--bwrlgp6w2ubxykjq--





^ permalink  raw  reply  [nested|flat] 107+ messages in thread

* [PATCH v5 10/10] Additional validation for buffer in the ring
@ 2025-06-11 12:45 Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
  0 siblings, 0 replies; 107+ messages in thread

From: Ashutosh Bapat @ 2025-06-11 12:45 UTC (permalink / raw)

If the buffer pool has been shrunk, the buffers in the buffer list may
not be valid anymore. Modify GetBufferFromRing to check if the buffer is
still valid before using it. This makes GetBufferFromRing() a bit more
expensive because of additional boolean condition. That may not be
expensive enough to affect query performance. The alternative to that is
more complex as explained below.

The strategy object is created in CurrentMemoryContext and is not
available in any global structure thus accessible when processing buffer
resizing barriers. We may modify GetAccessStrategy() to register
strategy in a global linked list and then arrange to deregister it once
it's no more in use. Looking at the places which use
GetAccessStrategy(), fixing all those may be some work.

Ashutosh Bapat
---
 src/backend/storage/buffer/freelist.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/src/backend/storage/buffer/freelist.c b/src/backend/storage/buffer/freelist.c
index 41641bb3ae6..74d070733a4 100644
--- a/src/backend/storage/buffer/freelist.c
+++ b/src/backend/storage/buffer/freelist.c
@@ -948,12 +948,13 @@ GetBufferFromRing(BufferAccessStrategy strategy, uint32 *buf_state)
 		strategy->current = 0;
 
 	/*
-	 * If the slot hasn't been filled yet, tell the caller to allocate a new
-	 * buffer with the normal allocation strategy.  He will then fill this
-	 * slot by calling AddBufferToRing with the new buffer.
+	 * If the slot hasn't been filled yet or the buffer in the slot has been
+	 * invalidated when buffer pool was shrunk, tell the caller to allocate a new
+	 * buffer with the normal allocation strategy.  He will then fill this slot
+	 * by calling AddBufferToRing with the new buffer.
 	 */
 	bufnum = strategy->buffers[strategy->current];
-	if (bufnum == InvalidBuffer)
+	if (bufnum == InvalidBuffer || bufnum > NBuffers)
 		return NULL;
 
 	/*
-- 
2.49.0


--bwrlgp6w2ubxykjq--





^ permalink  raw  reply  [nested|flat] 107+ messages in thread

* [PATCH v5 10/10] Additional validation for buffer in the ring
@ 2025-06-11 12:45 Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
  0 siblings, 0 replies; 107+ messages in thread

From: Ashutosh Bapat @ 2025-06-11 12:45 UTC (permalink / raw)

If the buffer pool has been shrunk, the buffers in the buffer list may
not be valid anymore. Modify GetBufferFromRing to check if the buffer is
still valid before using it. This makes GetBufferFromRing() a bit more
expensive because of additional boolean condition. That may not be
expensive enough to affect query performance. The alternative to that is
more complex as explained below.

The strategy object is created in CurrentMemoryContext and is not
available in any global structure thus accessible when processing buffer
resizing barriers. We may modify GetAccessStrategy() to register
strategy in a global linked list and then arrange to deregister it once
it's no more in use. Looking at the places which use
GetAccessStrategy(), fixing all those may be some work.

Ashutosh Bapat
---
 src/backend/storage/buffer/freelist.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/src/backend/storage/buffer/freelist.c b/src/backend/storage/buffer/freelist.c
index 41641bb3ae6..74d070733a4 100644
--- a/src/backend/storage/buffer/freelist.c
+++ b/src/backend/storage/buffer/freelist.c
@@ -948,12 +948,13 @@ GetBufferFromRing(BufferAccessStrategy strategy, uint32 *buf_state)
 		strategy->current = 0;
 
 	/*
-	 * If the slot hasn't been filled yet, tell the caller to allocate a new
-	 * buffer with the normal allocation strategy.  He will then fill this
-	 * slot by calling AddBufferToRing with the new buffer.
+	 * If the slot hasn't been filled yet or the buffer in the slot has been
+	 * invalidated when buffer pool was shrunk, tell the caller to allocate a new
+	 * buffer with the normal allocation strategy.  He will then fill this slot
+	 * by calling AddBufferToRing with the new buffer.
 	 */
 	bufnum = strategy->buffers[strategy->current];
-	if (bufnum == InvalidBuffer)
+	if (bufnum == InvalidBuffer || bufnum > NBuffers)
 		return NULL;
 
 	/*
-- 
2.49.0


--bwrlgp6w2ubxykjq--





^ permalink  raw  reply  [nested|flat] 107+ messages in thread

* [PATCH v5 10/10] Additional validation for buffer in the ring
@ 2025-06-11 12:45 Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
  0 siblings, 0 replies; 107+ messages in thread

From: Ashutosh Bapat @ 2025-06-11 12:45 UTC (permalink / raw)

If the buffer pool has been shrunk, the buffers in the buffer list may
not be valid anymore. Modify GetBufferFromRing to check if the buffer is
still valid before using it. This makes GetBufferFromRing() a bit more
expensive because of additional boolean condition. That may not be
expensive enough to affect query performance. The alternative to that is
more complex as explained below.

The strategy object is created in CurrentMemoryContext and is not
available in any global structure thus accessible when processing buffer
resizing barriers. We may modify GetAccessStrategy() to register
strategy in a global linked list and then arrange to deregister it once
it's no more in use. Looking at the places which use
GetAccessStrategy(), fixing all those may be some work.

Ashutosh Bapat
---
 src/backend/storage/buffer/freelist.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/src/backend/storage/buffer/freelist.c b/src/backend/storage/buffer/freelist.c
index 41641bb3ae6..74d070733a4 100644
--- a/src/backend/storage/buffer/freelist.c
+++ b/src/backend/storage/buffer/freelist.c
@@ -948,12 +948,13 @@ GetBufferFromRing(BufferAccessStrategy strategy, uint32 *buf_state)
 		strategy->current = 0;
 
 	/*
-	 * If the slot hasn't been filled yet, tell the caller to allocate a new
-	 * buffer with the normal allocation strategy.  He will then fill this
-	 * slot by calling AddBufferToRing with the new buffer.
+	 * If the slot hasn't been filled yet or the buffer in the slot has been
+	 * invalidated when buffer pool was shrunk, tell the caller to allocate a new
+	 * buffer with the normal allocation strategy.  He will then fill this slot
+	 * by calling AddBufferToRing with the new buffer.
 	 */
 	bufnum = strategy->buffers[strategy->current];
-	if (bufnum == InvalidBuffer)
+	if (bufnum == InvalidBuffer || bufnum > NBuffers)
 		return NULL;
 
 	/*
-- 
2.49.0


--bwrlgp6w2ubxykjq--





^ permalink  raw  reply  [nested|flat] 107+ messages in thread

* [PATCH v5 10/10] Additional validation for buffer in the ring
@ 2025-06-11 12:45 Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
  0 siblings, 0 replies; 107+ messages in thread

From: Ashutosh Bapat @ 2025-06-11 12:45 UTC (permalink / raw)

If the buffer pool has been shrunk, the buffers in the buffer list may
not be valid anymore. Modify GetBufferFromRing to check if the buffer is
still valid before using it. This makes GetBufferFromRing() a bit more
expensive because of additional boolean condition. That may not be
expensive enough to affect query performance. The alternative to that is
more complex as explained below.

The strategy object is created in CurrentMemoryContext and is not
available in any global structure thus accessible when processing buffer
resizing barriers. We may modify GetAccessStrategy() to register
strategy in a global linked list and then arrange to deregister it once
it's no more in use. Looking at the places which use
GetAccessStrategy(), fixing all those may be some work.

Ashutosh Bapat
---
 src/backend/storage/buffer/freelist.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/src/backend/storage/buffer/freelist.c b/src/backend/storage/buffer/freelist.c
index 41641bb3ae6..74d070733a4 100644
--- a/src/backend/storage/buffer/freelist.c
+++ b/src/backend/storage/buffer/freelist.c
@@ -948,12 +948,13 @@ GetBufferFromRing(BufferAccessStrategy strategy, uint32 *buf_state)
 		strategy->current = 0;
 
 	/*
-	 * If the slot hasn't been filled yet, tell the caller to allocate a new
-	 * buffer with the normal allocation strategy.  He will then fill this
-	 * slot by calling AddBufferToRing with the new buffer.
+	 * If the slot hasn't been filled yet or the buffer in the slot has been
+	 * invalidated when buffer pool was shrunk, tell the caller to allocate a new
+	 * buffer with the normal allocation strategy.  He will then fill this slot
+	 * by calling AddBufferToRing with the new buffer.
 	 */
 	bufnum = strategy->buffers[strategy->current];
-	if (bufnum == InvalidBuffer)
+	if (bufnum == InvalidBuffer || bufnum > NBuffers)
 		return NULL;
 
 	/*
-- 
2.49.0


--bwrlgp6w2ubxykjq--





^ permalink  raw  reply  [nested|flat] 107+ messages in thread

* [PATCH v12a 3/3] ci: macports improvements
@ 2026-06-04 14:17 Andres Freund <andres@anarazel.de>
  0 siblings, 0 replies; 107+ messages in thread

From: Andres Freund @ 2026-06-04 14:17 UTC (permalink / raw)

I realized two things:

1) We should save the macports cache before building & running tests, we don't
   want to again start from scratch if the task failed or was cancelled

2) We should use a partial cache match, as it's much faster to start from
   that, than from scratch.

This requires some additional complexity, we now need an explicit restore step
and need to check if the install step succeeded. But it's a very substantial
improvement in runtime, so it's worthwhile.
---
 .github/workflows/pg-ci.yml | 24 +++++++++++++++++++++---
 1 file changed, 21 insertions(+), 3 deletions(-)

diff --git a/.github/workflows/pg-ci.yml b/.github/workflows/pg-ci.yml
index dea8d95d729..dd4ff4c91d3 100644
--- a/.github/workflows/pg-ci.yml
+++ b/.github/workflows/pg-ci.yml
@@ -690,18 +690,23 @@ jobs:
           sudo sysctl kern.corefile="$HOME/cores/core.%P"
 
       - name: "Macports: Compute cache key"
-        id: mpkey
+        id: mp-key
         run: |
           macos_major=$(sw_vers -productVersion | sed 's/\..*//')
           pkglist_hash=$(printf '%s' "$MACOS_PACKAGE_LIST" | md5 -q)
           script_hash=$(md5 -q src/tools/ci/ci_macports_packages.sh)
           echo "key=macports-${macos_major}-${pkglist_hash}-${script_hash}" >> "$GITHUB_OUTPUT"
+          # It's faster to start with a partial cache for the same macos
+          # version than from scratch
+          echo "restore-key=macports-${macos_major}-" >> "$GITHUB_OUTPUT"
 
       - name: "MacPorts: Restore cache"
-        uses: actions/cache@v5
+        id: mp-restore
+        uses: actions/cache/restore@v5
         with:
           path: ${{ env.MACPORTS_CACHE }}
-          key: ${{ steps.mpkey.outputs.key }}
+          key: ${{ steps.mp-key.outputs.key }}
+          restore-keys: ${{ steps.mp-key.outputs.restore-key }}
 
       # Use MacPorts, even though Homebrew is installed. The installation
       # of the additional packages we need would take quite a while with
@@ -714,6 +719,7 @@ jobs:
       # actually p5.34-io-tty. Using the unversioned name works, but
       # updates MacPorts every time.
       - name: "MacPorts: Install dependencies"
+        id: mp-install
         env:
           # Pass token so the script's GitHub API call to list MacPorts
           # releases isn't subject to the 60/h/IP unauthenticated rate
@@ -727,6 +733,18 @@ jobs:
           echo /opt/local/sbin >> "$GITHUB_PATH"
           echo /opt/local/bin >> "$GITHUB_PATH"
 
+      # Save macports before running build / tests, creating macports can be
+      # quite slow, so we don't want to start from scratch in the next run.
+      - name: "MacPorts: Save cache"
+        uses: actions/cache/save@v5
+        # Don't save cache if we had an exact match
+        if: |
+          steps.mp-install.conclusion == 'success' &&
+          steps.mp-restore.outputs.cache-hit != 'true'
+        with:
+          path: ${{ env.MACPORTS_CACHE }}
+          key: ${{ steps.mp-key.outputs.key }}
+
       - name: Configure
         env:
           PKG_CONFIG_PATH: /opt/local/lib/pkgconfig/
-- 
2.54.0.380.gc69baaf57b


--ijwec7zgt2lxep65--





^ permalink  raw  reply  [nested|flat] 107+ messages in thread


end of thread, other threads:[~2026-06-04 14:17 UTC | newest]

Thread overview: 107+ messages (download: mbox mbox.gz follow: Atom feed)
-- links below jump to the message on this page --
2025-06-11 12:45 [PATCH v5 10/10] Additional validation for buffer in the ring Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
2025-06-11 12:45 [PATCH v5 10/10] Additional validation for buffer in the ring Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
2025-06-11 12:45 [PATCH v5 10/10] Additional validation for buffer in the ring Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
2025-06-11 12:45 [PATCH v5 10/10] Additional validation for buffer in the ring Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
2025-06-11 12:45 [PATCH v5 10/10] Additional validation for buffer in the ring Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
2025-06-11 12:45 [PATCH v5 10/10] Additional validation for buffer in the ring Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
2025-06-11 12:45 [PATCH v5 10/10] Additional validation for buffer in the ring Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
2025-06-11 12:45 [PATCH v5 10/10] Additional validation for buffer in the ring Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
2025-06-11 12:45 [PATCH v5 10/10] Additional validation for buffer in the ring Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
2025-06-11 12:45 [PATCH v5 10/10] Additional validation for buffer in the ring Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
2025-06-11 12:45 [PATCH v5 10/10] Additional validation for buffer in the ring Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
2025-06-11 12:45 [PATCH v5 10/10] Additional validation for buffer in the ring Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
2025-06-11 12:45 [PATCH v5 10/10] Additional validation for buffer in the ring Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
2025-06-11 12:45 [PATCH v5 10/10] Additional validation for buffer in the ring Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
2025-06-11 12:45 [PATCH v5 10/10] Additional validation for buffer in the ring Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
2025-06-11 12:45 [PATCH v5 10/10] Additional validation for buffer in the ring Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
2025-06-11 12:45 [PATCH v5 10/10] Additional validation for buffer in the ring Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
2025-06-11 12:45 [PATCH v5 10/10] Additional validation for buffer in the ring Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
2025-06-11 12:45 [PATCH v5 10/10] Additional validation for buffer in the ring Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
2025-06-11 12:45 [PATCH v5 10/10] Additional validation for buffer in the ring Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
2025-06-11 12:45 [PATCH v5 10/10] Additional validation for buffer in the ring Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
2025-06-11 12:45 [PATCH v5 10/10] Additional validation for buffer in the ring Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
2025-06-11 12:45 [PATCH v5 10/10] Additional validation for buffer in the ring Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
2025-06-11 12:45 [PATCH v5 10/10] Additional validation for buffer in the ring Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
2025-06-11 12:45 [PATCH v5 10/10] Additional validation for buffer in the ring Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
2025-06-11 12:45 [PATCH v5 10/10] Additional validation for buffer in the ring Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
2025-06-11 12:45 [PATCH v5 10/10] Additional validation for buffer in the ring Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
2025-06-11 12:45 [PATCH v5 10/10] Additional validation for buffer in the ring Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
2025-06-11 12:45 [PATCH v5 10/10] Additional validation for buffer in the ring Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
2025-06-11 12:45 [PATCH v5 10/10] Additional validation for buffer in the ring Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
2025-06-11 12:45 [PATCH v5 10/10] Additional validation for buffer in the ring Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
2025-06-11 12:45 [PATCH v5 10/10] Additional validation for buffer in the ring Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
2025-06-11 12:45 [PATCH v5 10/10] Additional validation for buffer in the ring Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
2025-06-11 12:45 [PATCH v5 10/10] Additional validation for buffer in the ring Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
2025-06-11 12:45 [PATCH v5 10/10] Additional validation for buffer in the ring Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
2025-06-11 12:45 [PATCH v5 10/10] Additional validation for buffer in the ring Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
2025-06-11 12:45 [PATCH v5 10/10] Additional validation for buffer in the ring Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
2025-06-11 12:45 [PATCH v5 10/10] Additional validation for buffer in the ring Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
2025-06-11 12:45 [PATCH v5 10/10] Additional validation for buffer in the ring Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
2025-06-11 12:45 [PATCH v5 10/10] Additional validation for buffer in the ring Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
2025-06-11 12:45 [PATCH v5 10/10] Additional validation for buffer in the ring Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
2025-06-11 12:45 [PATCH v5 10/10] Additional validation for buffer in the ring Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
2025-06-11 12:45 [PATCH v5 10/10] Additional validation for buffer in the ring Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
2025-06-11 12:45 [PATCH v5 10/10] Additional validation for buffer in the ring Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
2025-06-11 12:45 [PATCH v5 10/10] Additional validation for buffer in the ring Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
2025-06-11 12:45 [PATCH v5 10/10] Additional validation for buffer in the ring Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
2025-06-11 12:45 [PATCH v5 10/10] Additional validation for buffer in the ring Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
2025-06-11 12:45 [PATCH v5 10/10] Additional validation for buffer in the ring Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
2025-06-11 12:45 [PATCH v5 10/10] Additional validation for buffer in the ring Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
2025-06-11 12:45 [PATCH v5 10/10] Additional validation for buffer in the ring Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
2025-06-11 12:45 [PATCH v5 10/10] Additional validation for buffer in the ring Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
2025-06-11 12:45 [PATCH v5 10/10] Additional validation for buffer in the ring Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
2025-06-11 12:45 [PATCH v5 10/10] Additional validation for buffer in the ring Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
2025-06-11 12:45 [PATCH v5 10/10] Additional validation for buffer in the ring Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
2025-06-11 12:45 [PATCH v5 10/10] Additional validation for buffer in the ring Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
2025-06-11 12:45 [PATCH v5 10/10] Additional validation for buffer in the ring Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
2025-06-11 12:45 [PATCH v5 10/10] Additional validation for buffer in the ring Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
2025-06-11 12:45 [PATCH v5 10/10] Additional validation for buffer in the ring Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
2025-06-11 12:45 [PATCH v5 10/10] Additional validation for buffer in the ring Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
2025-06-11 12:45 [PATCH v5 10/10] Additional validation for buffer in the ring Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
2025-06-11 12:45 [PATCH v5 10/10] Additional validation for buffer in the ring Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
2025-06-11 12:45 [PATCH v5 10/10] Additional validation for buffer in the ring Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
2025-06-11 12:45 [PATCH v5 10/10] Additional validation for buffer in the ring Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
2025-06-11 12:45 [PATCH v5 10/10] Additional validation for buffer in the ring Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
2025-06-11 12:45 [PATCH v5 10/10] Additional validation for buffer in the ring Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
2025-06-11 12:45 [PATCH v5 10/10] Additional validation for buffer in the ring Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
2025-06-11 12:45 [PATCH v5 10/10] Additional validation for buffer in the ring Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
2025-06-11 12:45 [PATCH v5 10/10] Additional validation for buffer in the ring Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
2025-06-11 12:45 [PATCH v5 10/10] Additional validation for buffer in the ring Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
2025-06-11 12:45 [PATCH v5 10/10] Additional validation for buffer in the ring Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
2025-06-11 12:45 [PATCH v5 10/10] Additional validation for buffer in the ring Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
2025-06-11 12:45 [PATCH v5 10/10] Additional validation for buffer in the ring Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
2025-06-11 12:45 [PATCH v5 10/10] Additional validation for buffer in the ring Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
2025-06-11 12:45 [PATCH v5 10/10] Additional validation for buffer in the ring Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
2025-06-11 12:45 [PATCH v5 10/10] Additional validation for buffer in the ring Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
2025-06-11 12:45 [PATCH v5 10/10] Additional validation for buffer in the ring Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
2025-06-11 12:45 [PATCH v5 10/10] Additional validation for buffer in the ring Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
2025-06-11 12:45 [PATCH v5 10/10] Additional validation for buffer in the ring Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
2025-06-11 12:45 [PATCH v5 10/10] Additional validation for buffer in the ring Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
2025-06-11 12:45 [PATCH v5 10/10] Additional validation for buffer in the ring Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
2025-06-11 12:45 [PATCH v5 10/10] Additional validation for buffer in the ring Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
2025-06-11 12:45 [PATCH v5 10/10] Additional validation for buffer in the ring Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
2025-06-11 12:45 [PATCH v5 10/10] Additional validation for buffer in the ring Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
2025-06-11 12:45 [PATCH v5 10/10] Additional validation for buffer in the ring Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
2025-06-11 12:45 [PATCH v5 10/10] Additional validation for buffer in the ring Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
2025-06-11 12:45 [PATCH v5 10/10] Additional validation for buffer in the ring Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
2025-06-11 12:45 [PATCH v5 10/10] Additional validation for buffer in the ring Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
2025-06-11 12:45 [PATCH v5 10/10] Additional validation for buffer in the ring Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
2025-06-11 12:45 [PATCH v5 10/10] Additional validation for buffer in the ring Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
2025-06-11 12:45 [PATCH v5 10/10] Additional validation for buffer in the ring Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
2025-06-11 12:45 [PATCH v5 10/10] Additional validation for buffer in the ring Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
2025-06-11 12:45 [PATCH v5 10/10] Additional validation for buffer in the ring Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
2025-06-11 12:45 [PATCH v5 10/10] Additional validation for buffer in the ring Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
2025-06-11 12:45 [PATCH v5 10/10] Additional validation for buffer in the ring Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
2025-06-11 12:45 [PATCH v5 10/10] Additional validation for buffer in the ring Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
2025-06-11 12:45 [PATCH v5 10/10] Additional validation for buffer in the ring Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
2025-06-11 12:45 [PATCH v5 10/10] Additional validation for buffer in the ring Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
2025-06-11 12:45 [PATCH v5 10/10] Additional validation for buffer in the ring Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
2025-06-11 12:45 [PATCH v5 10/10] Additional validation for buffer in the ring Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
2025-06-11 12:45 [PATCH v5 10/10] Additional validation for buffer in the ring Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
2025-06-11 12:45 [PATCH v5 10/10] Additional validation for buffer in the ring Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
2025-06-11 12:45 [PATCH v5 10/10] Additional validation for buffer in the ring Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
2025-06-11 12:45 [PATCH v5 10/10] Additional validation for buffer in the ring Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
2025-06-11 12:45 [PATCH v5 10/10] Additional validation for buffer in the ring Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
2025-06-11 12:45 [PATCH v5 10/10] Additional validation for buffer in the ring Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
2025-06-11 12:45 [PATCH v5 10/10] Additional validation for buffer in the ring Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
2026-06-04 14:17 [PATCH v12a 3/3] ci: macports improvements Andres Freund <andres@anarazel.de>

This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox