{
char path[MAXPGPATH];
char tmppath[MAXPGPATH];
+ char *zbuffer;
XLogSegNo installed_segno;
int max_advance;
int fd;
- bool zero_fill = true;
+ int nbytes;
XLogFilePath(path, ThisTimeLineID, logsegno);
unlink(tmppath);
+ /*
+ * Allocate a buffer full of zeros. This is done before opening the file
+ * so that we don't leak the file descriptor if palloc fails.
+ *
+ * Note: palloc zbuffer, instead of just using a local char array, to
+ * ensure it is reasonably well-aligned; this may save a few cycles
+ * transferring data to the kernel.
+ */
+ zbuffer = (char *) palloc0(XLOG_BLCKSZ);
+
/* do not use get_sync_bit() here --- want to fsync only at end of fill */
fd = BasicOpenFile(tmppath, O_RDWR | O_CREAT | O_EXCL | PG_BINARY,
S_IRUSR | S_IWUSR);
(errcode_for_file_access(),
errmsg("could not create file \"%s\": %m", tmppath)));
-#ifdef HAVE_POSIX_FALLOCATE
/*
- * If posix_fallocate() is available and succeeds, then the file is
- * properly allocated and we don't need to zero-fill it (which is less
- * efficient). In case of an error, fall back to writing zeros, because on
- * some platforms posix_fallocate() is available but will not always
- * succeed in cases where zero-filling will.
+ * Zero-fill the file. We have to do this the hard way to ensure that all
+ * the file space has really been allocated --- on platforms that allow
+ * "holes" in files, just seeking to the end doesn't allocate intermediate
+ * space. This way, we know that we have all the space and (after the
+ * fsync below) that all the indirect blocks are down on disk. Therefore,
+ * fdatasync(2) or O_DSYNC will be sufficient to sync future writes to the
+ * log file.
*/
- if (posix_fallocate(fd, 0, XLogSegSize) == 0)
- zero_fill = false;
-#endif /* HAVE_POSIX_FALLOCATE */
-
- if (zero_fill)
+ for (nbytes = 0; nbytes < XLogSegSize; nbytes += XLOG_BLCKSZ)
{
- /*
- * Allocate a buffer full of zeros. This is done before opening the
- * file so that we don't leak the file descriptor if palloc fails.
- *
- * Note: palloc zbuffer, instead of just using a local char array, to
- * ensure it is reasonably well-aligned; this may save a few cycles
- * transferring data to the kernel.
- */
-
- char *zbuffer = (char *) palloc0(XLOG_BLCKSZ);
- int nbytes;
-
- /*
- * Zero-fill the file. We have to do this the hard way to ensure that
- * all the file space has really been allocated --- on platforms that
- * allow "holes" in files, just seeking to the end doesn't allocate
- * intermediate space. This way, we know that we have all the space
- * and (after the fsync below) that all the indirect blocks are down on
- * disk. Therefore, fdatasync(2) or O_DSYNC will be sufficient to sync
- * future writes to the log file.
- */
- for (nbytes = 0; nbytes < XLogSegSize; nbytes += XLOG_BLCKSZ)
+ errno = 0;
+ if ((int) write(fd, zbuffer, XLOG_BLCKSZ) != (int) XLOG_BLCKSZ)
{
- errno = 0;
- if ((int) write(fd, zbuffer, XLOG_BLCKSZ) != (int) XLOG_BLCKSZ)
- {
- int save_errno = errno;
+ int save_errno = errno;
- /*
- * If we fail to make the file, delete it to release disk space
- */
- unlink(tmppath);
+ /*
+ * If we fail to make the file, delete it to release disk space
+ */
+ unlink(tmppath);
- close(fd);
+ close(fd);
- /* if write didn't set errno, assume no disk space */
- errno = save_errno ? save_errno : ENOSPC;
+ /* if write didn't set errno, assume problem is no disk space */
+ errno = save_errno ? save_errno : ENOSPC;
- ereport(ERROR,
- (errcode_for_file_access(),
- errmsg("could not write to file \"%s\": %m",
- tmppath)));
- }
+ ereport(ERROR,
+ (errcode_for_file_access(),
+ errmsg("could not write to file \"%s\": %m", tmppath)));
}
- pfree(zbuffer);
}
+ pfree(zbuffer);
if (pg_fsync(fd) != 0)
{