From c184849dc3b79d631fb5f279c9868e5a6bc05990 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sun, 5 Jul 2009 21:43:57 +0000 Subject: Allow RaidFileWrite to test that the reference count of an object is correct before overwriting or deleting it. --- lib/raidfile/RaidFileException.txt | 3 +++ lib/raidfile/RaidFileWrite.cpp | 52 +++++++++++++++++++++++++++++++++++--- lib/raidfile/RaidFileWrite.h | 2 ++ 3 files changed, 54 insertions(+), 3 deletions(-) (limited to 'lib/raidfile') diff --git a/lib/raidfile/RaidFileException.txt b/lib/raidfile/RaidFileException.txt index c69dc2a2..c7ddfcc5 100644 --- a/lib/raidfile/RaidFileException.txt +++ b/lib/raidfile/RaidFileException.txt @@ -23,3 +23,6 @@ CanOnlyGetUsageBeforeCommit 19 CanOnlyGetFileSizeBeforeCommit 20 ErrorOpeningWriteFileOnTruncate 21 FileIsCurrentlyOpenForWriting 22 +RequestedModifyUnreferencedFile 23 Internal error: the server attempted to modify a file which has no references. +RequestedModifyMultiplyReferencedFile 24 Internal error: the server attempted to modify a file which has multiple references. +RequestedDeleteReferencedFile 25 Internal error: the server attempted to delete a file which is still referenced. diff --git a/lib/raidfile/RaidFileWrite.cpp b/lib/raidfile/RaidFileWrite.cpp index 00067f72..2d852f86 100644 --- a/lib/raidfile/RaidFileWrite.cpp +++ b/lib/raidfile/RaidFileWrite.cpp @@ -42,17 +42,47 @@ // // 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 @@ -250,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 @@ -638,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)); diff --git a/lib/raidfile/RaidFileWrite.h b/lib/raidfile/RaidFileWrite.h index d7e51f21..418f90ee 100644 --- a/lib/raidfile/RaidFileWrite.h +++ b/lib/raidfile/RaidFileWrite.h @@ -28,6 +28,7 @@ class RaidFileWrite : public IOStream { public: RaidFileWrite(int SetNumber, const std::string &Filename); + RaidFileWrite(int SetNumber, const std::string &Filename, int refcount); ~RaidFileWrite(); private: RaidFileWrite(const RaidFileWrite &rToCopy); @@ -60,6 +61,7 @@ private: int mSetNumber; std::string mFilename; int mOSFileHandle; + int mRefCount; }; #endif // RAIDFILEWRITE__H -- cgit v1.2.3