From: Vsevolod Stakhov Date: Sat, 7 Jul 2018 11:14:21 +0000 (+0100) Subject: [Project] Prepare cached map data X-Git-Tag: 1.7.8~24 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=0a6035cf22027b35a298c8870ab9156f82b5e7a6;p=rspamd.git [Project] Prepare cached map data --- diff --git a/src/libutil/map.c b/src/libutil/map.c index 4bcc7c83a..7faf24524 100644 --- a/src/libutil/map.c +++ b/src/libutil/map.c @@ -820,6 +820,80 @@ err: return 0; } +static gboolean +read_map_file_chunks (struct rspamd_map *map, struct map_cb_data *cbdata, + const gchar *fname, gsize len, goffset off) +{ + gint fd; + gssize r, avail; + gsize buflen = 1024 * 1024; + gchar *pos, *bytes; + + fd = rspamd_file_xopen (fname, O_RDONLY, 0, TRUE); + + if (fd == -1) { + msg_err_map ("can't open map for buffered reading %s: %s", + fname, strerror (errno)); + return FALSE; + } + + if (lseek (fd, off, SEEK_SET) == -1) { + msg_err_map ("can't seek in map to pos %d for buffered reading %s: %s", + (gint)off, fname, strerror (errno)); + return FALSE; + } + + buflen = MIN (len, buflen); + bytes = g_malloc (buflen); + avail = buflen; + pos = bytes; + + while ((r = read (fd, pos, avail)) > 0) { + gchar *end = bytes + (pos - bytes) + r; + msg_info_map ("%s: read map chunk, %z bytes", fname, + r); + pos = map->read_callback (bytes, end - bytes, cbdata, r == len); + + if (pos && pos > bytes && pos < end) { + guint remain = end - pos; + + memmove (bytes, pos, remain); + pos = bytes + remain; + /* Need to preserve the remain */ + avail = ((gssize)buflen) - remain; + + if (avail <= 0) { + /* Try realloc, too large element */ + g_assert (buflen >= remain); + bytes = g_realloc (bytes, buflen * 2); + + pos = bytes + remain; /* Adjust */ + avail += buflen; + buflen *= 2; + } + } + else { + avail = buflen; + pos = bytes; + } + + len -= r; + } + + if (r == -1) { + msg_err_map ("can't read from map %s: %s", fname, strerror (errno)); + close (fd); + g_free (bytes); + + return FALSE; + } + + close (fd); + g_free (bytes); + + return TRUE; +} + /** * Callback for reading data from file */ @@ -936,68 +1010,10 @@ read_map_file (struct rspamd_map *map, struct file_map_data *data, } else { /* Perform buffered read: fail-safe */ - gint fd; - gssize r, avail; - gsize buflen = 1024 * 1024; - gchar *pos; - - fd = rspamd_file_xopen (data->filename, O_RDONLY, 0, TRUE); - - if (fd == -1) { - msg_err_map ("can't open map for buffered reading %s: %s", - data->filename, strerror (errno)); - return FALSE; - } - - buflen = MIN (len, buflen); - bytes = g_malloc (buflen); - avail = buflen; - pos = bytes; - - while ((r = read (fd, pos, avail)) > 0) { - gchar *end = bytes + (pos - bytes) + r; - msg_info_map ("%s: read map chunk, %z bytes", data->filename, - r); - pos = map->read_callback (bytes, end - bytes, - &periodic->cbdata, r == len); - - if (pos && pos > bytes && pos < end) { - guint remain = end - pos; - - memmove (bytes, pos, remain); - pos = bytes + remain; - /* Need to preserve the remain */ - avail = ((gssize)buflen) - remain; - - if (avail <= 0) { - /* Try realloc, too large element */ - g_assert (buflen >= remain); - bytes = g_realloc (bytes, buflen * 2); - - pos = bytes + remain; /* Adjust */ - avail += buflen; - buflen *= 2; - } - } - else { - avail = buflen; - pos = bytes; - } - - len -= r; - } - - if (r == -1) { - msg_err_map ("can't read from map %s: %s", - data->filename, strerror (errno)); - close (fd); - g_free (bytes); - + if (!read_map_file_chunks (map, &periodic->cbdata, data->filename, + len, 0)) { return FALSE; } - - close (fd); - g_free (bytes); } } else { diff --git a/src/libutil/map_private.h b/src/libutil/map_private.h index 1b40e8e8a..67b813264 100644 --- a/src/libutil/map_private.h +++ b/src/libutil/map_private.h @@ -165,6 +165,16 @@ struct map_periodic_cbdata { ref_entry_t ref; }; +static const gchar rspamd_http_cached_magic[] = + {'r', 'm', 'c', 'd', '1', '0', '0', '0'}; + +struct rspamd_http_cached_data { + guchar magic[sizeof (rspamd_http_cached_magic)]; + goffset data_off; + gulong mtime; + gulong next_check; +}; + struct http_callback_data { struct event_base *ev_base; struct rspamd_http_connection *conn;