@@ -166,6 +166,8 @@ typedef enum /* behavior for mdopen & _mdfd_getseg */
166
166
} ExtensionBehavior ;
167
167
168
168
/* local routines */
169
+ static void mdunlinkfork (RelFileNodeBackend rnode , ForkNumber forkNum ,
170
+ bool isRedo );
169
171
static MdfdVec * mdopen (SMgrRelation reln , ForkNumber forknum ,
170
172
ExtensionBehavior behavior );
171
173
static void register_dirty_segment (SMgrRelation reln , ForkNumber forknum ,
@@ -308,6 +310,9 @@ mdcreate(SMgrRelation reln, ForkNumber forkNum, bool isRedo)
308
310
* Note that we're passed a RelFileNodeBackend --- by the time this is called,
309
311
* there won't be an SMgrRelation hashtable entry anymore.
310
312
*
313
+ * forkNum can be a fork number to delete a specific fork, or InvalidForkNumber
314
+ * to delete all forks.
315
+ *
311
316
* For regular relations, we don't unlink the first segment file of the rel,
312
317
* but just truncate it to zero length, and record a request to unlink it after
313
318
* the next checkpoint. Additional segments can be unlinked immediately,
@@ -349,17 +354,32 @@ mdcreate(SMgrRelation reln, ForkNumber forkNum, bool isRedo)
349
354
void
350
355
mdunlink (RelFileNodeBackend rnode , ForkNumber forkNum , bool isRedo )
351
356
{
352
- char * path ;
353
- int ret ;
354
-
355
357
/*
356
358
* We have to clean out any pending fsync requests for the doomed
357
359
* relation, else the next mdsync() will fail. There can't be any such
358
- * requests for a temp relation, though.
360
+ * requests for a temp relation, though. We can send just one request
361
+ * even when deleting multiple forks, since the fsync queuing code accepts
362
+ * the "InvalidForkNumber = all forks" convention.
359
363
*/
360
364
if (!RelFileNodeBackendIsTemp (rnode ))
361
365
ForgetRelationFsyncRequests (rnode .node , forkNum );
362
366
367
+ /* Now do the per-fork work */
368
+ if (forkNum == InvalidForkNumber )
369
+ {
370
+ for (forkNum = 0 ; forkNum <= MAX_FORKNUM ; forkNum ++ )
371
+ mdunlinkfork (rnode , forkNum , isRedo );
372
+ }
373
+ else
374
+ mdunlinkfork (rnode , forkNum , isRedo );
375
+ }
376
+
377
+ static void
378
+ mdunlinkfork (RelFileNodeBackend rnode , ForkNumber forkNum , bool isRedo )
379
+ {
380
+ char * path ;
381
+ int ret ;
382
+
363
383
path = relpath (rnode , forkNum );
364
384
365
385
/*
@@ -1340,7 +1360,8 @@ register_unlink(RelFileNodeBackend rnode)
1340
1360
* The range of possible segment numbers is way less than the range of
1341
1361
* BlockNumber, so we can reserve high values of segno for special purposes.
1342
1362
* We define three:
1343
- * - FORGET_RELATION_FSYNC means to cancel pending fsyncs for a relation
1363
+ * - FORGET_RELATION_FSYNC means to cancel pending fsyncs for a relation,
1364
+ * either for one fork, or all forks if forknum is InvalidForkNumber
1344
1365
* - FORGET_DATABASE_FSYNC means to cancel pending fsyncs for a whole database
1345
1366
* - UNLINK_RELATION_REQUEST is a request to delete the file after the next
1346
1367
* checkpoint.
@@ -1356,15 +1377,16 @@ RememberFsyncRequest(RelFileNode rnode, ForkNumber forknum, BlockNumber segno)
1356
1377
1357
1378
if (segno == FORGET_RELATION_FSYNC )
1358
1379
{
1359
- /* Remove any pending requests for the entire relation */
1380
+ /* Remove any pending requests for the relation (one or all forks) */
1360
1381
HASH_SEQ_STATUS hstat ;
1361
1382
PendingOperationEntry * entry ;
1362
1383
1363
1384
hash_seq_init (& hstat , pendingOpsTable );
1364
1385
while ((entry = (PendingOperationEntry * ) hash_seq_search (& hstat )) != NULL )
1365
1386
{
1366
1387
if (RelFileNodeEquals (entry -> tag .rnode , rnode ) &&
1367
- entry -> tag .forknum == forknum )
1388
+ (entry -> tag .forknum == forknum ||
1389
+ forknum == InvalidForkNumber ))
1368
1390
{
1369
1391
/* Okay, cancel this entry */
1370
1392
entry -> canceled = true;
@@ -1466,6 +1488,9 @@ RememberFsyncRequest(RelFileNode rnode, ForkNumber forknum, BlockNumber segno)
1466
1488
1467
1489
/*
1468
1490
* ForgetRelationFsyncRequests -- forget any fsyncs for a relation fork
1491
+ *
1492
+ * forknum == InvalidForkNumber means all forks, although this code doesn't
1493
+ * actually know that, since it's just forwarding the request elsewhere.
1469
1494
*/
1470
1495
void
1471
1496
ForgetRelationFsyncRequests (RelFileNode rnode , ForkNumber forknum )
0 commit comments