From 7d2d9f04b9d308745d1a99a47a67f17ced128562 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= <marko.makela@mariadb.com>
Date: Thu, 19 Aug 2021 11:29:32 +0300
Subject: [PATCH] MDEV-20931 fixup

The merge commit 4a2595727465648f2d4e794d1b2f182345f0bee8
caused a test failure on Windows. The suppression regexp
needs to accept the backslash.

fil_invalid_page_access_msg(): Simplify the implementation
and invoke sql_print_error() directly.

fil_space_t::io(): Invoke fil_invalid_page_access_msg() only from
one location.
---
 .../suite/innodb/r/import_corrupted.result    |  2 +-
 .../suite/innodb/t/import_corrupted.test      |  2 +-
 storage/innobase/fil/fil0fil.cc               | 45 ++++++++++---------
 3 files changed, 25 insertions(+), 24 deletions(-)

diff --git a/mysql-test/suite/innodb/r/import_corrupted.result b/mysql-test/suite/innodb/r/import_corrupted.result
index fe431e62eef..149a48dccfe 100644
--- a/mysql-test/suite/innodb/r/import_corrupted.result
+++ b/mysql-test/suite/innodb/r/import_corrupted.result
@@ -1,6 +1,6 @@
 call mtr.add_suppression("Table `test`.`t2` should have 2 indexes but the tablespace has 1 indexes");
 call mtr.add_suppression("Index for table 't2' is corrupt; try to repair it");
-call mtr.add_suppression("Trying to read .* bytes at .* outside the bounds of the file: ./test/t2.ibd");
+call mtr.add_suppression("Trying to read .* bytes at .* outside the bounds of the file: \\..test.t2\\.ibd");
 CREATE TABLE t1 (
 id INT AUTO_INCREMENT PRIMARY KEY,
 not_id INT,
diff --git a/mysql-test/suite/innodb/t/import_corrupted.test b/mysql-test/suite/innodb/t/import_corrupted.test
index fcdb03b4601..976cbe03dbb 100644
--- a/mysql-test/suite/innodb/t/import_corrupted.test
+++ b/mysql-test/suite/innodb/t/import_corrupted.test
@@ -2,7 +2,7 @@
 
 call mtr.add_suppression("Table `test`.`t2` should have 2 indexes but the tablespace has 1 indexes");
 call mtr.add_suppression("Index for table 't2' is corrupt; try to repair it");
-call mtr.add_suppression("Trying to read .* bytes at .* outside the bounds of the file: ./test/t2.ibd");
+call mtr.add_suppression("Trying to read .* bytes at .* outside the bounds of the file: \\..test.t2\\.ibd");
 
 let MYSQLD_DATADIR = `SELECT @@datadir`;
 
diff --git a/storage/innobase/fil/fil0fil.cc b/storage/innobase/fil/fil0fil.cc
index 1f3f73f3f8e..6af8b729d78 100644
--- a/storage/innobase/fil/fil0fil.cc
+++ b/storage/innobase/fil/fil0fil.cc
@@ -49,6 +49,7 @@ Created 10/25/1995 Heikki Tuuri
 #include "os0event.h"
 #include "sync0sync.h"
 #include "buf0flu.h"
+#include "log.h"
 #ifdef UNIV_LINUX
 # include <sys/types.h>
 # include <sys/sysmacros.h>
@@ -3217,14 +3218,17 @@ fil_space_for_table_exists_in_mem(
 
 /** Report information about an invalid page access. */
 ATTRIBUTE_COLD
-static std::string fil_invalid_page_access_msg(const char *name,
-                                               os_offset_t offset, ulint len,
-                                               bool is_read)
+static void fil_invalid_page_access_msg(bool fatal, const char *name,
+                                        os_offset_t offset, ulint len,
+                                        bool is_read)
 {
-  std::stringstream ss;
-  ss << "Trying to " << (is_read ? "read " : "write ") << len << " bytes at "
-     << offset << " outside the bounds of the file: " << name;
-  return ss.str();
+  sql_print_error("%s%s %zu bytes at " UINT64PF
+                  " outside the bounds of the file: %s",
+                  fatal ? "[FATAL] InnoDB: " : "InnoDB: ",
+                  is_read ? "Trying to read" : "Trying to write",
+                  len, offset, name);
+  if (fatal)
+    abort();
 }
 
 /** Update the data structures on write completion */
@@ -3280,6 +3284,7 @@ fil_io_t fil_space_t::io(const IORequest &type, os_offset_t offset, size_t len,
 	}
 
 	ulint p = static_cast<ulint>(offset >> srv_page_size_shift);
+	bool fatal;
 
 	if (UNIV_LIKELY_NULL(UT_LIST_GET_NEXT(chain, node))) {
 		ut_ad(this == fil_system.sys_space
@@ -3294,9 +3299,13 @@ fil_io_t fil_space_t::io(const IORequest &type, os_offset_t offset, size_t len,
 					release();
 					return {DB_ERROR, nullptr};
 				}
-				ib::fatal()
-					<< fil_invalid_page_access_msg(name,
-						offset, len, type.is_read());
+
+				fatal = true;
+fail:
+				fil_invalid_page_access_msg(fatal, node->name,
+							    offset, len,
+							    type.is_read());
+				return {DB_IO_ERROR, nullptr};
 			}
 		}
 
@@ -3304,25 +3313,17 @@ fil_io_t fil_space_t::io(const IORequest &type, os_offset_t offset, size_t len,
 	}
 
 	if (UNIV_UNLIKELY(node->size <= p)) {
+		release();
+
 		if (type.type == IORequest::READ_ASYNC) {
-			release();
 			/* If we can tolerate the non-existent pages, we
 			should return with DB_ERROR and let caller decide
 			what to do. */
 			return {DB_ERROR, nullptr};
 		}
 
-		if (node->space->purpose == FIL_TYPE_IMPORT) {
-			release();
-			ib::error() << fil_invalid_page_access_msg(
-				node->name, offset, len, type.is_read());
-
-
-			return {DB_IO_ERROR, nullptr};
-		}
-
-		ib::fatal() << fil_invalid_page_access_msg(
-			node->name, offset, len, type.is_read());
+		fatal = node->space->purpose != FIL_TYPE_IMPORT;
+		goto fail;
 	}
 
 	dberr_t err;
-- 
2.30.9