{
char tmppath[MAXPGPATH];
char path[MAXPGPATH];
+ struct stat st;
/*
* No need to take out the io_in_progress_lock, nobody else can see this
sprintf(path, "pg_replslot/%s", NameStr(slot->data.name));
sprintf(tmppath, "pg_replslot/%s.tmp", NameStr(slot->data.name));
+ /*
+ * It's just barely possible that some previous effort to create or
+ * drop a slot with this name left a temp directory lying around.
+ * If that seems to be the case, try to remove it. If the rmtree()
+ * fails, we'll error out at the mkdir() below, so we don't bother
+ * checking success.
+ */
+ if (stat(tmppath, &st) == 0 && S_ISDIR(st.st_mode))
+ rmtree(tmppath, true);
+
+ /* Create and fsync the temporary slot directory. */
if (mkdir(tmppath, S_IRWXU) < 0)
ereport(ERROR,
(errcode_for_file_access(),
errmsg("could not create directory \"%s\": %m",
tmppath)));
-
fsync_fname(tmppath, true);
+ /* Write the actual state file. */
slot->dirty = true; /* signal that we really need to write */
SaveSlotToPath(slot, tmppath, ERROR);
+ /* Rename the directory into place. */
if (rename(tmppath, path) != 0)
ereport(ERROR,
(errcode_for_file_access(),