*** a/src/backend/access/transam/clog.c --- b/src/backend/access/transam/clog.c *************** *** 445,451 **** BootStrapCLOG(void) slotno = ZeroCLOGPage(0, false); /* Make sure it's written out */ ! SimpleLruWritePage(ClogCtl, slotno, NULL); Assert(!ClogCtl->shared->page_dirty[slotno]); LWLockRelease(CLogControlLock); --- 445,451 ---- slotno = ZeroCLOGPage(0, false); /* Make sure it's written out */ ! SimpleLruWritePage(ClogCtl, slotno); Assert(!ClogCtl->shared->page_dirty[slotno]); LWLockRelease(CLogControlLock); *************** *** 698,704 **** clog_redo(XLogRecPtr lsn, XLogRecord *record) LWLockAcquire(CLogControlLock, LW_EXCLUSIVE); slotno = ZeroCLOGPage(pageno, false); ! SimpleLruWritePage(ClogCtl, slotno, NULL); Assert(!ClogCtl->shared->page_dirty[slotno]); LWLockRelease(CLogControlLock); --- 698,704 ---- LWLockAcquire(CLogControlLock, LW_EXCLUSIVE); slotno = ZeroCLOGPage(pageno, false); ! SimpleLruWritePage(ClogCtl, slotno); Assert(!ClogCtl->shared->page_dirty[slotno]); LWLockRelease(CLogControlLock); *** a/src/backend/access/transam/multixact.c --- b/src/backend/access/transam/multixact.c *************** *** 1454,1460 **** BootStrapMultiXact(void) slotno = ZeroMultiXactOffsetPage(0, false); /* Make sure it's written out */ ! SimpleLruWritePage(MultiXactOffsetCtl, slotno, NULL); Assert(!MultiXactOffsetCtl->shared->page_dirty[slotno]); LWLockRelease(MultiXactOffsetControlLock); --- 1454,1460 ---- slotno = ZeroMultiXactOffsetPage(0, false); /* Make sure it's written out */ ! SimpleLruWritePage(MultiXactOffsetCtl, slotno); Assert(!MultiXactOffsetCtl->shared->page_dirty[slotno]); LWLockRelease(MultiXactOffsetControlLock); *************** *** 1465,1471 **** BootStrapMultiXact(void) slotno = ZeroMultiXactMemberPage(0, false); /* Make sure it's written out */ ! SimpleLruWritePage(MultiXactMemberCtl, slotno, NULL); Assert(!MultiXactMemberCtl->shared->page_dirty[slotno]); LWLockRelease(MultiXactMemberControlLock); --- 1465,1471 ---- slotno = ZeroMultiXactMemberPage(0, false); /* Make sure it's written out */ ! SimpleLruWritePage(MultiXactMemberCtl, slotno); Assert(!MultiXactMemberCtl->shared->page_dirty[slotno]); LWLockRelease(MultiXactMemberControlLock); *************** *** 1986,1992 **** multixact_redo(XLogRecPtr lsn, XLogRecord *record) LWLockAcquire(MultiXactOffsetControlLock, LW_EXCLUSIVE); slotno = ZeroMultiXactOffsetPage(pageno, false); ! SimpleLruWritePage(MultiXactOffsetCtl, slotno, NULL); Assert(!MultiXactOffsetCtl->shared->page_dirty[slotno]); LWLockRelease(MultiXactOffsetControlLock); --- 1986,1992 ---- LWLockAcquire(MultiXactOffsetControlLock, LW_EXCLUSIVE); slotno = ZeroMultiXactOffsetPage(pageno, false); ! SimpleLruWritePage(MultiXactOffsetCtl, slotno); Assert(!MultiXactOffsetCtl->shared->page_dirty[slotno]); LWLockRelease(MultiXactOffsetControlLock); *************** *** 2001,2007 **** multixact_redo(XLogRecPtr lsn, XLogRecord *record) LWLockAcquire(MultiXactMemberControlLock, LW_EXCLUSIVE); slotno = ZeroMultiXactMemberPage(pageno, false); ! SimpleLruWritePage(MultiXactMemberCtl, slotno, NULL); Assert(!MultiXactMemberCtl->shared->page_dirty[slotno]); LWLockRelease(MultiXactMemberControlLock); --- 2001,2007 ---- LWLockAcquire(MultiXactMemberControlLock, LW_EXCLUSIVE); slotno = ZeroMultiXactMemberPage(pageno, false); ! SimpleLruWritePage(MultiXactMemberCtl, slotno); Assert(!MultiXactMemberCtl->shared->page_dirty[slotno]); LWLockRelease(MultiXactMemberControlLock); *** a/src/backend/access/transam/slru.c --- b/src/backend/access/transam/slru.c *************** *** 78,83 **** typedef struct SlruFlushData --- 78,85 ---- int segno[MAX_FLUSH_BUFFERS]; /* their log seg#s */ } SlruFlushData; + typedef struct SlruFlushData *SlruFlush; + /* * Macro to mark a buffer slot "most recently used". Note multiple evaluation * of arguments! *************** *** 123,128 **** static int slru_errno; --- 125,131 ---- static void SimpleLruZeroLSNs(SlruCtl ctl, int slotno); static void SimpleLruWaitIO(SlruCtl ctl, int slotno); + static void SlruInternalWritePage(SlruCtl ctl, int slotno, SlruFlush fdata); static bool SlruPhysicalReadPage(SlruCtl ctl, int pageno, int slotno); static bool SlruPhysicalWritePage(SlruCtl ctl, int pageno, int slotno, SlruFlush fdata); *************** *** 486,492 **** SimpleLruReadPage_ReadOnly(SlruCtl ctl, int pageno, TransactionId xid) * Control lock must be held at entry, and will be held at exit. */ void ! SimpleLruWritePage(SlruCtl ctl, int slotno, SlruFlush fdata) { SlruShared shared = ctl->shared; int pageno = shared->page_number[slotno]; --- 489,505 ---- * Control lock must be held at entry, and will be held at exit. */ void ! SimpleLruWritePage(SlruCtl ctl, int slotno) ! { ! SlruInternalWritePage(ctl, slotno, NULL); ! } ! ! /* ! * Page write for internal use, with option to specify a non-NULL SlruFlush ! * value. Currently a non-NULL value is only specified in SimpleLruFlush. ! */ ! static void ! SlruInternalWritePage(SlruCtl ctl, int slotno, SlruFlush fdata) { SlruShared shared = ctl->shared; int pageno = shared->page_number[slotno]; *************** *** 975,981 **** SlruSelectLRUPage(SlruCtl ctl, int pageno) * we wait for the existing I/O to complete. */ if (shared->page_status[bestslot] == SLRU_PAGE_VALID) ! SimpleLruWritePage(ctl, bestslot, NULL); else SimpleLruWaitIO(ctl, bestslot); --- 988,994 ---- * we wait for the existing I/O to complete. */ if (shared->page_status[bestslot] == SLRU_PAGE_VALID) ! SlruInternalWritePage(ctl, bestslot, NULL); else SimpleLruWaitIO(ctl, bestslot); *************** *** 1009,1015 **** SimpleLruFlush(SlruCtl ctl, bool checkpoint) for (slotno = 0; slotno < shared->num_slots; slotno++) { ! SimpleLruWritePage(ctl, slotno, &fdata); /* * When called during a checkpoint, we cannot assert that the slot is --- 1022,1028 ---- for (slotno = 0; slotno < shared->num_slots; slotno++) { ! SlruInternalWritePage(ctl, slotno, &fdata); /* * When called during a checkpoint, we cannot assert that the slot is *************** *** 1114,1120 **** restart:; * keep the logic the same as it was.) */ if (shared->page_status[slotno] == SLRU_PAGE_VALID) ! SimpleLruWritePage(ctl, slotno, NULL); else SimpleLruWaitIO(ctl, slotno); goto restart; --- 1127,1133 ---- * keep the logic the same as it was.) */ if (shared->page_status[slotno] == SLRU_PAGE_VALID) ! SlruInternalWritePage(ctl, slotno, NULL); else SimpleLruWaitIO(ctl, slotno); goto restart; *** a/src/backend/access/transam/subtrans.c --- b/src/backend/access/transam/subtrans.c *************** *** 205,211 **** BootStrapSUBTRANS(void) slotno = ZeroSUBTRANSPage(0); /* Make sure it's written out */ ! SimpleLruWritePage(SubTransCtl, slotno, NULL); Assert(!SubTransCtl->shared->page_dirty[slotno]); LWLockRelease(SubtransControlLock); --- 205,211 ---- slotno = ZeroSUBTRANSPage(0); /* Make sure it's written out */ ! SimpleLruWritePage(SubTransCtl, slotno); Assert(!SubTransCtl->shared->page_dirty[slotno]); LWLockRelease(SubtransControlLock); *** a/src/backend/commands/async.c --- b/src/backend/commands/async.c *************** *** 507,513 **** AsyncShmemInit(void) LWLockAcquire(AsyncCtlLock, LW_EXCLUSIVE); slotno = SimpleLruZeroPage(AsyncCtl, QUEUE_POS_PAGE(QUEUE_HEAD)); /* This write is just to verify that pg_notify/ is writable */ ! SimpleLruWritePage(AsyncCtl, slotno, NULL); LWLockRelease(AsyncCtlLock); } } --- 507,513 ---- LWLockAcquire(AsyncCtlLock, LW_EXCLUSIVE); slotno = SimpleLruZeroPage(AsyncCtl, QUEUE_POS_PAGE(QUEUE_HEAD)); /* This write is just to verify that pg_notify/ is writable */ ! SimpleLruWritePage(AsyncCtl, slotno); LWLockRelease(AsyncCtlLock); } } *** a/src/include/access/slru.h --- b/src/include/access/slru.h *************** *** 133,141 **** typedef struct SlruCtlData typedef SlruCtlData *SlruCtl; - /* Opaque struct known only in slru.c */ - typedef struct SlruFlushData *SlruFlush; - extern Size SimpleLruShmemSize(int nslots, int nlsns); extern void SimpleLruInit(SlruCtl ctl, const char *name, int nslots, int nlsns, --- 133,138 ---- *************** *** 145,151 **** extern int SimpleLruReadPage(SlruCtl ctl, int pageno, bool write_ok, TransactionId xid); extern int SimpleLruReadPage_ReadOnly(SlruCtl ctl, int pageno, TransactionId xid); ! extern void SimpleLruWritePage(SlruCtl ctl, int slotno, SlruFlush fdata); extern void SimpleLruFlush(SlruCtl ctl, bool checkpoint); extern void SimpleLruTruncate(SlruCtl ctl, int cutoffPage); extern bool SlruScanDirectory(SlruCtl ctl, int cutoffPage, bool doDeletions); --- 142,148 ---- TransactionId xid); extern int SimpleLruReadPage_ReadOnly(SlruCtl ctl, int pageno, TransactionId xid); ! extern void SimpleLruWritePage(SlruCtl ctl, int slotno); extern void SimpleLruFlush(SlruCtl ctl, bool checkpoint); extern void SimpleLruTruncate(SlruCtl ctl, int cutoffPage); extern bool SlruScanDirectory(SlruCtl ctl, int cutoffPage, bool doDeletions);