]> granicus.if.org Git - postgresql/commitdiff
TYPEALIGN doesn't work on int64 on 32-bit platforms.
authorHeikki Linnakangas <heikki.linnakangas@iki.fi>
Mon, 7 Oct 2013 22:59:57 +0000 (01:59 +0300)
committerHeikki Linnakangas <heikki.linnakangas@iki.fi>
Mon, 7 Oct 2013 22:59:57 +0000 (01:59 +0300)
The TYPEALIGN macro, and the related ones like MAXALIGN, don't work with
values larger than intptr_t, because TYPEALIGN casts the argument to
intptr_t to do the arithmetic. That's not a problem when dealing with
pointers or lengths or offsets related to pointers, but the XLogInsert
scaling patch added a call to MAXALIGN with an XLogRecPtr argument.

To fix, add wider variants of the macros, called TYPEALIGN64 and MAXALIGN64,
which are just like the existing variants but work with uint64 instead of
intptr_t.

Report and patch by David Rowley, analysis by Andres Freund.

src/backend/access/transam/xlog.c
src/include/c.h

index fc495d6a62df9782b990093d02fb2ffd190f0daa..06f5eb003cd2d9c238a59b9960457c191e39624b 100644 (file)
@@ -1482,7 +1482,7 @@ CopyXLogRecordToWAL(int write_len, bool isLogSwitch, XLogRecData *rdata,
        Assert(written == write_len);
 
        /* Align the end position, so that the next record starts aligned */
-       CurrPos = MAXALIGN(CurrPos);
+       CurrPos = MAXALIGN64(CurrPos);
 
        /*
         * If this was an xlog-switch, it's not enough to write the switch record,
index 14bfdcd4dab5afd18dde7303517388b1a1ee5a24..8916310b5bfa4a7b29761d335632c79ca62efdc3 100644 (file)
@@ -551,6 +551,18 @@ typedef NameData *Name;
 #define DOUBLEALIGN_DOWN(LEN)  TYPEALIGN_DOWN(ALIGNOF_DOUBLE, (LEN))
 #define MAXALIGN_DOWN(LEN)             TYPEALIGN_DOWN(MAXIMUM_ALIGNOF, (LEN))
 
+/*
+ * The above macros will not work with types wider than intptr_t, like with
+ * uint64 on 32-bit platforms.  That's not problem for the usual use where a
+ * pointer or a length is aligned, but for the odd case that you need to
+ * align something (potentially) wider, use TYPEALIGN64.
+ */
+#define TYPEALIGN64(ALIGNVAL,LEN)  \
+       (((uint64) (LEN) + ((ALIGNVAL) - 1)) & ~((uint64) ((ALIGNVAL) - 1)))
+
+/* we don't currently need wider versions of the other ALIGN macros */
+#define MAXALIGN64(LEN)                        TYPEALIGN64(MAXIMUM_ALIGNOF, (LEN))
+
 /* ----------------------------------------------------------------
  *                             Section 6:      assertions
  * ----------------------------------------------------------------