diff --git a/src/backend/storage/ipc/shmem.c b/src/backend/storage/ipc/shmem.c
index f2bdc3eb91dbffb05889d21442ec9d439444d7a9..0b80e0585ec58ad090e28241d977ee0a9b0cdbd0 100644
--- a/src/backend/storage/ipc/shmem.c
+++ b/src/backend/storage/ipc/shmem.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/storage/ipc/shmem.c,v 1.70 2003/08/04 02:40:03 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/storage/ipc/shmem.c,v 1.71 2003/09/21 17:57:21 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -131,6 +131,7 @@ InitShmemAllocation(void *seghdr)
 void *
 ShmemAlloc(Size size)
 {
+	uint32		newStart;
 	uint32		newFree;
 	void	   *newSpace;
 
@@ -146,10 +147,16 @@ ShmemAlloc(Size size)
 
 	SpinLockAcquire(ShmemLock);
 
-	newFree = shmemseghdr->freeoffset + size;
+	newStart = shmemseghdr->freeoffset;
+
+	/* extra alignment for large requests, since they are probably buffers */
+	if (size >= BLCKSZ)
+		newStart = BUFFERALIGN(newStart);
+
+	newFree = newStart + size;
 	if (newFree <= shmemseghdr->totalsize)
 	{
-		newSpace = (void *) MAKE_PTR(shmemseghdr->freeoffset);
+		newSpace = (void *) MAKE_PTR(newStart);
 		shmemseghdr->freeoffset = newFree;
 	}
 	else
diff --git a/src/include/c.h b/src/include/c.h
index 02d47bfe4617b9e015cef3d031f91e3a455ea672..934e976803cd541e7ae81c7082429114ac0f2f97 100644
--- a/src/include/c.h
+++ b/src/include/c.h
@@ -12,7 +12,7 @@
  * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: c.h,v 1.152 2003/08/04 02:40:10 momjian Exp $
+ * $Id: c.h,v 1.153 2003/09/21 17:57:21 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -522,13 +522,16 @@ typedef NameData *Name;
  * ----------------
  */
 
-#define TYPEALIGN(ALIGNVAL,LEN) (((long)(LEN) + (ALIGNVAL-1)) & ~(ALIGNVAL-1))
+#define TYPEALIGN(ALIGNVAL,LEN)  \
+	(((long) (LEN) + (ALIGNVAL-1)) & ~((long) (ALIGNVAL-1)))
 
 #define SHORTALIGN(LEN)			TYPEALIGN(ALIGNOF_SHORT, (LEN))
 #define INTALIGN(LEN)			TYPEALIGN(ALIGNOF_INT, (LEN))
 #define LONGALIGN(LEN)			TYPEALIGN(ALIGNOF_LONG, (LEN))
 #define DOUBLEALIGN(LEN)		TYPEALIGN(ALIGNOF_DOUBLE, (LEN))
 #define MAXALIGN(LEN)			TYPEALIGN(MAXIMUM_ALIGNOF, (LEN))
+/* MAXALIGN covers only built-in types, not buffers */
+#define BUFFERALIGN(LEN)		TYPEALIGN(ALIGNOF_BUFFER, (LEN))
 
 
 /* ----------------------------------------------------------------
diff --git a/src/include/pg_config_manual.h b/src/include/pg_config_manual.h
index 451ef351e65a767fc37243af1670dde58afb7e3d..98d357760dc7b03a1b2de4013a0adc506be23aa9 100644
--- a/src/include/pg_config_manual.h
+++ b/src/include/pg_config_manual.h
@@ -6,7 +6,7 @@
  * for developers.	If you edit any of these, be sure to do a *full*
  * rebuild (and an initdb if noted).
  *
- * $Id: pg_config_manual.h,v 1.5 2003/08/04 00:43:29 momjian Exp $
+ * $Id: pg_config_manual.h,v 1.6 2003/09/21 17:57:21 tgl Exp $
  *------------------------------------------------------------------------
  */
 
@@ -126,6 +126,14 @@
  */
 #define BITS_PER_BYTE		8
 
+/*
+ * Preferred alignment for disk I/O buffers.  On some CPUs, copies between
+ * user space and kernel space are significantly faster if the user buffer
+ * is aligned on a larger-than-MAXALIGN boundary.  Ideally this should be
+ * a platform-dependent value, but for now we just hard-wire it.
+ */
+#define ALIGNOF_BUFFER	32
+
 /*
  * Disable UNIX sockets for those operating system.
  */