summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris+github@qwirx.com>2006-08-31 22:50:02 +0000
committerChris Wilson <chris+github@qwirx.com>2006-08-31 22:50:02 +0000
commitf48dacd80f38fe1caa9f6374047f15b16e90a713 (patch)
treea554821e5c37ff56c75d207f53782408b3a9c23f
parent6852b32189e57e928b1941687ad07b3b486f9460 (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.
-rw-r--r--lib/raidfile/RaidFileWrite.cpp70
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