diff options
-rw-r--r-- | src/backend/storage/buffer/bufmgr.c | 32 | ||||
-rw-r--r-- | src/backend/storage/buffer/localbuf.c | 29 | ||||
-rw-r--r-- | src/include/storage/buf_internals.h | 2 |
3 files changed, 37 insertions, 26 deletions
diff --git a/src/backend/storage/buffer/bufmgr.c b/src/backend/storage/buffer/bufmgr.c index 8243f4b2445..a716074467f 100644 --- a/src/backend/storage/buffer/bufmgr.c +++ b/src/backend/storage/buffer/bufmgr.c @@ -1072,19 +1072,11 @@ ZeroAndLockBuffer(Buffer buffer, ReadBufferMode mode, bool already_valid) if (!isLocalBuf) LWLockAcquire(BufferDescriptorGetContentLock(bufHdr), LW_EXCLUSIVE); + /* Set BM_VALID, terminate IO, and wake up any waiters */ if (isLocalBuf) - { - /* Only need to adjust flags */ - uint32 buf_state = pg_atomic_read_u32(&bufHdr->state); - - buf_state |= BM_VALID; - pg_atomic_unlocked_write_u32(&bufHdr->state, buf_state); - } + TerminateLocalBufferIO(bufHdr, false, BM_VALID); else - { - /* Set BM_VALID, terminate IO, and wake up any waiters */ TerminateBufferIO(bufHdr, false, BM_VALID, true); - } } else if (!isLocalBuf) { @@ -1554,19 +1546,11 @@ WaitReadBuffers(ReadBuffersOperation *operation) relpath(operation->smgr->smgr_rlocator, forknum).str))); } - /* Terminate I/O and set BM_VALID. */ + /* Set BM_VALID, terminate IO, and wake up any waiters */ if (persistence == RELPERSISTENCE_TEMP) - { - uint32 buf_state = pg_atomic_read_u32(&bufHdr->state); - - buf_state |= BM_VALID; - pg_atomic_unlocked_write_u32(&bufHdr->state, buf_state); - } + TerminateLocalBufferIO(bufHdr, false, BM_VALID); else - { - /* Set BM_VALID, terminate IO, and wake up any waiters */ TerminateBufferIO(bufHdr, false, BM_VALID, true); - } /* Report I/Os as completing individually. */ TRACE_POSTGRESQL_BUFFER_READ_DONE(forknum, io_first_block + j, @@ -4501,8 +4485,7 @@ FlushRelationBuffers(Relation rel) IOCONTEXT_NORMAL, IOOP_WRITE, io_start, 1, BLCKSZ); - buf_state &= ~(BM_DIRTY | BM_JUST_DIRTIED); - pg_atomic_unlocked_write_u32(&bufHdr->state, buf_state); + TerminateLocalBufferIO(bufHdr, true, 0); pgBufferUsage.local_blks_written++; @@ -5589,8 +5572,11 @@ TerminateBufferIO(BufferDesc *buf, bool clear_dirty, uint32 set_flag_bits, buf_state = LockBufHdr(buf); Assert(buf_state & BM_IO_IN_PROGRESS); + buf_state &= ~BM_IO_IN_PROGRESS; + + /* Clear earlier errors, if this IO failed, it'll be marked again */ + buf_state &= ~BM_IO_ERROR; - buf_state &= ~(BM_IO_IN_PROGRESS | BM_IO_ERROR); if (clear_dirty && !(buf_state & BM_JUST_DIRTIED)) buf_state &= ~(BM_DIRTY | BM_CHECKPOINT_NEEDED); diff --git a/src/backend/storage/buffer/localbuf.c b/src/backend/storage/buffer/localbuf.c index 5331091132d..86b1c4c7c68 100644 --- a/src/backend/storage/buffer/localbuf.c +++ b/src/backend/storage/buffer/localbuf.c @@ -235,7 +235,6 @@ GetLocalVictimBuffer(void) */ if (pg_atomic_read_u32(&bufHdr->state) & BM_DIRTY) { - uint32 buf_state = pg_atomic_read_u32(&bufHdr->state); instr_time io_start; SMgrRelation oreln; Page localpage = (char *) LocalBufHdrGetBlock(bufHdr); @@ -259,8 +258,7 @@ GetLocalVictimBuffer(void) IOOP_WRITE, io_start, 1, BLCKSZ); /* Mark not-dirty now in case we error out below */ - buf_state &= ~BM_DIRTY; - pg_atomic_unlocked_write_u32(&bufHdr->state, buf_state); + TerminateLocalBufferIO(bufHdr, true, 0); pgBufferUsage.local_blks_written++; } @@ -484,6 +482,31 @@ MarkLocalBufferDirty(Buffer buffer) } /* + * Like TerminateBufferIO, but for local buffers + */ +void +TerminateLocalBufferIO(BufferDesc *bufHdr, bool clear_dirty, uint32 set_flag_bits) +{ + /* Only need to adjust flags */ + uint32 buf_state = pg_atomic_read_u32(&bufHdr->state); + + /* BM_IO_IN_PROGRESS isn't currently used for local buffers */ + + /* Clear earlier errors, if this IO failed, it'll be marked again */ + buf_state &= ~BM_IO_ERROR; + + if (clear_dirty) + buf_state &= ~BM_DIRTY; + + buf_state |= set_flag_bits; + pg_atomic_unlocked_write_u32(&bufHdr->state, buf_state); + + /* local buffers don't track IO using resowners */ + + /* local buffers don't use the IO CV, as no other process can see buffer */ +} + +/* * InvalidateLocalBuffer -- mark a local buffer invalid. * * If check_unreferenced is true, error out if the buffer is still diff --git a/src/include/storage/buf_internals.h b/src/include/storage/buf_internals.h index 8b32fb108b0..4611a60d3e0 100644 --- a/src/include/storage/buf_internals.h +++ b/src/include/storage/buf_internals.h @@ -471,6 +471,8 @@ extern BlockNumber ExtendBufferedRelLocal(BufferManagerRelation bmr, Buffer *buffers, uint32 *extended_by); extern void MarkLocalBufferDirty(Buffer buffer); +extern void TerminateLocalBufferIO(BufferDesc *bufHdr, bool clear_dirty, + uint32 set_flag_bits); extern void DropRelationLocalBuffers(RelFileLocator rlocator, ForkNumber forkNum, BlockNumber firstDelBlock); |