diff options
author | Chris Wilson <chris+github@qwirx.com> | 2006-08-31 22:50:02 +0000 |
---|---|---|
committer | Chris Wilson <chris+github@qwirx.com> | 2006-08-31 22:50:02 +0000 |
commit | f48dacd80f38fe1caa9f6374047f15b16e90a713 (patch) | |
tree | a554821e5c37ff56c75d207f53782408b3a9c23f /lib/raidfile | |
parent | 6852b32189e57e928b1941687ad07b3b486f9460 (diff) |
(refs #3)
Open files in binary mode (Win32)
Disable the lock failure block when we don't have any locking mechanism
Close and delete files before renaming over them on Win32. This breaks
Ben's desired recovery semantics, so it's not done on other platforms,
but Win32 requires it.
Diffstat (limited to 'lib/raidfile')
-rw-r--r-- | lib/raidfile/RaidFileWrite.cpp | 70 |
1 files changed, 60 insertions, 10 deletions
diff --git a/lib/raidfile/RaidFileWrite.cpp b/lib/raidfile/RaidFileWrite.cpp index e30162fa..2de9dde5 100644 --- a/lib/raidfile/RaidFileWrite.cpp +++ b/lib/raidfile/RaidFileWrite.cpp @@ -104,7 +104,8 @@ void RaidFileWrite::Open(bool AllowOverwrite) writeFilename += 'X'; // Attempt to open - mOSFileHandle = ::open(writeFilename.c_str(), O_WRONLY | O_CREAT, + mOSFileHandle = ::open(writeFilename.c_str(), + O_WRONLY | O_CREAT | O_BINARY, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH); if(mOSFileHandle == -1) { @@ -115,7 +116,7 @@ void RaidFileWrite::Open(bool AllowOverwrite) #ifdef HAVE_FLOCK int errnoBlock = EWOULDBLOCK; if(::flock(mOSFileHandle, LOCK_EX | LOCK_NB) != 0) -#else +#elif HAVE_DECL_F_SETLK int errnoBlock = EAGAIN; struct flock desc; desc.l_type = F_WRLCK; @@ -123,6 +124,9 @@ void RaidFileWrite::Open(bool AllowOverwrite) desc.l_start = 0; desc.l_len = 0; if(::fcntl(mOSFileHandle, F_SETLK, &desc) != 0) +#else + int errnoBlock = ENOSYS; + if (0) #endif { // Lock was not obtained. @@ -242,23 +246,46 @@ void RaidFileWrite::Commit(bool ConvertToRaidNow) } // Rename it into place -- BEFORE it's closed so lock remains + +#ifdef WIN32 + // Except on Win32 which doesn't allow renaming open files + // Close file... + if(::close(mOSFileHandle) != 0) + { + THROW_EXCEPTION(RaidFileException, OSError) + } + mOSFileHandle = -1; +#endif // WIN32 + RaidFileController &rcontroller(RaidFileController::GetController()); RaidFileDiscSet rdiscSet(rcontroller.GetDiscSet(mSetNumber)); // Get the filename for the write file std::string renameTo(RaidFileUtil::MakeWriteFileName(rdiscSet, mFilename)); // And the current name std::string renameFrom(renameTo + 'X'); + +#ifdef WIN32 + // need to delete the target first + if(::unlink(renameTo.c_str()) != 0 && + GetLastError() != ERROR_FILE_NOT_FOUND) + { + THROW_EXCEPTION(RaidFileException, OSError) + } +#endif + if(::rename(renameFrom.c_str(), renameTo.c_str()) != 0) { THROW_EXCEPTION(RaidFileException, OSError) } +#ifndef WIN32 // Close file... if(::close(mOSFileHandle) != 0) { THROW_EXCEPTION(RaidFileException, OSError) } mOSFileHandle = -1; +#endif // !WIN32 // Raid it? if(ConvertToRaidNow) @@ -292,8 +319,15 @@ void RaidFileWrite::Discard() writeFilename += 'X'; // Unlink and close it - if((::unlink(writeFilename.c_str()) != 0) - || (::close(mOSFileHandle) != 0)) + +#ifdef WIN32 + // On Win32 we must close it first + if (::close(mOSFileHandle) != 0 || + ::unlink(writeFilename.c_str()) != 0) +#else // !WIN32 + if (::unlink(writeFilename.c_str()) != 0 || + ::close(mOSFileHandle) != 0) +#endif // !WIN32 { THROW_EXCEPTION(RaidFileException, OSError) } @@ -388,13 +422,13 @@ void RaidFileWrite::TransformToRaidStorage() try { #if HAVE_DECL_O_EXLOCK - FileHandleGuard<(O_WRONLY | O_CREAT | O_EXCL | O_EXLOCK)> stripe1(stripe1FilenameW.c_str()); - FileHandleGuard<(O_WRONLY | O_CREAT | O_EXCL | O_EXLOCK)> stripe2(stripe2FilenameW.c_str()); - FileHandleGuard<(O_WRONLY | O_CREAT | O_EXCL | O_EXLOCK)> parity(parityFilenameW.c_str()); + FileHandleGuard<(O_WRONLY | O_CREAT | O_EXCL | O_EXLOCK | O_BINARY)> stripe1(stripe1FilenameW.c_str()); + FileHandleGuard<(O_WRONLY | O_CREAT | O_EXCL | O_EXLOCK | O_BINARY)> stripe2(stripe2FilenameW.c_str()); + FileHandleGuard<(O_WRONLY | O_CREAT | O_EXCL | O_EXLOCK | O_BINARY)> parity(parityFilenameW.c_str()); #else - FileHandleGuard<(O_WRONLY | O_CREAT | O_EXCL)> stripe1(stripe1FilenameW.c_str()); - FileHandleGuard<(O_WRONLY | O_CREAT | O_EXCL)> stripe2(stripe2FilenameW.c_str()); - FileHandleGuard<(O_WRONLY | O_CREAT | O_EXCL)> parity(parityFilenameW.c_str()); + FileHandleGuard<(O_WRONLY | O_CREAT | O_EXCL | O_BINARY)> stripe1(stripe1FilenameW.c_str()); + FileHandleGuard<(O_WRONLY | O_CREAT | O_EXCL | O_BINARY)> stripe2(stripe2FilenameW.c_str()); + FileHandleGuard<(O_WRONLY | O_CREAT | O_EXCL | O_BINARY)> parity(parityFilenameW.c_str()); #endif // Then... read in data... @@ -530,6 +564,22 @@ void RaidFileWrite::TransformToRaidStorage() parity.Close(); stripe2.Close(); stripe1.Close(); + +#ifdef WIN32 + // Must delete before renaming + if (::unlink(stripe1Filename.c_str()) != 0 && errno != ENOENT) + { + THROW_EXCEPTION(RaidFileException, OSError); + } + if (::unlink(stripe2Filename.c_str()) != 0 && errno != ENOENT) + { + THROW_EXCEPTION(RaidFileException, OSError); + } + if (::unlink(parityFilename.c_str()) != 0 && errno != ENOENT) + { + THROW_EXCEPTION(RaidFileException, OSError); + } +#endif // Rename them into place if(::rename(stripe1FilenameW.c_str(), stripe1Filename.c_str()) != 0 |