]> source.dussan.org Git - rspamd.git/commitdiff
* Add <fsync> option to turn on explicit fsync for file backend.
authorVsevolod Stakhov <vsevolod@rambler-co.ru>
Thu, 24 Nov 2011 14:24:37 +0000 (17:24 +0300)
committerVsevolod Stakhov <vsevolod@rambler-co.ru>
Thu, 24 Nov 2011 14:24:37 +0000 (17:24 +0300)
src/cfg_utils.c
src/kvstorage_config.c
src/kvstorage_config.h
src/kvstorage_file.c
src/kvstorage_file.h

index f4c708b83584b96411569247ba04b8f20d79369b..06faffbcd2e8554f1b7f1e927fd3ff5b875e984e 100644 (file)
@@ -420,19 +420,19 @@ parse_flag (const gchar *str)
        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;
        }
 
index 218d269535c277081787435f636c2680aa62f631..167b7c309ba2638670dbc83d8c864ec56158f82c 100644 (file)
@@ -54,6 +54,7 @@ struct kvstorage_config_parser {
                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;
@@ -110,7 +111,8 @@ kvstorage_init_callback (const gpointer key, const gpointer value, gpointer unus
                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:
@@ -210,6 +212,10 @@ void kvstorage_xml_start_element (GMarkupParseContext      *context,
                        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",
@@ -280,6 +286,7 @@ void kvstorage_xml_end_element (GMarkupParseContext *context,
        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:
@@ -416,6 +423,9 @@ void kvstorage_xml_text       (GMarkupParseContext          *context,
        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;
index 11b682506ac9066a6f796f3ec0a1707cfb2e4b19..bd78b5a4a070dde87b0154f12eaf8ede54ed2d45 100644 (file)
@@ -68,6 +68,7 @@ struct kvstorage_backend_config {
        enum kvstorage_backend_type type;
        gchar *filename;
        guint sync_ops;
+       gboolean do_fsync;
 };
 
 
index 3b658bc4b205c32ed5ee1484735f268c62b89d1c..c342b1fbfc2e1cd9d3a6be5f22bd021c987a9699 100644 (file)
@@ -53,6 +53,7 @@ struct rspamd_file_backend {
        guint levels;
        GQueue *ops_queue;
        GHashTable *ops_hash;
+       gboolean do_fsync;
        gboolean initialized;
 };
 
@@ -146,18 +147,20 @@ file_process_single_op (struct rspamd_file_backend *db, struct file_op *op, gint
 
 /* 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);
                }
        }
@@ -183,7 +186,7 @@ file_process_queue (struct rspamd_kv_backend *backend)
        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;
                }
@@ -191,7 +194,7 @@ file_process_queue (struct rspamd_kv_backend *backend)
                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 */
@@ -478,7 +481,7 @@ rspamd_file_destroy (struct rspamd_kv_backend *backend)
 
 /* 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;
@@ -504,6 +507,7 @@ rspamd_kv_file_new (const gchar *filename, guint sync_ops, guint levels)
        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);
 
index fab392894163937b21242a762544582697fd7106..85713355b06c4a7d3d91451fed2e8d4b8e3ba229 100644 (file)
@@ -29,7 +29,7 @@
 #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_ */