aboutsummaryrefslogtreecommitdiff
path: root/src/backend/access
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2022-11-17 16:54:30 -0500
committerTom Lane <tgl@sss.pgh.pa.us>2022-11-17 16:54:30 -0500
commit32d5a4974c81aeaca7ffc025f0a5fda88b71cba6 (patch)
tree3f825c996774f05980874253ed9becb658a46bfe /src/backend/access
parentaaf28c90654425c2e94dc2c8b2d0d8d971483c7e (diff)
downloadpostgresql-32d5a4974c81aeaca7ffc025f0a5fda88b71cba6.tar.gz
postgresql-32d5a4974c81aeaca7ffc025f0a5fda88b71cba6.zip
Replace RelationOpenSmgr() with RelationGetSmgr().
This is a back-patch of the v15-era commit f10f0ae42 into older supported branches. The idea is to design out bugs in which an ill-timed relcache flush clears rel->rd_smgr partway through some code sequence that wasn't expecting that. We had another report today of a corner case that reliably crashes v14 under debug_discard_caches (nee CLOBBER_CACHE_ALWAYS), and therefore would crash once in a blue moon in the field. We're unlikely to get rid of all such code paths unless we adopt the more rigorous coding rules instituted by f10f0ae42. Therefore, even though this is a bit invasive, it's time to back-patch. Some comfort can be taken in the fact that f10f0ae42 has been in v15 for 16 months without problems. I left the RelationOpenSmgr macro present in the back branches, even though no core code should use it anymore, in order to not break third-party extensions in minor releases. Such extensions might opt to start using RelationGetSmgr instead, to reduce their code differential between v15 and earlier branches. This carries a hazard of failing to compile against headers from existing minor releases. However, once compiled the extension should work fine even with such releases, because RelationGetSmgr is a "static inline" function so it creates no link-time dependency. So depending on distribution practices, that might be an OK tradeoff. Per report from Spyridon Dimitrios Agathos. Original patch by Amul Sul. Discussion: https://postgr.es/m/CAFM5RaqdgyusQvmWkyPYaWMwoK5gigdtW-7HcgHgOeAw7mqJ_Q@mail.gmail.com Discussion: https://postgr.es/m/CANiYTQsU7yMFpQYnv=BrcRVqK_3U3mtAzAsJCaqtzsDHfsUbdQ@mail.gmail.com
Diffstat (limited to 'src/backend/access')
-rw-r--r--src/backend/access/gist/gistbuild.c19
-rw-r--r--src/backend/access/hash/hashpage.c4
-rw-r--r--src/backend/access/heap/heapam_handler.c7
-rw-r--r--src/backend/access/heap/rewriteheap.c15
-rw-r--r--src/backend/access/heap/visibilitymap.c53
-rw-r--r--src/backend/access/nbtree/nbtree.c6
-rw-r--r--src/backend/access/nbtree/nbtsort.c14
-rw-r--r--src/backend/access/spgist/spginsert.c14
-rw-r--r--src/backend/access/table/tableam.c7
9 files changed, 59 insertions, 80 deletions
diff --git a/src/backend/access/gist/gistbuild.c b/src/backend/access/gist/gistbuild.c
index ec28bfe89f0..0d2184f7309 100644
--- a/src/backend/access/gist/gistbuild.c
+++ b/src/backend/access/gist/gistbuild.c
@@ -409,8 +409,7 @@ gist_indexsortbuild(GISTBuildState *state)
* replaced with the real root page at the end.
*/
page = palloc0(BLCKSZ);
- RelationOpenSmgr(state->indexrel);
- smgrextend(state->indexrel->rd_smgr, MAIN_FORKNUM, GIST_ROOT_BLKNO,
+ smgrextend(RelationGetSmgr(state->indexrel), MAIN_FORKNUM, GIST_ROOT_BLKNO,
page, true);
state->pages_allocated++;
state->pages_written++;
@@ -450,10 +449,9 @@ gist_indexsortbuild(GISTBuildState *state)
gist_indexsortbuild_flush_ready_pages(state);
/* Write out the root */
- RelationOpenSmgr(state->indexrel);
PageSetLSN(pagestate->page, GistBuildLSN);
PageSetChecksumInplace(pagestate->page, GIST_ROOT_BLKNO);
- smgrwrite(state->indexrel->rd_smgr, MAIN_FORKNUM, GIST_ROOT_BLKNO,
+ smgrwrite(RelationGetSmgr(state->indexrel), MAIN_FORKNUM, GIST_ROOT_BLKNO,
pagestate->page, true);
if (RelationNeedsWAL(state->indexrel))
log_newpage(&state->indexrel->rd_node, MAIN_FORKNUM, GIST_ROOT_BLKNO,
@@ -472,10 +470,7 @@ gist_indexsortbuild(GISTBuildState *state)
* still not be on disk when the crash occurs.
*/
if (RelationNeedsWAL(state->indexrel))
- {
- RelationOpenSmgr(state->indexrel);
- smgrimmedsync(state->indexrel->rd_smgr, MAIN_FORKNUM);
- }
+ smgrimmedsync(RelationGetSmgr(state->indexrel), MAIN_FORKNUM);
}
/*
@@ -577,8 +572,6 @@ gist_indexsortbuild_flush_ready_pages(GISTBuildState *state)
if (state->ready_num_pages == 0)
return;
- RelationOpenSmgr(state->indexrel);
-
for (int i = 0; i < state->ready_num_pages; i++)
{
Page page = state->ready_pages[i];
@@ -590,7 +583,8 @@ gist_indexsortbuild_flush_ready_pages(GISTBuildState *state)
PageSetLSN(page, GistBuildLSN);
PageSetChecksumInplace(page, blkno);
- smgrextend(state->indexrel->rd_smgr, MAIN_FORKNUM, blkno, page, true);
+ smgrextend(RelationGetSmgr(state->indexrel), MAIN_FORKNUM, blkno, page,
+ true);
state->pages_written++;
}
@@ -875,7 +869,8 @@ gistBuildCallback(Relation index,
*/
if ((buildstate->buildMode == GIST_BUFFERING_AUTO &&
buildstate->indtuples % BUFFERING_MODE_SWITCH_CHECK_STEP == 0 &&
- effective_cache_size < smgrnblocks(index->rd_smgr, MAIN_FORKNUM)) ||
+ effective_cache_size < smgrnblocks(RelationGetSmgr(index),
+ MAIN_FORKNUM)) ||
(buildstate->buildMode == GIST_BUFFERING_STATS &&
buildstate->indtuples >= BUFFERING_MODE_TUPLE_SIZE_STATS_TARGET))
{
diff --git a/src/backend/access/hash/hashpage.c b/src/backend/access/hash/hashpage.c
index ae2f3741334..14bde24e4de 100644
--- a/src/backend/access/hash/hashpage.c
+++ b/src/backend/access/hash/hashpage.c
@@ -1028,9 +1028,9 @@ _hash_alloc_buckets(Relation rel, BlockNumber firstblock, uint32 nblocks)
zerobuf.data,
true);
- RelationOpenSmgr(rel);
PageSetChecksumInplace(page, lastblock);
- smgrextend(rel->rd_smgr, MAIN_FORKNUM, lastblock, zerobuf.data, false);
+ smgrextend(RelationGetSmgr(rel), MAIN_FORKNUM, lastblock, zerobuf.data,
+ false);
return true;
}
diff --git a/src/backend/access/heap/heapam_handler.c b/src/backend/access/heap/heapam_handler.c
index 66339392d75..a9d8f8474d0 100644
--- a/src/backend/access/heap/heapam_handler.c
+++ b/src/backend/access/heap/heapam_handler.c
@@ -628,7 +628,6 @@ heapam_relation_copy_data(Relation rel, const RelFileNode *newrnode)
SMgrRelation dstrel;
dstrel = smgropen(*newrnode, rel->rd_backend);
- RelationOpenSmgr(rel);
/*
* Since we copy the file directly without looking at the shared buffers,
@@ -648,14 +647,14 @@ heapam_relation_copy_data(Relation rel, const RelFileNode *newrnode)
RelationCreateStorage(*newrnode, rel->rd_rel->relpersistence);
/* copy main fork */
- RelationCopyStorage(rel->rd_smgr, dstrel, MAIN_FORKNUM,
+ RelationCopyStorage(RelationGetSmgr(rel), dstrel, MAIN_FORKNUM,
rel->rd_rel->relpersistence);
/* copy those extra forks that exist */
for (ForkNumber forkNum = MAIN_FORKNUM + 1;
forkNum <= MAX_FORKNUM; forkNum++)
{
- if (smgrexists(rel->rd_smgr, forkNum))
+ if (smgrexists(RelationGetSmgr(rel), forkNum))
{
smgrcreate(dstrel, forkNum, false);
@@ -667,7 +666,7 @@ heapam_relation_copy_data(Relation rel, const RelFileNode *newrnode)
(rel->rd_rel->relpersistence == RELPERSISTENCE_UNLOGGED &&
forkNum == INIT_FORKNUM))
log_smgrcreate(newrnode, forkNum);
- RelationCopyStorage(rel->rd_smgr, dstrel, forkNum,
+ RelationCopyStorage(RelationGetSmgr(rel), dstrel, forkNum,
rel->rd_rel->relpersistence);
}
}
diff --git a/src/backend/access/heap/rewriteheap.c b/src/backend/access/heap/rewriteheap.c
index 15bef9f7d30..2c159cf76a5 100644
--- a/src/backend/access/heap/rewriteheap.c
+++ b/src/backend/access/heap/rewriteheap.c
@@ -326,9 +326,8 @@ end_heap_rewrite(RewriteState state)
PageSetChecksumInplace(state->rs_buffer, state->rs_blockno);
- RelationOpenSmgr(state->rs_new_rel);
- smgrextend(state->rs_new_rel->rd_smgr, MAIN_FORKNUM, state->rs_blockno,
- (char *) state->rs_buffer, true);
+ smgrextend(RelationGetSmgr(state->rs_new_rel), MAIN_FORKNUM,
+ state->rs_blockno, (char *) state->rs_buffer, true);
}
/*
@@ -339,11 +338,7 @@ end_heap_rewrite(RewriteState state)
* wrote before the checkpoint.
*/
if (RelationNeedsWAL(state->rs_new_rel))
- {
- /* for an empty table, this could be first smgr access */
- RelationOpenSmgr(state->rs_new_rel);
- smgrimmedsync(state->rs_new_rel->rd_smgr, MAIN_FORKNUM);
- }
+ smgrimmedsync(RelationGetSmgr(state->rs_new_rel), MAIN_FORKNUM);
logical_end_heap_rewrite(state);
@@ -695,11 +690,9 @@ raw_heap_insert(RewriteState state, HeapTuple tup)
* need for smgr to schedule an fsync for this write; we'll do it
* ourselves in end_heap_rewrite.
*/
- RelationOpenSmgr(state->rs_new_rel);
-
PageSetChecksumInplace(page, state->rs_blockno);
- smgrextend(state->rs_new_rel->rd_smgr, MAIN_FORKNUM,
+ smgrextend(RelationGetSmgr(state->rs_new_rel), MAIN_FORKNUM,
state->rs_blockno, (char *) page, true);
state->rs_blockno++;
diff --git a/src/backend/access/heap/visibilitymap.c b/src/backend/access/heap/visibilitymap.c
index e198df65d82..4720b35ee5c 100644
--- a/src/backend/access/heap/visibilitymap.c
+++ b/src/backend/access/heap/visibilitymap.c
@@ -455,13 +455,11 @@ visibilitymap_prepare_truncate(Relation rel, BlockNumber nheapblocks)
elog(DEBUG1, "vm_truncate %s %d", RelationGetRelationName(rel), nheapblocks);
#endif
- RelationOpenSmgr(rel);
-
/*
* If no visibility map has been created yet for this relation, there's
* nothing to truncate.
*/
- if (!smgrexists(rel->rd_smgr, VISIBILITYMAP_FORKNUM))
+ if (!smgrexists(RelationGetSmgr(rel), VISIBILITYMAP_FORKNUM))
return InvalidBlockNumber;
/*
@@ -528,7 +526,7 @@ visibilitymap_prepare_truncate(Relation rel, BlockNumber nheapblocks)
else
newnblocks = truncBlock;
- if (smgrnblocks(rel->rd_smgr, VISIBILITYMAP_FORKNUM) <= newnblocks)
+ if (smgrnblocks(RelationGetSmgr(rel), VISIBILITYMAP_FORKNUM) <= newnblocks)
{
/* nothing to do, the file was already smaller than requested size */
return InvalidBlockNumber;
@@ -547,30 +545,29 @@ static Buffer
vm_readbuf(Relation rel, BlockNumber blkno, bool extend)
{
Buffer buf;
+ SMgrRelation reln;
/*
- * 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.
+ * Caution: re-using this smgr pointer could fail if the relcache entry
+ * gets closed. It's safe as long as we only do smgr-level operations
+ * between here and the last use of the pointer.
*/
- RelationOpenSmgr(rel);
+ reln = RelationGetSmgr(rel);
/*
* If we haven't cached the size of the visibility map fork yet, check it
* first.
*/
- if (rel->rd_smgr->smgr_cached_nblocks[VISIBILITYMAP_FORKNUM] == InvalidBlockNumber)
+ if (reln->smgr_cached_nblocks[VISIBILITYMAP_FORKNUM] == InvalidBlockNumber)
{
- if (smgrexists(rel->rd_smgr, VISIBILITYMAP_FORKNUM))
- smgrnblocks(rel->rd_smgr, VISIBILITYMAP_FORKNUM);
+ if (smgrexists(reln, VISIBILITYMAP_FORKNUM))
+ smgrnblocks(reln, VISIBILITYMAP_FORKNUM);
else
- rel->rd_smgr->smgr_cached_nblocks[VISIBILITYMAP_FORKNUM] = 0;
+ reln->smgr_cached_nblocks[VISIBILITYMAP_FORKNUM] = 0;
}
/* Handle requests beyond EOF */
- if (blkno >= rel->rd_smgr->smgr_cached_nblocks[VISIBILITYMAP_FORKNUM])
+ if (blkno >= reln->smgr_cached_nblocks[VISIBILITYMAP_FORKNUM])
{
if (extend)
vm_extend(rel, blkno + 1);
@@ -618,6 +615,7 @@ vm_extend(Relation rel, BlockNumber vm_nblocks)
{
BlockNumber vm_nblocks_now;
PGAlignedBlock pg;
+ SMgrRelation reln;
PageInit((Page) pg.data, BLCKSZ, 0);
@@ -633,29 +631,32 @@ vm_extend(Relation rel, BlockNumber vm_nblocks)
*/
LockRelationForExtension(rel, ExclusiveLock);
- /* Might have to re-open if a cache flush happened */
- RelationOpenSmgr(rel);
+ /*
+ * Caution: re-using this smgr pointer could fail if the relcache entry
+ * gets closed. It's safe as long as we only do smgr-level operations
+ * between here and the last use of the pointer.
+ */
+ reln = RelationGetSmgr(rel);
/*
* Create the file first if it doesn't exist. If smgr_vm_nblocks is
* positive then it must exist, no need for an smgrexists call.
*/
- if ((rel->rd_smgr->smgr_cached_nblocks[VISIBILITYMAP_FORKNUM] == 0 ||
- rel->rd_smgr->smgr_cached_nblocks[VISIBILITYMAP_FORKNUM] == InvalidBlockNumber) &&
- !smgrexists(rel->rd_smgr, VISIBILITYMAP_FORKNUM))
- smgrcreate(rel->rd_smgr, VISIBILITYMAP_FORKNUM, false);
+ if ((reln->smgr_cached_nblocks[VISIBILITYMAP_FORKNUM] == 0 ||
+ reln->smgr_cached_nblocks[VISIBILITYMAP_FORKNUM] == InvalidBlockNumber) &&
+ !smgrexists(reln, VISIBILITYMAP_FORKNUM))
+ smgrcreate(reln, VISIBILITYMAP_FORKNUM, false);
/* Invalidate cache so that smgrnblocks() asks the kernel. */
- rel->rd_smgr->smgr_cached_nblocks[VISIBILITYMAP_FORKNUM] = InvalidBlockNumber;
- vm_nblocks_now = smgrnblocks(rel->rd_smgr, VISIBILITYMAP_FORKNUM);
+ reln->smgr_cached_nblocks[VISIBILITYMAP_FORKNUM] = InvalidBlockNumber;
+ vm_nblocks_now = smgrnblocks(reln, VISIBILITYMAP_FORKNUM);
/* Now extend the file */
while (vm_nblocks_now < vm_nblocks)
{
PageSetChecksumInplace((Page) pg.data, vm_nblocks_now);
- smgrextend(rel->rd_smgr, VISIBILITYMAP_FORKNUM, vm_nblocks_now,
- pg.data, false);
+ smgrextend(reln, VISIBILITYMAP_FORKNUM, vm_nblocks_now, pg.data, false);
vm_nblocks_now++;
}
@@ -666,7 +667,7 @@ vm_extend(Relation rel, BlockNumber vm_nblocks)
* to keep checking for creation or extension of the file, which happens
* infrequently.
*/
- CacheInvalidateSmgr(rel->rd_smgr->smgr_rnode);
+ CacheInvalidateSmgr(reln->smgr_rnode);
UnlockRelationForExtension(rel, ExclusiveLock);
}
diff --git a/src/backend/access/nbtree/nbtree.c b/src/backend/access/nbtree/nbtree.c
index 1360ab80c1e..be23395dfbb 100644
--- a/src/backend/access/nbtree/nbtree.c
+++ b/src/backend/access/nbtree/nbtree.c
@@ -163,9 +163,9 @@ btbuildempty(Relation index)
* this even when wal_level=minimal.
*/
PageSetChecksumInplace(metapage, BTREE_METAPAGE);
- smgrwrite(index->rd_smgr, INIT_FORKNUM, BTREE_METAPAGE,
+ smgrwrite(RelationGetSmgr(index), INIT_FORKNUM, BTREE_METAPAGE,
(char *) metapage, true);
- log_newpage(&index->rd_smgr->smgr_rnode.node, INIT_FORKNUM,
+ log_newpage(&RelationGetSmgr(index)->smgr_rnode.node, INIT_FORKNUM,
BTREE_METAPAGE, metapage, true);
/*
@@ -173,7 +173,7 @@ btbuildempty(Relation index)
* write did not go through shared_buffers and therefore a concurrent
* checkpoint may have moved the redo pointer past our xlog record.
*/
- smgrimmedsync(index->rd_smgr, INIT_FORKNUM);
+ smgrimmedsync(RelationGetSmgr(index), INIT_FORKNUM);
}
/*
diff --git a/src/backend/access/nbtree/nbtsort.c b/src/backend/access/nbtree/nbtsort.c
index 78f78e7341b..1e02be9746b 100644
--- a/src/backend/access/nbtree/nbtsort.c
+++ b/src/backend/access/nbtree/nbtsort.c
@@ -637,9 +637,6 @@ _bt_blnewpage(uint32 level)
static void
_bt_blwritepage(BTWriteState *wstate, Page page, BlockNumber blkno)
{
- /* Ensure rd_smgr is open (could have been closed by relcache flush!) */
- RelationOpenSmgr(wstate->index);
-
/* XLOG stuff */
if (wstate->btws_use_wal)
{
@@ -659,7 +656,7 @@ _bt_blwritepage(BTWriteState *wstate, Page page, BlockNumber blkno)
if (!wstate->btws_zeropage)
wstate->btws_zeropage = (Page) palloc0(BLCKSZ);
/* don't set checksum for all-zero page */
- smgrextend(wstate->index->rd_smgr, MAIN_FORKNUM,
+ smgrextend(RelationGetSmgr(wstate->index), MAIN_FORKNUM,
wstate->btws_pages_written++,
(char *) wstate->btws_zeropage,
true);
@@ -674,14 +671,14 @@ _bt_blwritepage(BTWriteState *wstate, Page page, BlockNumber blkno)
if (blkno == wstate->btws_pages_written)
{
/* extending the file... */
- smgrextend(wstate->index->rd_smgr, MAIN_FORKNUM, blkno,
+ smgrextend(RelationGetSmgr(wstate->index), MAIN_FORKNUM, blkno,
(char *) page, true);
wstate->btws_pages_written++;
}
else
{
/* overwriting a block we zero-filled before */
- smgrwrite(wstate->index->rd_smgr, MAIN_FORKNUM, blkno,
+ smgrwrite(RelationGetSmgr(wstate->index), MAIN_FORKNUM, blkno,
(char *) page, true);
}
@@ -1428,10 +1425,7 @@ _bt_load(BTWriteState *wstate, BTSpool *btspool, BTSpool *btspool2)
* still not be on disk when the crash occurs.
*/
if (wstate->btws_use_wal)
- {
- RelationOpenSmgr(wstate->index);
- smgrimmedsync(wstate->index->rd_smgr, MAIN_FORKNUM);
- }
+ smgrimmedsync(RelationGetSmgr(wstate->index), MAIN_FORKNUM);
}
/*
diff --git a/src/backend/access/spgist/spginsert.c b/src/backend/access/spgist/spginsert.c
index 1af0af7da21..cc4394b1c8d 100644
--- a/src/backend/access/spgist/spginsert.c
+++ b/src/backend/access/spgist/spginsert.c
@@ -169,27 +169,27 @@ spgbuildempty(Relation index)
* replayed.
*/
PageSetChecksumInplace(page, SPGIST_METAPAGE_BLKNO);
- smgrwrite(index->rd_smgr, INIT_FORKNUM, SPGIST_METAPAGE_BLKNO,
+ smgrwrite(RelationGetSmgr(index), INIT_FORKNUM, SPGIST_METAPAGE_BLKNO,
(char *) page, true);
- log_newpage(&index->rd_smgr->smgr_rnode.node, INIT_FORKNUM,
+ log_newpage(&(RelationGetSmgr(index))->smgr_rnode.node, INIT_FORKNUM,
SPGIST_METAPAGE_BLKNO, page, true);
/* Likewise for the root page. */
SpGistInitPage(page, SPGIST_LEAF);
PageSetChecksumInplace(page, SPGIST_ROOT_BLKNO);
- smgrwrite(index->rd_smgr, INIT_FORKNUM, SPGIST_ROOT_BLKNO,
+ smgrwrite(RelationGetSmgr(index), INIT_FORKNUM, SPGIST_ROOT_BLKNO,
(char *) page, true);
- log_newpage(&index->rd_smgr->smgr_rnode.node, INIT_FORKNUM,
+ log_newpage(&(RelationGetSmgr(index))->smgr_rnode.node, INIT_FORKNUM,
SPGIST_ROOT_BLKNO, page, true);
/* Likewise for the null-tuples root page. */
SpGistInitPage(page, SPGIST_LEAF | SPGIST_NULLS);
PageSetChecksumInplace(page, SPGIST_NULL_BLKNO);
- smgrwrite(index->rd_smgr, INIT_FORKNUM, SPGIST_NULL_BLKNO,
+ smgrwrite(RelationGetSmgr(index), INIT_FORKNUM, SPGIST_NULL_BLKNO,
(char *) page, true);
- log_newpage(&index->rd_smgr->smgr_rnode.node, INIT_FORKNUM,
+ log_newpage(&(RelationGetSmgr(index))->smgr_rnode.node, INIT_FORKNUM,
SPGIST_NULL_BLKNO, page, true);
/*
@@ -197,7 +197,7 @@ spgbuildempty(Relation index)
* writes did not go through shared buffers and therefore a concurrent
* checkpoint may have moved the redo pointer past our xlog record.
*/
- smgrimmedsync(index->rd_smgr, INIT_FORKNUM);
+ smgrimmedsync(RelationGetSmgr(index), INIT_FORKNUM);
}
/*
diff --git a/src/backend/access/table/tableam.c b/src/backend/access/table/tableam.c
index 5ea5bdd8104..66f0f84386c 100644
--- a/src/backend/access/table/tableam.c
+++ b/src/backend/access/table/tableam.c
@@ -629,17 +629,14 @@ table_block_relation_size(Relation rel, ForkNumber forkNumber)
{
uint64 nblocks = 0;
- /* Open it at the smgr level if not already done */
- RelationOpenSmgr(rel);
-
/* InvalidForkNumber indicates returning the size for all forks */
if (forkNumber == InvalidForkNumber)
{
for (int i = 0; i < MAX_FORKNUM; i++)
- nblocks += smgrnblocks(rel->rd_smgr, i);
+ nblocks += smgrnblocks(RelationGetSmgr(rel), i);
}
else
- nblocks = smgrnblocks(rel->rd_smgr, forkNumber);
+ nblocks = smgrnblocks(RelationGetSmgr(rel), forkNumber);
return nblocks * BLCKSZ;
}