diff options
author | Chris Wilson <chris+github@qwirx.com> | 2006-07-27 23:18:35 +0000 |
---|---|---|
committer | Chris Wilson <chris+github@qwirx.com> | 2006-07-27 23:18:35 +0000 |
commit | c7662795f519d2b6797e4b1ac7fa4a22afa26310 (patch) | |
tree | b1737dfa78d8e7bfb2d5a7e9831bab91869ade97 /lib/raidfile | |
parent | a85b710c46ec79e968da349304f30945cb9b7bc1 (diff) |
* merge
- This is my current patch queue. I think that all of these are safe
to apply. This is just under half of the pending changes in
chris/general (the easy half).
Diffstat (limited to 'lib/raidfile')
-rw-r--r-- | lib/raidfile/RaidFileRead.cpp | 31 | ||||
-rw-r--r-- | lib/raidfile/RaidFileWrite.cpp | 69 |
2 files changed, 83 insertions, 17 deletions
diff --git a/lib/raidfile/RaidFileRead.cpp b/lib/raidfile/RaidFileRead.cpp index d60936fc..bc728113 100644 --- a/lib/raidfile/RaidFileRead.cpp +++ b/lib/raidfile/RaidFileRead.cpp @@ -14,10 +14,20 @@ #include <fcntl.h> #include <errno.h> #include <sys/stat.h> + +#ifdef HAVE_SYS_UIO_H #include <sys/uio.h> +#endif + +#ifdef HAVE_SYSLOG_H #include <syslog.h> +#endif + #include <stdarg.h> + +#ifdef HAVE_DIRENT_H #include <dirent.h> +#endif #include <stdio.h> #include <string.h> @@ -583,7 +593,8 @@ void RaidFileRead_Raid::AttemptToRecoverFromIOError(bool Stripe1) // Open the parity file std::string parityFilename(RaidFileUtil::MakeRaidComponentName(rdiscSet, mFilename, (2 + startDisc) % READ_NUMBER_DISCS_REQUIRED)); - mParityHandle = ::open(parityFilename.c_str(), O_RDONLY, 0555); + mParityHandle = ::open(parityFilename.c_str(), + O_RDONLY | O_BINARY, 0555); if(mParityHandle == -1) { THROW_EXCEPTION(RaidFileException, OSError) @@ -1017,7 +1028,8 @@ std::auto_ptr<RaidFileRead> RaidFileRead::Open(int SetNumber, const std::string std::string writeFilename(RaidFileUtil::MakeWriteFileName(rdiscSet, Filename)); // Attempt to open - int osFileHandle = ::open(writeFilename.c_str(), O_RDONLY, 0); + int osFileHandle = ::open(writeFilename.c_str(), + O_RDONLY | O_BINARY, 0); if(osFileHandle == -1) { THROW_EXCEPTION(RaidFileException, ErrorOpeningFileForRead) @@ -1055,13 +1067,15 @@ std::auto_ptr<RaidFileRead> RaidFileRead::Open(int SetNumber, const std::string try { // Open stripe1 - stripe1 = ::open(stripe1Filename.c_str(), O_RDONLY, 0555); + stripe1 = ::open(stripe1Filename.c_str(), + O_RDONLY | O_BINARY, 0555); if(stripe1 == -1) { stripe1errno = errno; } // Open stripe2 - stripe2 = ::open(stripe2Filename.c_str(), O_RDONLY, 0555); + stripe2 = ::open(stripe2Filename.c_str(), + O_RDONLY | O_BINARY, 0555); if(stripe2 == -1) { stripe2errno = errno; @@ -1169,7 +1183,8 @@ std::auto_ptr<RaidFileRead> RaidFileRead::Open(int SetNumber, const std::string // Open stripe1? if(existingFiles & RaidFileUtil::Stripe1Exists) { - stripe1 = ::open(stripe1Filename.c_str(), O_RDONLY, 0555); + stripe1 = ::open(stripe1Filename.c_str(), + O_RDONLY | O_BINARY, 0555); if(stripe1 == -1) { THROW_EXCEPTION(RaidFileException, OSError) @@ -1178,14 +1193,16 @@ std::auto_ptr<RaidFileRead> RaidFileRead::Open(int SetNumber, const std::string // Open stripe2? if(existingFiles & RaidFileUtil::Stripe2Exists) { - stripe2 = ::open(stripe2Filename.c_str(), O_RDONLY, 0555); + stripe2 = ::open(stripe2Filename.c_str(), + O_RDONLY | O_BINARY, 0555); if(stripe2 == -1) { THROW_EXCEPTION(RaidFileException, OSError) } } // Open parity - parity = ::open(parityFilename.c_str(), O_RDONLY, 0555); + parity = ::open(parityFilename.c_str(), + O_RDONLY | O_BINARY, 0555); if(parity == -1) { THROW_EXCEPTION(RaidFileException, OSError) diff --git a/lib/raidfile/RaidFileWrite.cpp b/lib/raidfile/RaidFileWrite.cpp index e30162fa..b3c98701 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,21 @@ void RaidFileWrite::TransformToRaidStorage() parity.Close(); stripe2.Close(); stripe1.Close(); + +#ifdef WIN32 + // Must delete before renaming + #define CHECK_UNLINK(file) \ + { \ + if (::unlink(file) != 0 && errno != ENOENT) \ + { \ + THROW_EXCEPTION(RaidFileException, OSError); \ + } \ + } + CHECK_UNLINK(stripe1Filename.c_str()); + CHECK_UNLINK(stripe2Filename.c_str()); + CHECK_UNLINK(parityFilename.c_str()); + #undef CHECK_UNLINK +#endif // Rename them into place if(::rename(stripe1FilenameW.c_str(), stripe1Filename.c_str()) != 0 |