diff options
Diffstat (limited to 'lib/raidfile/RaidFileWrite.cpp')
-rw-r--r-- | lib/raidfile/RaidFileWrite.cpp | 62 |
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)); |