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