1
#define _FASTWRITER_DEFAULT_C
4
#define _XOPEN_SOURCE 600
5
#define _POSIX_C_SOURCE 200112L
6
#define _LARGEFILE64_SOURCE
19
#include <sys/types.h>
26
#ifdef HAVE_LINUX_FALLOC_H
27
# include <linux/falloc.h>
28
#endif /* HAVE_LINUX_FALLOC_H */
30
#include "fastwriter.h"
35
#define HAVE_FALLOCATE
36
#define EXT4_WRITEBLOCK 4194304
37
#define EXT4_PREALLOCATE 1073741824
43
size_t prior_size; /**< original size of file */
44
size_t preallocated; /**< preallocated bytes */
46
size_t wr_block; /**< minimal block of data to write */
47
size_t pa_block; /**< preallocation setp */
48
} fastwriter_default_t;
51
int fastwriter_open_default(fastwriter_t *fw, const char *name, fastwriter_flags_t flags) {
55
int open_flags = (O_CREAT|O_WRONLY|O_NOATIME|O_LARGEFILE);
56
int open_mode = (S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
59
open_flags |= O_DIRECT;//|O_SYNC;
60
#endif /* SYNC_MODE */
62
fastwriter_default_t *ctx;
64
err = get_file_fs(name, sizeof(fs) - 1, fs);
67
ctx = (fastwriter_default_t*)malloc(sizeof(fastwriter_default_t));
68
if (!ctx) return ENOMEM;
70
memset(ctx, 0, sizeof(fastwriter_default_t));
74
if (!strcmp(fs, "raw")) {
75
ctx->wr_block = EXT4_WRITEBLOCK;
77
} else if (!strcmp(fs, "ext4")) {
78
ctx->wr_block = EXT4_WRITEBLOCK;
79
ctx->pa_block = EXT4_PREALLOCATE;
80
} else if (!strcmp(fs, "btrfs")) {
81
ctx->wr_block = EXT4_WRITEBLOCK;
82
ctx->pa_block = EXT4_PREALLOCATE;
83
} else if (!strcmp(fs, "xfs")) {
84
ctx->wr_block = EXT4_WRITEBLOCK;
85
ctx->pa_block = EXT4_PREALLOCATE;
87
ctx->wr_block = EXT4_WRITEBLOCK;
91
if (flags&FASTWRITER_FLAGS_OVERWRITE)
92
open_flags |= O_TRUNC;
94
ctx->fd = open(name, open_flags, open_mode);
95
if (ctx->fd < 0) return errno;
99
#ifndef HAVE_LINUX_FALLOC_H
100
if (((open_flags&FASTWRITER_FLAGS_OVERWRITE)==0)&&(strcmp(fs, "raw"))) {
101
ctx->prior_size = lseek(ctx->fd, 0, SEEK_END);
103
#endif /* HAVE_LINUX_FALLOC_H */
105
ctx->preallocated = 0;
111
void fastwriter_close_default(fastwriter_t *fw) {
113
fastwriter_default_t *ctx = (fastwriter_default_t*)fw->ctx;
116
#ifndef HAVE_LINUX_FALLOC_H
117
if (ctx->prior_size) {
118
ftrucate(ctx->fd, ctx->prior_size + fw->written);
120
#endif /* HAVE_LINUX_FALLOC_H */
130
int fastwriter_write_default(fastwriter_t *fw, fastwriter_write_flags_t flags, size_t size, void *data, size_t *written) {
133
fastwriter_default_t *ctx = (fastwriter_default_t*)fw->ctx;
135
if ((flags&FASTWRITER_WRITE_FLAG_FORCE)==0) {
136
if (size < ctx->wr_block) {
141
size -= size % ctx->wr_block;
144
if ((ctx->pa_block)&&((fw->written + size) > ctx->preallocated)) {
145
#ifdef HAVE_LINUX_FALLOC_H
146
if (fallocate(ctx->fd, FALLOC_FL_KEEP_SIZE, ctx->preallocated, ctx->pa_block)) {
147
#else /* HAVE_LINUX_FALLOC_H */
148
if (posix_fallocate(ctx->fd, ctx->preallocated, ctx->pa_block)) {
149
#endif /* HAVE_LINUX_FALLOC_H */
152
ctx->preallocated += ctx->pa_block;
157
res = write(ctx->fd, data, size);
164
} while (sum < size);
167
posix_fadvise(ctx->fd, fw->written, size, POSIX_FADV_DONTNEED);
168
#endif /* SYNC_MODE */