summaryrefslogtreecommitdiff
path: root/indra/llvfs
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llvfs')
-rw-r--r--indra/llvfs/llvfs.cpp104
-rw-r--r--indra/llvfs/llvfs.h18
2 files changed, 77 insertions, 45 deletions
diff --git a/indra/llvfs/llvfs.cpp b/indra/llvfs/llvfs.cpp
index 97632b3496..ef8c4d6c7f 100644
--- a/indra/llvfs/llvfs.cpp
+++ b/indra/llvfs/llvfs.cpp
@@ -234,7 +234,9 @@ const S32 LLVFSFileBlock::SERIAL_SIZE = 34;
LLVFS::LLVFS(const std::string& index_filename, const std::string& data_filename, const BOOL read_only, const U32 presize, const BOOL remove_after_crash)
-: mRemoveAfterCrash(remove_after_crash)
+: mRemoveAfterCrash(remove_after_crash),
+ mDataFP(NULL),
+ mIndexFP(NULL)
{
mDataMutex = new LLMutex(0);
@@ -250,17 +252,21 @@ LLVFS::LLVFS(const std::string& index_filename, const std::string& data_filename
const char *file_mode = mReadOnly ? "rb" : "r+b";
- if (! (mDataFP = openAndLock(mDataFilename, file_mode, mReadOnly)))
+ LL_INFOS("VFS") << "Attempting to open VFS index file " << mIndexFilename << LL_ENDL;
+ LL_INFOS("VFS") << "Attempting to open VFS data file " << mDataFilename << LL_ENDL;
+
+ mDataFP = openAndLock(mDataFilename, file_mode, mReadOnly);
+ if (!mDataFP)
{
-
if (mReadOnly)
{
LL_WARNS("VFS") << "Can't find " << mDataFilename << " to open read-only VFS" << LL_ENDL;
mValid = VFSVALID_BAD_CANNOT_OPEN_READONLY;
return;
}
-
- if((mDataFP = openAndLock(mDataFilename, "w+b", FALSE)))
+
+ mDataFP = openAndLock(mDataFilename, "w+b", FALSE);
+ if (mDataFP)
{
// Since we're creating this data file, assume any index file is bogus
// remove the index, since this vfs is now blank
@@ -268,41 +274,12 @@ LLVFS::LLVFS(const std::string& index_filename, const std::string& data_filename
}
else
{
- LL_WARNS("VFS") << "Can't open VFS data file " << mDataFilename << " attempting to use alternate" << LL_ENDL;
-
- std::string temp_index;
- std::string temp_data;
-
- for (U32 count = 0; count < 256; count++)
- {
- temp_index = mIndexFilename + llformat(".%u",count);
- temp_data = mDataFilename + llformat(".%u", count);
-
- // try just opening, then creating, each alternate
- if ((mDataFP = openAndLock(temp_data, "r+b", FALSE)))
- {
- break;
- }
-
- if ((mDataFP = openAndLock(temp_data, "w+b", FALSE)))
- {
- // we're creating the datafile, so nuke the indexfile
- LLFile::remove(temp_index);
- break;
- }
- }
-
- if (! mDataFP)
- {
- LL_WARNS("VFS") << "Couldn't open vfs data file after trying many alternates" << LL_ENDL;
- mValid = VFSVALID_BAD_CANNOT_CREATE;
- return;
- }
-
- mIndexFilename = temp_index;
- mDataFilename = temp_data;
+ LL_WARNS("VFS") << "Couldn't open vfs data file "
+ << mDataFilename << LL_ENDL;
+ mValid = VFSVALID_BAD_CANNOT_CREATE;
+ return;
}
-
+
if (presize)
{
presizeDataFile(presize);
@@ -351,7 +328,7 @@ LLVFS::LLVFS(const std::string& index_filename, const std::string& data_filename
llstat fbuf;
if (! LLFile::stat(mIndexFilename, &fbuf) &&
fbuf.st_size >= LLVFSFileBlock::SERIAL_SIZE &&
- (mIndexFP = openAndLock(mIndexFilename, file_mode, mReadOnly))
+ (mIndexFP = openAndLock(mIndexFilename, file_mode, mReadOnly)) // Yes, this is an assignment and not '=='
)
{
std::vector<U8> buffer(fbuf.st_size);
@@ -539,7 +516,7 @@ LLVFS::LLVFS(const std::string& index_filename, const std::string& data_filename
addFreeBlock(new LLVFSBlock(0, data_size));
}
}
- else
+ else // Pre-existing index file wasn't opened
{
if (mReadOnly)
{
@@ -579,8 +556,8 @@ LLVFS::LLVFS(const std::string& index_filename, const std::string& data_filename
}
}
- LL_WARNS("VFS") << "Using index file " << mIndexFilename << LL_ENDL;
- LL_WARNS("VFS") << "Using data file " << mDataFilename << LL_ENDL;
+ LL_INFOS("VFS") << "Using VFS index file " << mIndexFilename << LL_ENDL;
+ LL_INFOS("VFS") << "Using VFS data file " << mDataFilename << LL_ENDL;
mValid = VFSVALID_OK;
}
@@ -619,6 +596,47 @@ LLVFS::~LLVFS()
delete mDataMutex;
}
+
+// Use this function normally to create LLVFS files.
+// Will append digits to the end of the filename with multiple re-trys
+// static
+LLVFS * LLVFS::createLLVFS(const std::string& index_filename,
+ const std::string& data_filename,
+ const BOOL read_only,
+ const U32 presize,
+ const BOOL remove_after_crash)
+{
+ LLVFS * new_vfs = new LLVFS(index_filename, data_filename, read_only, presize, remove_after_crash);
+
+ if( !new_vfs->isValid() )
+ { // First name failed, retry with new names
+ std::string retry_vfs_index_name;
+ std::string retry_vfs_data_name;
+ S32 count = 0;
+ while (!new_vfs->isValid() &&
+ count < 256)
+ { // Append '.<number>' to end of filenames
+ retry_vfs_index_name = index_filename + llformat(".%u",count);
+ retry_vfs_data_name = data_filename + llformat(".%u", count);
+
+ delete new_vfs; // Delete bad VFS and try again
+ new_vfs = new LLVFS(retry_vfs_index_name, retry_vfs_data_name, read_only, presize, remove_after_crash);
+
+ count++;
+ }
+ }
+
+ if( !new_vfs->isValid() )
+ {
+ delete new_vfs; // Delete bad VFS
+ new_vfs = NULL; // Total failure
+ }
+
+ return new_vfs;
+}
+
+
+
void LLVFS::presizeDataFile(const U32 size)
{
if (!mDataFP)
diff --git a/indra/llvfs/llvfs.h b/indra/llvfs/llvfs.h
index a68c8f4ef9..2acda7ae29 100644
--- a/indra/llvfs/llvfs.h
+++ b/indra/llvfs/llvfs.h
@@ -77,11 +77,25 @@ public:
class LLVFS
{
-public:
+private:
+ // Use createLLVFS() to open a VFS file
// Pass 0 to not presize
- LLVFS(const std::string& index_filename, const std::string& data_filename, const BOOL read_only, const U32 presize, const BOOL remove_after_crash);
+ LLVFS(const std::string& index_filename,
+ const std::string& data_filename,
+ const BOOL read_only,
+ const U32 presize,
+ const BOOL remove_after_crash);
+public:
~LLVFS();
+ // Use this function normally to create LLVFS files
+ // Pass 0 to not presize
+ static LLVFS * createLLVFS(const std::string& index_filename,
+ const std::string& data_filename,
+ const BOOL read_only,
+ const U32 presize,
+ const BOOL remove_after_crash);
+
BOOL isValid() const { return (VFSVALID_OK == mValid); }
EVFSValid getValidState() const { return mValid; }