|
|
|
|
@ -22,6 +22,7 @@ |
|
|
|
|
#include <unistd.h> |
|
|
|
|
#include <string.h> |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* put the temp files in the local directory |
|
|
|
|
* unless the user specifies otherwise
|
|
|
|
|
@ -34,21 +35,59 @@ |
|
|
|
|
#define NA_FORMAT LABEL_FORMAT "%18s" |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int loops = 2000; |
|
|
|
|
int ops_per_test = 2000; |
|
|
|
|
char full_buf[XLOG_SEG_SIZE], *buf, *filename = FSYNC_FILENAME; |
|
|
|
|
struct timeval start_t, stop_t; |
|
|
|
|
|
|
|
|
|
void die(char *str); |
|
|
|
|
|
|
|
|
|
void handle_args(int argc, char *argv[]); |
|
|
|
|
void prepare_buf(void); |
|
|
|
|
void test_open(void); |
|
|
|
|
void test_non_sync(void); |
|
|
|
|
void test_sync(int writes_per_op); |
|
|
|
|
void test_open_syncs(void); |
|
|
|
|
void test_file_descriptor_sync(void); |
|
|
|
|
void print_elapse(struct timeval start_t, struct timeval stop_t); |
|
|
|
|
void die(char *str); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int |
|
|
|
|
main(int argc, char *argv[]) |
|
|
|
|
{ |
|
|
|
|
struct timeval start_t, stop_t; |
|
|
|
|
int tmpfile, i; |
|
|
|
|
char *full_buf = (char *) malloc(XLOG_SEG_SIZE), |
|
|
|
|
*buf, *filename = FSYNC_FILENAME; |
|
|
|
|
handle_args(argc, argv); |
|
|
|
|
|
|
|
|
|
prepare_buf(); |
|
|
|
|
|
|
|
|
|
test_open(); |
|
|
|
|
|
|
|
|
|
test_non_sync(); |
|
|
|
|
|
|
|
|
|
/* Test using 1 8k write */ |
|
|
|
|
test_sync(1); |
|
|
|
|
|
|
|
|
|
/* Test using 2 8k writes */ |
|
|
|
|
test_sync(2); |
|
|
|
|
|
|
|
|
|
test_open_syncs(); |
|
|
|
|
|
|
|
|
|
test_file_descriptor_sync(); |
|
|
|
|
|
|
|
|
|
unlink(filename); |
|
|
|
|
|
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void |
|
|
|
|
handle_args(int argc, char *argv[]) |
|
|
|
|
{ |
|
|
|
|
if (argc > 1 && strcmp(argv[1], "-h") == 0) |
|
|
|
|
{ |
|
|
|
|
fprintf(stderr, "test_fsync [-f filename] [ops-per-test]\n"); |
|
|
|
|
exit(1); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* arguments: loops and filename (optional)
|
|
|
|
|
* arguments: ops_per_test and filename (optional)
|
|
|
|
|
*/ |
|
|
|
|
if (argc > 2 && strcmp(argv[1], "-f") == 0) |
|
|
|
|
{ |
|
|
|
|
@ -58,10 +97,27 @@ main(int argc, char *argv[]) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (argc > 1)
|
|
|
|
|
loops = atoi(argv[1]); |
|
|
|
|
ops_per_test = atoi(argv[1]); |
|
|
|
|
|
|
|
|
|
printf("Ops-per-test = %d\n\n", ops_per_test); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void |
|
|
|
|
prepare_buf(void) |
|
|
|
|
{ |
|
|
|
|
int ops; |
|
|
|
|
|
|
|
|
|
for (i = 0; i < XLOG_SEG_SIZE; i++) |
|
|
|
|
full_buf[i] = random(); |
|
|
|
|
/* write random data into buffer */ |
|
|
|
|
for (ops = 0; ops < XLOG_SEG_SIZE; ops++) |
|
|
|
|
full_buf[ops] = random(); |
|
|
|
|
|
|
|
|
|
buf = (char *) TYPEALIGN(ALIGNOF_XLOG_BUFFER, full_buf); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void |
|
|
|
|
test_open(void) |
|
|
|
|
{ |
|
|
|
|
int tmpfile; |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* test if we can open the target file
|
|
|
|
|
@ -70,25 +126,28 @@ main(int argc, char *argv[]) |
|
|
|
|
die("Cannot open output file."); |
|
|
|
|
if (write(tmpfile, full_buf, XLOG_SEG_SIZE) != XLOG_SEG_SIZE) |
|
|
|
|
die("write failed"); |
|
|
|
|
/*
|
|
|
|
|
* fsync now so that dirty buffers don't skew later tests |
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
/* fsync now so that dirty buffers don't skew later tests */ |
|
|
|
|
if (fsync(tmpfile) != 0) |
|
|
|
|
die("fsync failed"); |
|
|
|
|
close(tmpfile); |
|
|
|
|
|
|
|
|
|
buf = (char *) TYPEALIGN(ALIGNOF_XLOG_BUFFER, full_buf); |
|
|
|
|
close(tmpfile); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
printf("Loops = %d\n\n", loops); |
|
|
|
|
void |
|
|
|
|
test_non_sync(void) |
|
|
|
|
{ |
|
|
|
|
int tmpfile, ops; |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Test a simple write without fsync |
|
|
|
|
*/ |
|
|
|
|
printf("Simple write:\n"); |
|
|
|
|
printf("Simple non-sync'ed write:\n"); |
|
|
|
|
printf(LABEL_FORMAT, "8k write"); |
|
|
|
|
fflush(stdout); |
|
|
|
|
|
|
|
|
|
gettimeofday(&start_t, NULL); |
|
|
|
|
for (i = 0; i < loops; i++) |
|
|
|
|
for (ops = 0; ops < ops_per_test; ops++) |
|
|
|
|
{ |
|
|
|
|
if ((tmpfile = open(filename, O_RDWR, 0)) == -1) |
|
|
|
|
die("Cannot open output file."); |
|
|
|
|
@ -98,25 +157,37 @@ main(int argc, char *argv[]) |
|
|
|
|
} |
|
|
|
|
gettimeofday(&stop_t, NULL); |
|
|
|
|
print_elapse(start_t, stop_t); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Test all fsync methods using single 8k writes |
|
|
|
|
*/ |
|
|
|
|
printf("\nCompare file sync methods using one write:\n"); |
|
|
|
|
void |
|
|
|
|
test_sync(int writes_per_op) |
|
|
|
|
{ |
|
|
|
|
int tmpfile, ops, writes; |
|
|
|
|
|
|
|
|
|
if (writes_per_op == 1) |
|
|
|
|
printf("\nCompare file sync methods using one write:\n"); |
|
|
|
|
else |
|
|
|
|
printf("\nCompare file sync methods using two writes:\n"); |
|
|
|
|
printf("(in wal_sync_method preference order)\n"); |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Test open_datasync if available |
|
|
|
|
*/ |
|
|
|
|
#ifdef OPEN_DATASYNC_FLAG |
|
|
|
|
printf(LABEL_FORMAT, "open_datasync 8k write"); |
|
|
|
|
if (writes_per_op == 1) |
|
|
|
|
printf(LABEL_FORMAT, "open_datasync 8k write"); |
|
|
|
|
else |
|
|
|
|
printf(LABEL_FORMAT, "2 open_datasync 8k writes"); |
|
|
|
|
fflush(stdout); |
|
|
|
|
|
|
|
|
|
if ((tmpfile = open(filename, O_RDWR | O_DSYNC, 0)) == -1) |
|
|
|
|
die("Cannot open output file."); |
|
|
|
|
gettimeofday(&start_t, NULL); |
|
|
|
|
for (i = 0; i < loops; i++) |
|
|
|
|
for (ops = 0; ops < ops_per_test; ops++) |
|
|
|
|
{ |
|
|
|
|
if (write(tmpfile, buf, WRITE_SIZE) != WRITE_SIZE) |
|
|
|
|
die("write failed"); |
|
|
|
|
for (writes = 0; writes < writes_per_op; writes++) |
|
|
|
|
if (write(tmpfile, buf, WRITE_SIZE) != WRITE_SIZE) |
|
|
|
|
die("write failed"); |
|
|
|
|
if (lseek(tmpfile, 0, SEEK_SET) == -1) |
|
|
|
|
die("seek failed"); |
|
|
|
|
} |
|
|
|
|
@ -128,17 +199,22 @@ main(int argc, char *argv[]) |
|
|
|
|
* If O_DIRECT is enabled, test that with open_datasync |
|
|
|
|
*/ |
|
|
|
|
#if PG_O_DIRECT != 0 |
|
|
|
|
fflush(stdout); |
|
|
|
|
if ((tmpfile = open(filename, O_RDWR | O_DSYNC | PG_O_DIRECT, 0)) == -1) |
|
|
|
|
printf(NA_FORMAT, "o_direct", "n/a on this filesystem\n"); |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
printf(LABEL_FORMAT, "open_datasync 8k direct I/O write"); |
|
|
|
|
if (writes_per_op == 1) |
|
|
|
|
printf(LABEL_FORMAT, "open_datasync 8k direct I/O write"); |
|
|
|
|
else |
|
|
|
|
printf(LABEL_FORMAT, "2 open_datasync 8k direct I/O writes"); |
|
|
|
|
fflush(stdout); |
|
|
|
|
|
|
|
|
|
gettimeofday(&start_t, NULL); |
|
|
|
|
for (i = 0; i < loops; i++) |
|
|
|
|
for (ops = 0; ops < ops_per_test; ops++) |
|
|
|
|
{ |
|
|
|
|
if (write(tmpfile, buf, WRITE_SIZE) != WRITE_SIZE) |
|
|
|
|
die("write failed"); |
|
|
|
|
for (writes = 0; writes < writes_per_op; writes++) |
|
|
|
|
if (write(tmpfile, buf, WRITE_SIZE) != WRITE_SIZE) |
|
|
|
|
die("write failed"); |
|
|
|
|
if (lseek(tmpfile, 0, SEEK_SET) == -1) |
|
|
|
|
die("seek failed"); |
|
|
|
|
} |
|
|
|
|
@ -154,69 +230,24 @@ main(int argc, char *argv[]) |
|
|
|
|
printf(NA_FORMAT, "open_datasync", "n/a\n"); |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Test open_sync if available |
|
|
|
|
*/ |
|
|
|
|
#ifdef OPEN_SYNC_FLAG |
|
|
|
|
printf(LABEL_FORMAT, "open_sync 8k write"); |
|
|
|
|
fflush(stdout); |
|
|
|
|
if ((tmpfile = open(filename, O_RDWR | OPEN_SYNC_FLAG, 0)) == -1) |
|
|
|
|
die("Cannot open output file."); |
|
|
|
|
gettimeofday(&start_t, NULL); |
|
|
|
|
for (i = 0; i < loops; i++) |
|
|
|
|
{ |
|
|
|
|
if (write(tmpfile, buf, WRITE_SIZE) != WRITE_SIZE) |
|
|
|
|
die("write failed"); |
|
|
|
|
if (lseek(tmpfile, 0, SEEK_SET) == -1) |
|
|
|
|
die("seek failed"); |
|
|
|
|
} |
|
|
|
|
gettimeofday(&stop_t, NULL); |
|
|
|
|
close(tmpfile); |
|
|
|
|
print_elapse(start_t, stop_t); |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* If O_DIRECT is enabled, test that with open_sync |
|
|
|
|
*/ |
|
|
|
|
#if PG_O_DIRECT != 0 |
|
|
|
|
printf(LABEL_FORMAT, "open_sync 8k direct I/O write"); |
|
|
|
|
fflush(stdout); |
|
|
|
|
if ((tmpfile = open(filename, O_RDWR | OPEN_SYNC_FLAG | PG_O_DIRECT, 0)) == -1) |
|
|
|
|
printf(NA_FORMAT, "o_direct", "n/a on this filesystem\n"); |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
gettimeofday(&start_t, NULL); |
|
|
|
|
for (i = 0; i < loops; i++) |
|
|
|
|
{ |
|
|
|
|
if (write(tmpfile, buf, WRITE_SIZE) != WRITE_SIZE) |
|
|
|
|
die("write failed"); |
|
|
|
|
if (lseek(tmpfile, 0, SEEK_SET) == -1) |
|
|
|
|
die("seek failed"); |
|
|
|
|
} |
|
|
|
|
gettimeofday(&stop_t, NULL); |
|
|
|
|
close(tmpfile); |
|
|
|
|
print_elapse(start_t, stop_t); |
|
|
|
|
} |
|
|
|
|
#else |
|
|
|
|
printf(NA_FORMAT, "o_direct", "n/a\n"); |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
#else |
|
|
|
|
printf(NA_FORMAT, "open_sync", "n/a\n"); |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Test fdatasync if available |
|
|
|
|
*/ |
|
|
|
|
#ifdef HAVE_FDATASYNC |
|
|
|
|
printf(LABEL_FORMAT, "8k write, fdatasync"); |
|
|
|
|
if (writes_per_op == 1) |
|
|
|
|
printf(LABEL_FORMAT, "8k write, fdatasync"); |
|
|
|
|
else |
|
|
|
|
printf(LABEL_FORMAT, "8k write, 8k write, fdatasync"); |
|
|
|
|
fflush(stdout); |
|
|
|
|
|
|
|
|
|
if ((tmpfile = open(filename, O_RDWR, 0)) == -1) |
|
|
|
|
die("Cannot open output file."); |
|
|
|
|
gettimeofday(&start_t, NULL); |
|
|
|
|
for (i = 0; i < loops; i++) |
|
|
|
|
for (ops = 0; ops < ops_per_test; ops++) |
|
|
|
|
{ |
|
|
|
|
if (write(tmpfile, buf, WRITE_SIZE) != WRITE_SIZE) |
|
|
|
|
die("write failed"); |
|
|
|
|
for (writes = 0; writes < writes_per_op; writes++) |
|
|
|
|
if (write(tmpfile, buf, WRITE_SIZE) != WRITE_SIZE) |
|
|
|
|
die("write failed"); |
|
|
|
|
fdatasync(tmpfile); |
|
|
|
|
if (lseek(tmpfile, 0, SEEK_SET) == -1) |
|
|
|
|
die("seek failed"); |
|
|
|
|
@ -231,15 +262,20 @@ main(int argc, char *argv[]) |
|
|
|
|
/*
|
|
|
|
|
* Test fsync |
|
|
|
|
*/ |
|
|
|
|
printf(LABEL_FORMAT, "8k write, fsync"); |
|
|
|
|
if (writes_per_op == 1) |
|
|
|
|
printf(LABEL_FORMAT, "8k write, fsync"); |
|
|
|
|
else |
|
|
|
|
printf(LABEL_FORMAT, "8k write, 8k write, fsync"); |
|
|
|
|
fflush(stdout); |
|
|
|
|
|
|
|
|
|
if ((tmpfile = open(filename, O_RDWR, 0)) == -1) |
|
|
|
|
die("Cannot open output file."); |
|
|
|
|
gettimeofday(&start_t, NULL); |
|
|
|
|
for (i = 0; i < loops; i++) |
|
|
|
|
for (ops = 0; ops < ops_per_test; ops++) |
|
|
|
|
{ |
|
|
|
|
if (write(tmpfile, buf, WRITE_SIZE) != WRITE_SIZE) |
|
|
|
|
die("write failed"); |
|
|
|
|
for (writes = 0; writes < writes_per_op; writes++) |
|
|
|
|
if (write(tmpfile, buf, WRITE_SIZE) != WRITE_SIZE) |
|
|
|
|
die("write failed"); |
|
|
|
|
if (fsync(tmpfile) != 0) |
|
|
|
|
die("fsync failed"); |
|
|
|
|
if (lseek(tmpfile, 0, SEEK_SET) == -1) |
|
|
|
|
@ -253,15 +289,20 @@ main(int argc, char *argv[]) |
|
|
|
|
* If fsync_writethrough is available, test as well |
|
|
|
|
*/
|
|
|
|
|
#ifdef HAVE_FSYNC_WRITETHROUGH |
|
|
|
|
printf(LABEL_FORMAT, "8k write, fsync_writethrough"); |
|
|
|
|
if (writes_per_op == 1) |
|
|
|
|
printf(LABEL_FORMAT, "8k write, fsync_writethrough"); |
|
|
|
|
else |
|
|
|
|
printf(LABEL_FORMAT, "8k write, 8k write, fsync_writethrough"); |
|
|
|
|
fflush(stdout); |
|
|
|
|
|
|
|
|
|
if ((tmpfile = open(filename, O_RDWR, 0)) == -1) |
|
|
|
|
die("Cannot open output file."); |
|
|
|
|
gettimeofday(&start_t, NULL); |
|
|
|
|
for (i = 0; i < loops; i++) |
|
|
|
|
for (ops = 0; ops < ops_per_test; ops++) |
|
|
|
|
{ |
|
|
|
|
if (write(tmpfile, buf, WRITE_SIZE) != WRITE_SIZE) |
|
|
|
|
die("write failed"); |
|
|
|
|
for (writes = 0; writes < writes_per_op; writes++) |
|
|
|
|
if (write(tmpfile, buf, WRITE_SIZE) != WRITE_SIZE) |
|
|
|
|
die("write failed"); |
|
|
|
|
if (fcntl(tmpfile, F_FULLFSYNC ) != 0) |
|
|
|
|
die("fsync failed"); |
|
|
|
|
if (lseek(tmpfile, 0, SEEK_SET) == -1) |
|
|
|
|
@ -274,100 +315,58 @@ main(int argc, char *argv[]) |
|
|
|
|
printf(NA_FORMAT, "fsync_writethrough", "n/a\n"); |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Compare some of the file sync methods with
|
|
|
|
|
* two 8k writes to see if timing is different |
|
|
|
|
*/ |
|
|
|
|
printf("\nCompare file sync methods using two writes:\n"); |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Test open_datasync with and without o_direct |
|
|
|
|
*/ |
|
|
|
|
#ifdef OPEN_DATASYNC_FLAG |
|
|
|
|
printf(LABEL_FORMAT, "2 open_datasync 8k writes"); |
|
|
|
|
fflush(stdout); |
|
|
|
|
if ((tmpfile = open(filename, O_RDWR | O_DSYNC, 0)) == -1) |
|
|
|
|
die("Cannot open output file."); |
|
|
|
|
gettimeofday(&start_t, NULL); |
|
|
|
|
for (i = 0; i < loops; i++) |
|
|
|
|
{ |
|
|
|
|
if (write(tmpfile, buf, WRITE_SIZE) != WRITE_SIZE) |
|
|
|
|
die("write failed"); |
|
|
|
|
if (write(tmpfile, buf, WRITE_SIZE) != WRITE_SIZE) |
|
|
|
|
die("write failed"); |
|
|
|
|
if (lseek(tmpfile, 0, SEEK_SET) == -1) |
|
|
|
|
die("seek failed"); |
|
|
|
|
} |
|
|
|
|
gettimeofday(&stop_t, NULL); |
|
|
|
|
close(tmpfile); |
|
|
|
|
print_elapse(start_t, stop_t); |
|
|
|
|
|
|
|
|
|
#if PG_O_DIRECT != 0 |
|
|
|
|
printf(LABEL_FORMAT, "2 open_datasync direct I/O 8k writes"); |
|
|
|
|
fflush(stdout); |
|
|
|
|
if ((tmpfile = open(filename, O_RDWR | O_DSYNC | PG_O_DIRECT, 0)) == -1) |
|
|
|
|
die("Cannot open output file."); |
|
|
|
|
gettimeofday(&start_t, NULL); |
|
|
|
|
for (i = 0; i < loops; i++) |
|
|
|
|
{ |
|
|
|
|
if (write(tmpfile, buf, WRITE_SIZE) != WRITE_SIZE) |
|
|
|
|
die("write failed"); |
|
|
|
|
if (write(tmpfile, buf, WRITE_SIZE) != WRITE_SIZE) |
|
|
|
|
die("write failed"); |
|
|
|
|
if (lseek(tmpfile, 0, SEEK_SET) == -1) |
|
|
|
|
die("seek failed"); |
|
|
|
|
} |
|
|
|
|
gettimeofday(&stop_t, NULL); |
|
|
|
|
close(tmpfile); |
|
|
|
|
print_elapse(start_t, stop_t); |
|
|
|
|
#else |
|
|
|
|
printf(NA_FORMAT, "o_direct" "n/a\n"); |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
#else |
|
|
|
|
printf(NA_FORMAT, "open_datasync", "n/a\n"); |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Test open_sync with and without o_direct |
|
|
|
|
* Test open_sync if available |
|
|
|
|
*/ |
|
|
|
|
#ifdef OPEN_SYNC_FLAG |
|
|
|
|
printf(LABEL_FORMAT, "2 open_sync 8k writes"); |
|
|
|
|
if (writes_per_op == 1) |
|
|
|
|
printf(LABEL_FORMAT, "open_sync 8k write"); |
|
|
|
|
else |
|
|
|
|
printf(LABEL_FORMAT, "2 open_sync 8k writes"); |
|
|
|
|
fflush(stdout); |
|
|
|
|
|
|
|
|
|
if ((tmpfile = open(filename, O_RDWR | OPEN_SYNC_FLAG, 0)) == -1) |
|
|
|
|
die("Cannot open output file."); |
|
|
|
|
gettimeofday(&start_t, NULL); |
|
|
|
|
for (i = 0; i < loops; i++) |
|
|
|
|
for (ops = 0; ops < ops_per_test; ops++) |
|
|
|
|
{ |
|
|
|
|
if (write(tmpfile, buf, WRITE_SIZE) != WRITE_SIZE) |
|
|
|
|
die("write failed"); |
|
|
|
|
if (write(tmpfile, buf, WRITE_SIZE) != WRITE_SIZE) |
|
|
|
|
die("write failed"); |
|
|
|
|
for (writes = 0; writes < writes_per_op; writes++) |
|
|
|
|
if (write(tmpfile, buf, WRITE_SIZE) != WRITE_SIZE) |
|
|
|
|
die("write failed"); |
|
|
|
|
if (lseek(tmpfile, 0, SEEK_SET) == -1) |
|
|
|
|
die("seek failed"); |
|
|
|
|
} |
|
|
|
|
gettimeofday(&stop_t, NULL); |
|
|
|
|
close(tmpfile); |
|
|
|
|
print_elapse(start_t, stop_t); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* If O_DIRECT is enabled, test that with open_sync |
|
|
|
|
*/ |
|
|
|
|
#if PG_O_DIRECT != 0 |
|
|
|
|
printf(LABEL_FORMAT, "2 open_sync direct I/O 8k writes"); |
|
|
|
|
if (writes_per_op == 1) |
|
|
|
|
printf(LABEL_FORMAT, "open_sync 8k direct I/O write"); |
|
|
|
|
else |
|
|
|
|
printf(LABEL_FORMAT, "2 open_sync 8k direct I/O writes"); |
|
|
|
|
fflush(stdout); |
|
|
|
|
|
|
|
|
|
if ((tmpfile = open(filename, O_RDWR | OPEN_SYNC_FLAG | PG_O_DIRECT, 0)) == -1) |
|
|
|
|
die("Cannot open output file."); |
|
|
|
|
gettimeofday(&start_t, NULL); |
|
|
|
|
for (i = 0; i < loops; i++) |
|
|
|
|
printf(NA_FORMAT, "o_direct", "n/a on this filesystem\n"); |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
if (write(tmpfile, buf, WRITE_SIZE) != WRITE_SIZE) |
|
|
|
|
die("write failed"); |
|
|
|
|
if (write(tmpfile, buf, WRITE_SIZE) != WRITE_SIZE) |
|
|
|
|
die("write failed"); |
|
|
|
|
if (lseek(tmpfile, 0, SEEK_SET) == -1) |
|
|
|
|
die("seek failed"); |
|
|
|
|
gettimeofday(&start_t, NULL); |
|
|
|
|
for (ops = 0; ops < ops_per_test; ops++) |
|
|
|
|
{ |
|
|
|
|
for (writes = 0; writes < writes_per_op; writes++) |
|
|
|
|
if (write(tmpfile, buf, WRITE_SIZE) != WRITE_SIZE) |
|
|
|
|
die("write failed"); |
|
|
|
|
if (lseek(tmpfile, 0, SEEK_SET) == -1) |
|
|
|
|
die("seek failed"); |
|
|
|
|
} |
|
|
|
|
gettimeofday(&stop_t, NULL); |
|
|
|
|
close(tmpfile); |
|
|
|
|
print_elapse(start_t, stop_t); |
|
|
|
|
} |
|
|
|
|
gettimeofday(&stop_t, NULL); |
|
|
|
|
close(tmpfile); |
|
|
|
|
print_elapse(start_t, stop_t); |
|
|
|
|
#else |
|
|
|
|
printf(NA_FORMAT, "o_direct", "n/a\n"); |
|
|
|
|
#endif |
|
|
|
|
@ -375,82 +374,12 @@ main(int argc, char *argv[]) |
|
|
|
|
#else |
|
|
|
|
printf(NA_FORMAT, "open_sync", "n/a\n"); |
|
|
|
|
#endif |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Test fdatasync |
|
|
|
|
*/ |
|
|
|
|
#ifdef HAVE_FDATASYNC |
|
|
|
|
printf(LABEL_FORMAT, "8k write, 8k write, fdatasync"); |
|
|
|
|
fflush(stdout); |
|
|
|
|
if ((tmpfile = open(filename, O_RDWR, 0)) == -1) |
|
|
|
|
die("Cannot open output file."); |
|
|
|
|
gettimeofday(&start_t, NULL); |
|
|
|
|
for (i = 0; i < loops; i++) |
|
|
|
|
{ |
|
|
|
|
if (write(tmpfile, buf, WRITE_SIZE) != WRITE_SIZE) |
|
|
|
|
die("write failed"); |
|
|
|
|
if (write(tmpfile, buf, WRITE_SIZE) != WRITE_SIZE) |
|
|
|
|
die("write failed"); |
|
|
|
|
fdatasync(tmpfile); |
|
|
|
|
if (lseek(tmpfile, 0, SEEK_SET) == -1) |
|
|
|
|
die("seek failed"); |
|
|
|
|
} |
|
|
|
|
gettimeofday(&stop_t, NULL); |
|
|
|
|
close(tmpfile); |
|
|
|
|
print_elapse(start_t, stop_t); |
|
|
|
|
#else |
|
|
|
|
printf(NA_FORMAT, "fdatasync", "n/a\n"); |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Test basic fsync |
|
|
|
|
*/ |
|
|
|
|
printf(LABEL_FORMAT, "8k write, 8k write, fsync"); |
|
|
|
|
fflush(stdout); |
|
|
|
|
if ((tmpfile = open(filename, O_RDWR, 0)) == -1) |
|
|
|
|
die("Cannot open output file."); |
|
|
|
|
gettimeofday(&start_t, NULL); |
|
|
|
|
for (i = 0; i < loops; i++) |
|
|
|
|
{ |
|
|
|
|
if (write(tmpfile, buf, WRITE_SIZE) != WRITE_SIZE) |
|
|
|
|
die("write failed"); |
|
|
|
|
if (write(tmpfile, buf, WRITE_SIZE) != WRITE_SIZE) |
|
|
|
|
die("write failed"); |
|
|
|
|
if (fsync(tmpfile) != 0) |
|
|
|
|
die("fsync failed"); |
|
|
|
|
if (lseek(tmpfile, 0, SEEK_SET) == -1) |
|
|
|
|
die("seek failed"); |
|
|
|
|
} |
|
|
|
|
gettimeofday(&stop_t, NULL); |
|
|
|
|
close(tmpfile); |
|
|
|
|
print_elapse(start_t, stop_t); |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Test fsync_writethrough if available |
|
|
|
|
*/
|
|
|
|
|
#ifdef HAVE_FSYNC_WRITETHROUGH |
|
|
|
|
printf(LABEL_FORMAT, "8k write, 8k write, fsync_writethrough"); |
|
|
|
|
fflush(stdout); |
|
|
|
|
if ((tmpfile = open(filename, O_RDWR, 0)) == -1) |
|
|
|
|
die("Cannot open output file."); |
|
|
|
|
gettimeofday(&start_t, NULL); |
|
|
|
|
for (i = 0; i < loops; i++) |
|
|
|
|
{ |
|
|
|
|
if (write(tmpfile, buf, WRITE_SIZE) != WRITE_SIZE) |
|
|
|
|
die("write failed"); |
|
|
|
|
if (write(tmpfile, buf, WRITE_SIZE) != WRITE_SIZE) |
|
|
|
|
die("write failed"); |
|
|
|
|
if (fcntl(tmpfile, F_FULLFSYNC) != 0) |
|
|
|
|
die("fsync failed"); |
|
|
|
|
if (lseek(tmpfile, 0, SEEK_SET) == -1) |
|
|
|
|
die("seek failed"); |
|
|
|
|
} |
|
|
|
|
gettimeofday(&stop_t, NULL); |
|
|
|
|
close(tmpfile); |
|
|
|
|
print_elapse(start_t, stop_t); |
|
|
|
|
#else |
|
|
|
|
printf(NA_FORMAT, "fsync_writethrough", "n/a\n"); |
|
|
|
|
#endif |
|
|
|
|
void |
|
|
|
|
test_open_syncs(void) |
|
|
|
|
{ |
|
|
|
|
int tmpfile, ops; |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Compare 1 to 2 writes |
|
|
|
|
@ -465,10 +394,11 @@ main(int argc, char *argv[]) |
|
|
|
|
#ifdef OPEN_SYNC_FLAG |
|
|
|
|
printf(LABEL_FORMAT, "open_sync 16k write"); |
|
|
|
|
fflush(stdout); |
|
|
|
|
|
|
|
|
|
if ((tmpfile = open(filename, O_RDWR | OPEN_SYNC_FLAG, 0)) == -1) |
|
|
|
|
die("Cannot open output file."); |
|
|
|
|
gettimeofday(&start_t, NULL); |
|
|
|
|
for (i = 0; i < loops; i++) |
|
|
|
|
for (ops = 0; ops < ops_per_test; ops++) |
|
|
|
|
{ |
|
|
|
|
if (write(tmpfile, buf, WRITE_SIZE * 2) != WRITE_SIZE * 2) |
|
|
|
|
die("write failed"); |
|
|
|
|
@ -481,10 +411,11 @@ main(int argc, char *argv[]) |
|
|
|
|
|
|
|
|
|
printf(LABEL_FORMAT, "2 open_sync 8k writes"); |
|
|
|
|
fflush(stdout); |
|
|
|
|
|
|
|
|
|
if ((tmpfile = open(filename, O_RDWR | OPEN_SYNC_FLAG, 0)) == -1) |
|
|
|
|
die("Cannot open output file."); |
|
|
|
|
gettimeofday(&start_t, NULL); |
|
|
|
|
for (i = 0; i < loops; i++) |
|
|
|
|
for (ops = 0; ops < ops_per_test; ops++) |
|
|
|
|
{ |
|
|
|
|
if (write(tmpfile, buf, WRITE_SIZE) != WRITE_SIZE) |
|
|
|
|
die("write failed"); |
|
|
|
|
@ -499,6 +430,12 @@ main(int argc, char *argv[]) |
|
|
|
|
#else |
|
|
|
|
printf(NA_FORMAT, "open_sync", "n/a\n"); |
|
|
|
|
#endif |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void |
|
|
|
|
test_file_descriptor_sync(void) |
|
|
|
|
{ |
|
|
|
|
int tmpfile, ops; |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Test whether fsync can sync data written on a different |
|
|
|
|
@ -517,8 +454,9 @@ main(int argc, char *argv[]) |
|
|
|
|
*/ |
|
|
|
|
printf(LABEL_FORMAT, "8k write, fsync, close"); |
|
|
|
|
fflush(stdout); |
|
|
|
|
|
|
|
|
|
gettimeofday(&start_t, NULL); |
|
|
|
|
for (i = 0; i < loops; i++) |
|
|
|
|
for (ops = 0; ops < ops_per_test; ops++) |
|
|
|
|
{ |
|
|
|
|
if ((tmpfile = open(filename, O_RDWR, 0)) == -1) |
|
|
|
|
die("Cannot open output file."); |
|
|
|
|
@ -545,8 +483,9 @@ main(int argc, char *argv[]) |
|
|
|
|
*/ |
|
|
|
|
printf(LABEL_FORMAT, "8k write, close, fsync"); |
|
|
|
|
fflush(stdout); |
|
|
|
|
|
|
|
|
|
gettimeofday(&start_t, NULL); |
|
|
|
|
for (i = 0; i < loops; i++) |
|
|
|
|
for (ops = 0; ops < ops_per_test; ops++) |
|
|
|
|
{ |
|
|
|
|
if ((tmpfile = open(filename, O_RDWR, 0)) == -1) |
|
|
|
|
die("Cannot open output file."); |
|
|
|
|
@ -563,13 +502,6 @@ main(int argc, char *argv[]) |
|
|
|
|
gettimeofday(&stop_t, NULL); |
|
|
|
|
print_elapse(start_t, stop_t); |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* cleanup
|
|
|
|
|
*/ |
|
|
|
|
free(full_buf); |
|
|
|
|
unlink(filename); |
|
|
|
|
|
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
@ -580,7 +512,7 @@ print_elapse(struct timeval start_t, struct timeval stop_t) |
|
|
|
|
{ |
|
|
|
|
double total_time = (stop_t.tv_sec - start_t.tv_sec) + |
|
|
|
|
(stop_t.tv_usec - start_t.tv_usec) * 0.000001; |
|
|
|
|
double per_second = loops / total_time; |
|
|
|
|
double per_second = ops_per_test / total_time; |
|
|
|
|
|
|
|
|
|
printf("%9.3f ops/sec\n", per_second); |
|
|
|
|
} |
|
|
|
|
|