691 lines
17 KiB
C++
691 lines
17 KiB
C++
/*
|
|
* Copyright (c) 2022 Huawei Technologies Co.,Ltd.
|
|
*
|
|
* openGauss is licensed under Mulan PSL v2.
|
|
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
|
* You may obtain a copy of Mulan PSL v2 at:
|
|
*
|
|
* http://license.coscl.org.cn/MulanPSL2
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
|
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
|
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
|
* See the Mulan PSL v2 for more details.
|
|
* ---------------------------------------------------------------------------------------
|
|
*
|
|
* fio_dss.cpp
|
|
* DSS File System Adapter Interface.
|
|
*
|
|
*
|
|
* IDENTIFICATION
|
|
* src/gausskernel/storage/dss/fio_dss.cpp
|
|
*
|
|
* ---------------------------------------------------------------------------------------
|
|
*/
|
|
|
|
#include <dirent.h>
|
|
#include <fcntl.h>
|
|
#include <errno.h>
|
|
#include <sys/types.h>
|
|
#include "securec.h"
|
|
#include "securec_check.h"
|
|
#include "storage/file/fio_device.h"
|
|
|
|
static char zero_area[FILE_EXTEND_STEP_SIZE + ALIGNOF_BUFFER] = { 0 };
|
|
|
|
void dss_set_errno(int *errcode);
|
|
|
|
ssize_t buffer_align(char **unalign_buff, char **buff, size_t size);
|
|
ssize_t dss_align_read(int handle, void *buf, size_t size, off_t offset, bool use_p);
|
|
int dss_pwrite_file_by_zero(int handle, off_t offset, off_t len);
|
|
int dss_get_file_name(int handle, char *fname, size_t fname_size);
|
|
|
|
// interface for register raw device callback function
|
|
dss_device_op_t g_dss_device_op;
|
|
bool g_enable_dss = false;
|
|
|
|
/* Xlog Segment Size */
|
|
uint64 XLogSegmentSize = XLOG_SEG_SIZE;
|
|
|
|
void dss_device_register(dss_device_op_t *dss_device_op, bool enable_dss)
|
|
{
|
|
g_dss_device_op = *dss_device_op;
|
|
g_enable_dss = enable_dss;
|
|
}
|
|
|
|
bool is_dss_file(const char *name)
|
|
{
|
|
if (g_enable_dss) {
|
|
return (name[0] == '+') ? true : false;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool is_dss_file_dec(FILE *stream)
|
|
{
|
|
DSS_STREAM *dss_stream = (DSS_STREAM *)stream;
|
|
if (dss_stream->magic_head == DSS_MAGIC_NUMBER) {
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool is_dss_fd(int handle)
|
|
{
|
|
if (handle >= (int)DSS_HANDLE_BASE) {
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
void dss_set_errno(int *errcode)
|
|
{
|
|
int errorcode = 0;
|
|
const char *errormsg = NULL;
|
|
|
|
g_dss_device_op.dss_get_error(&errorcode, &errormsg);
|
|
errno = errorcode;
|
|
|
|
if (errcode != NULL) {
|
|
*errcode = errorcode;
|
|
}
|
|
}
|
|
|
|
|
|
int dss_access_file(const char *file_name, int mode)
|
|
{
|
|
struct stat statbuf = {0};
|
|
return dss_stat_file(file_name, &statbuf);
|
|
}
|
|
|
|
int dss_create_dir(const char *name, mode_t mode)
|
|
{
|
|
if (g_dss_device_op.dss_create_dir(name) != DSS_SUCCESS) {
|
|
dss_set_errno(NULL);
|
|
return GS_ERROR;
|
|
}
|
|
return GS_SUCCESS;
|
|
}
|
|
|
|
int dss_open_dir(const char *name, DIR **dir_handle)
|
|
{
|
|
DSS_DIR *dss_dir = NULL;
|
|
|
|
/* dss_dir_t will be free in dss_close_dir */
|
|
dss_dir = (DSS_DIR*)malloc(sizeof(DSS_DIR));
|
|
dss_dir->dir_handle = g_dss_device_op.dss_open_dir(name);
|
|
if (dss_dir->dir_handle == NULL) {
|
|
dss_set_errno(NULL);
|
|
free(dss_dir);
|
|
return GS_ERROR;
|
|
}
|
|
|
|
dss_dir->magic_head = DSS_MAGIC_NUMBER;
|
|
*dir_handle = (DIR*)dss_dir;
|
|
return GS_SUCCESS;
|
|
}
|
|
|
|
int dss_read_dir(DIR *dir_handle, struct dirent **result)
|
|
{
|
|
dss_dirent_t dirent_t;
|
|
dss_dir_item_t item_t;
|
|
errno_t rc;
|
|
DSS_DIR *dss_dir = (DSS_DIR*)dir_handle;
|
|
|
|
*result = NULL;
|
|
if (g_dss_device_op.dss_read_dir(dss_dir->dir_handle, &dirent_t, &item_t) != DSS_SUCCESS) {
|
|
dss_set_errno(NULL);
|
|
return GS_ERROR;
|
|
}
|
|
|
|
if (item_t == NULL) {
|
|
dss_set_errno(NULL);
|
|
return GS_SUCCESS;
|
|
}
|
|
|
|
rc = strcpy_s(dss_dir->filename, MAX_FILE_NAME_LEN, dirent_t.d_name);
|
|
securec_check_c(rc, "\0", "\0");
|
|
rc = strcpy_s(dss_dir->ret.d_name, MAX_FILE_NAME_LEN, dirent_t.d_name);
|
|
securec_check_c(rc, "\0", "\0");
|
|
|
|
*result = &dss_dir->ret;
|
|
|
|
return GS_SUCCESS;
|
|
}
|
|
|
|
int dss_close_dir(DIR *dir_handle)
|
|
{
|
|
DSS_DIR *dss_dir_t = (DSS_DIR*)dir_handle;
|
|
int result = GS_SUCCESS;
|
|
|
|
if (g_dss_device_op.dss_close_dir(dss_dir_t->dir_handle) != DSS_SUCCESS) {
|
|
dss_set_errno(NULL);
|
|
result = GS_ERROR;
|
|
}
|
|
free(dss_dir_t);
|
|
return result;
|
|
}
|
|
|
|
int dss_remove_dir(const char *name)
|
|
{
|
|
if (g_dss_device_op.dss_remove_dir(name) != DSS_SUCCESS) {
|
|
dss_set_errno(NULL);
|
|
return GS_ERROR;
|
|
}
|
|
return GS_SUCCESS;
|
|
}
|
|
|
|
int dss_rename_file(const char *src, const char *dst)
|
|
{
|
|
if (g_dss_device_op.dss_rename(src, dst) != DSS_SUCCESS) {
|
|
dss_set_errno(NULL);
|
|
return GS_ERROR;
|
|
}
|
|
return GS_SUCCESS;
|
|
}
|
|
|
|
int dss_remove_file(const char *name)
|
|
{
|
|
if (g_dss_device_op.dss_remove(name) != DSS_SUCCESS) {
|
|
dss_set_errno(NULL);
|
|
return GS_ERROR;
|
|
}
|
|
return GS_SUCCESS;
|
|
}
|
|
|
|
int dss_open_file(const char *name, int flags, mode_t mode, int *handle)
|
|
{
|
|
struct stat st;
|
|
if ((flags & O_CREAT) != 0 && dss_stat_file(name, &st) != GS_SUCCESS) {
|
|
// file not exists, create it first.
|
|
if (errno == ERR_DSS_FILE_NOT_EXIST && g_dss_device_op.dss_create(name, flags) != DSS_SUCCESS) {
|
|
dss_set_errno(NULL);
|
|
return GS_ERROR;
|
|
}
|
|
}
|
|
|
|
if (g_dss_device_op.dss_open(name, flags, handle) != DSS_SUCCESS) {
|
|
*handle = -1;
|
|
dss_set_errno(NULL);
|
|
return GS_ERROR;
|
|
}
|
|
return GS_SUCCESS;
|
|
}
|
|
|
|
int dss_fopen_file(const char *name, const char* mode, FILE **stream)
|
|
{
|
|
int openmode = 0;
|
|
int handle = -1;
|
|
off_t fsize = INVALID_DEVICE_SIZE;
|
|
DSS_STREAM *dss_fstream = NULL;
|
|
|
|
// check open mode
|
|
if (strstr(mode, "r+")) {
|
|
openmode |= O_RDWR;
|
|
} else if (strchr(mode, 'r')) {
|
|
openmode |= O_RDONLY;
|
|
}
|
|
|
|
if (strstr(mode, "w+")) {
|
|
openmode |= O_RDWR | O_CREAT | O_TRUNC;
|
|
} else if (strchr(mode, 'w')) {
|
|
openmode |= O_WRONLY | O_CREAT | O_TRUNC;
|
|
}
|
|
|
|
if (strstr(mode, "a+")) {
|
|
openmode |= O_RDWR | O_CREAT | O_APPEND;
|
|
} else if (strchr(mode, 'a')) {
|
|
openmode |= O_WRONLY | O_CREAT | O_APPEND;
|
|
}
|
|
|
|
// get handle and fsize of open file
|
|
if (dss_open_file(name, openmode, 0, &handle) != GS_SUCCESS) {
|
|
return GS_ERROR;
|
|
}
|
|
|
|
if ((fsize = dss_get_file_size(name)) == INVALID_DEVICE_SIZE) {
|
|
return GS_ERROR;
|
|
}
|
|
|
|
// init dss stream handle
|
|
dss_fstream = (DSS_STREAM*)malloc(sizeof(DSS_STREAM));
|
|
dss_fstream->fsize = fsize;
|
|
dss_fstream->errcode = 0;
|
|
dss_fstream->handle = handle;
|
|
|
|
dss_fstream->magic_head = DSS_MAGIC_NUMBER;
|
|
*stream = (FILE*)dss_fstream;
|
|
return GS_SUCCESS;
|
|
}
|
|
|
|
int dss_close_file(int handle)
|
|
{
|
|
if (g_dss_device_op.dss_close(handle) != DSS_SUCCESS) {
|
|
dss_set_errno(NULL);
|
|
return GS_ERROR;
|
|
}
|
|
return GS_SUCCESS;
|
|
}
|
|
|
|
int dss_fclose_file(FILE *stream)
|
|
{
|
|
// set errcode of stream in close is meaningless
|
|
int status = dss_close_file(dss_fileno(stream));
|
|
free(stream);
|
|
return status;
|
|
}
|
|
|
|
ssize_t dss_read_file(int handle, void *buf, size_t size)
|
|
{
|
|
return dss_align_read(handle, buf, size, -1, false);
|
|
}
|
|
|
|
ssize_t dss_pread_file(int handle, void *buf, size_t size, off_t offset)
|
|
{
|
|
return dss_align_read(handle, buf, size, offset, true);
|
|
}
|
|
|
|
ssize_t dss_align_read(int handle, void *buf, size_t size, off_t offset, bool use_p)
|
|
{
|
|
size_t newSize = size;
|
|
char* unalign_buff = NULL;
|
|
char* buff = NULL;
|
|
bool address_align = false;
|
|
int ret = DSS_ERROR;
|
|
int r_size = 0;
|
|
|
|
if ((((uint64)buf) % ALIGNOF_BUFFER) == 0) {
|
|
address_align = true;
|
|
}
|
|
|
|
if ((!address_align) || ((size % ALIGNOF_BUFFER) != 0)) {
|
|
newSize = buffer_align(&unalign_buff, &buff, size);
|
|
} else {
|
|
buff = (char*)buf;
|
|
}
|
|
|
|
if (use_p) {
|
|
ret = g_dss_device_op.dss_pread(handle, buff, newSize, offset, &r_size);
|
|
} else {
|
|
ret = g_dss_device_op.dss_read(handle, buff, newSize, &r_size);
|
|
}
|
|
|
|
if (ret != DSS_SUCCESS) {
|
|
dss_set_errno(NULL);
|
|
if (unalign_buff != NULL) {
|
|
free(unalign_buff);
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
if (unalign_buff != NULL) {
|
|
int move = (int)size - (int)newSize;
|
|
errno_t rc = memcpy_s(buf, size, buff, size);
|
|
securec_check_c(rc, "\0", "\0");
|
|
free(unalign_buff);
|
|
// change current access position to correct point
|
|
if (move < 0 && dss_seek_file(handle, move, SEEK_CUR) < 0) {
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
return (((ssize_t)(r_size)) < ((ssize_t)(size)) ? ((ssize_t)(r_size)) : ((ssize_t)(size)));
|
|
}
|
|
|
|
size_t dss_fread_file(void *buf, size_t size, size_t nmemb, FILE *stream)
|
|
{
|
|
ssize_t r_size = 0;
|
|
DSS_STREAM *dss_fstream = (DSS_STREAM*)stream;
|
|
if ((r_size = dss_align_read(dss_fstream->handle, buf, size * nmemb, -1, false)) == -1) {
|
|
dss_set_errno(&dss_fstream->errcode);
|
|
return 0;
|
|
}
|
|
return (size_t)r_size;
|
|
}
|
|
|
|
ssize_t dss_write_file(int handle, const void *buf, size_t size)
|
|
{
|
|
if (g_dss_device_op.dss_write(handle, buf, size) != DSS_SUCCESS) {
|
|
dss_set_errno(NULL);
|
|
return -1;
|
|
}
|
|
return (ssize_t)size;
|
|
}
|
|
|
|
ssize_t dss_pwrite_file(int handle, const void *buf, size_t size, off_t offset)
|
|
{
|
|
if (g_dss_device_op.dss_pwrite(handle, buf, size, offset) != DSS_SUCCESS) {
|
|
dss_set_errno(NULL);
|
|
return -1;
|
|
}
|
|
return (ssize_t)size;
|
|
}
|
|
|
|
size_t dss_fwrite_file(const void *buf, size_t size, size_t count, FILE *stream)
|
|
{
|
|
DSS_STREAM *dss_fstream = (DSS_STREAM*)stream;
|
|
if (g_dss_device_op.dss_write(dss_fstream->handle, buf, size * count) != DSS_SUCCESS) {
|
|
dss_set_errno(&dss_fstream->errcode);
|
|
return (size_t)-1;
|
|
}
|
|
return count;
|
|
}
|
|
|
|
off_t dss_seek_file(int handle, off_t offset, int origin)
|
|
{
|
|
if (origin == SEEK_END) {
|
|
origin = DSS_SEEK_MAXWR;
|
|
}
|
|
off_t size = (off_t)g_dss_device_op.dss_seek(handle, offset, origin);
|
|
if (size == -1) {
|
|
dss_set_errno(NULL);
|
|
}
|
|
return size;
|
|
}
|
|
|
|
int dss_fseek_file(FILE *stream, long offset, int whence)
|
|
{
|
|
if (whence == SEEK_END) {
|
|
whence = DSS_SEEK_MAXWR;
|
|
}
|
|
DSS_STREAM *dss_fstream = (DSS_STREAM*)stream;
|
|
off_t size = (off_t)g_dss_device_op.dss_seek(dss_fstream->handle, offset, whence);
|
|
if (size == -1) {
|
|
dss_set_errno(&dss_fstream->errcode);
|
|
return -1;
|
|
}
|
|
return (int)size;
|
|
}
|
|
|
|
long dss_ftell_file(FILE *stream)
|
|
{
|
|
DSS_STREAM *dss_fstream = (DSS_STREAM*)stream;
|
|
off_t size = (off_t)g_dss_device_op.dss_seek(dss_fstream->handle, 0, SEEK_CUR);
|
|
if (size == -1) {
|
|
dss_set_errno(&dss_fstream->errcode);
|
|
}
|
|
return size;
|
|
}
|
|
|
|
void dss_rewind_file(FILE *stream)
|
|
{
|
|
DSS_STREAM *dss_fstream = (DSS_STREAM*)stream;
|
|
off_t size = (off_t)g_dss_device_op.dss_seek(dss_fstream->handle, 0, SEEK_SET);
|
|
if (size == -1) {
|
|
dss_set_errno(&dss_fstream->errcode);
|
|
}
|
|
}
|
|
|
|
int dss_fflush_file(FILE *stream)
|
|
{
|
|
/* nothing to do, because DSS will enable O_SYNC and O_DIRECT for all IO */
|
|
return GS_SUCCESS;
|
|
}
|
|
|
|
int dss_sync_file(int handle)
|
|
{
|
|
/* nothing to do, because DSS will enable O_SYNC and O_DIRECT for all IO */
|
|
return GS_SUCCESS;
|
|
}
|
|
|
|
int dss_truncate_file(int handle, off_t keep_size)
|
|
{
|
|
/* not guarantee fill zero */
|
|
if (g_dss_device_op.dss_truncate(handle, keep_size) != DSS_SUCCESS) {
|
|
dss_set_errno(NULL);
|
|
return GS_ERROR;
|
|
}
|
|
return GS_SUCCESS;
|
|
}
|
|
|
|
int dss_ftruncate_file(FILE *stream, off_t keep_size)
|
|
{
|
|
/* file stream do not have truncate function, so it's ok we do not set errcode in stream */
|
|
return dss_truncate_file(dss_fileno(stream), keep_size);
|
|
}
|
|
|
|
int dss_get_file_name(int handle, char *fname, size_t fname_size)
|
|
{
|
|
if (g_dss_device_op.dss_fname(handle, fname, fname_size) != DSS_SUCCESS) {
|
|
dss_set_errno(NULL);
|
|
return GS_ERROR;
|
|
}
|
|
return GS_SUCCESS;
|
|
}
|
|
|
|
off_t dss_get_file_size(const char *fname)
|
|
{
|
|
off_t fsize = INVALID_DEVICE_SIZE;
|
|
|
|
g_dss_device_op.dss_fsize(fname, &fsize);
|
|
if (fsize == INVALID_DEVICE_SIZE) {
|
|
dss_set_errno(NULL);
|
|
}
|
|
|
|
return fsize;
|
|
}
|
|
|
|
int dss_fallocate_file(int handle, int mode, off_t offset, off_t len)
|
|
{
|
|
return dss_pwrite_file_by_zero(handle, offset, len);
|
|
}
|
|
|
|
int dss_link(const char *src, const char *dst)
|
|
{
|
|
if (g_dss_device_op.dss_link(src, dst) != DSS_SUCCESS) {
|
|
dss_set_errno(NULL);
|
|
return GS_ERROR;
|
|
}
|
|
return GS_SUCCESS;
|
|
}
|
|
|
|
int dss_unlink_target(const char *name)
|
|
{
|
|
if (g_dss_device_op.dss_unlink(name) != DSS_SUCCESS) {
|
|
dss_set_errno(NULL);
|
|
return GS_ERROR;
|
|
}
|
|
return GS_SUCCESS;
|
|
}
|
|
|
|
ssize_t dss_read_link(const char *path, char *buf, size_t buf_size)
|
|
{
|
|
ssize_t result = (ssize_t)g_dss_device_op.dss_read_link(path, buf, buf_size);
|
|
if (result == -1) {
|
|
dss_set_errno(NULL);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
int dss_setvbuf(FILE *stream, char *buf, int mode, size_t size)
|
|
{
|
|
/* nothing to do in dss mode */
|
|
return 0;
|
|
}
|
|
|
|
int dss_feof(FILE *stream)
|
|
{
|
|
DSS_STREAM *dss_fstream = (DSS_STREAM*)stream;
|
|
if (dss_ftell_file(stream) < dss_fstream->fsize) {
|
|
return 0;
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int dss_ferror(FILE *stream)
|
|
{
|
|
DSS_STREAM *dss_fstream = (DSS_STREAM*)stream;
|
|
if (dss_fstream->errcode) {
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int dss_fileno(FILE *stream)
|
|
{
|
|
DSS_STREAM *dss_fstream = (DSS_STREAM*)stream;
|
|
return dss_fstream->handle;
|
|
}
|
|
|
|
int dss_stat_file(const char *path, struct stat *buf)
|
|
{
|
|
dss_stat_t st;
|
|
if (g_dss_device_op.dss_stat(path, &st) != DSS_SUCCESS) {
|
|
dss_set_errno(NULL);
|
|
return -1;
|
|
}
|
|
|
|
// file type and mode
|
|
switch (st.type) {
|
|
case DSS_PATH:
|
|
buf->st_mode = S_IFDIR;
|
|
break;
|
|
case DSS_FILE:
|
|
buf->st_mode = S_IFREG;
|
|
break;
|
|
case DSS_LINK:
|
|
/* fall-through */
|
|
default:
|
|
return -1;
|
|
}
|
|
// total size, in bytes
|
|
buf->st_size = (long)st.written_size;
|
|
// time of last modification
|
|
buf->st_mtime = st.update_time;
|
|
|
|
return 0;
|
|
}
|
|
|
|
int dss_fstat_file(int handle, struct stat *buf)
|
|
{
|
|
dss_stat_t st;
|
|
if (g_dss_device_op.dss_fstat(handle, &st) != DSS_SUCCESS) {
|
|
dss_set_errno(NULL);
|
|
return -1;
|
|
}
|
|
|
|
// file type and mode
|
|
switch (st.type) {
|
|
case DSS_PATH:
|
|
buf->st_mode = S_IFDIR;
|
|
break;
|
|
case DSS_FILE:
|
|
buf->st_mode = S_IFREG;
|
|
break;
|
|
case DSS_LINK:
|
|
/* fall-through */
|
|
default:
|
|
return -1;
|
|
}
|
|
// total size, in bytes
|
|
buf->st_size = (long)st.written_size;
|
|
// time of last modification
|
|
buf->st_mtime = st.update_time;
|
|
|
|
return 0;
|
|
}
|
|
|
|
// return information of link itself when path is link
|
|
int dss_lstat_file(const char *path, struct stat *buf)
|
|
{
|
|
dss_stat_t st;
|
|
if (g_dss_device_op.dss_lstat(path, &st) != DSS_SUCCESS) {
|
|
dss_set_errno(NULL);
|
|
return -1;
|
|
}
|
|
|
|
// file type and mode
|
|
switch (st.type) {
|
|
case DSS_PATH:
|
|
buf->st_mode = S_IFDIR;
|
|
break;
|
|
case DSS_FILE:
|
|
buf->st_mode = S_IFREG;
|
|
break;
|
|
case DSS_LINK:
|
|
buf->st_mode = S_IFLNK;
|
|
break;
|
|
default:
|
|
return -1;
|
|
}
|
|
// total size, in bytes
|
|
buf->st_size = (long)st.written_size;
|
|
// time of last modification
|
|
buf->st_mtime = st.update_time;
|
|
|
|
return 0;
|
|
}
|
|
|
|
int dss_chmod_file(const char* path, mode_t mode)
|
|
{
|
|
// dss do not have mode
|
|
return 0;
|
|
}
|
|
|
|
ssize_t buffer_align(char **unalign_buff, char **buff, size_t size)
|
|
{
|
|
size_t newSize = size;
|
|
size_t size_mod = ALIGNOF_BUFFER - (newSize % ALIGNOF_BUFFER);
|
|
size_t size_move = 0;
|
|
|
|
if ((size % ALIGNOF_BUFFER) != 0) {
|
|
newSize = BUFFERALIGN(size);
|
|
size_move += size_mod;
|
|
}
|
|
|
|
size_move += ALIGNOF_BUFFER;
|
|
|
|
*unalign_buff = (char*)malloc(size + size_move);
|
|
*buff = (char*)BUFFERALIGN(*unalign_buff);
|
|
|
|
return (ssize_t)newSize;
|
|
}
|
|
|
|
int dss_pwrite_file_by_zero(int handle, off_t offset, off_t len)
|
|
{
|
|
char *zero_area_aligned = (char *)(((uintptr_t)zero_area + ALIGNOF_BUFFER - 1) & (~(ALIGNOF_BUFFER - 1)));
|
|
off_t remain_size = len;
|
|
ssize_t write_size;
|
|
while (remain_size > 0) {
|
|
write_size = (remain_size > FILE_EXTEND_STEP_SIZE) ? FILE_EXTEND_STEP_SIZE : (ssize_t)remain_size;
|
|
if (dss_pwrite_file(handle, zero_area_aligned, write_size, offset) != write_size) {
|
|
return GS_ERROR;
|
|
}
|
|
|
|
offset += write_size;
|
|
remain_size -= write_size;
|
|
}
|
|
|
|
return GS_SUCCESS;
|
|
}
|
|
|
|
int dss_set_server_status_wrapper()
|
|
{
|
|
return g_dss_device_op.dss_set_main_inst();
|
|
}
|
|
|
|
int dss_remove_dev(const char *name)
|
|
{
|
|
struct stat st;
|
|
int ret = lstat(name, &st);
|
|
if (ret == 0 && S_ISREG(st.st_mode)) {
|
|
return dss_remove_file(name);
|
|
} else if (ret == 0 && S_ISLNK(st.st_mode)) {
|
|
return dss_unlink_target(name);
|
|
} else {
|
|
return GS_SUCCESS;
|
|
}
|
|
}
|
|
|
|
int dss_aio_prep_pwrite(void *iocb, int fd, void *buf, size_t count, long long offset)
|
|
{
|
|
return g_dss_device_op.dss_aio_pwrite(iocb, fd, buf, count, offset);
|
|
}
|
|
|
|
int dss_aio_prep_pread(void *iocb, int fd, void *buf, size_t count, long long offset)
|
|
{
|
|
return g_dss_device_op.dss_aio_pread(iocb, fd, buf, count, offset);
|
|
}
|