diff options
author | Qi Wu <qi.wu@scaleflux.com> | 2020-07-03 20:34:46 +0300 |
---|---|---|
committer | Monty <monty@mariadb.org> | 2020-07-03 22:42:10 +0300 |
commit | 70684afef2ce6d797f78db192c4472260cd22660 (patch) | |
tree | 9be4b019515faa8a27d168cd25f85de04028cd62 /mysys | |
parent | 7a4afad969e5cb903cdf82386398a75710f5ed80 (diff) | |
download | mariadb-git-70684afef2ce6d797f78db192c4472260cd22660.tar.gz |
Atomic write support for ScaleFlux NVMe SSD's
Diffstat (limited to 'mysys')
-rw-r--r-- | mysys/my_atomic_writes.c | 114 |
1 files changed, 112 insertions, 2 deletions
diff --git a/mysys/my_atomic_writes.c b/mysys/my_atomic_writes.c index b383af11ba8..34207a6fd07 100644 --- a/mysys/my_atomic_writes.c +++ b/mysys/my_atomic_writes.c @@ -19,7 +19,8 @@ my_bool my_may_have_atomic_write= IF_WIN(1,0); #ifdef __linux__ -my_bool has_shannon_atomic_write= 0, has_fusion_io_atomic_write= 0; +my_bool has_shannon_atomic_write= 0, has_fusion_io_atomic_write= 0, + has_sfx_atomic_write= 0; #include <sys/ioctl.h> @@ -255,6 +256,109 @@ static my_bool shannon_has_atomic_write(File file, int page_size) /*********************************************************************** + ScaleFlux +************************************************************************/ + +#define SFX_GET_ATOMIC_SIZE _IO('N', 0x244) +#define SFX_MAX_DEVICES 32 +#define SFX_NO_ATOMIC_SIZE_YET -2 + +struct sfx_dev +{ + char dev_name[32]; + dev_t st_dev; + int atomic_size; +}; + +static struct sfx_dev sfx_devices[SFX_MAX_DEVICES + 1]; + +/** + Check if the system has a ScaleFlux card + If card exists, record device numbers to allow us to later check if + a given file is on this device. + @return TRUE Card exists +*/ + +static my_bool test_if_sfx_card_exists() +{ + uint sfx_found_devices = 0; + uint dev_num; + + for (dev_num = 0; dev_num < SFX_MAX_DEVICES; dev_num++) + { + struct stat stat_buff; + + 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) + break; + + sfx_devices[sfx_found_devices].st_dev= stat_buff.st_rdev; + /* + The atomic size will be checked on first access. This is needed + as a normal user can't open the /dev/sfdvXn1 file + */ + sfx_devices[sfx_found_devices].atomic_size = SFX_NO_ATOMIC_SIZE_YET; + if (++sfx_found_devices == SFX_MAX_DEVICES) + goto end; + } +end: + sfx_devices[sfx_found_devices].st_dev= 0; + return sfx_found_devices > 0; +} + +static my_bool sfx_dev_has_atomic_write(struct sfx_dev *dev, + int page_size) +{ + if (dev->atomic_size == SFX_NO_ATOMIC_SIZE_YET) + { + int fd= open(dev->dev_name, 0); + if (fd < 0) + { + perror("open() failed!"); + dev->atomic_size= 0; /* Don't try again */ + return FALSE; + } + + dev->atomic_size= ioctl(fd, SFX_GET_ATOMIC_SIZE); + close(fd); + } + + return (page_size <= dev->atomic_size); +} + + +/** + Check if a file is on a ScaleFlux device and that it supports atomic_write + @param[in] file OS file handle + @param[in] page_size page size + @return TRUE Atomic write supported + + @notes + This is called only at first open of a file. In this case it's doesn't + matter so much that we loop over all cards. + We update the atomic size on first access. +*/ + +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); + } + return 0; +} +/*********************************************************************** Generic atomic write code ************************************************************************/ @@ -266,7 +370,8 @@ static my_bool shannon_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_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; #ifdef TEST_SHANNON printf("%s(): has_shannon_atomic_write=%d, my_may_have_atomic_write=%d\n", @@ -294,6 +399,7 @@ my_bool my_test_if_atomic_write(File handle, int page_size) #endif if (!my_may_have_atomic_write) return 0; + if (has_shannon_atomic_write && shannon_has_atomic_write(handle, page_size)) return 1; @@ -302,6 +408,10 @@ my_bool my_test_if_atomic_write(File handle, int page_size) fusion_io_has_atomic_write(handle, page_size)) return 1; + if (has_sfx_atomic_write && + sfx_has_atomic_write(handle, page_size)) + return 1; + return 0; } |