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