Attached is a patch that attempts to fix the issues with stat() not
properly updating st_size on win32, as reported in this thread:
http://archives.postgresql.org/pgsql-hackers/2008-03/msg01181.php

It has to have a chance to affect things beyond just the
pg_relation_size() function, so this patch fixes all cases where we do
stat() and use the st_size member. It doesn't change all occurances of
stat() since I didn't want to incur the double filesystem lookups
unnecessary cases.

Any objections?

//Magnus
Index: src/backend/access/transam/xlog.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/access/transam/xlog.c,v
retrieving revision 1.296
diff -c -r1.296 xlog.c
*** src/backend/access/transam/xlog.c	5 Apr 2008 01:34:06 -0000	1.296
--- src/backend/access/transam/xlog.c	9 Apr 2008 17:01:50 -0000
***************
*** 2560,2566 ****
--- 2560,2570 ----
  		 * isn't one, and we'd incorrectly conclude we've reached the end of
  		 * WAL and we're done recovering ...
  		 */
+ #ifndef WIN32
  		if (stat(xlogpath, &stat_buf) == 0)
+ #else
+ 		if (pgwin32_safestat(xlogpath, &stat_buf) == 0)
+ #endif
  		{
  			if (expectedSize > 0 && stat_buf.st_size != expectedSize)
  				ereport(FATAL,
Index: src/backend/storage/file/fd.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/storage/file/fd.c,v
retrieving revision 1.144
diff -c -r1.144 fd.c
*** src/backend/storage/file/fd.c	10 Mar 2008 20:06:27 -0000	1.144
--- src/backend/storage/file/fd.c	9 Apr 2008 17:00:22 -0000
***************
*** 999,1005 ****
--- 999,1009 ----
  		vfdP->fdstate &= ~FD_TEMPORARY;
  		if (log_temp_files >= 0)
  		{
+ #ifndef WIN32
  			if (stat(vfdP->fileName, &filestats) == 0)
+ #else
+ 			if (pgwin32_safestat(vfdP->fileName, &filestats) == 0)
+ #endif
  			{
  				if (filestats.st_size >= log_temp_files)
  					ereport(LOG,
Index: src/backend/utils/adt/dbsize.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/utils/adt/dbsize.c,v
retrieving revision 1.18
diff -c -r1.18 dbsize.c
*** src/backend/utils/adt/dbsize.c	31 Mar 2008 01:31:43 -0000	1.18
--- src/backend/utils/adt/dbsize.c	9 Apr 2008 17:09:44 -0000
***************
*** 52,58 ****
--- 52,62 ----
  
  		snprintf(filename, MAXPGPATH, "%s/%s", path, direntry->d_name);
  
+ #ifndef WIN32
  		if (stat(filename, &fst) < 0)
+ #else
+ 		if (pgwin32_safestat(filename, &fst) < 0)
+ #endif
  		{
  			if (errno == ENOENT)
  				continue;
***************
*** 199,205 ****
--- 203,213 ----
  
  		snprintf(pathname, MAXPGPATH, "%s/%s", tblspcPath, direntry->d_name);
  
+ #ifndef WIN32
  		if (stat(pathname, &fst) < 0)
+ #else
+ 		if (pgwin32_safestat(pathname, &fst) < 0)
+ #endif
  		{
  			if (errno == ENOENT)
  				continue;
***************
*** 268,274 ****
--- 276,286 ----
  			snprintf(pathname, MAXPGPATH, "%s.%u",
  					 relationpath, segcount);
  
+ #ifndef WIN32
  		if (stat(pathname, &fst) < 0)
+ #else
+ 		if (pgwin32_safestat(pathname, &fst) < 0)
+ #endif
  		{
  			if (errno == ENOENT)
  				break;
Index: src/backend/utils/adt/genfile.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/utils/adt/genfile.c,v
retrieving revision 1.19
diff -c -r1.19 genfile.c
*** src/backend/utils/adt/genfile.c	31 Mar 2008 01:31:43 -0000	1.19
--- src/backend/utils/adt/genfile.c	9 Apr 2008 16:59:25 -0000
***************
*** 161,167 ****
--- 161,171 ----
  
  	filename = convert_and_check_filename(filename_t);
  
+ #ifndef WIN32
  	if (stat(filename, &fst) < 0)
+ #else
+ 	if (pgwin32_safestat(filename, &fst) < 0)
+ #endif
  		ereport(ERROR,
  				(errcode_for_file_access(),
  				 errmsg("could not stat file \"%s\": %m", filename)));
Index: src/include/port.h
===================================================================
RCS file: /projects/cvsroot/pgsql/src/include/port.h,v
retrieving revision 1.118
diff -c -r1.118 port.h
*** src/include/port.h	29 Feb 2008 15:31:33 -0000	1.118
--- src/include/port.h	9 Apr 2008 16:35:26 -0000
***************
*** 298,303 ****
--- 298,306 ----
  #define popen(a,b) _popen(a,b)
  #define pclose(a) _pclose(a)
  
+ /* stat() is not guaranteed to report the current size of the file */
+ extern int pgwin32_safestat(const char *path, struct stat *buf);
+ 
  /* Missing rand functions */
  extern long lrand48(void);
  extern void srand48(long seed);
Index: src/port/dirmod.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/port/dirmod.c,v
retrieving revision 1.51
diff -c -r1.51 dirmod.c
*** src/port/dirmod.c	1 Jan 2008 19:46:00 -0000	1.51
--- src/port/dirmod.c	9 Apr 2008 17:06:58 -0000
***************
*** 447,449 ****
--- 447,480 ----
  	pgfnames_cleanup(filenames);
  	return false;
  }
+ 
+ 
+ /*
+  * The stat() function in win32 is not guaranteed to report the st_size
+  * field properly. So we define our own version that uses the Win32 API
+  * to update this field.
+  */
+ int 
+ pgwin32_safestat(const char *path, struct stat *buf)
+ {
+ 	int r;
+ 	WIN32_FILE_ATTRIBUTE_DATA attr;
+ 
+ 	r = stat(path, buf);
+ 	if (r < 0)
+ 		return r;
+ 
+ 	if (!GetFileAttributesEx(path, GetFileExInfoStandard, &attr))
+ 	{
+ 		_dosmaperr(GetLastError());
+ 		return -1;
+ 	}
+ 
+ 	/*
+ 	 * XXX no support for >2Gb files here, but we don't do that in
+ 	 * general on Win32 yet.
+ 	 */
+ 	buf->st_size = attr.nFileSizeLow;
+ 
+ 	return 0;
+ }
-- 
Sent via pgsql-patches mailing list (pgsql-patches@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-patches

Reply via email to