summaryrefslogtreecommitdiff
path: root/src/backend/storage/smgr/smgr.c
diff options
context:
space:
mode:
authorThomas Munro <tmunro@postgresql.org>2022-05-07 16:19:42 +1200
committerThomas Munro <tmunro@postgresql.org>2022-05-07 16:32:10 +1200
commitb74e94dc27fdbb13954f230b1d1298430afa6c0c (patch)
treee67f872e3a7ce3cd62480978831c541529d36e45 /src/backend/storage/smgr/smgr.c
parent701d918a426b394620ce4d046533f77262c70829 (diff)
Rethink PROCSIGNAL_BARRIER_SMGRRELEASE.
With sufficiently bad luck, it was possible for IssuePendingWritebacks() to reopen a file after we'd processed PROCSIGNAL_BARRIER_SMGRRELEASE and before the file was unlinked by some other backend. That left a small hole in commit 4eb21763's plan to fix all spurious errors from DROP TABLESPACE and similar on Windows. Fix by closing md.c's segments, instead of just closing fd.c's descriptors, and then teaching smgrwriteback() not to open files that aren't already open. Reported-by: Andres Freund <andres@anarazel.de> Reviewed-by: Robert Haas <robertmhaas@gmail.com> Discussion: https://postgr.es/m/20220209220004.kb3dgtn2x2k2gtdm%40alap3.anarazel.de
Diffstat (limited to 'src/backend/storage/smgr/smgr.c')
-rw-r--r--src/backend/storage/smgr/smgr.c45
1 files changed, 37 insertions, 8 deletions
diff --git a/src/backend/storage/smgr/smgr.c b/src/backend/storage/smgr/smgr.c
index 2c7a2b28572..a477f70f0e3 100644
--- a/src/backend/storage/smgr/smgr.c
+++ b/src/backend/storage/smgr/smgr.c
@@ -41,7 +41,6 @@ typedef struct f_smgr
{
void (*smgr_init) (void); /* may be NULL */
void (*smgr_shutdown) (void); /* may be NULL */
- void (*smgr_release) (void); /* may be NULL */
void (*smgr_open) (SMgrRelation reln);
void (*smgr_close) (SMgrRelation reln, ForkNumber forknum);
void (*smgr_create) (SMgrRelation reln, ForkNumber forknum,
@@ -70,7 +69,6 @@ static const f_smgr smgrsw[] = {
{
.smgr_init = mdinit,
.smgr_shutdown = NULL,
- .smgr_release = mdrelease,
.smgr_open = mdopen,
.smgr_close = mdclose,
.smgr_create = mdcreate,
@@ -282,6 +280,42 @@ smgrclose(SMgrRelation reln)
}
/*
+ * smgrrelease() -- Release all resources used by this object.
+ *
+ * The object remains valid.
+ */
+void
+smgrrelease(SMgrRelation reln)
+{
+ for (ForkNumber forknum = 0; forknum <= MAX_FORKNUM; forknum++)
+ {
+ smgrsw[reln->smgr_which].smgr_close(reln, forknum);
+ reln->smgr_cached_nblocks[forknum] = InvalidBlockNumber;
+ }
+}
+
+/*
+ * smgrreleaseall() -- Release resources used by all objects.
+ *
+ * This is called for PROCSIGNAL_BARRIER_SMGRRELEASE.
+ */
+void
+smgrreleaseall(void)
+{
+ HASH_SEQ_STATUS status;
+ SMgrRelation reln;
+
+ /* Nothing to do if hashtable not set up */
+ if (SMgrRelationHash == NULL)
+ return;
+
+ hash_seq_init(&status, SMgrRelationHash);
+
+ while ((reln = (SMgrRelation) hash_seq_search(&status)) != NULL)
+ smgrrelease(reln);
+}
+
+/*
* smgrcloseall() -- Close all existing SMgrRelation objects.
*/
void
@@ -698,11 +732,6 @@ AtEOXact_SMgr(void)
bool
ProcessBarrierSmgrRelease(void)
{
- for (int i = 0; i < NSmgr; i++)
- {
- if (smgrsw[i].smgr_release)
- smgrsw[i].smgr_release();
- }
-
+ smgrreleaseall();
return true;
}