/* * Read a visibility map page. * * If the page doesn't exist, InvalidBuffer is returned, or if 'extend' is * true, the visibility map file is extended. */ static Buffer vm_readbuf(Relation rel, BlockNumber blkno, bool extend) { Buffer buf; /* * We might not have opened the relation at the smgr level yet, or we * might have been forced to close it by a sinval message. The code below * won't necessarily notice relation extension immediately when extend = * false, so we rely on sinval messages to ensure that our ideas about the * size of the map aren't too far out of date. */ RelationOpenSmgr(rel); /* * If we haven't cached the size of the visibility map fork yet, check it * first. */ if (rel->rd_smgr->smgr_vm_nblocks == InvalidBlockNumber) { if (smgrexists(rel->rd_smgr, VISIBILITYMAP_FORKNUM)) rel->rd_smgr->smgr_vm_nblocks = smgrnblocks(rel->rd_smgr, VISIBILITYMAP_FORKNUM); else rel->rd_smgr->smgr_vm_nblocks = 0; } /* Handle requests beyond EOF */ if (blkno >= rel->rd_smgr->smgr_vm_nblocks) { if (extend) vm_extend(rel, blkno + 1); else return InvalidBuffer; } /* * Use ZERO_ON_ERROR mode, and initialize the page if necessary. It's * always safe to clear bits, so it's better to clear corrupt pages than * error out. */ buf = ReadBufferExtended(rel, VISIBILITYMAP_FORKNUM, blkno, RBM_ZERO_ON_ERROR, NULL); if (PageIsNew(BufferGetPage(buf))) PageInit(BufferGetPage(buf), BLCKSZ, 0); return buf; }
/* * Read a visibility map page. * * If the page doesn't exist, InvalidBuffer is returned, or if 'extend' is * true, the visibility map file is extended. */ static Buffer vm_readbuf(Relation rel, BlockNumber blkno, bool extend) { Buffer buf; RelationOpenSmgr(rel); /* * If we haven't cached the size of the visibility map fork yet, check it * first. Also recheck if the requested block seems to be past end, since * our cached value might be stale. (We send smgr inval messages on * truncation, but not on extension.) */ if (rel->rd_smgr->smgr_vm_nblocks == InvalidBlockNumber || blkno >= rel->rd_smgr->smgr_vm_nblocks) { if (smgrexists(rel->rd_smgr, VISIBILITYMAP_FORKNUM)) rel->rd_smgr->smgr_vm_nblocks = smgrnblocks(rel->rd_smgr, VISIBILITYMAP_FORKNUM); else rel->rd_smgr->smgr_vm_nblocks = 0; } /* Handle requests beyond EOF */ if (blkno >= rel->rd_smgr->smgr_vm_nblocks) { if (extend) vm_extend(rel, blkno + 1); else return InvalidBuffer; } /* * Use ZERO_ON_ERROR mode, and initialize the page if necessary. It's * always safe to clear bits, so it's better to clear corrupt pages than * error out. */ buf = ReadBufferExtended(rel, VISIBILITYMAP_FORKNUM, blkno, RBM_ZERO_ON_ERROR, NULL); if (PageIsNew(BufferGetPage(buf))) PageInit(BufferGetPage(buf), BLCKSZ, 0); return buf; }
/* * Read a visibility map page. * * If the page doesn't exist, InvalidBuffer is returned, or if 'extend' is * true, the visibility map file is extended. */ static Buffer vm_readbuf(Relation rel, BlockNumber blkno, bool extend) { Buffer buf; RelationOpenSmgr(rel); /* * The current size of the visibility map fork is kept in relcache, to * avoid reading beyond EOF. If we haven't cached the size of the map yet, * do that first. */ if (rel->rd_vm_nblocks == InvalidBlockNumber) { if (smgrexists(rel->rd_smgr, VISIBILITYMAP_FORKNUM)) rel->rd_vm_nblocks = smgrnblocks(rel->rd_smgr, VISIBILITYMAP_FORKNUM); else rel->rd_vm_nblocks = 0; } /* Handle requests beyond EOF */ if (blkno >= rel->rd_vm_nblocks) { if (extend) vm_extend(rel, blkno + 1); else return InvalidBuffer; } /* * Use ZERO_ON_ERROR mode, and initialize the page if necessary. It's * always safe to clear bits, so it's better to clear corrupt pages than * error out. */ buf = ReadBufferExtended(rel, VISIBILITYMAP_FORKNUM, blkno, RBM_ZERO_ON_ERROR, NULL); if (PageIsNew(BufferGetPage(buf))) PageInit(BufferGetPage(buf), BLCKSZ, 0); return buf; }