diff --git a/src/backend/commands/tablespace.c b/src/backend/commands/tablespace.c index f7e9160a4f..5447a396ff 100644 --- a/src/backend/commands/tablespace.c +++ b/src/backend/commands/tablespace.c @@ -565,11 +565,14 @@ static void create_tablespace_directories(const char *location, const Oid tablespaceoid) { char *linkloc; + char *location_with_timestamp; char *location_with_version_dir; struct stat st; linkloc = psprintf("pg_tblspc/%u", tablespaceoid); - location_with_version_dir = psprintf("%s/%s", location, + location_with_timestamp = psprintf("%s/PG_" INT64_FORMAT, + location, GetCurrentTimestamp()); + location_with_version_dir = psprintf("%s/%s", location_with_timestamp, TABLESPACE_VERSION_DIRECTORY); /* @@ -608,6 +611,20 @@ create_tablespace_directories(const char *location, const Oid tablespaceoid) } } + if (MakePGDirectory(location_with_timestamp) < 0) + { + if (errno == EEXIST) + ereport(ERROR, + (errcode(ERRCODE_OBJECT_IN_USE), + errmsg("directory \"%s\" already present", + location_with_timestamp))); + else + ereport(ERROR, + (errcode_for_file_access(), + errmsg("could not create directory \"%s\": %m", + location_with_timestamp))); + } + /* * The creation of the version directory prevents more than one tablespace * in a single location. @@ -635,13 +652,14 @@ create_tablespace_directories(const char *location, const Oid tablespaceoid) /* * Create the symlink under PGDATA */ - if (symlink(location, linkloc) < 0) + if (symlink(location_with_timestamp, linkloc) < 0) ereport(ERROR, (errcode_for_file_access(), errmsg("could not create symbolic link \"%s\": %m", linkloc))); pfree(linkloc); + pfree(location_with_timestamp); pfree(location_with_version_dir); } @@ -797,6 +815,15 @@ remove_symlink: #ifdef S_ISLNK else if (S_ISLNK(st.st_mode)) { + char targetpath[MAXPGPATH]; + int rllen; + + rllen = readlink(linkloc, targetpath, sizeof(targetpath)); + if (rllen < 0 || rllen >= sizeof(targetpath)) + ereport(ERROR, + (errmsg("could not read symbolic link \"%s\": %m", linkloc))); + targetpath[rllen] = '\0'; + if (unlink(linkloc) < 0) { int saved_errno = errno; @@ -806,6 +833,12 @@ remove_symlink: errmsg("could not remove symbolic link \"%s\": %m", linkloc))); } + + if (rmdir(targetpath) < 0) + ereport(WARNING, + (errcode_for_file_access(), + errmsg("could not remove directory \"%s\": %m", + targetpath))); } #endif else