@@ -265,6 +265,87 @@ xb_fil_cur_open(
265
265
return (XB_FIL_CUR_SUCCESS);
266
266
}
267
267
268
+ static bool page_is_corrupted (byte *page, ulint page_no, xb_fil_cur_t *cursor, fil_space_t *space)
269
+ {
270
+ byte tmp_frame[UNIV_PAGE_SIZE_MAX];
271
+ byte tmp_page[UNIV_PAGE_SIZE_MAX];
272
+
273
+ ulint page_type = mach_read_from_2 (page + FIL_PAGE_TYPE);
274
+
275
+ /* We ignore the doublewrite buffer pages.*/
276
+ if (cursor->space_id == TRX_SYS_SPACE
277
+ && page_no >= FSP_EXTENT_SIZE
278
+ && page_no < FSP_EXTENT_SIZE * 3 ) {
279
+ return false ;
280
+ }
281
+
282
+ /* Validate page number. */
283
+ if (mach_read_from_4 (page + FIL_PAGE_OFFSET) != page_no
284
+ && space->id != TRX_SYS_SPACE) {
285
+ /* On pages that are not all zero, the
286
+ page number must match.
287
+
288
+ There may be a mismatch on tablespace ID,
289
+ because files may be renamed during backup.
290
+ We disable the page number check
291
+ on the system tablespace, because it may consist
292
+ of multiple files, and here we count the pages
293
+ from the start of each file.)
294
+
295
+ The first 38 and last 8 bytes are never encrypted. */
296
+ const ulint* p = reinterpret_cast <ulint*>(page);
297
+ const ulint* const end = reinterpret_cast <ulint*>(
298
+ page + cursor->page_size );
299
+ do {
300
+ if (*p++) {
301
+ return true ;
302
+ }
303
+ } while (p != end);
304
+
305
+ /* Whole zero page is valid. */
306
+ return false ;
307
+ }
308
+
309
+ /* Validate encrypted pages. */
310
+ if (mach_read_from_4 (page + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION) &&
311
+ (space->crypt_data && space->crypt_data ->type != CRYPT_SCHEME_UNENCRYPTED)) {
312
+
313
+ if (!fil_space_verify_crypt_checksum (page, cursor->zip_size ))
314
+ return true ;
315
+
316
+ /* Compressed encrypted need to be unencryped and uncompressed for verification. */
317
+ if (page_type != FIL_PAGE_PAGE_COMPRESSED_ENCRYPTED && !opt_extended_validation)
318
+ return false ;
319
+
320
+ memcpy (tmp_page, page, cursor->page_size );
321
+
322
+ bool decrypted = false ;
323
+ if (!fil_space_decrypt (space, tmp_frame,tmp_page, &decrypted)) {
324
+ return true ;
325
+ }
326
+
327
+ if (page_type != FIL_PAGE_PAGE_COMPRESSED_ENCRYPTED) {
328
+ return buf_page_is_corrupted (true , tmp_page, cursor->zip_size , space);
329
+ }
330
+ }
331
+
332
+ if (page_type == FIL_PAGE_PAGE_COMPRESSED) {
333
+ memcpy (tmp_page, page, cursor->page_size );
334
+ }
335
+
336
+ if (page_type == FIL_PAGE_PAGE_COMPRESSED || page_type == FIL_PAGE_PAGE_COMPRESSED_ENCRYPTED) {
337
+ ulint decomp = fil_page_decompress (tmp_frame, tmp_page);
338
+ page_type = mach_read_from_2 (tmp_page + FIL_PAGE_TYPE);
339
+
340
+ return (!decomp
341
+ || (decomp != srv_page_size && cursor->zip_size )
342
+ || page_type == FIL_PAGE_PAGE_COMPRESSED
343
+ || page_type == FIL_PAGE_PAGE_COMPRESSED_ENCRYPTED
344
+ || buf_page_is_corrupted (true , tmp_page, cursor->zip_size , space));
345
+ }
346
+
347
+ return buf_page_is_corrupted (true , page, cursor->zip_size , space);
348
+ }
268
349
/* ***********************************************************************
269
350
Reads and verifies the next block of pages from the source
270
351
file. Positions the cursor after the last read non-corrupted page.
@@ -284,8 +365,6 @@ xb_fil_cur_read(
284
365
xb_fil_cur_result_t ret;
285
366
ib_int64_t offset;
286
367
ib_int64_t to_read;
287
- byte tmp_frame[UNIV_PAGE_SIZE_MAX];
288
- byte tmp_page[UNIV_PAGE_SIZE_MAX];
289
368
290
369
cursor->read_filter ->get_next_batch (&cursor->read_filter_ctxt ,
291
370
&offset, &to_read);
@@ -347,78 +426,8 @@ xb_fil_cur_read(
347
426
for (page = cursor->buf , i = 0 ; i < npages;
348
427
page += cursor->page_size , i++) {
349
428
ulint page_no = cursor->buf_page_no + i;
350
- ulint page_type = mach_read_from_2 (page + FIL_PAGE_TYPE);
351
-
352
- if (cursor->space_id == TRX_SYS_SPACE
353
- && page_no >= FSP_EXTENT_SIZE
354
- && page_no < FSP_EXTENT_SIZE * 3 ) {
355
- /* We ignore the doublewrite buffer pages */
356
- } else if (mach_read_from_4 (page + FIL_PAGE_OFFSET) != page_no
357
- && space->id != TRX_SYS_SPACE) {
358
- /* On pages that are not all zero, the
359
- page number must match.
360
-
361
- There may be a mismatch on tablespace ID,
362
- because files may be renamed during backup.
363
- We disable the page number check
364
- on the system tablespace, because it may consist
365
- of multiple files, and here we count the pages
366
- from the start of each file.)
367
-
368
- The first 38 and last 8 bytes are never encrypted. */
369
- const ulint* p = reinterpret_cast <ulint*>(page);
370
- const ulint* const end = reinterpret_cast <ulint*>(
371
- page + cursor->page_size );
372
- do {
373
- if (*p++) {
374
- goto corrupted;
375
- }
376
- } while (p != end);
377
- } else if (mach_read_from_4 (
378
- page
379
- + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION)
380
- && space->crypt_data
381
- && space->crypt_data ->type
382
- != CRYPT_SCHEME_UNENCRYPTED
383
- && fil_space_verify_crypt_checksum (
384
- page, cursor->zip_size )) {
385
- bool decrypted = false ;
386
-
387
- memcpy (tmp_page, page, cursor->page_size );
388
-
389
- if (!fil_space_decrypt (space, tmp_frame,
390
- tmp_page, &decrypted)) {
391
- goto corrupted;
392
- }
393
-
394
- if (page_type == FIL_PAGE_PAGE_COMPRESSED_ENCRYPTED) {
395
- goto page_decomp;
396
- }
397
-
398
- if (buf_page_is_corrupted (
399
- true , tmp_page, cursor->zip_size , space)) {
400
- goto corrupted;
401
- }
402
- } else if (page_type == FIL_PAGE_PAGE_COMPRESSED) {
403
- memcpy (tmp_page, page, cursor->page_size );
404
- page_decomp:
405
- ulint decomp = fil_page_decompress (tmp_frame, tmp_page);
406
- page_type = mach_read_from_2 (tmp_page + FIL_PAGE_TYPE);
407
-
408
- if (!decomp
409
- || (decomp != srv_page_size && cursor->zip_size )
410
- || page_type == FIL_PAGE_PAGE_COMPRESSED
411
- || page_type == FIL_PAGE_PAGE_COMPRESSED_ENCRYPTED
412
- || buf_page_is_corrupted (true , tmp_page,
413
- cursor->zip_size ,
414
- space)) {
415
- goto corrupted;
416
- }
417
429
418
- } else if (page_type == FIL_PAGE_PAGE_COMPRESSED_ENCRYPTED
419
- || buf_page_is_corrupted (true , page,
420
- cursor->zip_size , space)) {
421
- corrupted:
430
+ if (page_is_corrupted (page, page_no, cursor, space)){
422
431
retry_count--;
423
432
424
433
if (retry_count == 0 ) {
0 commit comments