add function get_path_block_size and get_device_block_size

iovec_array
YuQing 2021-06-02 11:07:28 +08:00
parent 48f108b40d
commit e068391c87
3 changed files with 129 additions and 1 deletions

View File

@ -1,7 +1,8 @@
Version 1.52 2021-06-01
Version 1.52 2021-06-02
* process_stop more gracefully (kill -9 on timeout)
* add function fc_queue_pop_to_queue_ex
* add function get_path_block_size and get_device_block_size
Version 1.51 2021-05-27
* fast_mblock.[hc]: support batch alloc and batch free

View File

@ -36,6 +36,7 @@
#ifdef OS_LINUX
#include <sys/sysinfo.h>
#include <sys/vfs.h>
#include <sys/sysmacros.h>
#else
#ifdef OS_FREEBSD
#include <sys/sysctl.h>
@ -835,3 +836,124 @@ int get_kernel_version(Version *version)
version->patch = numbers[1];
return 0;
}
#ifdef OS_LINUX
int get_device_block_size(const char *device, int *block_size)
{
int result;
int fd;
size_t bs;
if ((fd=open(device, O_RDONLY)) < 0) {
result = errno != 0 ? errno : ENOENT;
logError("file: "__FILE__", line: %d, "
"open device %s fail, errno: %d, error info: %s",
__LINE__, device, result, strerror(result));
return result;
}
if (ioctl(fd, BLKSSZGET, &bs) == 0) {
*block_size = bs;
result = 0;
} else {
result = errno != 0 ? errno : EPERM;
logError("file: "__FILE__", line: %d, "
"ioctl device %s fail, errno: %d, error info: %s",
__LINE__, device, result, strerror(result));
}
close(fd);
return result;
}
static int get_block_size_by_write(const char *path, int *block_size)
{
#define MAX_BLK_SIZE (128 * 1024)
char tmp_filename[PATH_MAX];
char *buff;
int result;
int fd;
if ((result=posix_memalign((void **)&buff,
MAX_BLK_SIZE, MAX_BLK_SIZE)) != 0)
{
logError("file: "__FILE__", line: %d, "
"posix_memalign %d bytes fail, "
"errno: %d, error info: %s", __LINE__,
MAX_BLK_SIZE, result, STRERROR(result));
return result;
}
snprintf(tmp_filename, sizeof(tmp_filename),
"%s/.blksize-test.tmp", path);
if ((fd=open(tmp_filename, O_WRONLY | O_CREAT | O_DIRECT)) < 0) {
result = errno != 0 ? errno : ENOENT;
logError("file: "__FILE__", line: %d, "
"open file %s fail, errno: %d, error info: %s",
__LINE__, tmp_filename, result, strerror(result));
free(buff);
return result;
}
result = EINVAL;
*block_size = 512;
while (*block_size <= MAX_BLK_SIZE) {
if (write(fd, buff, *block_size) == *block_size) {
result = 0;
break;
}
result = errno != 0 ? errno : EINTR;
if (result == EINTR) {
continue;
}
if (result != EINVAL) {
logError("file: "__FILE__", line: %d, "
"write to file %s fail, errno: %d, error info: %s",
__LINE__, tmp_filename, result, strerror(result));
break;
}
*block_size *= 2;
}
free(buff);
close(fd);
unlink(tmp_filename);
return result;
}
int get_path_block_size(const char *path, int *block_size)
{
char dev_path[64];
struct stat statbuf;
int result;
if (stat(path, &statbuf) != 0) {
result = errno != 0 ? errno : EPERM;
logError("file: "__FILE__", line: %d, "
"stat %s fail, errno: %d, error info: %s",
__LINE__, path, result, strerror(result));
return result;
}
if (S_ISBLK(statbuf.st_mode)) {
return get_device_block_size(path, block_size);
}
if (!S_ISDIR(statbuf.st_mode)) {
logError("file: "__FILE__", line: %d, "
"%s is NOT a directory!", __LINE__, path);
return ENOTDIR;
}
sprintf(dev_path, "/dev/block/%d:%d", (int)major(statbuf.st_dev),
(int)minor(statbuf.st_dev));
if (access(dev_path, R_OK) == 0) {
if ((result=get_device_block_size(dev_path, block_size)) == 0) {
return 0;
}
}
return get_block_size_by_write(path, block_size);
}
#endif

View File

@ -164,6 +164,11 @@ int get_sysinfo(struct fast_sysinfo *info);
int get_kernel_version(Version *version);
#ifdef OS_LINUX
int get_device_block_size(const char *device, int *block_size);
int get_path_block_size(const char *path, int *block_size);
#endif
#endif
#ifdef __cplusplus