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)
    {
                                    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,
                                        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++;
 
    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);
 
 
     */
    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);
                                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++;
    }
    pg_atomic_unlocked_write_u32(&bufHdr->state, buf_state);
 }
 
+/*
+ * 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.
  *