dbz.c patch for greater than 2^31 history table files

Chris Caputo ccaputo at alt.net
Mon Jan 22 03:11:41 EST 2007


Hi.  Please review and consider the following patch to lib/dbz.c.  The 
patch does the following:

 - the getcore() type changes are needed to prevent memset() in getcore()  
   from getting a negative byte count when the size of a table exceeds 
   2^31 bytes.

 - the putcore() changes are needed because pwrite(), and write() for that 
   matter, may validly succeed even while writing less than actually 
   requested.  In particular I have noticed that Linux limits write system 
   calls to 2^31 minus pagesize bytes.  This fix is needed in order to 
   have table sizes above that number.

 - the munmap() and msync() removal of the int typecasts doesn't address a 
   problem I have actually experienced, but I think it is correct.  I am 
   not sure if there will be a compilation problem due to this change on 
   certain operating systems.

These changes have only been tested on an x86-64 Linux machine:

-rw-rw-r-- 1 news news 13613202251 Jan 22 08:10 history
-rw-rw-r-- 1 news news         132 Jan 22 08:10 history.dir
-rw-rw-r-- 1 news news  2458490400 Jan 22 07:46 history.hash
-rw-rw-r-- 1 news news  3277987200 Jan 22 07:46 history.index

Feedback welcome,
Chris

----


--- lib/dbz.c.old	2007-01-22 07:44:28.000000000 +0000
+++ lib/dbz.c	2007-01-22 07:39:18.000000000 +0000
@@ -701,7 +701,7 @@
 	free(tab->core);
     if (tab->incore == INCORE_MMAP) {
 #if defined(HAVE_MMAP)
-	if (munmap(tab->core, (int)conf.tsize * tab->reclen) == -1) {
+	if (munmap(tab->core, conf.tsize * tab->reclen) == -1) {
 	    syswarn("closehashtable: munmap failed");
 	}
 #else
@@ -1246,8 +1246,8 @@
 getcore(hash_table *tab)
 {
     char *it;
-    int nread;
-    int i;
+    ssize_t nread;
+    size_t i;
     struct stat st;
     size_t length = conf.tsize * tab->reclen;
 
@@ -1304,14 +1304,18 @@
 static bool
 putcore(hash_table *tab)
 {
-    int size;
+    size_t size;
+    off_t savepos = -1;
     
     if (tab->incore == INCORE_MEM) {
 	if(options.writethrough)
 	    return true;
 	nonblocking(tab->fd, false);
 	size = tab->reclen * conf.tsize;
-	if (pwrite(tab->fd, tab->core, size, 0) != size) {
+	if ((savepos = lseek(tab->fd, 0, SEEK_CUR)) == -1 ||
+	    lseek(tab->fd, 0, SEEK_SET) != 0 ||
+	    xwrite(tab->fd, tab->core, size) != size ||
+	    lseek(tab->fd, savepos, SEEK_SET) != savepos) {
 	    nonblocking(tab->fd, options.nonblock);
 	    return false;
 	}
@@ -1319,7 +1323,7 @@
     }
 #ifdef HAVE_MMAP
     if(tab->incore == INCORE_MMAP) {
-	msync(tab->core, (int)conf.tsize * tab->reclen, MS_ASYNC);
+	msync(tab->core, conf.tsize * tab->reclen, MS_ASYNC);
     }
 #endif
     return true;




More information about the inn-workers mailing list