Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit8c62d9d

Browse files
committed
Make checksum_impl.h safe to compile with -fstrict-aliasing.
In general, Postgres requires -fno-strict-aliasing with compilers thatimplement C99 strict aliasing rules. There's little hope of gettingrid of that overall. But it seems like it would be a good idea ifstorage/checksum_impl.h in particular didn't depend on it, becausethat header is explicitly intended to be included by external programs.We don't have a lot of control over the compiler switches that anexternal program might use, as shown by Michael Banck's report offailure in a privately-modified version of pg_verify_checksums.Hence, switch to using a union in place of willy-nilly pointer castinginside this file. I think this makes the code a bit more readableanyway.checksum_impl.h hasn't changed since it was introduced in 9.3,so back-patch all the way.Discussion:https://postgr.es/m/1535618100.1286.3.camel@credativ.de
1 parent7cfdc77 commit8c62d9d

File tree

1 file changed

+23
-15
lines changed

1 file changed

+23
-15
lines changed

‎src/include/storage/checksum_impl.h

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,13 @@
107107
/* prime multiplier of FNV-1a hash */
108108
#defineFNV_PRIME 16777619
109109

110+
/* Use a union so that this code is valid under strict aliasing */
111+
typedefunion
112+
{
113+
PageHeaderDataphdr;
114+
uint32data[BLCKSZ / (sizeof(uint32)*N_SUMS)][N_SUMS];
115+
}PGChecksummablePage;
116+
110117
/*
111118
* Base offsets to initialize each of the parallel FNV hashes into a
112119
* different initial state.
@@ -132,28 +139,27 @@ do { \
132139
} while (0)
133140

134141
/*
135-
* Block checksum algorithm. Thedata argumentmust bealigned on a 4-byte
136-
* boundary.
142+
* Block checksum algorithm. Thepagemust beadequately aligned
143+
*(at least on 4-byteboundary).
137144
*/
138145
staticuint32
139-
pg_checksum_block(char*data,uint32size)
146+
pg_checksum_block(constPGChecksummablePage*page)
140147
{
141148
uint32sums[N_SUMS];
142-
uint32(*dataArr)[N_SUMS]= (uint32 (*)[N_SUMS])data;
143149
uint32result=0;
144150
uint32i,
145151
j;
146152

147153
/* ensure that the size is compatible with the algorithm */
148-
Assert((size % (sizeof(uint32)*N_SUMS))==0);
154+
Assert(sizeof(PGChecksummablePage)==BLCKSZ);
149155

150156
/* initialize partial checksums to their corresponding offsets */
151157
memcpy(sums,checksumBaseOffsets,sizeof(checksumBaseOffsets));
152158

153159
/* main checksum calculation */
154-
for (i=0;i<size /sizeof(uint32)/N_SUMS;i++)
160+
for (i=0;i<(uint32) (BLCKSZ / (sizeof(uint32)*N_SUMS));i++)
155161
for (j=0;j<N_SUMS;j++)
156-
CHECKSUM_COMP(sums[j],dataArr[i][j]);
162+
CHECKSUM_COMP(sums[j],page->data[i][j]);
157163

158164
/* finally add in two rounds of zeroes for additional mixing */
159165
for (i=0;i<2;i++)
@@ -168,8 +174,10 @@ pg_checksum_block(char *data, uint32 size)
168174
}
169175

170176
/*
171-
* Compute the checksum for a Postgres page. The page must be aligned on a
172-
* 4-byte boundary.
177+
* Compute the checksum for a Postgres page.
178+
*
179+
* The page must be adequately aligned (at least on a 4-byte boundary).
180+
* Beware also that the checksum field of the page is transiently zeroed.
173181
*
174182
* The checksum includes the block number (to detect the case where a page is
175183
* somehow moved to a different location), the page header (excluding the
@@ -178,23 +186,23 @@ pg_checksum_block(char *data, uint32 size)
178186
uint16
179187
pg_checksum_page(char*page,BlockNumberblkno)
180188
{
181-
PageHeaderphdr= (PageHeader)page;
189+
PGChecksummablePage*cpage= (PGChecksummablePage*)page;
182190
uint16save_checksum;
183191
uint32checksum;
184192

185193
/* We only calculate the checksum for properly-initialized pages */
186-
Assert(!PageIsNew(page));
194+
Assert(!PageIsNew(&cpage->phdr));
187195

188196
/*
189197
* Save pd_checksum and temporarily set it to zero, so that the checksum
190198
* calculation isn't affected by the old checksum stored on the page.
191199
* Restore it after, because actually updating the checksum is NOT part of
192200
* the API of this function.
193201
*/
194-
save_checksum=phdr->pd_checksum;
195-
phdr->pd_checksum=0;
196-
checksum=pg_checksum_block(page,BLCKSZ);
197-
phdr->pd_checksum=save_checksum;
202+
save_checksum=cpage->phdr.pd_checksum;
203+
cpage->phdr.pd_checksum=0;
204+
checksum=pg_checksum_block(cpage);
205+
cpage->phdr.pd_checksum=save_checksum;
198206

199207
/* Mix in the block number to detect transposed pages */
200208
checksum ^=blkno;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp