Skip to content

Commit d25fbf9

Browse files
committed
Fix two off-by-one errors in bufmgr.c.
In 4b4b680 I passed a buffer index number (starting from 0) instead of a proper Buffer id (which start from 1 for shared buffers) in two places. This wasn't noticed so far as one of those locations isn't compiled at all (PrintPinnedBufs) and the other one (InvalidBuffer) requires a unlikely, but possible, set of circumstances to trigger a symptom. To reduce the likelihood of such incidents a bit also convert existing open coded mappings from buffer descriptors to buffer ids with BufferDescriptorGetBuffer(). Author: Qingqing Zhou Reported-By: Qingqing Zhou Discussion: CAJjS0u2ai9ooUisKtkV8cuVUtEkMTsbK8c7juNAjv8K11zeCQg@mail.gmail.com Backpatch: 9.5 where the private ref count infrastructure was introduced
1 parent 8a0258c commit d25fbf9

File tree

1 file changed

+19
-17
lines changed

1 file changed

+19
-17
lines changed

src/backend/storage/buffer/bufmgr.c

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1273,7 +1273,7 @@ InvalidateBuffer(volatile BufferDesc *buf)
12731273
UnlockBufHdr(buf);
12741274
LWLockRelease(oldPartitionLock);
12751275
/* safety check: should definitely not be our *own* pin */
1276-
if (GetPrivateRefCount(buf->buf_id) > 0)
1276+
if (GetPrivateRefCount(BufferDescriptorGetBuffer(buf)) > 0)
12771277
elog(ERROR, "buffer is pinned in InvalidateBuffer");
12781278
WaitIO(buf);
12791279
goto retry;
@@ -1426,16 +1426,16 @@ ReleaseAndReadBuffer(Buffer buffer,
14261426
static bool
14271427
PinBuffer(volatile BufferDesc *buf, BufferAccessStrategy strategy)
14281428
{
1429-
int b = buf->buf_id;
1429+
Buffer b = BufferDescriptorGetBuffer(buf);
14301430
bool result;
14311431
PrivateRefCountEntry *ref;
14321432

1433-
ref = GetPrivateRefCountEntry(b + 1, true);
1433+
ref = GetPrivateRefCountEntry(b, true);
14341434

14351435
if (ref == NULL)
14361436
{
14371437
ReservePrivateRefCountEntry();
1438-
ref = NewPrivateRefCountEntry(b + 1);
1438+
ref = NewPrivateRefCountEntry(b);
14391439

14401440
LockBufHdr(buf);
14411441
buf->refcount++;
@@ -1460,8 +1460,7 @@ PinBuffer(volatile BufferDesc *buf, BufferAccessStrategy strategy)
14601460

14611461
ref->refcount++;
14621462
Assert(ref->refcount > 0);
1463-
ResourceOwnerRememberBuffer(CurrentResourceOwner,
1464-
BufferDescriptorGetBuffer(buf));
1463+
ResourceOwnerRememberBuffer(CurrentResourceOwner, b);
14651464
return result;
14661465
}
14671466

@@ -1489,23 +1488,24 @@ PinBuffer(volatile BufferDesc *buf, BufferAccessStrategy strategy)
14891488
static void
14901489
PinBuffer_Locked(volatile BufferDesc *buf)
14911490
{
1492-
int b = buf->buf_id;
1491+
Buffer b;
14931492
PrivateRefCountEntry *ref;
14941493

14951494
/*
14961495
* As explained, We don't expect any preexisting pins. That allows us to
14971496
* manipulate the PrivateRefCount after releasing the spinlock
14981497
*/
1499-
Assert(GetPrivateRefCountEntry(b + 1, false) == NULL);
1498+
Assert(GetPrivateRefCountEntry(BufferDescriptorGetBuffer(buf), false) == NULL);
15001499

15011500
buf->refcount++;
15021501
UnlockBufHdr(buf);
15031502

1504-
ref = NewPrivateRefCountEntry(b + 1);
1503+
b = BufferDescriptorGetBuffer(buf);
1504+
1505+
ref = NewPrivateRefCountEntry(b);
15051506
ref->refcount++;
15061507

1507-
ResourceOwnerRememberBuffer(CurrentResourceOwner,
1508-
BufferDescriptorGetBuffer(buf));
1508+
ResourceOwnerRememberBuffer(CurrentResourceOwner, b);
15091509
}
15101510

15111511
/*
@@ -1520,14 +1520,14 @@ static void
15201520
UnpinBuffer(volatile BufferDesc *buf, bool fixOwner)
15211521
{
15221522
PrivateRefCountEntry *ref;
1523+
Buffer b = BufferDescriptorGetBuffer(buf);
15231524

15241525
/* not moving as we're likely deleting it soon anyway */
1525-
ref = GetPrivateRefCountEntry(buf->buf_id + 1, false);
1526+
ref = GetPrivateRefCountEntry(b, false);
15261527
Assert(ref != NULL);
15271528

15281529
if (fixOwner)
1529-
ResourceOwnerForgetBuffer(CurrentResourceOwner,
1530-
BufferDescriptorGetBuffer(buf));
1530+
ResourceOwnerForgetBuffer(CurrentResourceOwner, b);
15311531

15321532
Assert(ref->refcount > 0);
15331533
ref->refcount--;
@@ -2739,6 +2739,7 @@ PrintBufferDescs(void)
27392739
for (i = 0; i < NBuffers; ++i)
27402740
{
27412741
volatile BufferDesc *buf = GetBufferDescriptor(i);
2742+
Buffer b = BufferDescriptorGetBuffer(buf);
27422743

27432744
/* theoretically we should lock the bufhdr here */
27442745
elog(LOG,
@@ -2747,7 +2748,7 @@ PrintBufferDescs(void)
27472748
i, buf->freeNext,
27482749
relpathbackend(buf->tag.rnode, InvalidBackendId, buf->tag.forkNum),
27492750
buf->tag.blockNum, buf->flags,
2750-
buf->refcount, GetPrivateRefCount(i));
2751+
buf->refcount, GetPrivateRefCount(b));
27512752
}
27522753
}
27532754
#endif
@@ -2761,8 +2762,9 @@ PrintPinnedBufs(void)
27612762
for (i = 0; i < NBuffers; ++i)
27622763
{
27632764
volatile BufferDesc *buf = GetBufferDescriptor(i);
2765+
Buffer b = BufferDescriptorGetBuffer(buf);
27642766

2765-
if (GetPrivateRefCount(i + 1) > 0)
2767+
if (GetPrivateRefCount(b) > 0)
27662768
{
27672769
/* theoretically we should lock the bufhdr here */
27682770
elog(LOG,
@@ -2771,7 +2773,7 @@ PrintPinnedBufs(void)
27712773
i, buf->freeNext,
27722774
relpathperm(buf->tag.rnode, buf->tag.forkNum),
27732775
buf->tag.blockNum, buf->flags,
2774-
buf->refcount, GetPrivateRefCount(i + 1));
2776+
buf->refcount, GetPrivateRefCount(b));
27752777
}
27762778
}
27772779
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy