Skip to content

Commit 58252ff

Browse files
committed
MDEV-26040 os_file_set_size() may not work on O_DIRECT files
os_file_set_size(): Trim the current size down to the file system block size, to obey the constraints for unbuffered I/O.
1 parent 8147d2e commit 58252ff

File tree

1 file changed

+33
-5
lines changed

1 file changed

+33
-5
lines changed

storage/innobase/os/os0file.cc

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5420,6 +5420,8 @@ os_file_set_size(
54205420

54215421
fallback:
54225422
#else
5423+
struct stat statbuf;
5424+
54235425
if (is_sparse) {
54245426
bool success = !ftruncate(file, size);
54255427
if (!success) {
@@ -5433,10 +5435,17 @@ os_file_set_size(
54335435
# ifdef HAVE_POSIX_FALLOCATE
54345436
int err;
54355437
do {
5436-
os_offset_t current_size = os_file_get_size(file);
5437-
err = current_size >= size
5438-
? 0 : posix_fallocate(file, current_size,
5438+
if (fstat(file, &statbuf)) {
5439+
err = errno;
5440+
} else {
5441+
os_offset_t current_size = statbuf.st_size;
5442+
if (current_size >= size) {
5443+
return true;
5444+
}
5445+
current_size &= ~os_offset_t(statbuf.st_blksize - 1);
5446+
err = posix_fallocate(file, current_size,
54395447
size - current_size);
5448+
}
54405449
} while (err == EINTR
54415450
&& srv_shutdown_state <= SRV_SHUTDOWN_INITIATED);
54425451

@@ -5459,6 +5468,27 @@ os_file_set_size(
54595468
# endif /* HAVE_POSIX_ALLOCATE */
54605469
#endif /* _WIN32*/
54615470

5471+
#ifdef _WIN32
5472+
os_offset_t current_size = os_file_get_size(file);
5473+
FILE_STORAGE_INFO info;
5474+
if (GetFileInformationByHandleEx(file, FileStorageInfo, &info,
5475+
sizeof info)) {
5476+
if (info.LogicalBytesPerSector) {
5477+
current_size &= ~os_offset_t(info.LogicalBytesPerSector
5478+
- 1);
5479+
}
5480+
}
5481+
#else
5482+
if (fstat(file, &statbuf)) {
5483+
return false;
5484+
}
5485+
os_offset_t current_size = statbuf.st_size
5486+
& ~os_offset_t(statbuf.st_blksize - 1);
5487+
#endif
5488+
if (current_size >= size) {
5489+
return true;
5490+
}
5491+
54625492
/* Write up to 1 megabyte at a time. */
54635493
ulint buf_size = ut_min(
54645494
static_cast<ulint>(64),
@@ -5476,8 +5506,6 @@ os_file_set_size(
54765506
/* Write buffer full of zeros */
54775507
memset(buf, 0, buf_size);
54785508

5479-
os_offset_t current_size = os_file_get_size(file);
5480-
54815509
while (current_size < size
54825510
&& srv_shutdown_state <= SRV_SHUTDOWN_INITIATED) {
54835511
ulint n_bytes;

0 commit comments

Comments
 (0)