diff options
Diffstat (limited to 'src/backend/commands/tablespace.c')
-rw-r--r-- | src/backend/commands/tablespace.c | 33 |
1 files changed, 25 insertions, 8 deletions
diff --git a/src/backend/commands/tablespace.c b/src/backend/commands/tablespace.c index c80821e2d57..82d4fbbcf53 100644 --- a/src/backend/commands/tablespace.c +++ b/src/backend/commands/tablespace.c @@ -543,6 +543,7 @@ create_tablespace_directories(const char *location, const Oid tablespaceoid) char *linkloc = palloc(OIDCHARS + OIDCHARS + 1); char *location_with_version_dir = palloc(strlen(location) + 1 + strlen(TABLESPACE_VERSION_DIRECTORY) + 1); + struct stat st; sprintf(linkloc, "pg_tblspc/%u", tablespaceoid); sprintf(location_with_version_dir, "%s/%s", location, @@ -569,8 +570,6 @@ create_tablespace_directories(const char *location, const Oid tablespaceoid) if (InRecovery) { - struct stat st; - /* * Our theory for replaying a CREATE is to forcibly drop the target * subdirectory if present, and then recreate it. This may be more @@ -604,14 +603,32 @@ create_tablespace_directories(const char *location, const Oid tablespaceoid) location_with_version_dir))); } - /* Remove old symlink in recovery, in case it points to the wrong place */ + /* + * In recovery, remove old symlink, in case it points to the wrong place. + * + * On Windows, junction points act like directories so we must be able to + * apply rmdir; in general it seems best to make this code work like the + * symlink removal code in destroy_tablespace_directories, except that + * failure to remove is always an ERROR. + */ if (InRecovery) { - if (unlink(linkloc) < 0 && errno != ENOENT) - ereport(ERROR, - (errcode_for_file_access(), - errmsg("could not remove symbolic link \"%s\": %m", - linkloc))); + if (lstat(linkloc, &st) == 0 && S_ISDIR(st.st_mode)) + { + if (rmdir(linkloc) < 0) + ereport(ERROR, + (errcode_for_file_access(), + errmsg("could not remove directory \"%s\": %m", + linkloc))); + } + else + { + if (unlink(linkloc) < 0 && errno != ENOENT) + ereport(ERROR, + (errcode_for_file_access(), + errmsg("could not remove symbolic link \"%s\": %m", + linkloc))); + } } /* |