|
@@ -40,6 +40,8 @@
|
|
|
|
|
|
typedef struct {
|
|
|
int fd;
|
|
|
+
|
|
|
+ int sync_mode;
|
|
|
|
|
|
size_t prior_size; /**< original size of file */
|
|
|
size_t preallocated; /**< preallocated bytes */
|
|
@@ -56,9 +58,6 @@ int fastwriter_default_open(fastwriter_t *fw, const char *name, fastwriter_flags
|
|
|
int open_flags = (O_CREAT|O_WRONLY|O_NOATIME|O_LARGEFILE);
|
|
|
int open_mode = (S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
|
|
|
|
|
|
-#ifdef SYNC_MODE
|
|
|
- open_flags |= O_DIRECT;//|O_SYNC;
|
|
|
-#endif /* SYNC_MODE */
|
|
|
|
|
|
fastwriter_default_t *ctx;
|
|
|
|
|
@@ -72,9 +71,17 @@ int fastwriter_default_open(fastwriter_t *fw, const char *name, fastwriter_flags
|
|
|
|
|
|
fw->ctx = ctx;
|
|
|
|
|
|
+#ifdef SYNC_MODE
|
|
|
+ open_flags |= O_DIRECT;
|
|
|
+ ctx->sync_mode = 1;
|
|
|
+#endif /* SYNC_MODE */
|
|
|
+
|
|
|
+ ctx->prior_size = 0;
|
|
|
+
|
|
|
if (!strcmp(fs, "raw")) {
|
|
|
ctx->wr_block = EXT4_WRITEBLOCK;
|
|
|
ctx->pa_block = 0;
|
|
|
+ ctx->prior_size = (size_t)-1;
|
|
|
} else if (!strcmp(fs, "ext4")) {
|
|
|
ctx->wr_block = EXT4_WRITEBLOCK;
|
|
|
ctx->pa_block = EXT4_PREALLOCATE;
|
|
@@ -95,13 +102,21 @@ int fastwriter_default_open(fastwriter_t *fw, const char *name, fastwriter_flags
|
|
|
ctx->fd = open(name, open_flags, open_mode);
|
|
|
if (ctx->fd < 0) return errno;
|
|
|
|
|
|
- ctx->prior_size = 0;
|
|
|
-
|
|
|
-#ifndef HAVE_LINUX_FALLOC_H
|
|
|
if (((open_flags&FASTWRITER_FLAGS_OVERWRITE)==0)&&(strcmp(fs, "raw"))) {
|
|
|
ctx->prior_size = lseek(ctx->fd, 0, SEEK_END);
|
|
|
+# ifdef SYNC_MODE
|
|
|
+ if (ctx->prior_size%FASTWRITER_SYNCIO_ALIGN) {
|
|
|
+ close(ctx->fd);
|
|
|
+
|
|
|
+ ctx->fd = open(name, open_flags&~O_DIRECT, open_mode);
|
|
|
+ if (ctx->fd < 0) return errno;
|
|
|
+
|
|
|
+ ctx->prior_size = lseek(ctx->fd, 0, SEEK_END);
|
|
|
+
|
|
|
+ ctx->sync_mode = 0;
|
|
|
+ }
|
|
|
+# endif /* SYNC_MODE */
|
|
|
}
|
|
|
-#endif /* HAVE_LINUX_FALLOC_H */
|
|
|
|
|
|
ctx->preallocated = 0;
|
|
|
|
|
@@ -114,11 +129,11 @@ void fastwriter_default_close(fastwriter_t *fw) {
|
|
|
fastwriter_default_t *ctx = (fastwriter_default_t*)fw->ctx;
|
|
|
|
|
|
if (ctx->fd >= 0) {
|
|
|
-#ifndef HAVE_LINUX_FALLOC_H
|
|
|
- if (ctx->prior_size) {
|
|
|
- ftrucate(ctx->fd, ctx->prior_size + fw->written);
|
|
|
+#if defined(SYNC_MODE)||!defined(HAVE_LINUX_FALLOC_H)
|
|
|
+ if (ctx->prior_size != (size_t)-1) {
|
|
|
+ ftruncate(ctx->fd, ctx->prior_size + fw->written);
|
|
|
}
|
|
|
-#endif /* HAVE_LINUX_FALLOC_H */
|
|
|
+#endif
|
|
|
close(ctx->fd);
|
|
|
}
|
|
|
|
|
@@ -130,9 +145,10 @@ void fastwriter_default_close(fastwriter_t *fw) {
|
|
|
|
|
|
int fastwriter_default_write(fastwriter_t *fw, fastwriter_write_flags_t flags, size_t size, void *data, size_t *written) {
|
|
|
size_t sum = 0;
|
|
|
+ size_t delta = 0;
|
|
|
ssize_t res;
|
|
|
fastwriter_default_t *ctx = (fastwriter_default_t*)fw->ctx;
|
|
|
-
|
|
|
+
|
|
|
if ((flags&FASTWRITER_WRITE_FLAG_FORCE)==0) {
|
|
|
if (size < ctx->wr_block) {
|
|
|
*written = 0;
|
|
@@ -141,6 +157,7 @@ int fastwriter_default_write(fastwriter_t *fw, fastwriter_write_flags_t flags, s
|
|
|
|
|
|
size -= size % ctx->wr_block;
|
|
|
}
|
|
|
+
|
|
|
|
|
|
if ((ctx->pa_block)&&((fw->written + size) > ctx->preallocated)) {
|
|
|
#ifdef HAVE_LINUX_FALLOC_H
|
|
@@ -153,9 +170,17 @@ int fastwriter_default_write(fastwriter_t *fw, fastwriter_write_flags_t flags, s
|
|
|
ctx->preallocated += ctx->pa_block;
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+#ifdef SYNC_MODE
|
|
|
+ // we expect this to happen only at last iteration (buffer is multiply of the required align)
|
|
|
+ if ((ctx->sync_mode)&&(size%FASTWRITER_SYNCIO_ALIGN)) {
|
|
|
+ delta = FASTWRITER_SYNCIO_ALIGN - size%FASTWRITER_SYNCIO_ALIGN;
|
|
|
+ }
|
|
|
+#endif /* SYNC_MODE */
|
|
|
|
|
|
do {
|
|
|
- res = write(ctx->fd, data, size);
|
|
|
+ res = write(ctx->fd, data + sum, size + delta - sum);
|
|
|
+// printf("%i %i %p %zu %i\n", res, ctx->fd, data, size, delta);
|
|
|
if (res < 0) {
|
|
|
*written = sum;
|
|
|
return errno;
|