mirror of
https://github.com/MariaDB/server.git
synced 2025-01-15 19:42:28 +01:00
MDEV-26029: Implement my_test_if_thinly_provisioned() for ScaleFlux
This is based on code that was contributed by Ning Zheng and Ray Kuan from ScaleFlux.
This commit is contained in:
parent
30edd5549d
commit
4b0070f642
2 changed files with 104 additions and 20 deletions
|
@ -183,11 +183,12 @@ extern BOOL my_obtain_privilege(LPCSTR lpPrivilege);
|
|||
#endif
|
||||
|
||||
void my_init_atomic_write(void);
|
||||
#define my_test_if_thinly_provisioned(A) 0
|
||||
#ifdef __linux__
|
||||
my_bool my_test_if_atomic_write(File handle, int pagesize);
|
||||
my_bool my_test_if_thinly_provisioned(File handle);
|
||||
#else
|
||||
# define my_test_if_atomic_write(A, B) 0
|
||||
# define my_test_if_thinly_provisioned(A) 0
|
||||
#endif /* __linux__ */
|
||||
extern my_bool my_may_have_atomic_write;
|
||||
|
||||
|
|
|
@ -19,8 +19,9 @@ 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,
|
||||
has_sfx_atomic_write= 0;
|
||||
my_bool has_shannon_atomic_write, has_fusion_io_atomic_write,
|
||||
has_sfx_atomic_write;
|
||||
my_bool has_sfx_card;
|
||||
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
|
@ -225,7 +226,7 @@ static my_bool shannon_dev_has_atomic_write(struct shannon_dev *dev,
|
|||
@return TRUE Atomic write supported
|
||||
|
||||
@notes
|
||||
This is called only at first open of a file. In this case it's doesn't
|
||||
This is called only at first open of a file. In this case it doesn't
|
||||
matter so much that we loop over all cards.
|
||||
We update the atomic size on first access.
|
||||
*/
|
||||
|
@ -264,15 +265,26 @@ 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
|
||||
#define SFX_GET_ATOMIC_SIZE _IOR('N', 0x243, int)
|
||||
#define SFX_MAX_DEVICES (32)
|
||||
#define SFX_UNKNOWN_ATOMIC_WRITE_YET (-2)
|
||||
#define SFX_MAX_ATOMIC_SIZE (256 * 1024)
|
||||
|
||||
#define SFX_GET_SPACE_RATIO _IO('N', 0x244)
|
||||
#define SFX_UNKNOWN_PUNCH_HOLE_YET (-3)
|
||||
|
||||
/**
|
||||
Threshold for logical_space / physical_space
|
||||
No less than the threshold means we can disable hole punching
|
||||
*/
|
||||
#define SFX_DISABLE_PUNCH_HOLE_RATIO (2)
|
||||
|
||||
struct sfx_dev
|
||||
{
|
||||
char dev_name[32];
|
||||
dev_t st_dev;
|
||||
int atomic_size;
|
||||
int atomic_write;
|
||||
int disable_punch_hole;
|
||||
};
|
||||
|
||||
static struct sfx_dev sfx_devices[SFX_MAX_DEVICES + 1];
|
||||
|
@ -280,7 +292,8 @@ 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.
|
||||
a given file is on this device
|
||||
Variables for atomic_write and disable_punch_hole will be initialized
|
||||
@return TRUE Card exists
|
||||
*/
|
||||
|
||||
|
@ -303,38 +316,41 @@ static my_bool test_if_sfx_card_exists()
|
|||
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;
|
||||
sfx_devices[sfx_found_devices].atomic_write= SFX_UNKNOWN_ATOMIC_WRITE_YET;
|
||||
sfx_devices[sfx_found_devices].disable_punch_hole=
|
||||
SFX_UNKNOWN_PUNCH_HOLE_YET;
|
||||
if (++sfx_found_devices == SFX_MAX_DEVICES)
|
||||
goto end;
|
||||
}
|
||||
end:
|
||||
sfx_devices[sfx_found_devices].st_dev= 0;
|
||||
has_sfx_card = (sfx_found_devices > 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 result= -1, max_atomic_size= SFX_MAX_ATOMIC_SIZE;
|
||||
|
||||
if (dev->atomic_write == SFX_UNKNOWN_ATOMIC_WRITE_YET)
|
||||
{
|
||||
int fd= open(dev->dev_name, 0);
|
||||
if (fd < 0)
|
||||
{
|
||||
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 */
|
||||
}
|
||||
else
|
||||
{
|
||||
dev->atomic_size= ioctl(fd, SFX_GET_ATOMIC_SIZE);
|
||||
result= ioctl(fd, SFX_GET_ATOMIC_SIZE, &max_atomic_size);
|
||||
close(fd);
|
||||
}
|
||||
dev->atomic_write= result == 0 && page_size <= max_atomic_size;
|
||||
}
|
||||
|
||||
return (page_size <= dev->atomic_size);
|
||||
return dev->atomic_write;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Check if a file is on a ScaleFlux device and that it supports atomic_write
|
||||
@param[in] file OS file handle
|
||||
|
@ -342,7 +358,7 @@ static my_bool sfx_dev_has_atomic_write(struct sfx_dev *dev,
|
|||
@return TRUE Atomic write supported
|
||||
|
||||
@notes
|
||||
This is called only at first open of a file. In this case it's doesn't
|
||||
This is called only at first open of a file. In this case it doesn't
|
||||
matter so much that we loop over all cards.
|
||||
We update the atomic size on first access.
|
||||
*/
|
||||
|
@ -358,12 +374,63 @@ static my_bool sfx_has_atomic_write(File file, int page_size)
|
|||
return sfx_dev_has_atomic_write(dev, page_size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static my_bool sfx_dev_could_disable_punch_hole(struct sfx_dev *dev, File file)
|
||||
{
|
||||
int result = 0;
|
||||
|
||||
if (dev->disable_punch_hole == SFX_UNKNOWN_PUNCH_HOLE_YET)
|
||||
{
|
||||
int fd= open(dev->dev_name, 0);
|
||||
if (fd < 0)
|
||||
{
|
||||
fprintf(stderr, "Unable to determine if thin provisioning is used:"
|
||||
" open(\"%s\"): %m\n", dev->dev_name);
|
||||
dev->disable_punch_hole= 0; /* Don't try again */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
Ratio left-shifts 8 (multiplies 256) inside the ioctl;
|
||||
will also add 1 to guarantee a round-up integer.
|
||||
*/
|
||||
result= ioctl(fd, SFX_GET_SPACE_RATIO);
|
||||
result+= 1;
|
||||
dev->disable_punch_hole= (result >= (((double)SFX_DISABLE_PUNCH_HOLE_RATIO) * 256));
|
||||
}
|
||||
|
||||
return dev->disable_punch_hole;
|
||||
}
|
||||
|
||||
/**
|
||||
Check if a file is on a ScaleFlux device and whether it is possible to
|
||||
disable hole punch.
|
||||
@param[in] file OS file handle
|
||||
@return TRUE Could disable hole punch
|
||||
|
||||
@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
|
||||
*/
|
||||
|
||||
static my_bool sfx_could_disable_punch_hole(File file)
|
||||
{
|
||||
struct sfx_dev *dev;
|
||||
struct stat stat_buff;
|
||||
|
||||
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_could_disable_punch_hole(dev, file);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
Generic atomic write code
|
||||
************************************************************************/
|
||||
|
||||
/*
|
||||
Initialize automic write sub systems.
|
||||
/**
|
||||
Initialize the atomic write subsystem.
|
||||
Checks if we have any devices that supports atomic write
|
||||
*/
|
||||
|
||||
|
@ -418,6 +485,22 @@ my_bool my_test_if_atomic_write(File handle, int page_size)
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Check if a file resides on thinly provisioned storage.
|
||||
|
||||
@return FALSE File cannot disable hole punch
|
||||
TRUE File could disable hole punch
|
||||
*/
|
||||
|
||||
my_bool my_test_if_thinly_provisioned(File handle)
|
||||
{
|
||||
if (has_sfx_card && sfx_could_disable_punch_hole(handle))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef TEST_SHANNON
|
||||
int main()
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue