#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/sysmacros.h>
-#include <dlfcn.h>
#include <libgen.h>
+#include <libpmem.h>
#include "../fio.h"
#include "../verify.h"
/*
- * Limits us to 1GB of mapped files in total to model after
+ * Limits us to 1GiB of mapped files in total to model after
* mmap engine behavior
*/
#define MMAP_TOTAL_SZ (1 * 1024 * 1024 * 1024UL)
off_t devdax_off;
};
-static void * (*pmem_memcpy_persist)(void *dest, const void *src, size_t len);
-
static int fio_devdax_file(struct thread_data *td, struct fio_file *f,
size_t length, off_t off)
{
struct fio_devdax_data *fdd = FILE_ENG_DATA(f);
if (io_u->buflen > f->real_file_size) {
- log_err("fio: bs too big for dev-dax engine\n");
+ log_err("dev-dax: bs too big for dev-dax engine\n");
return EIO;
}
* It fits within existing mapping, use it
*/
if (io_u->offset >= fdd->devdax_off &&
- io_u->offset + io_u->buflen < fdd->devdax_off + fdd->devdax_sz)
+ io_u->offset + io_u->buflen <= fdd->devdax_off + fdd->devdax_sz)
goto done;
/*
return 0;
}
-static int fio_devdax_queue(struct thread_data *td, struct io_u *io_u)
+static enum fio_q_status fio_devdax_queue(struct thread_data *td,
+ struct io_u *io_u)
{
fio_ro_check(td, io_u);
io_u->error = 0;
static int fio_devdax_init(struct thread_data *td)
{
struct thread_options *o = &td->o;
- const char *path;
- void *dl;
if ((o->rw_min_bs & page_mask) &&
(o->fsync_blocks || o->fdatasync_blocks)) {
- log_err("fio: mmap options dictate a minimum block size of "
- "%llu bytes\n", (unsigned long long) page_size);
- return 1;
- }
-
- path = getenv("FIO_PMEM_LIB");
- if (!path)
- path = "libpmem.so";
-
- dl = dlopen(path, RTLD_NOW | RTLD_NODELETE);
- if (!dl) {
- log_err("fio: unable to open libpmem: %s\n", dlerror());
- return 1;
- }
-
- pmem_memcpy_persist = dlsym(dl, "pmem_memcpy_persist");
- if (!pmem_memcpy_persist) {
- log_err("fio: unable to load libpmem: %s\n", dlerror());
+ log_err("dev-dax: mmap options dictate a minimum block size of %llu bytes\n",
+ (unsigned long long) page_size);
return 1;
}
{
char spath[PATH_MAX];
char npath[PATH_MAX];
- char *rpath;
+ char *rpath, *basename;
FILE *sfile;
uint64_t size;
struct stat st;
rc = stat(f->file_name, &st);
if (rc < 0) {
- log_err("%s: failed to stat file %s: %d\n",
- td->o.name, f->file_name, errno);
+ log_err("%s: failed to stat file %s (%s)\n",
+ td->o.name, f->file_name, strerror(errno));
return -errno;
}
rpath = realpath(spath, npath);
if (!rpath) {
- log_err("%s: realpath on %s failed: %d\n",
- td->o.name, spath, errno);
+ log_err("%s: realpath on %s failed (%s)\n",
+ td->o.name, spath, strerror(errno));
return -errno;
}
/* check if DAX device */
- if (strcmp("/sys/class/dax", rpath)) {
+ basename = strrchr(rpath, '/');
+ if (!basename || strcmp("dax", basename+1)) {
log_err("%s: %s not a DAX device!\n",
td->o.name, f->file_name);
}
sfile = fopen(spath, "r");
if (!sfile) {
- log_err("%s: fopen on %s failed: %d\n",
- td->o.name, spath, errno);
+ log_err("%s: fopen on %s failed (%s)\n",
+ td->o.name, spath, strerror(errno));
return 1;
}
rc = fscanf(sfile, "%lu", &size);
if (rc < 0) {
- log_err("%s: fscanf on %s failed: %d\n",
- td->o.name, spath, errno);
+ log_err("%s: fscanf on %s failed (%s)\n",
+ td->o.name, spath, strerror(errno));
+ fclose(sfile);
return 1;
}