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