*** xlog.c	Tue Jun  7 18:50:50 2005
--- xlog.dio.c	Tue Jun 28 12:27:15 2005
***************
*** 70,75 ****
--- 70,115 ----
  #endif
  #endif
  
+ #if defined(O_DIRECT)
+ /* fsync_direct */
+ #define FSYNC_DIRECT_FLAG		O_DIRECT
+ #if defined(HAVE_FDATASYNC)
+ #define SYNC_METHOD_FSYNC_DIRECT	SYNC_METHOD_FDATASYNC
+ #elif !defined(HAVE_FSYNC_WRITETHROUGH_ONLY)
+ #define SYNC_METHOD_FSYNC_DIRECT	SYNC_METHOD_FSYNC
+ #else
+ #define SYNC_METHOD_FSYNC_DIRECT	SYNC_METHOD_FSYNC_WRITETHROUGH
+ #endif
+ /* open_direct */
+ #if defined(O_DSYNC)
+ #define OPEN_DIRECT_FLAG		(O_DIRECT | O_DSYNC)
+ #elif defined(O_SYNC)
+ #define OPEN_DIRECT_FLAG		(O_DIRECT | O_SYNC)
+ #endif
+ /*
+  * Limitation of buffer-alignment for direct io depend on OS and filesystem,
+  * but BLCKSZ is assumed to be enough for it. 
+  */
+ #define ALIGNOF_XLOG_BUFFER		BLCKSZ
+ #else /* !defined(O_DIRECT) */
+ #define ALIGNOF_XLOG_BUFFER		MAXIMUM_ALIGNOF
+ #endif
+ 
+ /*
+  * Switch the alignment routine because ShmemAlloc() returns a max-aligned
+  * buffer and ALIGNOF_XLOG_BUFFER may be greater than MAXIMUM_ALIGNOF.
+  */
+ #if ALIGNOF_XLOG_BUFFER <= MAXIMUM_ALIGNOF
+ #define XLOG_BUFFER_ALIGN(LEN)	MAXALIGN((LEN))
+ #else
+ #define XLOG_BUFFER_ALIGN(LEN)	((LEN) + (ALIGNOF_XLOG_BUFFER))
+ #endif
+ /* assume sizeof(ptrdiff_t) == sizeof(void*) */
+ #define POINTERALIGN(ALIGNVAL,PTR)	\
+ 	((char *)(((ptrdiff_t) (PTR) + (ALIGNVAL-1)) & ~((ptrdiff_t) (ALIGNVAL-1))))
+ #define XLOG_BUFFER_POINTERALIGN(PTR)	\
+ 	POINTERALIGN((ALIGNOF_XLOG_BUFFER), (PTR))
+ 
  #if defined(OPEN_DATASYNC_FLAG)
  #define DEFAULT_SYNC_METHOD_STR    "open_datasync"
  #define DEFAULT_SYNC_METHOD		   SYNC_METHOD_OPEN
*************** XLOGShmemSize(void)
*** 3569,3575 ****
  	if (XLOGbuffers < MinXLOGbuffers)
  		XLOGbuffers = MinXLOGbuffers;
  
! 	return MAXALIGN(sizeof(XLogCtlData) + sizeof(XLogRecPtr) * XLOGbuffers)
  		+ BLCKSZ * XLOGbuffers +
  		MAXALIGN(sizeof(ControlFileData));
  }
--- 3609,3615 ----
  	if (XLOGbuffers < MinXLOGbuffers)
  		XLOGbuffers = MinXLOGbuffers;
  
! 	return XLOG_BUFFER_ALIGN(sizeof(XLogCtlData) + sizeof(XLogRecPtr) * XLOGbuffers)
  		+ BLCKSZ * XLOGbuffers +
  		MAXALIGN(sizeof(ControlFileData));
  }
*************** XLOGShmemInit(void)
*** 3586,3592 ****
  
  	XLogCtl = (XLogCtlData *)
  		ShmemInitStruct("XLOG Ctl",
! 						MAXALIGN(sizeof(XLogCtlData) +
  								 sizeof(XLogRecPtr) * XLOGbuffers)
  						+ BLCKSZ * XLOGbuffers,
  						&foundXLog);
--- 3626,3632 ----
  
  	XLogCtl = (XLogCtlData *)
  		ShmemInitStruct("XLOG Ctl",
! 						XLOG_BUFFER_ALIGN(sizeof(XLogCtlData) +
  								 sizeof(XLogRecPtr) * XLOGbuffers)
  						+ BLCKSZ * XLOGbuffers,
  						&foundXLog);
*************** XLOGShmemInit(void)
*** 3615,3623 ****
  	 * Here, on the other hand, we must MAXALIGN to ensure the page
  	 * buffers have worst-case alignment.
  	 */
! 	XLogCtl->pages =
! 		((char *) XLogCtl) + MAXALIGN(sizeof(XLogCtlData) +
! 									  sizeof(XLogRecPtr) * XLOGbuffers);
  	memset(XLogCtl->pages, 0, BLCKSZ * XLOGbuffers);
  
  	/*
--- 3655,3663 ----
  	 * Here, on the other hand, we must MAXALIGN to ensure the page
  	 * buffers have worst-case alignment.
  	 */
! 	XLogCtl->pages = XLOG_BUFFER_POINTERALIGN(
! 		((char *) XLogCtl)
! 		+ sizeof(XLogCtlData) + sizeof(XLogRecPtr) * XLOGbuffers);
  	memset(XLogCtl->pages, 0, BLCKSZ * XLOGbuffers);
  
  	/*
*************** BootStrapXLOG(void)
*** 3647,3652 ****
--- 3687,3693 ----
  {
  	CheckPoint	checkPoint;
  	char	   *buffer;
+ 	char		buffer0[BLCKSZ + ALIGNOF_XLOG_BUFFER];
  	XLogPageHeader page;
  	XLogLongPageHeader longpage;
  	XLogRecord *record;
*************** BootStrapXLOG(void)
*** 3675,3682 ****
  	/* First timeline ID is always 1 */
  	ThisTimeLineID = 1;
  
! 	/* Use malloc() to ensure buffer is MAXALIGNED */
! 	buffer = (char *) malloc(BLCKSZ);
  	page = (XLogPageHeader) buffer;
  	memset(buffer, 0, BLCKSZ);
  
--- 3716,3722 ----
  	/* First timeline ID is always 1 */
  	ThisTimeLineID = 1;
  
! 	buffer = XLOG_BUFFER_POINTERALIGN(buffer0);
  	page = (XLogPageHeader) buffer;
  	memset(buffer, 0, BLCKSZ);
  
*************** assign_xlog_sync_method(const char *meth
*** 5431,5436 ****
--- 5471,5490 ----
  		new_sync_bit = OPEN_DATASYNC_FLAG;
  	}
  #endif
+ #ifdef FSYNC_DIRECT_FLAG
+ 	else if (pg_strcasecmp(method, "fsync_direct") == 0)
+ 	{
+ 		new_sync_method = SYNC_METHOD_FSYNC_DIRECT;
+ 		new_sync_bit = FSYNC_DIRECT_FLAG;
+ 	}
+ #endif
+ #ifdef OPEN_DIRECT_FLAG
+ 	else if (pg_strcasecmp(method, "open_direct") == 0)
+ 	{
+ 		new_sync_method = SYNC_METHOD_OPEN;
+ 		new_sync_bit = OPEN_DIRECT_FLAG;
+ 	}
+ #endif
  	else
  		return NULL;
  
