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 ([email protected])
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-patches