[Pkg-clamav-commits] [SCM] Debian repository for ClamAV branch, debian/unstable, updated. debian/0.95+dfsg-1-6156-g094ec9b
acab (none)
acab at 1337ness.
Sun Apr 4 01:04:42 UTC 2010
The following commit has been merged in the debian/unstable branch:
commit 5a078ca98c4df284c002b557e96f1139f872aea5
Author: acab <acab at 1337ness.(none)>
Date: Thu Sep 10 03:20:02 2009 +0200
fuck mmap_sem!
diff --git a/libclamav/fmap.c b/libclamav/fmap.c
index a267e67..0105028 100644
--- a/libclamav/fmap.c
+++ b/libclamav/fmap.c
@@ -37,6 +37,9 @@
#endif
#endif
+#include <pthread.h>
+
+
#include "others.h"
#include "cltypes.h"
@@ -54,9 +57,14 @@
/* FIXME: tune this stuff */
#define UNPAGE_THRSHLD_LO 4*1024*1024
#define UNPAGE_THRSHLD_HI 8*1024*1024
-#define DUMB_SIZE 1*1024*1024
+#define READAHEAD_PAGES 8
+
+/* FIXME: remove the malloc fallback, it only makes thing slower */
+#define DUMB_SIZE 0
+
+/* DON'T ASK ME */
+pthread_mutex_t fmap_mutex = PTHREAD_MUTEX_INITIALIZER;
-#define READAHEAD_PAGES 4
static unsigned int fmap_align_items(unsigned int sz, unsigned int al) {
return sz / al + (sz % al != 0);
@@ -99,10 +107,15 @@ struct F_MAP *fmap(int fd, off_t offset, size_t len) {
mapsz = pages * pgsz + hdrsz;
#if HAVE_MMAP
if(mapsz >= DUMB_SIZE) {
- if ((m = (struct F_MAP *)mmap(NULL, mapsz, PROT_READ | PROT_WRITE, MAP_PRIVATE|ANONYMOUS_MAP, -1, 0)) == MAP_FAILED)
+ pthread_mutex_lock(&fmap_mutex);
+ if ((m = (struct F_MAP *)mmap(NULL, mapsz, PROT_READ | PROT_WRITE, MAP_PRIVATE|/*FIXME: MAP_POPULATE is ~8% faster but more memory intensive */ANONYMOUS_MAP, -1, 0)) == MAP_FAILED)
m = NULL;
- else
+ else {
dumb = 0;
+ madvise(m, mapsz, MADV_RANDOM|MADV_DONTFORK);
+ madvise(m, hdrsz, MADV_WILLNEED);
+ }
+ pthread_mutex_unlock(&fmap_mutex);
} else
#endif
m = (struct F_MAP *)cli_malloc(mapsz);
@@ -120,7 +133,13 @@ struct F_MAP *fmap(int fd, off_t offset, size_t len) {
m->pgsz = pgsz;
m->paged = 0;
memset(m->bitmap, 0, sizeof(uint32_t) * pages);
-// cli_errmsg("FMAPDBG: created %p - len %u pages %u hdrsz %u\n", m, len, pages, hdrsz);
+#ifdef FMAPDEBUG
+ m->page_needs = 0;
+ m->page_reads = 0;
+ m->page_locks = 0;
+ m->page_unlocks = 0;
+ m->page_unmaps = 0;
+#endif
return m;
}
@@ -179,8 +198,13 @@ static void fmap_aging(struct F_MAP *m) {
m->bitmap[freeme[i]] = FM_MASK_SEEN;
m->paged--;
/* and we mmap the page over so the kernel knows there's nothing good in there */
+ pthread_mutex_lock(&fmap_mutex);
if(mmap(pptr, m->pgsz, PROT_READ | PROT_WRITE, MAP_FIXED|MAP_PRIVATE|ANONYMOUS_MAP, -1, 0) == MAP_FAILED)
cli_warnmsg("fmap_aging: kernel hates you\n");
+ pthread_mutex_unlock(&fmap_mutex);
+#ifdef FMAPDEBUG
+ m->page_unmaps++;
+#endif
}
}
free(freeme);
@@ -192,9 +216,16 @@ static void fmap_aging(struct F_MAP *m) {
static int fmap_readpage(struct F_MAP *m, unsigned int first_page, unsigned int count, unsigned int lock_count) {
size_t readsz = 0, got;
char *pptr = NULL;
- uint32_t s;
+ volatile uint32_t s;
unsigned int i, page = first_page, force_read = 0;
+ for(i=0; i<count; i++) { /* REAL MEN DON'T MADVISE: seriously, it sucks! */
+ volatile char faultme = ((char *)m)[(first_page+i) * m->pgsz + m->hdrsz];
+ }
+#ifdef FMAPDEBUG
+ m->page_needs += count;
+ m->page_locks += lock_count;
+#endif
for(i=0; i<=count; i++, page++) {
int lock;
if(lock_count) {
@@ -254,6 +285,9 @@ static int fmap_readpage(struct F_MAP *m, unsigned int first_page, unsigned int
cli_warnmsg("pread fail: page %u pages %u map-offset %lu - asked for %lu bytes, got %lu\n", first_page, m->pages, (long unsigned int)m->offset, (long unsigned int)readsz, (long unsigned int)got);
return 1;
}
+#ifdef FMAPDEBUG
+ m->page_reads += count;
+#endif
pptr = NULL;
force_read = 0;
readsz = 0;
@@ -285,12 +319,12 @@ static void *fmap_need(struct F_MAP *m, size_t at, size_t len, int lock) {
char *ret;
if(!len) {
- cli_warnmsg("fmap: attempted void need\n");
+// cli_warnmsg("fmap: attempted void need\n");
return NULL;
}
if(!CLI_ISCONTAINED(0, m->len, at, len)) {
- cli_warnmsg("fmap: attempted oof need\n");
+ // cli_warnmsg("fmap: attempted oof need\n");
return NULL;
}
@@ -304,8 +338,6 @@ static void *fmap_need(struct F_MAP *m, size_t at, size_t len, int lock) {
if(last_page >= m->pages) last_page = m->pages - 1;
#endif
-// cli_errmsg("FMAPDBG: +++ map %p - len %u lock: %d (page %u to %u)\n", m, len, lock, first_page, last_page);
-
if(fmap_readpage(m, first_page, last_page-first_page+1, lock_count))
return NULL;
@@ -315,19 +347,15 @@ static void *fmap_need(struct F_MAP *m, size_t at, size_t len, int lock) {
}
void *fmap_need_off(struct F_MAP *m, size_t at, size_t len) {
-// cli_errmsg("FMAPDBG: need_off map %p at %u len %u\n", m, at, len);
return fmap_need(m, at, len, 1);
}
void *fmap_need_off_once(struct F_MAP *m, size_t at, size_t len) {
-// cli_errmsg("FMAPDBG: need_off_once map %p at %u len %u\n", m, at, len);
return fmap_need(m, at, len, 0);
}
void *fmap_need_ptr(struct F_MAP *m, void *ptr, size_t len) {
-// cli_errmsg("FMAPDBG: need_ptr map %p at %p len %u\n", m, ptr, len);
return fmap_need_off(m, (char *)ptr - (char *)m - m->hdrsz, len);
}
void *fmap_need_ptr_once(struct F_MAP *m, void *ptr, size_t len) {
-// cli_errmsg("FMAPDBG: need_ptr_once map %p at %p len %u\n", m, ptr, len);
return fmap_need_off_once(m, (char *)ptr - (char *)m - m->hdrsz, len);
}
@@ -339,11 +367,12 @@ void *fmap_need_str(struct F_MAP *m, void *ptr, size_t len_hint) {
static void fmap_unneed_page(struct F_MAP *m, unsigned int page) {
uint32_t s = m->bitmap[page];
-// cli_errmsg("FMAPDBG: --- map %p - page %u status %u count %u\n", m, page, s>>30, s & FM_MASK_COUNT);
-
if((s & (FM_MASK_PAGED | FM_MASK_LOCKED)) == (FM_MASK_PAGED | FM_MASK_LOCKED)) {
/* page is paged and locked: check lock count */
s &= FM_MASK_COUNT;
+#ifdef FMAPDEBUG
+ m->page_unlocks ++;
+#endif
if(s > 1) /* locked more than once: dec lock count */
m->bitmap[page]--;
else if (s == 1) /* only one lock left: unlock and begin aging */
@@ -399,10 +428,16 @@ int fmap_readn(struct F_MAP *m, void *dst, size_t at, size_t len) {
}
void fmunmap(struct F_MAP *m) {
+#ifdef FMAPDEBUG
+ cli_errmsg("FMAPDEBUG: Needs:%u reads:%u locks:%u unlocks:%u unmaps:%u\n", m->page_needs, m->page_reads, m->page_locks, m->page_unlocks, m->page_unmaps);
+#endif
+
#if HAVE_MMAP
if(!m->dumb) {
size_t len = m->pages * m->pgsz + m->hdrsz;
+ pthread_mutex_lock(&fmap_mutex);
munmap((void *)m, len);
+ pthread_mutex_unlock(&fmap_mutex);
} else
#endif
free((void *)m);
@@ -416,7 +451,7 @@ void *fmap_need_offstr(struct F_MAP *m, size_t at, size_t len_hint) {
len_hint = m->len - at;
if(!CLI_ISCONTAINED(0, m->len, at, len_hint)) {
- cli_warnmsg("fmap: attempted oof need_str\n");
+ // cli_warnmsg("fmap: attempted oof need_str\n");
return NULL;
}
@@ -435,11 +470,12 @@ void *fmap_need_offstr(struct F_MAP *m, size_t at, size_t len_hint) {
}
if(i == first_page) {
scanat = at % m->pgsz;
- scansz = m->pgsz - scanat;
+ scansz = MIN(len_hint, m->pgsz - scanat);
} else {
scanat = 0;
- scansz = m->pgsz;
+ scansz = MIN(len_hint, m->pgsz);
}
+ len_hint -= scansz;
if(memchr(&thispage[scanat], 0, scansz))
return ptr;
}
@@ -447,3 +483,52 @@ void *fmap_need_offstr(struct F_MAP *m, size_t at, size_t len_hint) {
fmap_unneed_page(m, i);
return NULL;
}
+
+
+void *fmap_gets(struct F_MAP *m, char *dst, size_t *at, size_t max_len) {
+ unsigned int i, first_page, last_page;
+ char *src = (void *)((char *)m + m->hdrsz + *at), *endptr = NULL;
+ size_t len = MIN(max_len-1, m->len - *at), fullen = len;
+
+ if(!len || !CLI_ISCONTAINED(0, m->len, *at, len)) {
+ //cli_warnmsg("fmap: attempted oof need_str\n");
+ return NULL;
+ }
+
+ fmap_aging(m);
+
+ first_page = fmap_which_page(m, *at);
+ last_page = fmap_which_page(m, *at + len - 1);
+
+ for(i=first_page; i<=last_page; i++) {
+ char *thispage = (char *)m + m->hdrsz + i * m->pgsz;
+ unsigned int scanat, scansz;
+
+ if(fmap_readpage(m, i, 1, 0))
+ return NULL;
+
+ if(i == first_page) {
+ scanat = *at % m->pgsz;
+ scansz = MIN(len, m->pgsz - scanat);
+ } else {
+ scanat = 0;
+ scansz = MIN(len, m->pgsz);
+ }
+ len -= scansz;
+
+ if((endptr = memchr(&thispage[scanat], '\n', scansz))) {
+ endptr++;
+ break;
+ }
+ }
+ if(endptr) {
+ memcpy(dst, src, endptr - src);
+ dst[endptr - src] = '\0';
+ *at += endptr - src;
+ } else {
+ memcpy(dst, src, fullen);
+ dst[fullen] = '\0';
+ *at += fullen;
+ }
+ return dst;
+}
--
Debian repository for ClamAV
More information about the Pkg-clamav-commits
mailing list