summaryrefslogtreecommitdiff
path: root/mysys
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2021-06-29 15:04:27 +0300
committerMarko Mäkelä <marko.makela@mariadb.com>2021-06-29 15:04:27 +0300
commit617dee34886987c53b14e09a9ee73abe923a18e4 (patch)
treecd06f3e9c6dace89412485c761ed6dda6a58e772 /mysys
parent3d15e3c0859a3ac73b968c3376e09f991ecb1adf (diff)
downloadmariadb-git-617dee34886987c53b14e09a9ee73abe923a18e4.tar.gz
MDEV-26042 Atomic write capability is not detected correctly
my_init_atomic_write(): Detect all forms of SSD, in case multiple types of devices are installed in the same machine. This was broken in commit ed008a74cf4cfe8619595ec71a6073a9e94f984c and further in commit 70684afef2ce6d797f78db192c4472260cd22660. SAME_DEV(): Match block devices, ignoring partition numbers. Let us use stat() instead of lstat(), in case someone has a symbolic link in /dev. Instead of reporting errors with perror(), let us use fprintf(stderr) with the file name, the impact of the error, and the strerror(errno). Because this code is specific to Linux, we may depend on the GNU libc/uClibc/musl extension %m for strerror(errno).
Diffstat (limited to 'mysys')
-rw-r--r--mysys/my_atomic_writes.c61
1 files changed, 32 insertions, 29 deletions
diff --git a/mysys/my_atomic_writes.c b/mysys/my_atomic_writes.c
index 34207a6fd07..cfd7dbb3cbf 100644
--- a/mysys/my_atomic_writes.c
+++ b/mysys/my_atomic_writes.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2016, MariaDB Corporation
+/* Copyright (c) 2016, 2021, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -24,6 +24,10 @@ my_bool has_shannon_atomic_write= 0, has_fusion_io_atomic_write= 0,
#include <sys/ioctl.h>
+/* Linux seems to allow up to 15 partitions per block device.
+Partition number 0 is the whole block device. */
+# define SAME_DEV(fs_dev, blk_dev) \
+ (fs_dev == blk_dev) || ((fs_dev & ~15U) == blk_dev)
/***********************************************************************
FUSION_IO
@@ -115,9 +119,9 @@ static my_bool test_if_shannon_card_exists()
sprintf(path, "/dev/df%c", dev_part);
#ifdef TEST_SHANNON
- if (lstat(path, &stat_buff) < 0)
+ if (stat(path, &stat_buff) < 0)
{
- printf("%s(): lstat failed.\n", __func__);
+ printf("%s(): stat %s failed.\n", __func__, path);
break;
}
#endif
@@ -147,7 +151,7 @@ static my_bool test_if_shannon_card_exists()
for (dev_no= 1 ; dev_no < 9 ; dev_no++)
{
sprintf(path, "/dev/df%c%d", dev_part, dev_no);
- if (lstat(path, &stat_buff) < 0)
+ if (stat(path, &stat_buff) < 0)
break;
shannon_devices[shannon_found_devices].st_dev= stat_buff.st_rdev;
@@ -194,12 +198,13 @@ static my_bool shannon_dev_has_atomic_write(struct shannon_dev *dev,
int fd= open(dev->dev_name, 0);
if (fd < 0)
{
- perror("open() failed!");
+ fprintf(stderr, "Unable to determine if atomic writes are supported:"
+ " open(\"%s\"): %m\n", dev->dev_name);
dev->atomic_size= 0; /* Don't try again */
return FALSE;
}
- dev->atomic_size= ioctl(fd, SHANNON_IOCQATOMIC_SIZE);
- close(fd);
+ dev->atomic_size= ioctl(fd, SHANNON_IOCQATOMIC_SIZE);
+ close(fd);
}
#ifdef TEST_SHANNON
@@ -248,7 +253,7 @@ static my_bool shannon_has_atomic_write(File file, int page_size)
#ifdef TEST_SHANNON
printf("%s(): st_rdev=0x%lx\n", __func__, (ulong) dev->st_dev);
#endif
- if (stat_buff.st_dev == dev->st_dev)
+ if (SAME_DEV(stat_buff.st_dev, dev->st_dev))
return shannon_dev_has_atomic_write(dev, page_size);
}
return 0;
@@ -290,8 +295,7 @@ static my_bool test_if_sfx_card_exists()
sprintf(sfx_devices[sfx_found_devices].dev_name, "/dev/sfdv%dn1",
dev_num);
- if (lstat(sfx_devices[sfx_found_devices].dev_name,
- &stat_buff) < 0)
+ if (stat(sfx_devices[sfx_found_devices].dev_name, &stat_buff) < 0)
break;
sfx_devices[sfx_found_devices].st_dev= stat_buff.st_rdev;
@@ -316,13 +320,15 @@ static my_bool sfx_dev_has_atomic_write(struct sfx_dev *dev,
int fd= open(dev->dev_name, 0);
if (fd < 0)
{
- perror("open() failed!");
+ fprintf(stderr, "Unable to determine if atomic writes are supported:"
+ " open(\"%s\"): %m\n", dev->dev_name);
dev->atomic_size= 0; /* Don't try again */
- return FALSE;
}
-
- dev->atomic_size= ioctl(fd, SFX_GET_ATOMIC_SIZE);
- close(fd);
+ else
+ {
+ dev->atomic_size= ioctl(fd, SFX_GET_ATOMIC_SIZE);
+ close(fd);
+ }
}
return (page_size <= dev->atomic_size);
@@ -346,16 +352,10 @@ static my_bool sfx_has_atomic_write(File file, int page_size)
struct sfx_dev *dev;
struct stat stat_buff;
- if (fstat(file, &stat_buff) < 0)
- {
- return 0;
- }
-
- for (dev = sfx_devices; dev->st_dev; dev++)
- {
- if (stat_buff.st_dev == dev->st_dev)
- return sfx_dev_has_atomic_write(dev, page_size);
- }
+ if (fstat(file, &stat_buff) == 0)
+ for (dev= sfx_devices; dev->st_dev; dev++)
+ if (SAME_DEV(stat_buff.st_dev, dev->st_dev))
+ return sfx_dev_has_atomic_write(dev, page_size);
return 0;
}
/***********************************************************************
@@ -369,10 +369,13 @@ static my_bool sfx_has_atomic_write(File file, int page_size)
void my_init_atomic_write(void)
{
- if ((has_shannon_atomic_write= test_if_shannon_card_exists()) ||
- (has_fusion_io_atomic_write= test_if_fusion_io_card_exists()) ||
- (has_sfx_atomic_write= test_if_sfx_card_exists()))
- my_may_have_atomic_write= 1;
+ has_shannon_atomic_write= test_if_shannon_card_exists();
+ has_fusion_io_atomic_write= test_if_fusion_io_card_exists();
+ has_sfx_atomic_write= test_if_sfx_card_exists();
+
+ my_may_have_atomic_write= has_shannon_atomic_write ||
+ has_fusion_io_atomic_write || has_sfx_atomic_write;
+
#ifdef TEST_SHANNON
printf("%s(): has_shannon_atomic_write=%d, my_may_have_atomic_write=%d\n",
__func__,