PATCH inn-2.4.5 : fixes for buffindex storage method

Kirill Berezin kyb at
Fri Nov 28 07:38:43 UTC 2008



> I may appear a bit lame but I do not understand exactly how your patch
> fixes the limit of 2 or 4GB.  How does it do that?
The idea of a patch is pretty simple, I'll show it by example.

  if (mmapwrite(ovbuff->fd, &ovindexhead, sizeof(OVINDEXHEAD), 
ovbuff->base + ov.blocknum * OV_BLOCKSIZE) != sizeof(OVINDEXHEAD)) {

This is a part of current ovsetcurindexblock function. Third argument is 
the offset from the beginning of buffer: ovbuff->base is off_t and 
ov.blocknum is unsigned int. For the case of inn compiled without 
--enable-largefiles it works fine, but in other case the size of off_t 
is 8 bytes and unsigned int still use 4 bytes.

Now say we have a 5Gb buffer, which is roughly equal to 625000 8000 byte 
blocks, and we are going to access to block # 620000 that is equal to 
offset of 4960000000 bytes, or about at very end of the buffer. BUT C 
standard does not require to cast all parts of statement to type of 
argument with longest size before calculation of result, instead is 
requires a cast of arguments of current operation only.
As a result, because multiplication is operation with higher priority 
and the size of blocknum is 4 bytes and constant have no size hints, we 
will have an offset somewhere in the beginning of buffer instead of very 
end of it.
To resolve such a limitation one can change blocknum type to off_t 
instead of unsigned int or make a hint to compiler by casting constant 
to off_t or by adding a suffix `llu` to constant. The second way is more 
elegant on my mind. To avoid errors and make lines of text shorter  I 
use macros OV_OFFSET to calculate an offset.

> What is the new limit?
I fact the patch does not change any limits, it fixes wrapping over 4Gb.


More information about the inn-workers mailing list