PATCH: fix bug in 2.4.2 dbz.c:getcore()

Chris Caputo ccaputo at alt.net
Thu Jun 2 21:21:54 UTC 2005


Hi.  getcore() in inn-2.4.2's lib/dbz.c calls madvise() with an incorrect
length.  In addition to defeating the purpose of madvise(), on Linux this
results in extra virtual memory being used since madvise() creates a
second map when a length does not match an existing map.

This patch fixes this and cleans up the function a little by adding a
variable for a common calculation.

Patch is below and also at:

  http://www.caputo.com/foss/inn-2.4.2-dbz_getcorefix.patch

Thanks,
Chris

--- inn-2.4.2-stock/lib/dbz.c	2004-12-22 04:21:19.000000000 +0000
+++ inn-2.4.2/lib/dbz.c	2005-06-02 20:55:29.676186007 +0000
@@ -1238,9 +1238,9 @@
     return ret;
 }
 
-/* getcore - try to set up an in-core copy of .pag file
+/* getcore - try to set up an in-core copy of file
  *
- * Returns: pointer to copy of .pag or NULL on errror
+ * Returns: pointer to copy of file or NULL on errror
  */
 static bool
 getcore(hash_table *tab)
@@ -1249,6 +1249,7 @@
     int nread;
     int i;
     struct stat st;
+    size_t length = conf.tsize * tab->reclen;
 
     if (tab->incore == INCORE_MMAP) {
 #if defined(HAVE_MMAP)
@@ -1256,14 +1257,14 @@
 	    syswarn("dbz: getcore: fstat failed");
 	    return false;
 	}
-	if ((conf.tsize * tab->reclen) > st.st_size) {
+	if (length > st.st_size) {
 	    /* file too small; extend it */
-	    if (ftruncate(tab->fd, conf.tsize * tab->reclen) == -1) {
+	    if (ftruncate(tab->fd, length) == -1) {
 		syswarn("dbz: getcore: ftruncate failed");
 		return false;
 	    }
 	}
-	it = mmap(NULL, (size_t)conf.tsize * tab->reclen,
+	it = mmap(NULL, length,
                   readonly ? PROT_READ : PROT_WRITE | PROT_READ, MAP_SHARED,
                   tab->fd, 0);
 	if (it == (char *)-1) {
@@ -1272,23 +1273,23 @@
 	}
 #if defined (MADV_RANDOM) && defined(HAVE_MADVISE)
 	/* not present in all versions of mmap() */
-	madvise(it, (size_t)conf.tsize * sizeof(tab->reclen), MADV_RANDOM);
+	madvise(it, length, MADV_RANDOM);
 #endif
 #else
 	warn("dbz: getcore: can't mmap files");
 	return false;
 #endif
     } else {
-	it = xmalloc(conf.tsize * tab->reclen);
+	it = xmalloc(length);
 	
-	nread = read(tab->fd, it, tab->reclen * conf.tsize);
+	nread = read(tab->fd, it, length);
 	if (nread < 0) {
 	    syswarn("dbz: getcore: read failed");
 	    free(it);
 	    return false;
 	}
 	
-	i = (size_t)(conf.tsize * tab->reclen) - nread;
+	i = length - nread;
 	memset(it + nread, '\0', i);
     }



More information about the inn-workers mailing list