Change the PageGetContents() macro to guarantee its result is maxalign'd,
authorTom Lane <tgl@sss.pgh.pa.us>
Sun, 13 Jul 2008 21:50:04 +0000 (21:50 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Sun, 13 Jul 2008 21:50:04 +0000 (21:50 +0000)
thereby forestalling any problems with alignment of the data structure placed
there.  Since SizeOfPageHeaderData is maxalign'd anyway in 8.3 and HEAD, this
does not actually change anything right now, but it is foreseeable that the
header size will change again someday.  I had to fix a couple of places that
were assuming that the content offset is just SizeOfPageHeaderData rather than
MAXALIGN(SizeOfPageHeaderData).  Per discussion of Zdenek's page-macros patch.

src/backend/storage/page/bufpage.c
src/include/access/gin.h
src/include/storage/bufpage.h

index f8c86dfa1c892316e26cefabf48c2e716d6fa087..fb4e953dd1f2258efa406a0b72f66a74bd386fef 100644 (file)
@@ -260,7 +260,6 @@ Page
 PageGetTempPage(Page page, Size specialSize)
 {
        Size            pageSize;
-       Size            size;
        Page            temp;
        PageHeader      thdr;
 
@@ -271,15 +270,13 @@ PageGetTempPage(Page page, Size specialSize)
        /* copy old page in */
        memcpy(temp, page, pageSize);
 
-       /* clear out the middle */
-       size = pageSize - SizeOfPageHeaderData;
-       size -= MAXALIGN(specialSize);
-       MemSet(PageGetContents(thdr), 0, size);
-
        /* set high, low water marks */
        thdr->pd_lower = SizeOfPageHeaderData;
        thdr->pd_upper = pageSize - MAXALIGN(specialSize);
 
+       /* clear out the middle */
+       MemSet((char *) temp + thdr->pd_lower, 0, thdr->pd_upper - thdr->pd_lower);
+
        return temp;
 }
 
index 92e84132483cba8abdd277403544b57cd5c411e1..1e6bba7c2f64418035bc1cdd15dd601be7b040cf 100644 (file)
@@ -121,17 +121,19 @@ typedef struct
 /*
  * Data (posting tree) pages
  */
+#define GinDataPageGetRightBound(page) ((ItemPointer) PageGetContents(page))
 #define GinDataPageGetData(page)       \
-       (PageGetContents(page)+MAXALIGN(sizeof(ItemPointerData)))
-#define GinDataPageGetRightBound(page) ((ItemPointer)PageGetContents(page))
-#define GinSizeOfItem(page) ( (GinPageIsLeaf(page)) ? sizeof(ItemPointerData) : sizeof(PostingItem) )
-#define GinDataPageGetItem(page,i) ( GinDataPageGetData(page) + ((i)-1) * GinSizeOfItem(page) )
+       (PageGetContents(page) + MAXALIGN(sizeof(ItemPointerData)))
+#define GinSizeOfItem(page)    \
+       (GinPageIsLeaf(page) ? sizeof(ItemPointerData) : sizeof(PostingItem))
+#define GinDataPageGetItem(page,i)     \
+       (GinDataPageGetData(page) + ((i)-1) * GinSizeOfItem(page))
 
 #define GinDataPageGetFreeSpace(page)  \
-       ( BLCKSZ - SizeOfPageHeaderData - MAXALIGN(sizeof(GinPageOpaqueData)) - \
-               GinPageGetOpaque(page)->maxoff * GinSizeOfItem(page) - \
-               MAXALIGN(sizeof(ItemPointerData)))
-
+       (BLCKSZ - MAXALIGN(SizeOfPageHeaderData) \
+        - MAXALIGN(sizeof(ItemPointerData)) \
+        - GinPageGetOpaque(page)->maxoff * GinSizeOfItem(page) \
+        - MAXALIGN(sizeof(GinPageOpaqueData)))
 
 
 #define GIN_UNLOCK     BUFFER_LOCK_UNLOCK
index cabc48f68b6c3c9f70e0e92eeff51cd1042a53a8..5a7fd1bdd16996f21de9a153d891827a02032650 100644 (file)
@@ -206,9 +206,13 @@ typedef PageHeaderData *PageHeader;
 /*
  * PageGetContents
  *             To be used in case the page does not contain item pointers.
+ *
+ * Note: prior to 8.3 this was not guaranteed to yield a MAXALIGN'd result.
+ * Now it is.  Beware of old code that might think the offset to the contents
+ * is just SizeOfPageHeaderData rather than MAXALIGN(SizeOfPageHeaderData).
  */
 #define PageGetContents(page) \
-       ((char *) (&((PageHeader) (page))->pd_linp[0]))
+       ((char *) (page) + MAXALIGN(SizeOfPageHeaderData))
 
 /* ----------------
  *             macros to access page size info