From: Alex Rousskov Date: Thu, 14 Apr 2011 20:16:35 +0000 (-0600) Subject: Use off_t instead of int and size_t for segment sizes X-Git-Tag: take06~25 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e08b0f778791043501c04a4a0a4b1dd5c97f8bc6;p=thirdparty%2Fsquid.git Use off_t instead of int and size_t for segment sizes to be able to allocated larger than 4GB segments on some platforms. Double check the newly created segment size using fstat(). --- diff --git a/src/ipc/mem/Segment.cc b/src/ipc/mem/Segment.cc index 1bd100a525..3c0305fe37 100644 --- a/src/ipc/mem/Segment.cc +++ b/src/ipc/mem/Segment.cc @@ -6,7 +6,7 @@ */ #include "config.h" - +#include "base/TextException.h" #include "ipc/mem/Segment.h" #include "protos.h" @@ -31,7 +31,7 @@ Ipc::Mem::Segment::~Segment() { } void -Ipc::Mem::Segment::create(const int aSize) +Ipc::Mem::Segment::create(const off_t aSize) { assert(aSize > 0); assert(theFD < 0); @@ -48,6 +48,8 @@ Ipc::Mem::Segment::create(const int aSize) fatal("Ipc::Mem::Segment::create failed to ftruncate"); } + assert(statSize("Ipc::Mem::Segment::create") == aSize); // paranoid + theSize = aSize; theReserved = 0; @@ -69,18 +71,7 @@ Ipc::Mem::Segment::open() fatal(s.termedBuf()); } - { - struct stat s; - memset(&s, 0, sizeof(s)); - if (fstat(theFD, &s)) { - debugs(54, 5, HERE << "fstat: " << xstrerror()); - String s = "Ipc::Mem::Segment::open failed to fstat"; - s.append(theName); - fatal(s.termedBuf()); - } - - theSize = s.st_size; - } + theSize = statSize("Ipc::Mem::Segment::open"); debugs(54, 3, HERE << "opened " << theName << " segment: " << theSize); @@ -120,13 +111,35 @@ Ipc::Mem::Segment::detach() void * Ipc::Mem::Segment::reserve(size_t chunkSize) { - assert(chunkSize <= theSize); - assert(theReserved <= theSize - chunkSize); + // check for overflows + assert(static_cast(chunkSize) >= 0); + assert(static_cast(chunkSize) <= theSize); + assert(theReserved <= theSize - static_cast(chunkSize)); void *result = reinterpret_cast(mem()) + theReserved; theReserved += chunkSize; return result; } +/// determines the size of the underlying "file" +off_t +Ipc::Mem::Segment::statSize(const char *context) const +{ + Must(theFD >= 0); + + struct stat s; + memset(&s, 0, sizeof(s)); + + if (fstat(theFD, &s) != 0) { + debugs(54, 5, HERE << "fstat: " << xstrerror()); + String s = context; + s.append("failed to fstat(2)"); + s.append(theName); + fatal(s.termedBuf()); + } + + return s.st_size; +} + /// Generate name for shared memory segment. Replaces all slashes with dots. String Ipc::Mem::Segment::GenerateName(const char *id) diff --git a/src/ipc/mem/Segment.h b/src/ipc/mem/Segment.h index 807b24fa38..f05481729f 100644 --- a/src/ipc/mem/Segment.h +++ b/src/ipc/mem/Segment.h @@ -21,11 +21,11 @@ public: /// Create a new shared memory segment. Fails if a segment with /// the same name already exists. - void create(const int aSize); + void create(const off_t aSize); void open(); ///< Open an existing shared memory segment. const String &name() { return theName; } ///< shared memory segment name - int size() { return theSize; } ///< shared memory segment size + off_t size() { return theSize; } ///< shared memory segment size void *mem() { return theMem; } ///< pointer to mmapped shared memory segment void *reserve(size_t chunkSize); ///< reserve and return the next chunk // TODO: convert most mem() calls to reserve() @@ -33,14 +33,15 @@ public: private: void attach(); void detach(); + off_t statSize(const char *context) const; static String GenerateName(const char *id); const String theName; ///< shared memory segment file name int theFD; ///< shared memory segment file descriptor void *theMem; ///< pointer to mmapped shared memory segment - size_t theSize; ///< shared memory segment size - size_t theReserved; ///< the total number of reserve()d bytes + off_t theSize; ///< shared memory segment size + off_t theReserved; ///< the total number of reserve()d bytes }; } // namespace Mem