summaryrefslogtreecommitdiff
path: root/util/logfile.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'util/logfile.cpp')
-rw-r--r--util/logfile.cpp87
1 files changed, 69 insertions, 18 deletions
diff --git a/util/logfile.cpp b/util/logfile.cpp
index 0386a59..609edb8 100644
--- a/util/logfile.cpp
+++ b/util/logfile.cpp
@@ -77,18 +77,35 @@ namespace mongo {
CloseHandle(_fd);
}
- void LogFile::synchronousAppend(const void *buf, size_t len) {
- assert(_fd);
- DWORD written;
- if( !WriteFile(_fd, buf, len, &written, NULL) ) {
- DWORD e = GetLastError();
- if( e == 87 )
- massert(13519, "error appending to file - misaligned direct write?", false);
- else
- uasserted(13517, str::stream() << "error appending to file " << errnoWithDescription(e));
+ void LogFile::truncate() {
+ verify(15870, _fd != INVALID_HANDLE_VALUE);
+
+ if (!SetEndOfFile(_fd)){
+ msgasserted(15871, "Couldn't truncate file: " + errnoWithDescription());
}
- else {
- dassert( written == len );
+ }
+
+ void LogFile::synchronousAppend(const void *_buf, size_t _len) {
+ const size_t BlockSize = 8 * 1024 * 1024;
+ assert(_fd);
+ assert(_len % 4096 == 0);
+ const char *buf = (const char *) _buf;
+ size_t left = _len;
+ while( left ) {
+ size_t toWrite = min(left, BlockSize);
+ DWORD written;
+ if( !WriteFile(_fd, buf, toWrite, &written, NULL) ) {
+ DWORD e = GetLastError();
+ if( e == 87 )
+ msgasserted(13519, "error 87 appending to file - invalid parameter");
+ else
+ uasserted(13517, str::stream() << "error appending to file " << _name << ' ' << _len << ' ' << toWrite << ' ' << errnoWithDescription(e));
+ }
+ else {
+ dassert( written == toWrite );
+ }
+ left -= written;
+ buf += written;
}
}
@@ -96,28 +113,44 @@ namespace mongo {
#else
+// posix
+
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
+#include "paths.h"
namespace mongo {
LogFile::LogFile(string name) : _name(name) {
- _fd = open(name.c_str(),
- O_CREAT
- | O_WRONLY
+ int options = O_CREAT
+ | O_WRONLY
#if defined(O_DIRECT)
- | O_DIRECT
+ | O_DIRECT
#endif
#if defined(O_NOATIME)
- | O_NOATIME
+ | O_NOATIME
+#endif
+ ;
+
+ _fd = open(name.c_str(), options, S_IRUSR | S_IWUSR);
+
+#if defined(O_DIRECT)
+ _direct = true;
+ if( _fd < 0 ) {
+ _direct = false;
+ options &= ~O_DIRECT;
+ _fd = open(name.c_str(), options, S_IRUSR | S_IWUSR);
+ }
+#else
+ _direct = false;
#endif
- ,
- S_IRUSR | S_IWUSR);
+
if( _fd < 0 ) {
uasserted(13516, str::stream() << "couldn't open file " << name << " for writing " << errnoWithDescription());
}
+ flushMyDirectory(name);
}
LogFile::~LogFile() {
@@ -126,7 +159,21 @@ namespace mongo {
_fd = -1;
}
+ void LogFile::truncate() {
+ verify(15872, _fd >= 0);
+
+ BOOST_STATIC_ASSERT(sizeof(off_t) == 8); // we don't want overflow here
+ const off_t pos = lseek(_fd, 0, SEEK_CUR); // doesn't actually seek
+ if (ftruncate(_fd, pos) != 0){
+ msgasserted(15873, "Couldn't truncate file: " + errnoWithDescription());
+ }
+ }
+
void LogFile::synchronousAppend(const void *b, size_t len) {
+#ifdef POSIX_FADV_DONTNEED
+ const off_t pos = lseek(_fd, 0, SEEK_CUR); // doesn't actually seek
+#endif
+
const char *buf = (char *) b;
assert(_fd);
assert(((size_t)buf)%4096==0); // aligned
@@ -150,6 +197,10 @@ namespace mongo {
uasserted(13514, str::stream() << "error appending to file on fsync " << ' ' << errnoWithDescription());
}
+#ifdef POSIX_FADV_DONTNEED
+ if (!_direct)
+ posix_fadvise(_fd, pos, len, POSIX_FADV_DONTNEED);
+#endif
}
}