postgres.git / summary / log / commit / refs

commit    462a2f1f019fa16087fe2f59e96e339a703923b2
Author:   Heikki Linnakangas <heikki.linnakangas@iki.fi>
Date:     Wed May 13 06:44:43 2015 +0000
First released in: 9.0.20, 9.1.16, 9.2.11, 9.3.7, 9.4.2

    Fix RBM_ZERO_AND_LOCK mode to not acquire lock on local buffers.
    
    Commit 81c45081 introduced a new RBM_ZERO_AND_LOCK mode to ReadBuffer, which
    takes a lock on the buffer before zeroing it. However, you cannot take a
    lock on a local buffer, and you got a segfault instead. The version of that
    patch committed to master included a check for !isLocalBuf, and therefore
    didn't crash, but oddly I missed that in the back-patched versions. This
    patch adds that check to the back-branches too.
    
    RBM_ZERO_AND_LOCK mode is only used during WAL replay, and in hash indexes.
    WAL replay only deals with shared buffers, so the only way to trigger the
    bug is with a temporary hash index.
    
    Reported by Artem Ignatyev, analysis by Tom Lane.


src/backend/storage/buffer/bufmgr.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/backend/storage/buffer/bufmgr.c b/src/backend/storage/buffer/bufmgr.c index 2f753e52dbb..19ec7eb231e 100644 --- a/src/backend/storage/buffer/bufmgr.c +++ b/src/backend/storage/buffer/bufmgr.c @@ -515,7 +515,8 @@ ReadBuffer_common(SMgrRelation smgr, char relpersistence, ForkNumber forkNum, * (Note that we cannot use LockBuffer() of LockBufferForCleanup() here, * because they assert that the buffer is already valid.) */ - if (mode == RBM_ZERO_AND_LOCK || mode == RBM_ZERO_AND_CLEANUP_LOCK) + if ((mode == RBM_ZERO_AND_LOCK || mode == RBM_ZERO_AND_CLEANUP_LOCK) && + !isLocalBuf) LWLockAcquire(bufHdr->content_lock, LW_EXCLUSIVE); if (isLocalBuf) [parent: 4d3d9719d28f]