if (!str || !*str)
return -1;
- if ((*str == 'Y' || *str == 'y') && *(str + 1) == '\0') {
+ if ((*str == 'Y' || *str == 'y')) {
return 1;
}
- if ((*str == 'Y' || *str == 'y') && (*(str + 1) == 'E' || *(str + 1) == 'e') && (*(str + 2) == 'S' || *(str + 2) == 's') && *(str + 3) == '\0') {
+ if ((*str == 'Y' || *str == 'y') && (*(str + 1) == 'E' || *(str + 1) == 'e') && (*(str + 2) == 'S' || *(str + 2) == 's')) {
return 1;
}
- if ((*str == 'N' || *str == 'n') && *(str + 1) == '\0') {
+ if ((*str == 'N' || *str == 'n')) {
return 0;
}
- if ((*str == 'N' || *str == 'n') && (*(str + 1) == 'O' || *(str + 1) == 'o') && *(str + 2) == '\0') {
+ if ((*str == 'N' || *str == 'n') && (*(str + 1) == 'O' || *(str + 1) == 'o')) {
return 0;
}
KVSTORAGE_STATE_BACKEND_TYPE,
KVSTORAGE_STATE_BACKEND_FILENAME,
KVSTORAGE_STATE_BACKEND_SYNC_OPS,
+ KVSTORAGE_STATE_BACKEND_DO_FSYNC,
KVSTORAGE_STATE_EXPIRE_TYPE,
KVSTORAGE_STATE_ERROR
} state;
backend = NULL;
break;
case KVSTORAGE_TYPE_BACKEND_FILE:
- backend = rspamd_kv_file_new (kconf->backend.filename, kconf->backend.sync_ops, FILE_STORAGE_LEVELS);
+ backend = rspamd_kv_file_new (kconf->backend.filename, kconf->backend.sync_ops,
+ FILE_STORAGE_LEVELS, kconf->backend.do_fsync);
break;
#ifdef WITH_DB
case KVSTORAGE_TYPE_BACKEND_BDB:
kv_parser->state = KVSTORAGE_STATE_BACKEND_SYNC_OPS;
kv_parser->cur_elt = "sync_ops";
}
+ else if (g_ascii_strcasecmp (element_name, "fsync") == 0) {
+ kv_parser->state = KVSTORAGE_STATE_BACKEND_DO_FSYNC;
+ kv_parser->cur_elt = "fsync";
+ }
else {
if (*error == NULL) {
*error = g_error_new (xml_error_quark (), XML_EXTRA_ELEMENT, "element %s is unexpected in backend definition",
case KVSTORAGE_STATE_BACKEND_TYPE:
case KVSTORAGE_STATE_BACKEND_FILENAME:
case KVSTORAGE_STATE_BACKEND_SYNC_OPS:
+ case KVSTORAGE_STATE_BACKEND_DO_FSYNC:
CHECK_TAG (KVSTORAGE_STATE_BACKEND);
break;
case KVSTORAGE_STATE_EXPIRE_TYPE:
case KVSTORAGE_STATE_BACKEND_SYNC_OPS:
kv_parser->current_storage->backend.sync_ops = parse_limit (text, text_len);
break;
+ case KVSTORAGE_STATE_BACKEND_DO_FSYNC:
+ kv_parser->current_storage->backend.do_fsync = parse_flag (text);
+ break;
case KVSTORAGE_STATE_EXPIRE_TYPE:
if (g_ascii_strncasecmp (text, "lru", MIN (text_len, sizeof ("lru") - 1)) == 0) {
kv_parser->current_storage->expire.type = KVSTORAGE_TYPE_EXPIRE_LRU;
enum kvstorage_backend_type type;
gchar *filename;
guint sync_ops;
+ gboolean do_fsync;
};
guint levels;
GQueue *ops_queue;
GHashTable *ops_hash;
+ gboolean do_fsync;
gboolean initialized;
};
/* Sync vector of descriptors */
static void
-file_sync_fds (gint *fds, gint len)
+file_sync_fds (gint *fds, gint len, gboolean fsync)
{
gint i, fd;
for (i = 0; i < len; i ++) {
fd = fds[i];
if (fd != -1) {
+ if (fsync) {
#ifdef HAVE_FDATASYNC
- fdatasync (fd);
+ fdatasync (fd);
#else
- fsync (fd);
+ fsync (fd);
#endif
+ }
close (fd);
}
}
while (cur) {
op = cur->data;
if (! file_process_single_op (db, op, &fds[i])) {
- file_sync_fds (fds, i);
+ file_sync_fds (fds, i, db->do_fsync);
g_slice_free1 (len * sizeof (gint), fds);
return FALSE;
}
cur = g_list_next (cur);
}
- file_sync_fds (fds, i);
+ file_sync_fds (fds, i, db->do_fsync);
g_slice_free1 (len * sizeof (gint), fds);
/* Clean the queue */
/* Create new file backend */
struct rspamd_kv_backend *
-rspamd_kv_file_new (const gchar *filename, guint sync_ops, guint levels)
+rspamd_kv_file_new (const gchar *filename, guint sync_ops, guint levels, gboolean do_fsync)
{
struct rspamd_file_backend *new;
struct stat st;
new->filename = g_strdup (filename);
new->sync_ops = sync_ops;
new->levels = levels;
+ new->do_fsync = do_fsync;
new->ops_queue = g_queue_new ();
new->ops_hash = g_hash_table_new (kv_elt_hash_func, kv_elt_compare_func);
#include "kvstorage.h"
/* Create new file backend */
-struct rspamd_kv_backend* rspamd_kv_file_new (const gchar *filename, guint sync_ops, guint levels);
+struct rspamd_kv_backend* rspamd_kv_file_new (const gchar *filename, guint sync_ops, guint levels, gboolean do_fsync);
#endif /* KVSTORAGE_FILE_H_ */