@ -60,6 +60,7 @@
# include "sys/mman.h"
# endif
# include "catalog/catalog.h"
# include "common/username.h"
# include "mb/pg_wchar.h"
# include "getaddrinfo.h"
@ -218,6 +219,7 @@ static char **filter_lines_with_token(char **lines, const char *token);
static char * * readfile ( const char * path ) ;
static void writefile ( char * path , char * * lines ) ;
static void walkdir ( char * path , void ( * action ) ( char * fname , bool isdir ) ) ;
static void walktblspc_links ( char * path , void ( * action ) ( char * fname , bool isdir ) ) ;
static void pre_sync_fname ( char * fname , bool isdir ) ;
static void fsync_fname ( char * fname , bool isdir ) ;
static FILE * popen_check ( const char * command , const char * mode ) ;
@ -587,6 +589,55 @@ walkdir(char *path, void (*action) (char *fname, bool isdir))
( * action ) ( path , true ) ;
}
/*
* walktblspc_links : call walkdir on each entry under the given
* pg_tblspc directory , or do nothing if pg_tblspc doesn ' t exist .
*/
static void
walktblspc_links ( char * path , void ( * action ) ( char * fname , bool isdir ) )
{
DIR * dir ;
struct dirent * direntry ;
char subpath [ MAXPGPATH ] ;
dir = opendir ( path ) ;
if ( dir = = NULL )
{
if ( errno = = ENOENT )
return ;
fprintf ( stderr , _ ( " %s: could not open directory \" %s \" : %s \n " ) ,
progname , path , strerror ( errno ) ) ;
exit_nicely ( ) ;
}
while ( errno = 0 , ( direntry = readdir ( dir ) ) ! = NULL )
{
if ( strcmp ( direntry - > d_name , " . " ) = = 0 | |
strcmp ( direntry - > d_name , " .. " ) = = 0 )
continue ;
/* fsync the version specific tablespace subdirectory */
snprintf ( subpath , sizeof ( subpath ) , " %s/%s/%s " ,
path , direntry - > d_name , TABLESPACE_VERSION_DIRECTORY ) ;
walkdir ( subpath , action ) ;
}
if ( errno )
{
fprintf ( stderr , _ ( " %s: could not read directory \" %s \" : %s \n " ) ,
progname , path , strerror ( errno ) ) ;
exit_nicely ( ) ;
}
if ( closedir ( dir ) )
{
fprintf ( stderr , _ ( " %s: could not close directory \" %s \" : %s \n " ) ,
progname , path , strerror ( errno ) ) ;
exit_nicely ( ) ;
}
}
/*
* Hint to the OS that it should get ready to fsync ( ) this file .
*/
@ -2377,6 +2428,7 @@ static void
perform_fsync ( void )
{
char pdir [ MAXPGPATH ] ;
char pg_tblspc [ MAXPGPATH ] ;
fputs ( _ ( " syncing data to disk ... " ) , stdout ) ;
fflush ( stdout ) ;
@ -2395,9 +2447,13 @@ perform_fsync(void)
/* first the parent of the PGDATA directory */
pre_sync_fname ( pdir , true ) ;
/* then recursively through the directory */
/* then recursively through the data d irectory */
walkdir ( pg_data , pre_sync_fname ) ;
/* now do the same thing for everything under pg_tblspc */
snprintf ( pg_tblspc , MAXPGPATH , " %s/pg_tblspc " , pg_data ) ;
walktblspc_links ( pg_tblspc , pre_sync_fname ) ;
/*
* Now , do the fsync ( ) s in the same order .
*/
@ -2405,9 +2461,12 @@ perform_fsync(void)
/* first the parent of the PGDATA directory */
fsync_fname ( pdir , true ) ;
/* then recursively through the directory */
/* then recursively through the data d irectory */
walkdir ( pg_data , fsync_fname ) ;
/* and now the same for all tablespaces */
walktblspc_links ( pg_tblspc , fsync_fname ) ;
check_ok ( ) ;
}