6060#include "sys/mman.h"
6161#endif
6262
63+ #include "catalog/catalog.h"
6364#include "common/username.h"
6465#include "mb/pg_wchar.h"
6566#include "getaddrinfo.h"
@@ -218,6 +219,7 @@ static char **filter_lines_with_token(char **lines, const char *token);
218219static char * * readfile (const char * path );
219220static void writefile (char * path ,char * * lines );
220221static void walkdir (char * path ,void (* action ) (char * fname ,bool isdir ));
222+ static void walktblspc_links (char * path ,void (* action ) (char * fname ,bool isdir ));
221223static void pre_sync_fname (char * fname ,bool isdir );
222224static void fsync_fname (char * fname ,bool isdir );
223225static FILE * popen_check (const char * command ,const char * mode );
@@ -587,6 +589,55 @@ walkdir(char *path, void (*action) (char *fname, bool isdir))
587589(* action ) (path , true);
588590}
589591
592+ /*
593+ * walktblspc_links: call walkdir on each entry under the given
594+ * pg_tblspc directory, or do nothing if pg_tblspc doesn't exist.
595+ */
596+ static void
597+ walktblspc_links (char * path ,void (* action ) (char * fname ,bool isdir ))
598+ {
599+ DIR * dir ;
600+ struct dirent * direntry ;
601+ char subpath [MAXPGPATH ];
602+
603+ dir = opendir (path );
604+ if (dir == NULL )
605+ {
606+ if (errno == ENOENT )
607+ return ;
608+ fprintf (stderr ,_ ("%s: could not open directory \"%s\": %s\n" ),
609+ progname ,path ,strerror (errno ));
610+ exit_nicely ();
611+ }
612+
613+ while (errno = 0 , (direntry = readdir (dir ))!= NULL )
614+ {
615+ if (strcmp (direntry -> d_name ,"." )== 0 ||
616+ strcmp (direntry -> d_name ,".." )== 0 )
617+ continue ;
618+
619+ /* fsync the version specific tablespace subdirectory */
620+ snprintf (subpath ,sizeof (subpath ),"%s/%s/%s" ,
621+ path ,direntry -> d_name ,TABLESPACE_VERSION_DIRECTORY );
622+
623+ walkdir (subpath ,action );
624+ }
625+
626+ if (errno )
627+ {
628+ fprintf (stderr ,_ ("%s: could not read directory \"%s\": %s\n" ),
629+ progname ,path ,strerror (errno ));
630+ exit_nicely ();
631+ }
632+
633+ if (closedir (dir ))
634+ {
635+ fprintf (stderr ,_ ("%s: could not close directory \"%s\": %s\n" ),
636+ progname ,path ,strerror (errno ));
637+ exit_nicely ();
638+ }
639+ }
640+
590641/*
591642 * Hint to the OS that it should get ready to fsync() this file.
592643 */
@@ -2375,6 +2426,7 @@ static void
23752426perform_fsync (void )
23762427{
23772428char pdir [MAXPGPATH ];
2429+ char pg_tblspc [MAXPGPATH ];
23782430
23792431fputs (_ ("syncing data to disk ... " ),stdout );
23802432fflush (stdout );
@@ -2393,19 +2445,26 @@ perform_fsync(void)
23932445/* first the parent of the PGDATA directory */
23942446pre_sync_fname (pdir , true);
23952447
2396- /* then recursively through the directory */
2448+ /* then recursively through thedata directory */
23972449walkdir (pg_data ,pre_sync_fname );
23982450
2451+ /* now do the same thing for everything under pg_tblspc */
2452+ snprintf (pg_tblspc ,MAXPGPATH ,"%s/pg_tblspc" ,pg_data );
2453+ walktblspc_links (pg_tblspc ,pre_sync_fname );
2454+
23992455/*
24002456 * Now, do the fsync()s in the same order.
24012457 */
24022458
24032459/* first the parent of the PGDATA directory */
24042460fsync_fname (pdir , true);
24052461
2406- /* then recursively through the directory */
2462+ /* then recursively through thedata directory */
24072463walkdir (pg_data ,fsync_fname );
24082464
2465+ /* and now the same for all tablespaces */
2466+ walktblspc_links (pg_tblspc ,fsync_fname );
2467+
24092468check_ok ();
24102469}
24112470