diff --git a/contrib/amcheck/verify_gin.c b/contrib/amcheck/verify_gin.c index f7a15a21467..abfad07d5e4 100644 --- a/contrib/amcheck/verify_gin.c +++ b/contrib/amcheck/verify_gin.c @@ -368,8 +368,7 @@ gin_check_posting_tree_parent_keys_consistency(Relation rel, BlockNumber posting stack->next = ptr; } } - LockBuffer(buffer, GIN_UNLOCK); - ReleaseBuffer(buffer); + UnlockReleaseBuffer(buffer); /* Step to next item in the queue */ stack_next = stack->next; @@ -642,8 +641,7 @@ gin_check_parent_keys_consistency(Relation rel, prev_attnum = current_attnum; } - LockBuffer(buffer, GIN_UNLOCK); - ReleaseBuffer(buffer); + UnlockReleaseBuffer(buffer); /* Step to next item in the queue */ stack_next = stack->next; diff --git a/contrib/pageinspect/rawpage.c b/contrib/pageinspect/rawpage.c index 86fe245cac5..f3996dc39fc 100644 --- a/contrib/pageinspect/rawpage.c +++ b/contrib/pageinspect/rawpage.c @@ -193,8 +193,7 @@ get_raw_page_internal(text *relname, ForkNumber forknum, BlockNumber blkno) memcpy(raw_page_data, BufferGetPage(buf), BLCKSZ); - LockBuffer(buf, BUFFER_LOCK_UNLOCK); - ReleaseBuffer(buf); + UnlockReleaseBuffer(buf); relation_close(rel, AccessShareLock); diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c index 044f385e477..eb1f67f31cd 100644 --- a/src/backend/access/heap/heapam.c +++ b/src/backend/access/heap/heapam.c @@ -1697,8 +1697,7 @@ heap_fetch(Relation relation, offnum = ItemPointerGetOffsetNumber(tid); if (offnum < FirstOffsetNumber || offnum > PageGetMaxOffsetNumber(page)) { - LockBuffer(buffer, BUFFER_LOCK_UNLOCK); - ReleaseBuffer(buffer); + UnlockReleaseBuffer(buffer); *userbuf = InvalidBuffer; tuple->t_data = NULL; return false; @@ -1714,8 +1713,7 @@ heap_fetch(Relation relation, */ if (!ItemIdIsNormal(lp)) { - LockBuffer(buffer, BUFFER_LOCK_UNLOCK); - ReleaseBuffer(buffer); + UnlockReleaseBuffer(buffer); *userbuf = InvalidBuffer; tuple->t_data = NULL; return false; diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c index d26ceacd38c..1097f44a74e 100644 --- a/src/backend/access/heap/hio.c +++ b/src/backend/access/heap/hio.c @@ -711,14 +711,15 @@ loop: * unlock the two buffers in, so this can be slightly simpler than the * code above. */ - LockBuffer(buffer, BUFFER_LOCK_UNLOCK); if (otherBuffer == InvalidBuffer) - ReleaseBuffer(buffer); + UnlockReleaseBuffer(buffer); else if (otherBlock != targetBlock) { + UnlockReleaseBuffer(buffer); LockBuffer(otherBuffer, BUFFER_LOCK_UNLOCK); - ReleaseBuffer(buffer); } + else + LockBuffer(buffer, BUFFER_LOCK_UNLOCK); /* Is there an ongoing bulk extension? */ if (bistate && bistate->next_free != InvalidBlockNumber) diff --git a/src/backend/access/nbtree/nbtpage.c b/src/backend/access/nbtree/nbtpage.c index cc9c45dc40c..0547038616e 100644 --- a/src/backend/access/nbtree/nbtpage.c +++ b/src/backend/access/nbtree/nbtpage.c @@ -1011,24 +1011,47 @@ _bt_relandgetbuf(Relation rel, Buffer obuf, BlockNumber blkno, int access) Assert(BlockNumberIsValid(blkno)); if (BufferIsValid(obuf)) - _bt_unlockbuf(rel, obuf); - buf = ReleaseAndReadBuffer(obuf, rel, blkno); - _bt_lockbuf(rel, buf, access); + { + if (BufferGetBlockNumber(obuf) == blkno) + { + /* trade in old lock mode for new lock */ + _bt_unlockbuf(rel, obuf); + buf = obuf; + } + else + { + /* release lock and pin at once, that's a bit more efficient */ + _bt_relbuf(rel, obuf); + buf = ReadBuffer(rel, blkno); + } + } + else + buf = ReadBuffer(rel, blkno); + _bt_lockbuf(rel, buf, access); _bt_checkpage(rel, buf); + return buf; } /* * _bt_relbuf() -- release a locked buffer. * - * Lock and pin (refcount) are both dropped. + * Lock and pin (refcount) are both dropped. This is a bit more efficient than + * doing the two operations separately. */ void _bt_relbuf(Relation rel, Buffer buf) { - _bt_unlockbuf(rel, buf); - ReleaseBuffer(buf); + /* + * Buffer is pinned and locked, which means that it is expected to be + * defined and addressable. Check that proactively. + */ + VALGRIND_CHECK_MEM_IS_DEFINED(BufferGetPage(buf), BLCKSZ); + if (!RelationUsesLocalBuffers(rel)) + VALGRIND_MAKE_MEM_NOACCESS(BufferGetPage(buf), BLCKSZ); + + UnlockReleaseBuffer(buf); } /* diff --git a/src/backend/storage/buffer/bufmgr.c b/src/backend/storage/buffer/bufmgr.c index f4f07c9a1c0..8a8c4adb9e1 100644 --- a/src/backend/storage/buffer/bufmgr.c +++ b/src/backend/storage/buffer/bufmgr.c @@ -2561,8 +2561,7 @@ again: XLogNeedsFlush(BufferGetLSN(buf_hdr)) && StrategyRejectBuffer(strategy, buf_hdr, from_ring)) { - LockBuffer(buf, BUFFER_LOCK_UNLOCK); - UnpinBuffer(buf_hdr); + UnlockReleaseBuffer(buf); goto again; } diff --git a/src/backend/storage/freespace/freespace.c b/src/backend/storage/freespace/freespace.c index b9a8f368a63..40d67a96178 100644 --- a/src/backend/storage/freespace/freespace.c +++ b/src/backend/storage/freespace/freespace.c @@ -915,9 +915,8 @@ fsm_vacuum_page(Relation rel, FSMAddress addr, ((FSMPage) PageGetContents(page))->fp_next_slot = 0; BufferFinishSetHintBits(buf, false, false); } - LockBuffer(buf, BUFFER_LOCK_UNLOCK); - ReleaseBuffer(buf); + UnlockReleaseBuffer(buf); return max_avail; } diff --git a/src/test/modules/test_aio/test_aio.c b/src/test/modules/test_aio/test_aio.c index 2ae4a559fab..138e1259dfd 100644 --- a/src/test/modules/test_aio/test_aio.c +++ b/src/test/modules/test_aio/test_aio.c @@ -221,9 +221,7 @@ modify_rel_block(PG_FUNCTION_ARGS) */ memcpy(page, BufferGetPage(buf), BLCKSZ); - LockBuffer(buf, BUFFER_LOCK_UNLOCK); - - ReleaseBuffer(buf); + UnlockReleaseBuffer(buf); /* * Don't want to have a buffer in-memory that's marked valid where the @@ -496,8 +494,7 @@ invalidate_rel_block(PG_FUNCTION_ARGS) else FlushOneBuffer(buf); } - LockBuffer(buf, BUFFER_LOCK_UNLOCK); - ReleaseBuffer(buf); + UnlockReleaseBuffer(buf); if (BufferIsLocal(buf)) InvalidateLocalBuffer(GetLocalBufferDescriptor(-buf - 1), true);