[Box Backup-commit] COMMIT r2543 - in box/trunk: lib/raidfile test/raidfile
boxbackup-dev@boxbackup.org
boxbackup-dev@boxbackup.org
Sun, 5 Jul 2009 22:43:57 +0100 (BST)
Author: chris
Date: 2009-07-05 22:43:57 +0100 (Sun, 05 Jul 2009)
New Revision: 2543
Modified:
box/trunk/lib/raidfile/RaidFileException.txt
box/trunk/lib/raidfile/RaidFileWrite.cpp
box/trunk/lib/raidfile/RaidFileWrite.h
box/trunk/test/raidfile/testraidfile.cpp
Log:
Allow RaidFileWrite to test that the reference count of an object is
correct before overwriting or deleting it.
Modified: box/trunk/lib/raidfile/RaidFileException.txt
===================================================================
--- box/trunk/lib/raidfile/RaidFileException.txt 2009-06-28 19:33:34 UTC (rev 2542)
+++ box/trunk/lib/raidfile/RaidFileException.txt 2009-07-05 21:43:57 UTC (rev 2543)
@@ -23,3 +23,6 @@
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.
Modified: box/trunk/lib/raidfile/RaidFileWrite.cpp
===================================================================
--- box/trunk/lib/raidfile/RaidFileWrite.cpp 2009-06-28 19:33:34 UTC (rev 2542)
+++ box/trunk/lib/raidfile/RaidFileWrite.cpp 2009-07-05 21:43:57 UTC (rev 2543)
@@ -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
@@ -250,7 +280,15 @@
{
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::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));
Modified: box/trunk/lib/raidfile/RaidFileWrite.h
===================================================================
--- box/trunk/lib/raidfile/RaidFileWrite.h 2009-06-28 19:33:34 UTC (rev 2542)
+++ box/trunk/lib/raidfile/RaidFileWrite.h 2009-07-05 21:43:57 UTC (rev 2543)
@@ -28,6 +28,7 @@
{
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 @@
int mSetNumber;
std::string mFilename;
int mOSFileHandle;
+ int mRefCount;
};
#endif // RAIDFILEWRITE__H
Modified: box/trunk/test/raidfile/testraidfile.cpp
===================================================================
--- box/trunk/test/raidfile/testraidfile.cpp 2009-06-28 19:33:34 UTC (rev 2542)
+++ box/trunk/test/raidfile/testraidfile.cpp 2009-07-05 21:43:57 UTC (rev 2543)
@@ -627,6 +627,30 @@
"', '" << n3);
}
+ // Test that creating and deleting a RaidFile with the wrong
+ // reference counts throws the expected errors.
+ {
+ RaidFileWrite write1(0, "write1", 1);
+ write1.Open();
+ write1.Commit();
+ TEST_CHECK_THROWS(write1.Delete(), RaidFileException,
+ RequestedDeleteReferencedFile);
+ }
+
+ {
+ RaidFileWrite write1(0, "write1", 0);
+ write1.Open(true);
+ TEST_CHECK_THROWS(write1.Commit(), RaidFileException,
+ RequestedModifyUnreferencedFile);
+ write1.Delete();
+ }
+
+ {
+ TEST_CHECK_THROWS(RaidFileWrite write1(0, "write1", 2),
+ RaidFileException,
+ RequestedModifyMultiplyReferencedFile);
+ }
+
// Create a RaidFile
RaidFileWrite write1(0, "test1");
IOStream &write1stream = write1; // use the stream interface where possible