diff options
Diffstat (limited to 'lib/raidfile/RaidFileWrite.cpp')
-rw-r--r-- | lib/raidfile/RaidFileWrite.cpp | 189 |
1 files changed, 189 insertions, 0 deletions
diff --git a/lib/raidfile/RaidFileWrite.cpp b/lib/raidfile/RaidFileWrite.cpp index f24c2422..cb1f9699 100644 --- a/lib/raidfile/RaidFileWrite.cpp +++ b/lib/raidfile/RaidFileWrite.cpp @@ -11,10 +11,24 @@ #include <errno.h> #include <fcntl.h> +<<<<<<< HEAD #include <sys/types.h> #include <sys/stat.h> #include <unistd.h> #include <sys/file.h> +======= + +#ifdef HAVE_UNISTD_H +# include <unistd.h> +#endif + +#include <sys/types.h> +#include <sys/stat.h> + +#ifdef HAVE_SYS_FILE_H +# include <sys/file.h> +#endif +>>>>>>> 0.12 #include <stdio.h> #include <string.h> @@ -95,7 +109,32 @@ RaidFileWrite::~RaidFileWrite() { if(mOSFileHandle != -1) { +<<<<<<< HEAD Discard(); +======= + // We must not throw exceptions from the destructor + // http://stackoverflow.com/a/130123 + try + { + Discard(); + } + catch(BoxException &e) + { + BOX_ERROR("Failed to discard RaidFile update " + "in destructor: " << e.what() << " (" << + e.GetType() << "/" << e.GetSubType() << ")"); + } + catch(std::exception &e) + { + BOX_ERROR("Failed to discard RaidFile update " + "in destructor: " << e.what()); + } + catch(...) + { + BOX_ERROR("Failed to discard RaidFile update " + "in destructor: unknown exception"); + } +>>>>>>> 0.12 } } @@ -126,25 +165,45 @@ void RaidFileWrite::Open(bool AllowOverwrite) RaidFileUtil::ExistType existance = RaidFileUtil::RaidFileExists(rdiscSet, mFilename); if(existance != RaidFileUtil::NoFile) { +<<<<<<< HEAD BOX_ERROR("Attempted to overwrite raidfile " << mSetNumber << " " << mFilename); THROW_EXCEPTION(RaidFileException, CannotOverwriteExistingFile) +======= + THROW_FILE_ERROR("Attempted to overwrite raidfile " << + mSetNumber, mFilename, RaidFileException, + CannotOverwriteExistingFile); +>>>>>>> 0.12 } } // Get the filename for the write file +<<<<<<< HEAD std::string writeFilename(RaidFileUtil::MakeWriteFileName(rdiscSet, mFilename)); // Add on a temporary extension writeFilename += 'X'; // Attempt to open mOSFileHandle = ::open(writeFilename.c_str(), +======= + mTempFilename = RaidFileUtil::MakeWriteFileName(rdiscSet, mFilename); + // Add on a temporary extension + mTempFilename += 'X'; + + // Attempt to open + mOSFileHandle = ::open(mTempFilename.c_str(), +>>>>>>> 0.12 O_WRONLY | O_CREAT | O_BINARY, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH); if(mOSFileHandle == -1) { +<<<<<<< HEAD BOX_LOG_SYS_ERROR("Failed to open file: " << writeFilename); THROW_EXCEPTION(RaidFileException, ErrorOpeningWriteFile) +======= + THROW_SYS_FILE_ERROR("Failed to open RaidFile", mTempFilename, + RaidFileException, ErrorOpeningWriteFile); +>>>>>>> 0.12 } // Get a lock on the write file @@ -164,6 +223,7 @@ void RaidFileWrite::Open(bool AllowOverwrite) if (0) #endif { +<<<<<<< HEAD // Lock was not obtained. bool wasLocked = (errno == errnoBlock); // Close the file @@ -173,18 +233,54 @@ void RaidFileWrite::Open(bool AllowOverwrite) if(wasLocked) { THROW_EXCEPTION(RaidFileException, FileIsCurrentlyOpenForWriting) +======= + int errnoSaved = errno; + + // Lock was not obtained. + bool wasLocked = (errno == errnoBlock); + + // Close the file + ::close(mOSFileHandle); + mOSFileHandle = -1; + + // Report an exception? + if(wasLocked) + { + THROW_SYS_FILE_ERRNO("Failed to lock RaidFile, " + "already locked", mTempFilename, errnoSaved, + RaidFileException, + FileIsCurrentlyOpenForWriting); +>>>>>>> 0.12 } else { // Random error occured +<<<<<<< HEAD THROW_EXCEPTION(RaidFileException, OSError) +======= + THROW_SYS_FILE_ERRNO("Failed to lock RaidFile", + mTempFilename, errnoSaved, RaidFileException, + OSError); +>>>>>>> 0.12 } } // Truncate it to size zero if(::ftruncate(mOSFileHandle, 0) != 0) { +<<<<<<< HEAD THROW_EXCEPTION(RaidFileException, ErrorOpeningWriteFileOnTruncate) +======= + int errnoSaved = errno; + + // Close the file + ::close(mOSFileHandle); + mOSFileHandle = -1; + + THROW_SYS_FILE_ERRNO("Failed to truncate RaidFile", + mTempFilename, errnoSaved, RaidFileException, + ErrorOpeningWriteFileOnTruncate); +>>>>>>> 0.12 } // Done! @@ -210,9 +306,16 @@ void RaidFileWrite::Write(const void *pBuffer, int Length) int written = ::write(mOSFileHandle, pBuffer, Length); if(written != Length) { +<<<<<<< HEAD BOX_LOG_SYS_ERROR("RaidFileWrite failed, Length = " << Length << ", written = " << written); THROW_EXCEPTION(RaidFileException, OSError) +======= + THROW_SYS_FILE_ERROR("Failed to write to RaidFile (attempted " + "to write " << Length << " bytes but managed only " << + written << ")", mTempFilename, RaidFileException, + OSError); +>>>>>>> 0.12 } } @@ -236,7 +339,12 @@ IOStream::pos_type RaidFileWrite::GetPosition() const off_t p = ::lseek(mOSFileHandle, 0, SEEK_CUR); if(p == -1) { +<<<<<<< HEAD THROW_EXCEPTION(RaidFileException, OSError) +======= + THROW_SYS_FILE_ERROR("Failed to get position in RaidFile", + mTempFilename, RaidFileException, OSError); +>>>>>>> 0.12 } return p; @@ -261,7 +369,12 @@ void RaidFileWrite::Seek(IOStream::pos_type SeekTo, int SeekType) // Seek... if(::lseek(mOSFileHandle, SeekTo, ConvertSeekTypeToOSWhence(SeekType)) == -1) { +<<<<<<< HEAD THROW_EXCEPTION(RaidFileException, OSError) +======= + THROW_SYS_FILE_ERROR("Failed to set position in RaidFile", + mTempFilename, RaidFileException, OSError); +>>>>>>> 0.12 } } @@ -283,9 +396,14 @@ void RaidFileWrite::Commit(bool ConvertToRaidNow) if (mRefCount == 0) { +<<<<<<< HEAD BOX_ERROR("Attempted to modify object " << mFilename << ", which has no references"); THROW_EXCEPTION(RaidFileException, +======= + THROW_FILE_ERROR("Attempted to modify object file with " + "no references", mTempFilename, RaidFileException, +>>>>>>> 0.12 RequestedModifyUnreferencedFile); } @@ -296,7 +414,12 @@ void RaidFileWrite::Commit(bool ConvertToRaidNow) // Close file... if(::close(mOSFileHandle) != 0) { +<<<<<<< HEAD THROW_EXCEPTION(RaidFileException, OSError) +======= + THROW_WIN_FILE_ERROR("Failed to close RaidFile for rename", + mTempFilename, RaidFileException, OSError); +>>>>>>> 0.12 } mOSFileHandle = -1; #endif // WIN32 @@ -310,26 +433,47 @@ void RaidFileWrite::Commit(bool ConvertToRaidNow) #ifdef WIN32 // need to delete the target first +<<<<<<< HEAD if(::unlink(renameTo.c_str()) != 0 && GetLastError() != ERROR_FILE_NOT_FOUND) { BOX_LOG_WIN_ERROR("Failed to delete file: " << renameTo); THROW_EXCEPTION(RaidFileException, OSError) +======= + if(::unlink(renameTo.c_str()) != 0) + { + DWORD errorNumber = GetLastError(); + if (errorNumber != ERROR_FILE_NOT_FOUND) + { + THROW_WIN_FILE_ERRNO("Failed to delete file", renameTo, + errorNumber, RaidFileException, OSError); + } +>>>>>>> 0.12 } #endif if(::rename(renameFrom.c_str(), renameTo.c_str()) != 0) { +<<<<<<< HEAD BOX_LOG_SYS_ERROR("Failed to rename file: " << renameFrom << " to " << renameTo); THROW_EXCEPTION(RaidFileException, OSError) +======= + THROW_SYS_ERROR("Failed to rename file: " << renameFrom << + " to " << renameTo, RaidFileException, OSError); +>>>>>>> 0.12 } #ifndef WIN32 // Close file... if(::close(mOSFileHandle) != 0) { +<<<<<<< HEAD THROW_EXCEPTION(RaidFileException, OSError) +======= + THROW_SYS_FILE_ERROR("Failed to close committed RaidFile", + mTempFilename, RaidFileException, OSError); +>>>>>>> 0.12 } mOSFileHandle = -1; #endif // !WIN32 @@ -376,8 +520,13 @@ void RaidFileWrite::Discard() ::close(mOSFileHandle) != 0) #endif // !WIN32 { +<<<<<<< HEAD BOX_LOG_SYS_ERROR("Failed to delete file: " << writeFilename); THROW_EXCEPTION(RaidFileException, OSError) +======= + THROW_SYS_FILE_ERROR("Failed to delete file", writeFilename, + RaidFileException, OSError); +>>>>>>> 0.12 } // reset file handle @@ -678,10 +827,16 @@ void RaidFileWrite::Delete() { if (mRefCount != 0 && mRefCount != -1) { +<<<<<<< HEAD BOX_ERROR("Attempted to delete object " << mFilename << " which has " << mRefCount << " references"); THROW_EXCEPTION(RaidFileException, RequestedDeleteReferencedFile); +======= + THROW_FILE_ERROR("Attempted to delete object with " << + mRefCount << " references", mFilename, + RaidFileException, RequestedDeleteReferencedFile); +>>>>>>> 0.12 } // Get disc set @@ -692,7 +847,13 @@ void RaidFileWrite::Delete() RaidFileUtil::ExistType existance = RaidFileUtil::RaidFileExists(rdiscSet, mFilename); if(existance == RaidFileUtil::NoFile) { +<<<<<<< HEAD THROW_EXCEPTION(RaidFileException, RaidFileDoesntExist) +======= + THROW_FILE_ERROR("Attempted to delete object which doesn't " + "exist", mFilename, RaidFileException, + RaidFileDoesntExist); +>>>>>>> 0.12 } // Get the filename for the write file @@ -731,7 +892,12 @@ void RaidFileWrite::Delete() // Check something happened if(!deletedSomething) { +<<<<<<< HEAD THROW_EXCEPTION(RaidFileException, OSError) +======= + THROW_FILE_ERROR("Failed to delete a RaidFile stripe set", + mFilename, RaidFileException, OSError); +>>>>>>> 0.12 } } @@ -802,11 +968,24 @@ void RaidFileWrite::CreateDirectory(const RaidFileDiscSet &rSet, const std::stri if(errno == EEXIST) { // No. Bad things. +<<<<<<< HEAD THROW_EXCEPTION(RaidFileException, FileExistsInDirectoryCreation) } else { THROW_EXCEPTION(RaidFileException, OSError) +======= + THROW_SYS_FILE_ERROR("Failed to create " + "RaidFile directory", dn, + RaidFileException, + FileExistsInDirectoryCreation); + } + else + { + THROW_SYS_FILE_ERROR("Failed to create " + "RaidFile directory", dn, + RaidFileException, OSError); +>>>>>>> 0.12 } } } @@ -889,7 +1068,12 @@ IOStream::pos_type RaidFileWrite::GetFileSize() struct stat st; if(fstat(mOSFileHandle, &st) != 0) { +<<<<<<< HEAD THROW_EXCEPTION(RaidFileException, OSError) +======= + THROW_SYS_FILE_ERROR("Failed to stat RaidFile", mTempFilename, + RaidFileException, OSError); +>>>>>>> 0.12 } return st.st_size; @@ -918,7 +1102,12 @@ IOStream::pos_type RaidFileWrite::GetDiscUsageInBlocks() struct stat st; if(fstat(mOSFileHandle, &st) != 0) { +<<<<<<< HEAD THROW_EXCEPTION(RaidFileException, OSError) +======= + THROW_SYS_FILE_ERROR("Failed to stat RaidFile", mTempFilename, + RaidFileException, OSError); +>>>>>>> 0.12 } // Then return calculation |