mirror of https://github.com/ceph/ceph
251 lines
5.4 KiB
C
251 lines
5.4 KiB
C
#include <sys/types.h>
|
|
#include <sys/stat.h>
|
|
#include <fcntl.h>
|
|
#include <unistd.h>
|
|
#include <stdio.h>
|
|
#include <inttypes.h>
|
|
#include <linux/types.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <sys/ioctl.h>
|
|
#include <errno.h>
|
|
|
|
//#include "../client/ioctl.h"
|
|
|
|
#include <linux/ioctl.h>
|
|
#define CEPH_IOCTL_MAGIC 0x97
|
|
#define CEPH_IOC_SYNCIO _IO(CEPH_IOCTL_MAGIC, 5)
|
|
|
|
void write_pattern()
|
|
{
|
|
printf("writing pattern\n");
|
|
|
|
uint64_t i;
|
|
int r;
|
|
|
|
int fd = open("foo", O_CREAT|O_WRONLY, 0644);
|
|
if (fd < 0) {
|
|
r = errno;
|
|
printf("write_pattern: error: open() failed with: %d (%s)\n", r, strerror(r));
|
|
exit(r);
|
|
}
|
|
for (i=0; i<1048576 * sizeof(i); i += sizeof(i)) {
|
|
r = write(fd, &i, sizeof(i));
|
|
if (r == -1) {
|
|
r = errno;
|
|
printf("write_pattern: error: write() failed with: %d (%s)\n", r, strerror(r));
|
|
break;
|
|
}
|
|
}
|
|
|
|
close(fd);
|
|
}
|
|
|
|
int verify_pattern(char *buf, size_t len, uint64_t off)
|
|
{
|
|
size_t i;
|
|
|
|
for (i = 0; i < len; i += sizeof(uint64_t)) {
|
|
uint64_t expected = i + off;
|
|
uint64_t actual = *(uint64_t*)(buf + i);
|
|
if (expected != actual) {
|
|
printf("error: offset %llu had %llu\n", (unsigned long long)expected,
|
|
(unsigned long long)actual);
|
|
exit(1);
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
void generate_pattern(void *buf, size_t len, uint64_t offset)
|
|
{
|
|
uint64_t *v = buf;
|
|
size_t i;
|
|
|
|
for (i=0; i<len / sizeof(v); i++)
|
|
v[i] = i * sizeof(v) + offset;
|
|
verify_pattern(buf, len, offset);
|
|
}
|
|
|
|
int read_file(int buf_align, uint64_t offset, int len, int direct) {
|
|
|
|
printf("read_file buf_align %d offset %llu len %d\n", buf_align,
|
|
(unsigned long long)offset, len);
|
|
void *rawbuf;
|
|
int r;
|
|
int flags;
|
|
int err = 0;
|
|
|
|
if(direct)
|
|
flags = O_RDONLY|O_DIRECT;
|
|
else
|
|
flags = O_RDONLY;
|
|
|
|
int fd = open("foo", flags);
|
|
if (fd < 0) {
|
|
err = errno;
|
|
printf("read_file: error: open() failed with: %d (%s)\n", err, strerror(err));
|
|
exit(err);
|
|
}
|
|
|
|
if (!direct)
|
|
ioctl(fd, CEPH_IOC_SYNCIO);
|
|
|
|
if ((r = posix_memalign(&rawbuf, 4096, len + buf_align)) != 0) {
|
|
printf("read_file: error: posix_memalign failed with %d", r);
|
|
close(fd);
|
|
exit (r);
|
|
}
|
|
|
|
void *buf = (char *)rawbuf + buf_align;
|
|
memset(buf, 0, len);
|
|
r = pread(fd, buf, len, offset);
|
|
if (r == -1) {
|
|
err = errno;
|
|
printf("read_file: error: pread() failed with: %d (%s)\n", err, strerror(err));
|
|
goto out;
|
|
}
|
|
r = verify_pattern(buf, len, offset);
|
|
|
|
out:
|
|
close(fd);
|
|
free(rawbuf);
|
|
return r;
|
|
}
|
|
|
|
int read_direct(int buf_align, uint64_t offset, int len)
|
|
{
|
|
printf("read_direct buf_align %d offset %llu len %d\n", buf_align,
|
|
(unsigned long long)offset, len);
|
|
return read_file(buf_align, offset, len, 1);
|
|
}
|
|
|
|
int read_sync(int buf_align, uint64_t offset, int len)
|
|
{
|
|
printf("read_sync buf_align %d offset %llu len %d\n", buf_align,
|
|
(unsigned long long)offset, len);
|
|
return read_file(buf_align, offset, len, 0);
|
|
}
|
|
|
|
int write_file(int buf_align, uint64_t offset, int len, int direct)
|
|
{
|
|
printf("write_file buf_align %d offset %llu len %d\n", buf_align,
|
|
(unsigned long long)offset, len);
|
|
void *rawbuf;
|
|
int r;
|
|
int err = 0;
|
|
int flags;
|
|
if (direct)
|
|
flags = O_WRONLY|O_DIRECT|O_CREAT;
|
|
else
|
|
flags = O_WRONLY|O_CREAT;
|
|
|
|
int fd = open("foo", flags, 0644);
|
|
if (fd < 0) {
|
|
int err = errno;
|
|
printf("write_file: error: open() failed with: %d (%s)\n", err, strerror(err));
|
|
exit(err);
|
|
}
|
|
|
|
if ((r = posix_memalign(&rawbuf, 4096, len + buf_align)) != 0) {
|
|
printf("write_file: error: posix_memalign failed with %d", r);
|
|
err = r;
|
|
goto out_close;
|
|
}
|
|
|
|
if (!direct)
|
|
ioctl(fd, CEPH_IOC_SYNCIO);
|
|
|
|
void *buf = (char *)rawbuf + buf_align;
|
|
|
|
generate_pattern(buf, len, offset);
|
|
|
|
r = pwrite(fd, buf, len, offset);
|
|
close(fd);
|
|
|
|
fd = open("foo", O_RDONLY);
|
|
if (fd < 0) {
|
|
err = errno;
|
|
printf("write_file: error: open() failed with: %d (%s)\n", err, strerror(err));
|
|
free(rawbuf);
|
|
goto out_unlink;
|
|
}
|
|
void *buf2 = malloc(len);
|
|
if (!buf2) {
|
|
err = -ENOMEM;
|
|
printf("write_file: error: malloc failed\n");
|
|
goto out_free;
|
|
}
|
|
|
|
memset(buf2, 0, len);
|
|
r = pread(fd, buf2, len, offset);
|
|
if (r == -1) {
|
|
err = errno;
|
|
printf("write_file: error: pread() failed with: %d (%s)\n", err, strerror(err));
|
|
goto out_free_buf;
|
|
}
|
|
r = verify_pattern(buf2, len, offset);
|
|
|
|
out_free_buf:
|
|
free(buf2);
|
|
out_free:
|
|
free(rawbuf);
|
|
out_close:
|
|
close(fd);
|
|
out_unlink:
|
|
unlink("foo");
|
|
if (err)
|
|
exit(err);
|
|
return r;
|
|
}
|
|
|
|
int write_direct(int buf_align, uint64_t offset, int len)
|
|
{
|
|
printf("write_direct buf_align %d offset %llu len %d\n", buf_align,
|
|
(unsigned long long)offset, len);
|
|
return write_file (buf_align, offset, len, 1);
|
|
}
|
|
|
|
int write_sync(int buf_align, uint64_t offset, int len)
|
|
{
|
|
printf("write_sync buf_align %d offset %llu len %d\n", buf_align,
|
|
(unsigned long long)offset, len);
|
|
return write_file (buf_align, offset, len, 0);
|
|
}
|
|
|
|
int main(int argc, char **argv)
|
|
{
|
|
uint64_t i, j, k;
|
|
int read = 1;
|
|
int write = 1;
|
|
|
|
if (argc >= 2 && strcmp(argv[1], "read") == 0)
|
|
write = 0;
|
|
if (argc >= 2 && strcmp(argv[1], "write") == 0)
|
|
read = 0;
|
|
|
|
if (read) {
|
|
write_pattern();
|
|
|
|
for (i = 0; i < 4096; i += 512)
|
|
for (j = 4*1024*1024 - 4096; j < 4*1024*1024 + 4096; j += 512)
|
|
for (k = 1024; k <= 16384; k *= 2) {
|
|
read_direct(i, j, k);
|
|
read_sync(i, j, k);
|
|
}
|
|
|
|
}
|
|
unlink("foo");
|
|
if (write) {
|
|
for (i = 0; i < 4096; i += 512)
|
|
for (j = 4*1024*1024 - 4096 + 512; j < 4*1024*1024 + 4096; j += 512)
|
|
for (k = 1024; k <= 16384; k *= 2) {
|
|
write_direct(i, j, k);
|
|
write_sync(i, j, k);
|
|
}
|
|
}
|
|
|
|
|
|
return 0;
|
|
}
|