diff -crNB upstream/postgresql-8.4.8//src/backend/access/transam/slru.c trunk//src/backend/access/transam/slru.c *** upstream/postgresql-8.4.8//src/backend/access/transam/slru.c 2011-04-15 13:17:14.000000000 +1000 --- trunk//src/backend/access/transam/slru.c 2011-09-07 11:53:32.000000000 +1000 *************** *** 56,61 **** --- 56,62 ---- #include "access/xlog.h" #include "storage/fd.h" #include "storage/shmem.h" + #include "storage/write.h" #include "miscadmin.h" *************** *** 785,791 **** } errno = 0; ! if (write(fd, shared->page_buffer[slotno], BLCKSZ) != BLCKSZ) { /* if write didn't set errno, assume problem is no disk space */ if (errno == 0) --- 786,792 ---- } errno = 0; ! if (WriteAll(fd, shared->page_buffer[slotno], BLCKSZ) != BLCKSZ) { /* if write didn't set errno, assume problem is no disk space */ if (errno == 0) diff -crNB upstream/postgresql-8.4.8//src/backend/access/transam/twophase.c trunk//src/backend/access/transam/twophase.c *** upstream/postgresql-8.4.8//src/backend/access/transam/twophase.c 2011-04-15 13:17:14.000000000 +1000 --- trunk//src/backend/access/transam/twophase.c 2011-09-07 11:54:19.000000000 +1000 *************** *** 58,63 **** --- 58,64 ---- #include "storage/fd.h" #include "storage/procarray.h" #include "storage/smgr.h" + #include "storage/write.h" #include "utils/builtins.h" #include "utils/memutils.h" *************** *** 941,947 **** for (record = records.head; record != NULL; record = record->next) { COMP_CRC32(statefile_crc, record->data, record->len); ! if ((write(fd, record->data, record->len)) != record->len) { close(fd); ereport(ERROR, --- 942,948 ---- for (record = records.head; record != NULL; record = record->next) { COMP_CRC32(statefile_crc, record->data, record->len); ! if ((WriteAll(fd, record->data, record->len)) != record->len) { close(fd); ereport(ERROR, *************** *** 958,964 **** */ bogus_crc = ~statefile_crc; ! if ((write(fd, &bogus_crc, sizeof(pg_crc32))) != sizeof(pg_crc32)) { close(fd); ereport(ERROR, --- 959,965 ---- */ bogus_crc = ~statefile_crc; ! if ((WriteAll(fd, &bogus_crc, sizeof(pg_crc32))) != sizeof(pg_crc32)) { close(fd); ereport(ERROR, *************** *** 1007,1013 **** /* If we crash now, we have prepared: WAL replay will fix things */ /* write correct CRC and close file */ ! if ((write(fd, &statefile_crc, sizeof(pg_crc32))) != sizeof(pg_crc32)) { close(fd); ereport(ERROR, --- 1008,1014 ---- /* If we crash now, we have prepared: WAL replay will fix things */ /* write correct CRC and close file */ ! if ((WriteAll(fd, &statefile_crc, sizeof(pg_crc32))) != sizeof(pg_crc32)) { close(fd); ereport(ERROR, *************** *** 1371,1384 **** path))); /* Write content and CRC */ ! if (write(fd, content, len) != len) { close(fd); ereport(ERROR, (errcode_for_file_access(), errmsg("could not write two-phase state file: %m"))); } ! if (write(fd, &statefile_crc, sizeof(pg_crc32)) != sizeof(pg_crc32)) { close(fd); ereport(ERROR, --- 1372,1385 ---- path))); /* Write content and CRC */ ! if (WriteAll(fd, content, len) != len) { close(fd); ereport(ERROR, (errcode_for_file_access(), errmsg("could not write two-phase state file: %m"))); } ! if (WriteAll(fd, &statefile_crc, sizeof(pg_crc32)) != sizeof(pg_crc32)) { close(fd); ereport(ERROR, diff -crNB upstream/postgresql-8.4.8//src/backend/access/transam/xlog.c trunk//src/backend/access/transam/xlog.c *** upstream/postgresql-8.4.8//src/backend/access/transam/xlog.c 2011-04-15 13:17:14.000000000 +1000 --- trunk//src/backend/access/transam/xlog.c 2011-09-07 11:55:22.000000000 +1000 *************** *** 47,52 **** --- 47,53 ---- #include "storage/procarray.h" #include "storage/smgr.h" #include "storage/spin.h" + #include "storage/write.h" #include "utils/builtins.h" #include "utils/flatfiles.h" #include "utils/guc.h" *************** *** 1644,1650 **** from = XLogCtl->pages + startidx * (Size) XLOG_BLCKSZ; nbytes = npages * (Size) XLOG_BLCKSZ; errno = 0; ! if (write(openLogFile, from, nbytes) != nbytes) { /* if write didn't set errno, assume no disk space */ if (errno == 0) --- 1645,1651 ---- from = XLogCtl->pages + startidx * (Size) XLOG_BLCKSZ; nbytes = npages * (Size) XLOG_BLCKSZ; errno = 0; ! if (WriteAll(openLogFile, from, nbytes) != nbytes) { /* if write didn't set errno, assume no disk space */ if (errno == 0) *************** *** 2231,2237 **** for (nbytes = 0; nbytes < XLogSegSize; nbytes += XLOG_BLCKSZ) { errno = 0; ! if ((int) write(fd, zbuffer, XLOG_BLCKSZ) != (int) XLOG_BLCKSZ) { int save_errno = errno; --- 2232,2238 ---- for (nbytes = 0; nbytes < XLogSegSize; nbytes += XLOG_BLCKSZ) { errno = 0; ! if ((int) WriteAll(fd, zbuffer, XLOG_BLCKSZ) != (int) XLOG_BLCKSZ) { int save_errno = errno; *************** *** 2364,2370 **** (errmsg("not enough data in file \"%s\"", path))); } errno = 0; ! if ((int) write(fd, buffer, sizeof(buffer)) != (int) sizeof(buffer)) { int save_errno = errno; --- 2365,2371 ---- (errmsg("not enough data in file \"%s\"", path))); } errno = 0; ! if ((int) WriteAll(fd, buffer, sizeof(buffer)) != (int) sizeof(buffer)) { int save_errno = errno; *************** *** 4122,4128 **** if (nbytes == 0) break; errno = 0; ! if ((int) write(fd, buffer, nbytes) != nbytes) { int save_errno = errno; --- 4123,4129 ---- if (nbytes == 0) break; errno = 0; ! if ((int) WriteAll(fd, buffer, nbytes) != nbytes) { int save_errno = errno; *************** *** 4164,4170 **** nbytes = strlen(buffer); errno = 0; ! if ((int) write(fd, buffer, nbytes) != nbytes) { int save_errno = errno; --- 4165,4171 ---- nbytes = strlen(buffer); errno = 0; ! if ((int) WriteAll(fd, buffer, nbytes) != nbytes) { int save_errno = errno; *************** *** 4298,4304 **** XLOG_CONTROL_FILE))); errno = 0; ! if (write(fd, buffer, PG_CONTROL_SIZE) != PG_CONTROL_SIZE) { /* if write didn't set errno, assume problem is no disk space */ if (errno == 0) --- 4299,4305 ---- XLOG_CONTROL_FILE))); errno = 0; ! if (WriteAll(fd, buffer, PG_CONTROL_SIZE) != PG_CONTROL_SIZE) { /* if write didn't set errno, assume problem is no disk space */ if (errno == 0) *************** *** 4523,4529 **** XLOG_CONTROL_FILE))); errno = 0; ! if (write(fd, ControlFile, sizeof(ControlFileData)) != sizeof(ControlFileData)) { /* if write didn't set errno, assume problem is no disk space */ if (errno == 0) --- 4524,4530 ---- XLOG_CONTROL_FILE))); errno = 0; ! if (WriteAll(fd, ControlFile, sizeof(ControlFileData)) != sizeof(ControlFileData)) { /* if write didn't set errno, assume problem is no disk space */ if (errno == 0) *************** *** 4718,4724 **** /* Write the first page with the initial record */ errno = 0; ! if (write(openLogFile, page, XLOG_BLCKSZ) != XLOG_BLCKSZ) { /* if write didn't set errno, assume problem is no disk space */ if (errno == 0) --- 4719,4725 ---- /* Write the first page with the initial record */ errno = 0; ! if (WriteAll(openLogFile, page, XLOG_BLCKSZ) != XLOG_BLCKSZ) { /* if write didn't set errno, assume problem is no disk space */ if (errno == 0) diff -crNB upstream/postgresql-8.4.8//src/backend/storage/file/copydir.c trunk//src/backend/storage/file/copydir.c *** upstream/postgresql-8.4.8//src/backend/storage/file/copydir.c 2011-04-15 13:17:14.000000000 +1000 --- trunk//src/backend/storage/file/copydir.c 2011-09-07 11:58:04.000000000 +1000 *************** *** 23,28 **** --- 23,29 ---- #include #include "storage/fd.h" + #include "storage/write.h" #include "miscadmin.h" /* *************** *** 145,151 **** if (nbytes == 0) break; errno = 0; ! if ((int) write(dstfd, buffer, nbytes) != nbytes) { /* if write didn't set errno, assume problem is no disk space */ if (errno == 0) --- 146,152 ---- if (nbytes == 0) break; errno = 0; ! if ((int) WriteAll(dstfd, buffer, nbytes) != nbytes) { /* if write didn't set errno, assume problem is no disk space */ if (errno == 0) diff -crNB upstream/postgresql-8.4.8//src/backend/storage/file/fd.c trunk//src/backend/storage/file/fd.c *** upstream/postgresql-8.4.8//src/backend/storage/file/fd.c 2011-04-15 13:17:14.000000000 +1000 --- trunk//src/backend/storage/file/fd.c 2011-09-07 11:59:33.000000000 +1000 *************** *** 54,59 **** --- 54,60 ---- #include "catalog/pg_tablespace.h" #include "storage/fd.h" #include "storage/ipc.h" + #include "storage/write.h" #include "utils/guc.h" #include "utils/resowner.h" *************** *** 1204,1210 **** retry: errno = 0; ! returnCode = write(VfdCache[file].fd, buffer, amount); /* if write didn't set errno, assume problem is no disk space */ if (returnCode != amount && errno == 0) --- 1205,1211 ---- retry: errno = 0; ! returnCode = WriteAll(VfdCache[file].fd, buffer, amount); /* if write didn't set errno, assume problem is no disk space */ if (returnCode != amount && errno == 0) diff -crNB upstream/postgresql-8.4.8//src/backend/storage/file/Makefile trunk//src/backend/storage/file/Makefile *** upstream/postgresql-8.4.8//src/backend/storage/file/Makefile 2011-04-15 13:17:14.000000000 +1000 --- trunk//src/backend/storage/file/Makefile 2011-09-07 11:57:25.000000000 +1000 *************** *** 12,17 **** top_builddir = ../../../.. include $(top_builddir)/src/Makefile.global ! OBJS = fd.o buffile.o copydir.o include $(top_srcdir)/src/backend/common.mk --- 12,17 ---- top_builddir = ../../../.. include $(top_builddir)/src/Makefile.global ! OBJS = fd.o buffile.o copydir.o write.o include $(top_srcdir)/src/backend/common.mk diff -crNB upstream/postgresql-8.4.8//src/backend/storage/file/write.c trunk//src/backend/storage/file/write.c *** upstream/postgresql-8.4.8//src/backend/storage/file/write.c 1970-01-01 10:00:00.000000000 +1000 --- trunk//src/backend/storage/file/write.c 2011-09-07 11:57:45.000000000 +1000 *************** *** 0 **** --- 1,46 ---- + /*------------------------------------------------------------------------- + * + * write.h + * write wrapper public interface declarations. + * + * + * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * $ver:$ + * + *------------------------------------------------------------------------- + */ + + #include "postgres.h" + #include "storage/write.h" + + #include + + int WriteAll(int fd, const void *bytes, Size amount) + { + int returnCode; + int written; + + written = 0; + + while (amount > 0) + { + returnCode = write(fd, bytes, amount); + if (returnCode < 0) + return -1; + + /* Catche the case where theres no diskspace */ + if (returnCode == 0 && errno == 0) + { + errno = ENOSPC; + return 0; + } + + bytes = ConstPtrOffset(bytes, returnCode); + amount -= returnCode; + written += returnCode; + } + + return written; + } diff -crNB upstream/postgresql-8.4.8//src/backend/utils/init/miscinit.c trunk//src/backend/utils/init/miscinit.c *** upstream/postgresql-8.4.8//src/backend/utils/init/miscinit.c 2011-04-15 13:17:14.000000000 +1000 --- trunk//src/backend/utils/init/miscinit.c 2011-09-07 12:06:00.000000000 +1000 *************** *** 38,43 **** --- 38,44 ---- #include "storage/pg_shmem.h" #include "storage/proc.h" #include "storage/procarray.h" + #include "storage/write.h" #include "utils/builtins.h" #include "utils/guc.h" #include "utils/syscache.h" *************** *** 933,939 **** amPostmaster ? (int) my_pid : -((int) my_pid), DataDir); errno = 0; ! if (write(fd, buffer, strlen(buffer)) != strlen(buffer)) { int save_errno = errno; --- 934,940 ---- amPostmaster ? (int) my_pid : -((int) my_pid), DataDir); errno = 0; ! if (WriteAll(fd, buffer, strlen(buffer)) != strlen(buffer)) { int save_errno = errno; *************** *** 1105,1111 **** len = strlen(buffer); errno = 0; if (lseek(fd, (off_t) 0, SEEK_SET) != 0 || ! (int) write(fd, buffer, len) != len) { /* if write didn't set errno, assume problem is no disk space */ if (errno == 0) --- 1106,1112 ---- len = strlen(buffer); errno = 0; if (lseek(fd, (off_t) 0, SEEK_SET) != 0 || ! (int) WriteAll(fd, buffer, len) != len) { /* if write didn't set errno, assume problem is no disk space */ if (errno == 0) diff -crNB upstream/postgresql-8.4.8//src/include/c.h trunk//src/include/c.h *** upstream/postgresql-8.4.8//src/include/c.h 2011-04-15 13:17:14.000000000 +1000 --- trunk//src/include/c.h 2011-09-05 13:27:40.000000000 +1000 *************** *** 742,747 **** --- 742,749 ---- #define PG_TEXTDOMAIN(domain) (domain "-" PG_MAJORVERSION) #endif + /* Pointer increment macros for WriteAll */ + #define ConstPtrOffset(ptr, amt) ((const void *) (((const unsigned char *) (ptr)) + (amt))) /* ---------------------------------------------------------------- * Section 8: system-specific hacks diff -crNB upstream/postgresql-8.4.8//src/include/storage/write.h trunk//src/include/storage/write.h *** upstream/postgresql-8.4.8//src/include/storage/write.h 1970-01-01 10:00:00.000000000 +1000 --- trunk//src/include/storage/write.h 2011-09-07 12:09:07.000000000 +1000 *************** *** 0 **** --- 1,32 ---- + /*------------------------------------------------------------------------- + * + * write.h + * write wrapper public interface declarations. + * + * + * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * $ver:$ + * + *------------------------------------------------------------------------- + */ + + #ifndef WRITE_H + #define WRITE_H + + #include "postgres.h" + #include "storage/write.h" + + /* + * GNU libc will generally write all data when a write() is called. According + * to the docs, this is not always the case as write() may return without + * writing all data. In this case, the return value will be the amount written. + * The remaining data should be written in a further write call. + * + * It is required to wrap write()s in a loop to ensure all data is correctly + * write. + */ + int WriteAll(int fd, const void *bytes, Size amount); + + #endif