diff options
Diffstat (limited to 'indra/llvfs')
| -rw-r--r-- | indra/llvfs/llvfs.cpp | 104 | ||||
| -rw-r--r-- | indra/llvfs/llvfs.h | 18 | 
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; } | 
