Commit bc229af6 authored by Philip Carns's avatar Philip Carns
Browse files

add fallocate() wrapper

- also add simple test program that exercises a few basic functions,
  including fallocate().
parent ff51879c
......@@ -50,6 +50,18 @@ LIBS="$ARGOBOTS_LIBS $LIBS"
CPPFLAGS="$ARGOBOTS_CFLAGS $CPPFLAGS"
CFLAGS="$ARGOBOTS_CFLAGS $CFLAGS"
AC_MSG_CHECKING([for fallocate])
AC_TRY_COMPILE([
#define _GNU_SOURCE
#include <fcntl.h>
], [
int ret = fallocate(0, 0, 0, 0);
],
AC_MSG_RESULT(yes)
AC_DEFINE([HAVE_FALLOCATE], [], [Define if fallocate available])
,
AC_MSG_RESULT(no))
NONCOMPLIANT_IO=""
AC_MSG_CHECKING([for O_DIRECT])
......
......@@ -196,6 +196,16 @@ int abt_io_close(abt_io_instance_id aid, int fd);
*/
abt_io_op_t* abt_io_close_nb(abt_io_instance_id aid, int fd, int *ret);
/**
* wrapper for fallocate() (if available on this platform)
*/
int abt_io_fallocate(abt_io_instance_id aid, int fd, int mode, off_t offset, off_t len);
/**
* non-blocking wrapper for fallocate() (if available on this platform)
*/
abt_io_op_t* abt_io_fallocate_nb(abt_io_instance_id aid, int fd, int mode, off_t offset, off_t len, int *ret);
/**
* wait on an abt-io operation
* return: 0 if success, non-zero on failure
......
......@@ -5,6 +5,8 @@
* See COPYRIGHT in top-level directory.
*/
#include "abt-io-config.h"
#define _GNU_SOURCE
#include <assert.h>
......@@ -17,7 +19,6 @@
#include <fcntl.h>
#include <abt.h>
#include "abt-io.h"
struct abt_io_instance
......@@ -915,6 +916,97 @@ abt_io_op_t* abt_io_fdatasync_nb(abt_io_instance_id aid, int fd, int *ret)
else return op;
}
struct abt_io_fallocate_state
{
int *ret;
int fd;
int mode;
off_t offset;
off_t len;
ABT_eventual eventual;
};
static void abt_io_fallocate_fn(void *foo)
{
struct abt_io_fallocate_state *state = foo;
#ifdef HAVE_FALLOCATE
*state->ret = fallocate(state->fd, state->mode, state->offset, state->len);
if(*state->ret < 0)
*state->ret = -errno;
#else
*state->ret = -ENOSYS;
#endif
ABT_eventual_set(state->eventual, NULL, 0);
return;
}
static int issue_fallocate(ABT_pool pool, abt_io_op_t *op, int fd, int mode, off_t offset, off_t len, int *ret)
{
struct abt_io_fallocate_state state;
struct abt_io_fallocate_state *pstate = NULL;
int rc;
if (op == NULL) pstate = &state;
else {
pstate = malloc(sizeof(*pstate));
if (pstate == NULL) { *ret = -ENOMEM; goto err; }
}
*ret = -ENOSYS;
pstate->ret = ret;
pstate->fd = fd;
pstate->mode = mode;
pstate->offset = offset;
pstate->len = len;
pstate->eventual = NULL;
rc = ABT_eventual_create(0, &pstate->eventual);
if (rc != ABT_SUCCESS) { *ret = -ENOMEM; goto err; }
if (op != NULL) op->e = pstate->eventual;
rc = ABT_task_create(pool, abt_io_fallocate_fn, pstate, NULL);
if(rc != ABT_SUCCESS) { *ret = -EINVAL; goto err; }
if (op == NULL) {
rc = ABT_eventual_wait(pstate->eventual, NULL);
// what error should we use here?
if (rc != ABT_SUCCESS) { *ret = -EINVAL; goto err; }
}
else {
op->e = pstate->eventual;
op->state = pstate;
op->free_fn = free;
}
return 0;
err:
if (pstate->eventual != NULL) ABT_eventual_free(&pstate->eventual);
if (pstate != NULL && op != NULL) free(pstate);
return -1;
}
int abt_io_fallocate(abt_io_instance_id aid, int fd, int mode, off_t offset, off_t len)
{
int ret = -1;
issue_fallocate(aid->progress_pool, NULL, fd, mode, offset, len, &ret);
return ret;
}
abt_io_op_t* abt_io_fallocate_nb(abt_io_instance_id aid, int fd, int mode, off_t offset, off_t len, int *ret)
{
abt_io_op_t *op;
int iret;
op = malloc(sizeof(*op));
if (op == NULL) return NULL;
iret = issue_fallocate(aid->progress_pool, op, fd, mode, offset, len, ret);
if (iret != 0) { free(op); return NULL; }
else return op;
}
int abt_io_op_wait(abt_io_op_t* op)
{
int ret;
......
EXTRA_DIST += \
tests/concurrent-write-bench.sh
check_PROGRAMS += \
tests/basic
tests_basic_LDADD = src/libabt-io.la
TESTS += \
tests/concurrent-write-bench.sh
tests/concurrent-write-bench.sh\
tests/basic
#define _GNU_SOURCE
#include <stdio.h>
#include <assert.h>
#include <unistd.h>
#include <sys/time.h>
#include <stdlib.h>
#include <pthread.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <float.h>
#include <errno.h>
#include <abt.h>
#include <abt-io.h>
/* test program to exercise a few basic abt-io functions */
int main(int argc, char **argv)
{
int ret;
ABT_sched self_sched;
ABT_xstream self_xstream;
abt_io_instance_id aid;
int fd;
char template[64];
ABT_init(argc, argv);
if(argc != 1)
{
fprintf(stderr, "Error: this program accepts no arguments.\n");
return(-1);
}
/* set caller (self) ES to sleep when idle by using SCHED_BASIC_WAIT */
ret = ABT_sched_create_basic(ABT_SCHED_BASIC_WAIT, 0, NULL,
ABT_SCHED_CONFIG_NULL, &self_sched);
assert(ret == ABT_SUCCESS);
ret = ABT_xstream_self(&self_xstream);
assert(ret == ABT_SUCCESS);
ret = ABT_xstream_set_main_sched(self_xstream, self_sched);
assert(ret == ABT_SUCCESS);
/* start up abt-io */
aid = abt_io_init(2);
assert(aid != NULL);
sprintf(template, "/tmp/XXXXXX");
fd = abt_io_mkostemp(aid, template, 0);
assert(ret >= 0);
ret = abt_io_pwrite(aid, fd, &fd, sizeof(fd), 0);
assert(ret == sizeof(fd));
ret = abt_io_fallocate(aid, fd, FALLOC_FL_PUNCH_HOLE|FALLOC_FL_KEEP_SIZE,
0, sizeof(fd));
assert(ret == 0);
ret = abt_io_close(aid, fd);
assert(ret == 0);
ret = abt_io_unlink(aid, template);
assert(ret == 0);
abt_io_finalize(aid);
ABT_finalize();
return(0);
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment