From b477649c6c50aba8d52e6a578159e02bf931986d Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Sun, 13 Jul 2008 21:50:04 +0000 Subject: [PATCH] Change the PageGetContents() macro to guarantee its result is maxalign'd, 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 | 9 +++------ src/include/access/gin.h | 18 ++++++++++-------- src/include/storage/bufpage.h | 6 +++++- 3 files changed, 18 insertions(+), 15 deletions(-) diff --git a/src/backend/storage/page/bufpage.c b/src/backend/storage/page/bufpage.c index f8c86dfa1c..fb4e953dd1 100644 --- a/src/backend/storage/page/bufpage.c +++ b/src/backend/storage/page/bufpage.c @@ -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; } diff --git a/src/include/access/gin.h b/src/include/access/gin.h index 92e8413248..1e6bba7c2f 100644 --- a/src/include/access/gin.h +++ b/src/include/access/gin.h @@ -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 diff --git a/src/include/storage/bufpage.h b/src/include/storage/bufpage.h index cabc48f68b..5a7fd1bdd1 100644 --- a/src/include/storage/bufpage.h +++ b/src/include/storage/bufpage.h @@ -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 -- 2.39.5