summaryrefslogtreecommitdiff
path: root/lib/raidfile/RaidFileWrite.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/raidfile/RaidFileWrite.cpp')
-rw-r--r--lib/raidfile/RaidFileWrite.cpp62
1 files changed, 58 insertions, 4 deletions
diff --git a/lib/raidfile/RaidFileWrite.cpp b/lib/raidfile/RaidFileWrite.cpp
index efec43a2..2d852f86 100644
--- a/lib/raidfile/RaidFileWrite.cpp
+++ b/lib/raidfile/RaidFileWrite.cpp
@@ -42,20 +42,50 @@
//
// Function
// Name: RaidFileWrite::RaidFileWrite(int, const std::string &)
-// Purpose: Construtor, just stores requried details
+// Purpose: Simple constructor, just stores required details
// Created: 2003/07/10
//
// --------------------------------------------------------------------------
RaidFileWrite::RaidFileWrite(int SetNumber, const std::string &Filename)
: mSetNumber(SetNumber),
mFilename(Filename),
- mOSFileHandle(-1) // not valid file handle
+ mOSFileHandle(-1), // not valid file handle
+ mRefCount(-1) // unknown refcount
{
}
// --------------------------------------------------------------------------
//
// Function
+// Name: RaidFileWrite::RaidFileWrite(int,
+// const std::string &, int refcount)
+// Purpose: Constructor with check for overwriting file
+// with multiple references
+// Created: 2009/07/05
+//
+// --------------------------------------------------------------------------
+RaidFileWrite::RaidFileWrite(int SetNumber, const std::string &Filename,
+ int refcount)
+ : mSetNumber(SetNumber),
+ mFilename(Filename),
+ mOSFileHandle(-1), // not valid file handle
+ mRefCount(refcount)
+{
+ // Can't check for zero refcount here, because it's legal
+ // to create a RaidFileWrite to delete an object with zero refcount.
+ // Check in Commit() and Delete() instead.
+ if (refcount > 1)
+ {
+ BOX_ERROR("Attempted to modify object " << mFilename <<
+ ", which has " << refcount << " references");
+ THROW_EXCEPTION(RaidFileException,
+ RequestedModifyMultiplyReferencedFile);
+ }
+}
+
+// --------------------------------------------------------------------------
+//
+// Function
// Name: RaidFileWrite::~RaidFileWrite()
// Purpose: Destructor (will discard written file if not commited)
// Created: 2003/07/10
@@ -113,6 +143,7 @@ void RaidFileWrite::Open(bool AllowOverwrite)
S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
if(mOSFileHandle == -1)
{
+ BOX_LOG_SYS_ERROR("Failed to open file: " << writeFilename);
THROW_EXCEPTION(RaidFileException, ErrorOpeningWriteFile)
}
@@ -249,7 +280,15 @@ void RaidFileWrite::Commit(bool ConvertToRaidNow)
{
THROW_EXCEPTION(RaidFileException, NotOpen)
}
-
+
+ if (mRefCount == 0)
+ {
+ BOX_ERROR("Attempted to modify object " << mFilename <<
+ ", which has no references");
+ THROW_EXCEPTION(RaidFileException,
+ RequestedModifyUnreferencedFile);
+ }
+
// Rename it into place -- BEFORE it's closed so lock remains
#ifdef WIN32
@@ -274,13 +313,15 @@ void RaidFileWrite::Commit(bool ConvertToRaidNow)
if(::unlink(renameTo.c_str()) != 0 &&
GetLastError() != ERROR_FILE_NOT_FOUND)
{
- BOX_LOG_WIN_ERROR("failed to delete file: " << renameTo);
+ BOX_LOG_WIN_ERROR("Failed to delete file: " << renameTo);
THROW_EXCEPTION(RaidFileException, OSError)
}
#endif
if(::rename(renameFrom.c_str(), renameTo.c_str()) != 0)
{
+ BOX_LOG_SYS_ERROR("Failed to rename file: " << renameFrom <<
+ " to " << renameTo);
THROW_EXCEPTION(RaidFileException, OSError)
}
@@ -335,6 +376,7 @@ void RaidFileWrite::Discard()
::close(mOSFileHandle) != 0)
#endif // !WIN32
{
+ BOX_LOG_SYS_ERROR("Failed to delete file: " << writeFilename);
THROW_EXCEPTION(RaidFileException, OSError)
}
@@ -562,6 +604,8 @@ void RaidFileWrite::TransformToRaidStorage()
ASSERT((::lseek(parity, 0, SEEK_CUR) % blockSize) == 0);
if(::write(parity, &sw, sizeof(sw)) != sizeof(sw))
{
+ BOX_LOG_SYS_ERROR("Failed to write to file: " <<
+ writeFilename);
THROW_EXCEPTION(RaidFileException, OSError)
}
}
@@ -600,6 +644,8 @@ void RaidFileWrite::TransformToRaidStorage()
// Finally delete the write file
if(::unlink(writeFilename.c_str()) != 0)
{
+ BOX_LOG_SYS_ERROR("Failed to delete file: " <<
+ writeFilename);
THROW_EXCEPTION(RaidFileException, OSError)
}
}
@@ -630,6 +676,14 @@ void RaidFileWrite::TransformToRaidStorage()
// --------------------------------------------------------------------------
void RaidFileWrite::Delete()
{
+ if (mRefCount != 0 && mRefCount != -1)
+ {
+ BOX_ERROR("Attempted to delete object " << mFilename <<
+ " which has " << mRefCount << " references");
+ THROW_EXCEPTION(RaidFileException,
+ RequestedDeleteReferencedFile);
+ }
+
// Get disc set
RaidFileController &rcontroller(RaidFileController::GetController());
RaidFileDiscSet rdiscSet(rcontroller.GetDiscSet(mSetNumber));