summaryrefslogtreecommitdiff
path: root/src/mongo/db/storage/mmap_v1/mmap_posix.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/db/storage/mmap_v1/mmap_posix.cpp')
-rw-r--r--src/mongo/db/storage/mmap_v1/mmap_posix.cpp394
1 files changed, 198 insertions, 196 deletions
diff --git a/src/mongo/db/storage/mmap_v1/mmap_posix.cpp b/src/mongo/db/storage/mmap_v1/mmap_posix.cpp
index f7dffae468f..a673d3e5fde 100644
--- a/src/mongo/db/storage/mmap_v1/mmap_posix.cpp
+++ b/src/mongo/db/storage/mmap_v1/mmap_posix.cpp
@@ -53,38 +53,37 @@ using std::vector;
using namespace mongoutils;
namespace {
- mongo::AtomicUInt64 mmfNextId(0);
+mongo::AtomicUInt64 mmfNextId(0);
}
namespace mongo {
- static size_t fetchMinOSPageSizeBytes() {
- size_t minOSPageSizeBytes = sysconf( _SC_PAGESIZE );
- minOSPageSizeBytesTest(minOSPageSizeBytes);
- return minOSPageSizeBytes;
- }
- const size_t g_minOSPageSizeBytes = fetchMinOSPageSizeBytes();
-
-
-
- MemoryMappedFile::MemoryMappedFile() : _uniqueId(mmfNextId.fetchAndAdd(1)) {
- fd = 0;
- maphandle = 0;
- len = 0;
- created();
- }
+static size_t fetchMinOSPageSizeBytes() {
+ size_t minOSPageSizeBytes = sysconf(_SC_PAGESIZE);
+ minOSPageSizeBytesTest(minOSPageSizeBytes);
+ return minOSPageSizeBytes;
+}
+const size_t g_minOSPageSizeBytes = fetchMinOSPageSizeBytes();
- void MemoryMappedFile::close() {
- LockMongoFilesShared::assertExclusivelyLocked();
- for( vector<void*>::iterator i = views.begin(); i != views.end(); i++ ) {
- munmap(*i,len);
- }
- views.clear();
- if ( fd )
- ::close(fd);
- fd = 0;
- destroyed(); // cleans up from the master list of mmaps
+MemoryMappedFile::MemoryMappedFile() : _uniqueId(mmfNextId.fetchAndAdd(1)) {
+ fd = 0;
+ maphandle = 0;
+ len = 0;
+ created();
+}
+
+void MemoryMappedFile::close() {
+ LockMongoFilesShared::assertExclusivelyLocked();
+ for (vector<void*>::iterator i = views.begin(); i != views.end(); i++) {
+ munmap(*i, len);
}
+ views.clear();
+
+ if (fd)
+ ::close(fd);
+ fd = 0;
+ destroyed(); // cleans up from the master list of mmaps
+}
#ifndef O_NOATIME
#define O_NOATIME (0)
@@ -94,231 +93,234 @@ namespace mongo {
#define MAP_NORESERVE (0)
#endif
- namespace {
- void* _pageAlign( void* p ) {
- return (void*)((int64_t)p & ~(g_minOSPageSizeBytes-1));
+namespace {
+void* _pageAlign(void* p) {
+ return (void*)((int64_t)p & ~(g_minOSPageSizeBytes - 1));
+}
+
+class PageAlignTest : public StartupTest {
+public:
+ void run() {
+ {
+ int64_t x = g_minOSPageSizeBytes + 123;
+ void* y = _pageAlign(reinterpret_cast<void*>(x));
+ invariant(g_minOSPageSizeBytes == reinterpret_cast<size_t>(y));
}
+ {
+ int64_t a = static_cast<uint64_t>(numeric_limits<int>::max());
+ a = a / g_minOSPageSizeBytes;
+ a = a * g_minOSPageSizeBytes;
+ // a should now be page aligned
- class PageAlignTest : public StartupTest {
- public:
- void run() {
- {
- int64_t x = g_minOSPageSizeBytes + 123;
- void* y = _pageAlign( reinterpret_cast<void*>( x ) );
- invariant( g_minOSPageSizeBytes == reinterpret_cast<size_t>(y) );
- }
- {
- int64_t a = static_cast<uint64_t>( numeric_limits<int>::max() );
- a = a / g_minOSPageSizeBytes;
- a = a * g_minOSPageSizeBytes;
- // a should now be page aligned
-
- // b is not page aligned
- int64_t b = a + 123;
-
- void* y = _pageAlign( reinterpret_cast<void*>( b ) );
- invariant( a == reinterpret_cast<int64_t>(y) );
- }
+ // b is not page aligned
+ int64_t b = a + 123;
- }
- } pageAlignTest;
+ void* y = _pageAlign(reinterpret_cast<void*>(b));
+ invariant(a == reinterpret_cast<int64_t>(y));
+ }
}
+} pageAlignTest;
+}
#if defined(__sun)
- MAdvise::MAdvise(void *,unsigned, Advice) { }
- MAdvise::~MAdvise() { }
+MAdvise::MAdvise(void*, unsigned, Advice) {}
+MAdvise::~MAdvise() {}
#else
- MAdvise::MAdvise(void *p, unsigned len, Advice a) {
+MAdvise::MAdvise(void* p, unsigned len, Advice a) {
+ _p = _pageAlign(p);
- _p = _pageAlign( p );
+ _len = len + static_cast<unsigned>(reinterpret_cast<size_t>(p) - reinterpret_cast<size_t>(_p));
- _len = len + static_cast<unsigned>( reinterpret_cast<size_t>(p) -
- reinterpret_cast<size_t>(_p) );
-
- int advice = 0;
- switch ( a ) {
+ int advice = 0;
+ switch (a) {
case Sequential:
advice = MADV_SEQUENTIAL;
break;
case Random:
advice = MADV_RANDOM;
break;
- }
-
- if ( madvise(_p,_len,advice ) ) {
- error() << "madvise failed: " << errnoWithDescription();
- }
-
}
- MAdvise::~MAdvise() {
- madvise(_p,_len,MADV_NORMAL);
+
+ if (madvise(_p, _len, advice)) {
+ error() << "madvise failed: " << errnoWithDescription();
}
+}
+MAdvise::~MAdvise() {
+ madvise(_p, _len, MADV_NORMAL);
+}
#endif
- void* MemoryMappedFile::map(const char *filename, unsigned long long &length, int options) {
- // length may be updated by callee.
- setFilename(filename);
- FileAllocator::get()->allocateAsap( filename, length );
- len = length;
+void* MemoryMappedFile::map(const char* filename, unsigned long long& length, int options) {
+ // length may be updated by callee.
+ setFilename(filename);
+ FileAllocator::get()->allocateAsap(filename, length);
+ len = length;
- massert( 10446 , str::stream() << "mmap: can't map area of size 0 file: " << filename, length > 0 );
+ massert(
+ 10446, str::stream() << "mmap: can't map area of size 0 file: " << filename, length > 0);
- fd = open(filename, O_RDWR | O_NOATIME);
- if ( fd <= 0 ) {
- log() << "couldn't open " << filename << ' ' << errnoWithDescription() << endl;
- fd = 0; // our sentinel for not opened
- return 0;
- }
+ fd = open(filename, O_RDWR | O_NOATIME);
+ if (fd <= 0) {
+ log() << "couldn't open " << filename << ' ' << errnoWithDescription() << endl;
+ fd = 0; // our sentinel for not opened
+ return 0;
+ }
- unsigned long long filelen = lseek(fd, 0, SEEK_END);
- uassert(10447, str::stream() << "map file alloc failed, wanted: " << length << " filelen: " << filelen << ' ' << sizeof(size_t), filelen == length );
- lseek( fd, 0, SEEK_SET );
-
- void * view = mmap(NULL, length, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
- if ( view == MAP_FAILED ) {
- error() << " mmap() failed for " << filename << " len:" << length << " " << errnoWithDescription() << endl;
- if ( errno == ENOMEM ) {
- if( sizeof(void*) == 4 )
- error() << "mmap failed with out of memory. You are using a 32-bit build and probably need to upgrade to 64" << endl;
- else
- error() << "mmap failed with out of memory. (64 bit build)" << endl;
- }
- return 0;
+ unsigned long long filelen = lseek(fd, 0, SEEK_END);
+ uassert(10447,
+ str::stream() << "map file alloc failed, wanted: " << length << " filelen: " << filelen
+ << ' ' << sizeof(size_t),
+ filelen == length);
+ lseek(fd, 0, SEEK_SET);
+
+ void* view = mmap(NULL, length, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+ if (view == MAP_FAILED) {
+ error() << " mmap() failed for " << filename << " len:" << length << " "
+ << errnoWithDescription() << endl;
+ if (errno == ENOMEM) {
+ if (sizeof(void*) == 4)
+ error() << "mmap failed with out of memory. You are using a 32-bit build and "
+ "probably need to upgrade to 64" << endl;
+ else
+ error() << "mmap failed with out of memory. (64 bit build)" << endl;
}
+ return 0;
+ }
#if defined(__sun)
#warning madvise not supported on solaris yet
#else
- if ( options & SEQUENTIAL ) {
- if ( madvise( view , length , MADV_SEQUENTIAL ) ) {
- warning() << "map: madvise failed for " << filename << ' ' << errnoWithDescription() << endl;
- }
+ if (options & SEQUENTIAL) {
+ if (madvise(view, length, MADV_SEQUENTIAL)) {
+ warning() << "map: madvise failed for " << filename << ' ' << errnoWithDescription()
+ << endl;
}
+ }
#endif
- views.push_back( view );
+ views.push_back(view);
- return view;
- }
+ return view;
+}
- void* MemoryMappedFile::createReadOnlyMap() {
- void * x = mmap( /*start*/0 , len , PROT_READ , MAP_SHARED , fd , 0 );
- if( x == MAP_FAILED ) {
- if ( errno == ENOMEM ) {
- if( sizeof(void*) == 4 )
- error() << "mmap ro failed with out of memory. You are using a 32-bit build and probably need to upgrade to 64" << endl;
- else
- error() << "mmap ro failed with out of memory. (64 bit build)" << endl;
- }
- return 0;
+void* MemoryMappedFile::createReadOnlyMap() {
+ void* x = mmap(/*start*/ 0, len, PROT_READ, MAP_SHARED, fd, 0);
+ if (x == MAP_FAILED) {
+ if (errno == ENOMEM) {
+ if (sizeof(void*) == 4)
+ error() << "mmap ro failed with out of memory. You are using a 32-bit build and "
+ "probably need to upgrade to 64" << endl;
+ else
+ error() << "mmap ro failed with out of memory. (64 bit build)" << endl;
}
- return x;
+ return 0;
}
+ return x;
+}
- void* MemoryMappedFile::createPrivateMap() {
- void * x = mmap( /*start*/0 , len , PROT_READ|PROT_WRITE , MAP_PRIVATE|MAP_NORESERVE , fd , 0 );
- if( x == MAP_FAILED ) {
- if ( errno == ENOMEM ) {
- if( sizeof(void*) == 4 ) {
- error() << "mmap private failed with out of memory. You are using a 32-bit build and probably need to upgrade to 64" << endl;
- }
- else {
- error() << "mmap private failed with out of memory. (64 bit build)" << endl;
- }
+void* MemoryMappedFile::createPrivateMap() {
+ void* x = mmap(/*start*/ 0, len, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_NORESERVE, fd, 0);
+ if (x == MAP_FAILED) {
+ if (errno == ENOMEM) {
+ if (sizeof(void*) == 4) {
+ error() << "mmap private failed with out of memory. You are using a 32-bit build "
+ "and probably need to upgrade to 64" << endl;
+ } else {
+ error() << "mmap private failed with out of memory. (64 bit build)" << endl;
}
- else {
- error() << "mmap private failed " << errnoWithDescription() << endl;
- }
- return 0;
+ } else {
+ error() << "mmap private failed " << errnoWithDescription() << endl;
}
-
- views.push_back(x);
- return x;
+ return 0;
}
- void* MemoryMappedFile::remapPrivateView(void *oldPrivateAddr) {
-#if defined(__sun) // SERVER-8795
- LockMongoFilesExclusive lockMongoFiles;
+ views.push_back(x);
+ return x;
+}
+
+void* MemoryMappedFile::remapPrivateView(void* oldPrivateAddr) {
+#if defined(__sun) // SERVER-8795
+ LockMongoFilesExclusive lockMongoFiles;
#endif
- // don't unmap, just mmap over the old region
- void * x = mmap( oldPrivateAddr, len , PROT_READ|PROT_WRITE , MAP_PRIVATE|MAP_NORESERVE|MAP_FIXED , fd , 0 );
- if( x == MAP_FAILED ) {
- int err = errno;
- error() << "13601 Couldn't remap private view: " << errnoWithDescription(err) << endl;
- log() << "aborting" << endl;
- printMemInfo();
- abort();
- }
- verify( x == oldPrivateAddr );
- return x;
+ // don't unmap, just mmap over the old region
+ void* x = mmap(oldPrivateAddr,
+ len,
+ PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_NORESERVE | MAP_FIXED,
+ fd,
+ 0);
+ if (x == MAP_FAILED) {
+ int err = errno;
+ error() << "13601 Couldn't remap private view: " << errnoWithDescription(err) << endl;
+ log() << "aborting" << endl;
+ printMemInfo();
+ abort();
}
+ verify(x == oldPrivateAddr);
+ return x;
+}
- void MemoryMappedFile::flush(bool sync) {
- if ( views.empty() || fd == 0 )
- return;
+void MemoryMappedFile::flush(bool sync) {
+ if (views.empty() || fd == 0)
+ return;
- bool useFsync = sync && !ProcessInfo::preferMsyncOverFSync();
+ bool useFsync = sync && !ProcessInfo::preferMsyncOverFSync();
- if ( useFsync ?
- fsync(fd) != 0 :
- msync(viewForFlushing(), len, sync ? MS_SYNC : MS_ASYNC) ) {
- // msync failed, this is very bad
- log() << (useFsync ? "fsync failed: " : "msync failed: ") << errnoWithDescription()
- << " file: " << filename() << endl;
- dataSyncFailedHandler();
- }
+ if (useFsync ? fsync(fd) != 0 : msync(viewForFlushing(), len, sync ? MS_SYNC : MS_ASYNC)) {
+ // msync failed, this is very bad
+ log() << (useFsync ? "fsync failed: " : "msync failed: ") << errnoWithDescription()
+ << " file: " << filename() << endl;
+ dataSyncFailedHandler();
}
+}
- class PosixFlushable : public MemoryMappedFile::Flushable {
- public:
- PosixFlushable( MemoryMappedFile* theFile, void* view , HANDLE fd , long len)
- : _theFile( theFile ), _view( view ), _fd(fd), _len(len), _id(_theFile->getUniqueId()) {
- }
-
- void flush() {
- if ( _view == NULL || _fd == 0 )
- return;
-
- if ( ProcessInfo::preferMsyncOverFSync() ?
- msync(_view, _len, MS_SYNC ) == 0 :
- fsync(_fd) == 0 ) {
- return;
- }
+class PosixFlushable : public MemoryMappedFile::Flushable {
+public:
+ PosixFlushable(MemoryMappedFile* theFile, void* view, HANDLE fd, long len)
+ : _theFile(theFile), _view(view), _fd(fd), _len(len), _id(_theFile->getUniqueId()) {}
- if ( errno == EBADF ) {
- // ok, we were unlocked, so this file was closed
- return;
- }
+ void flush() {
+ if (_view == NULL || _fd == 0)
+ return;
- // some error, lets see if we're supposed to exist
- LockMongoFilesShared mmfilesLock;
- std::set<MongoFile*> mmfs = MongoFile::getAllFiles();
- std::set<MongoFile*>::const_iterator it = mmfs.find(_theFile);
- if ( (it == mmfs.end()) || ((*it)->getUniqueId() != _id) ) {
- log() << "msync failed with: " << errnoWithDescription()
- << " but file doesn't exist anymore, so ignoring";
- // this was deleted while we were unlocked
- return;
- }
+ if (ProcessInfo::preferMsyncOverFSync() ? msync(_view, _len, MS_SYNC) == 0
+ : fsync(_fd) == 0) {
+ return;
+ }
- // we got an error, and we still exist, so this is bad, we fail
- log() << "msync " << errnoWithDescription() << endl;
- dataSyncFailedHandler();
+ if (errno == EBADF) {
+ // ok, we were unlocked, so this file was closed
+ return;
}
- MemoryMappedFile* _theFile;
- void * _view;
- HANDLE _fd;
- long _len;
- const uint64_t _id;
- };
+ // some error, lets see if we're supposed to exist
+ LockMongoFilesShared mmfilesLock;
+ std::set<MongoFile*> mmfs = MongoFile::getAllFiles();
+ std::set<MongoFile*>::const_iterator it = mmfs.find(_theFile);
+ if ((it == mmfs.end()) || ((*it)->getUniqueId() != _id)) {
+ log() << "msync failed with: " << errnoWithDescription()
+ << " but file doesn't exist anymore, so ignoring";
+ // this was deleted while we were unlocked
+ return;
+ }
- MemoryMappedFile::Flushable * MemoryMappedFile::prepareFlush() {
- return new PosixFlushable( this, viewForFlushing(), fd, len);
+ // we got an error, and we still exist, so this is bad, we fail
+ log() << "msync " << errnoWithDescription() << endl;
+ dataSyncFailedHandler();
}
+ MemoryMappedFile* _theFile;
+ void* _view;
+ HANDLE _fd;
+ long _len;
+ const uint64_t _id;
+};
+
+MemoryMappedFile::Flushable* MemoryMappedFile::prepareFlush() {
+ return new PosixFlushable(this, viewForFlushing(), fd, len);
+}
-} // namespace mongo
+} // namespace mongo