summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2017-11-03 16:09:43 +0200
committerMarko Mäkelä <marko.makela@mariadb.com>2017-11-06 08:53:51 +0200
commit51679e5c380e3a140c78a611c28d99bd3a8be2da (patch)
tree3f7f5b45d9959d49b325d33afb4b6ec7c5a644d8
parent30a8764b924a8d90cdd1ad7ad356e6a32b1b29ff (diff)
downloadmariadb-git-51679e5c380e3a140c78a611c28d99bd3a8be2da.tar.gz
MDEV-14132 InnoDB page corruption
On some old GNU/Linux systems, invoking posix_fallocate() with offset=0 would sometimes cause already allocated bytes in the data file to be overwritten. Fix a correctness regression that was introduced in commit 420798a81ac9a81d20629535fac3032e025e7733 by invoking posix_fallocate() in a safer way. A similar change was made in MDEV-5746 earlier. os_file_get_size(): Avoid changing the state of the file handle, by invoking fstat() instead of lseek(). os_file_set_size(): Determine the current size of the file by os_file_get_size(), and then extend the file from that point onwards.
-rw-r--r--storage/innobase/os/os0file.cc9
-rw-r--r--storage/xtradb/os/os0file.cc9
2 files changed, 12 insertions, 6 deletions
diff --git a/storage/innobase/os/os0file.cc b/storage/innobase/os/os0file.cc
index 7edf69a4571..e9abdc91ff8 100644
--- a/storage/innobase/os/os0file.cc
+++ b/storage/innobase/os/os0file.cc
@@ -2335,8 +2335,8 @@ os_file_get_size(
return(offset);
#else
- return((os_offset_t) lseek(file, 0, SEEK_END));
-
+ struct stat statbuf;
+ return fstat(file, &statbuf) ? os_offset_t(-1) : statbuf.st_size;
#endif /* __WIN__ */
}
@@ -2390,7 +2390,10 @@ os_file_set_size(
if (srv_use_posix_fallocate) {
int err;
do {
- err = posix_fallocate(file, 0, size);
+ os_offset_t current_size = os_file_get_size(file);
+ err = current_size >= size
+ ? 0 : posix_fallocate(file, current_size,
+ size - current_size);
} while (err == EINTR
&& srv_shutdown_state == SRV_SHUTDOWN_NONE);
diff --git a/storage/xtradb/os/os0file.cc b/storage/xtradb/os/os0file.cc
index 69b8a9da671..8b0fa059100 100644
--- a/storage/xtradb/os/os0file.cc
+++ b/storage/xtradb/os/os0file.cc
@@ -2570,8 +2570,8 @@ os_file_get_size(
return(offset);
#else
- return((os_offset_t) lseek(file, 0, SEEK_END));
-
+ struct stat statbuf;
+ return fstat(file, &statbuf) ? os_offset_t(-1) : statbuf.st_size;
#endif /* __WIN__ */
}
@@ -2625,7 +2625,10 @@ os_file_set_size(
if (srv_use_posix_fallocate) {
int err;
do {
- err = posix_fallocate(file, 0, size);
+ os_offset_t current_size = os_file_get_size(file);
+ err = current_size >= size
+ ? 0 : posix_fallocate(file, current_size,
+ size - current_size);
} while (err == EINTR
&& srv_shutdown_state == SRV_SHUTDOWN_NONE);