diff --git a/indra/llcommon/llapr.cpp b/indra/llcommon/llapr.cpp
index 7330b00bcfd44c3b2e272127eb5e2134313fcbaa..dca4cf7c3ffc4c39e4d4128baf20346358da0678 100644
--- a/indra/llcommon/llapr.cpp
+++ b/indra/llcommon/llapr.cpp
@@ -417,7 +417,11 @@ apr_pool_t* LLAPRFile::getAPRFilePool(apr_pool_t* pool)
 // File I/O
 S32 LLAPRFile::read(void *buf, S32 nbytes)
 {
-	llassert_always(mFile) ;
+	if(!mFile) 
+	{
+		llwarns << "apr mFile is removed by somebody else. Can not read." << llendl ;
+		return 0;
+	}
 	
 	apr_size_t sz = nbytes;
 	apr_status_t s = apr_file_read(mFile, buf, &sz);
@@ -435,7 +439,11 @@ S32 LLAPRFile::read(void *buf, S32 nbytes)
 
 S32 LLAPRFile::write(const void *buf, S32 nbytes)
 {
-	llassert_always(mFile) ;
+	if(!mFile) 
+	{
+		llwarns << "apr mFile is removed by somebody else. Can not write." << llendl ;
+		return 0;
+	}
 	
 	apr_size_t sz = nbytes;
 	apr_status_t s = apr_file_write(mFile, buf, &sz);
diff --git a/indra/newview/lltexturecache.cpp b/indra/newview/lltexturecache.cpp
index 403692951f225526cbe2afa5f68df624c0c35537..952f893015612694b4cd691a0dc06cd90fc2ed0c 100644
--- a/indra/newview/lltexturecache.cpp
+++ b/indra/newview/lltexturecache.cpp
@@ -998,7 +998,11 @@ LLAPRFile* LLTextureCache::openHeaderEntriesFile(bool readonly, S32 offset)
 
 void LLTextureCache::closeHeaderEntriesFile()
 {
-	llassert_always(mHeaderAPRFile != NULL);
+	if(!mHeaderAPRFile)
+	{
+		return ;
+	}
+
 	delete mHeaderAPRFile;
 	mHeaderAPRFile = NULL;
 }
@@ -1115,7 +1119,7 @@ S32 LLTextureCache::openAndReadEntry(const LLUUID& id, Entry& entry, bool create
 }
 
 //mHeaderMutex is locked before calling this.
-void LLTextureCache::writeEntryToHeaderImmediately(S32 idx, Entry& entry, bool write_header)
+void LLTextureCache::writeEntryToHeaderImmediately(S32& idx, Entry& entry, bool write_header)
 {	
 	LLAPRFile* aprfile ;
 	S32 bytes_written ;
@@ -1124,7 +1128,13 @@ void LLTextureCache::writeEntryToHeaderImmediately(S32 idx, Entry& entry, bool w
 	{
 		aprfile = openHeaderEntriesFile(false, 0);		
 		bytes_written = aprfile->write((U8*)&mHeaderEntriesInfo, sizeof(EntriesInfo)) ;
-		llassert_always(bytes_written == sizeof(EntriesInfo));
+		if(bytes_written != sizeof(EntriesInfo))
+		{
+			clearCorruptedCache() ; //clear the cache.
+			idx = -1 ;//mark the idx invalid.
+			return ;
+		}
+
 		mHeaderAPRFile->seek(APR_SET, offset);
 	}
 	else
@@ -1132,19 +1142,31 @@ void LLTextureCache::writeEntryToHeaderImmediately(S32 idx, Entry& entry, bool w
 		aprfile = openHeaderEntriesFile(false, offset);
 	}
 	bytes_written = aprfile->write((void*)&entry, (S32)sizeof(Entry));
-	llassert_always(bytes_written == sizeof(Entry));
+	if(bytes_written != sizeof(Entry))
+	{
+		clearCorruptedCache() ; //clear the cache.
+		idx = -1 ;//mark the idx invalid.
+
+		return ;
+	}
+
 	closeHeaderEntriesFile();
 	mUpdatedEntryMap.erase(idx) ;
 }
 
 //mHeaderMutex is locked before calling this.
-void LLTextureCache::readEntryFromHeaderImmediately(S32 idx, Entry& entry)
+void LLTextureCache::readEntryFromHeaderImmediately(S32& idx, Entry& entry)
 {
 	S32 offset = sizeof(EntriesInfo) + idx * sizeof(Entry);
 	LLAPRFile* aprfile = openHeaderEntriesFile(true, offset);
 	S32 bytes_read = aprfile->read((void*)&entry, (S32)sizeof(Entry));
-	llassert_always(bytes_read == sizeof(Entry));			
 	closeHeaderEntriesFile();
+
+	if(bytes_read != sizeof(Entry))
+	{
+		clearCorruptedCache() ; //clear the cache.
+		idx = -1 ;//mark the idx invalid.
+	}
 }
 
 //mHeaderMutex is locked before calling this.
@@ -1169,7 +1191,7 @@ void LLTextureCache::updateEntryTimeStamp(S32 idx, Entry& entry)
 }
 
 //update an existing entry, write to header file immediately.
-bool LLTextureCache::updateEntry(S32 idx, Entry& entry, S32 new_image_size, S32 new_data_size)
+bool LLTextureCache::updateEntry(S32& idx, Entry& entry, S32 new_image_size, S32 new_data_size)
 {
 	S32 new_body_size = llmax(0, new_data_size - TEXTURE_CACHE_ENTRY_SIZE) ;
 	
@@ -1240,6 +1262,10 @@ U32 LLTextureCache::openAndReadEntries(std::vector<Entry>& entries)
 	{
 		aprfile = openHeaderEntriesFile(false, 0);
 		updatedHeaderEntriesFile() ;
+		if(!aprfile)
+		{
+			return 0;
+		}
 		aprfile->seek(APR_SET, (S32)sizeof(EntriesInfo));
 	}
 	for (U32 idx=0; idx<num_entries; idx++)
@@ -1281,7 +1307,11 @@ void LLTextureCache::writeEntriesAndClose(const std::vector<Entry>& entries)
 		for (S32 idx=0; idx<num_entries; idx++)
 		{
 			S32 bytes_written = aprfile->write((void*)(&entries[idx]), (S32)sizeof(Entry));
-			llassert_always(bytes_written == sizeof(Entry));
+			if(bytes_written != sizeof(Entry))
+			{
+				clearCorruptedCache() ; //clear the cache.
+				return ;
+			}
 		}
 		closeHeaderEntriesFile();
 	}
@@ -1307,7 +1337,11 @@ void LLTextureCache::updatedHeaderEntriesFile()
 		//entriesInfo
 		mHeaderAPRFile->seek(APR_SET, 0);
 		S32 bytes_written = mHeaderAPRFile->write((U8*)&mHeaderEntriesInfo, sizeof(EntriesInfo)) ;
-		llassert_always(bytes_written == sizeof(EntriesInfo));
+		if(bytes_written != sizeof(EntriesInfo))
+		{
+			clearCorruptedCache() ; //clear the cache.
+			return ;
+		}
 		
 		//write each updated entry
 		S32 entry_size = (S32)sizeof(Entry) ;
@@ -1323,7 +1357,11 @@ void LLTextureCache::updatedHeaderEntriesFile()
 			}
 			
 			bytes_written = mHeaderAPRFile->write((void*)(&iter->second), entry_size);
-			llassert_always(bytes_written == entry_size);
+			if(bytes_written != entry_size)
+			{
+				clearCorruptedCache() ; //clear the cache.
+				return ;
+			}
 		}
 		mUpdatedEntryMap.clear() ;
 	}
@@ -1444,6 +1482,29 @@ void LLTextureCache::readHeaderCache()
 
 //////////////////////////////////////////////////////////////////////////////
 
+//the header mutex is locked before calling this.
+void LLTextureCache::clearCorruptedCache()
+{
+	llwarns << "the texture cache is corrupted, need to be cleared." << llendl ;
+
+	closeHeaderEntriesFile();//close possible file handler
+	purgeAllTextures(false) ; //clear the cache.
+	
+	if (!mReadOnly) //regenerate the directory tree if not exists.
+	{
+		LLFile::mkdir(mTexturesDirName);
+		
+		const char* subdirs = "0123456789abcdef";
+		for (S32 i=0; i<16; i++)
+		{
+			std::string dirname = mTexturesDirName + gDirUtilp->getDirDelimiter() + subdirs[i];
+			LLFile::mkdir(dirname);
+		}
+	}
+
+	return ;
+}
+
 void LLTextureCache::purgeAllTextures(bool purge_directories)
 {
 	if (!mReadOnly)
@@ -1472,11 +1533,14 @@ void LLTextureCache::purgeAllTextures(bool purge_directories)
 	mTexturesSizeTotal = 0;
 	mFreeList.clear();
 	mTexturesSizeTotal = 0;
+	mUpdatedEntryMap.clear();
 
 	// Info with 0 entries
 	mHeaderEntriesInfo.mVersion = sHeaderCacheVersion;
 	mHeaderEntriesInfo.mEntries = 0;
 	writeEntriesHeader();
+
+	llinfos << "The entire texture cache is cleared." << llendl ;
 }
 
 void LLTextureCache::purgeTextures(bool validate)
@@ -1644,7 +1708,8 @@ S32 LLTextureCache::setHeaderCacheEntry(const LLUUID& id, Entry& entry, S32 imag
 	{
 		updateEntry(idx, entry, imagesize, datasize);				
 	}
-	else // retry
+
+	if(idx < 0) // retry
 	{
 		readHeaderCache(); // We couldn't write an entry, so refresh the LRU
 	
diff --git a/indra/newview/lltexturecache.h b/indra/newview/lltexturecache.h
index 0fceee3011d1972d743d2209d1685751dad889f6..f80be0056b6c5753636162c2c737dcd154db7162 100644
--- a/indra/newview/lltexturecache.h
+++ b/indra/newview/lltexturecache.h
@@ -154,6 +154,7 @@ protected:
 private:
 	void setDirNames(ELLPath location);
 	void readHeaderCache();
+	void clearCorruptedCache();
 	void purgeAllTextures(bool purge_directories);
 	void purgeTextures(bool validate);
 	LLAPRFile* openHeaderEntriesFile(bool readonly, S32 offset);
@@ -161,12 +162,12 @@ private:
 	void readEntriesHeader();
 	void writeEntriesHeader();
 	S32 openAndReadEntry(const LLUUID& id, Entry& entry, bool create);
-	bool updateEntry(S32 idx, Entry& entry, S32 new_image_size, S32 new_body_size);
+	bool updateEntry(S32& idx, Entry& entry, S32 new_image_size, S32 new_body_size);
 	void updateEntryTimeStamp(S32 idx, Entry& entry) ;
 	U32 openAndReadEntries(std::vector<Entry>& entries);
 	void writeEntriesAndClose(const std::vector<Entry>& entries);
-	void readEntryFromHeaderImmediately(S32 idx, Entry& entry) ;
-	void writeEntryToHeaderImmediately(S32 idx, Entry& entry, bool write_header = false) ;
+	void readEntryFromHeaderImmediately(S32& idx, Entry& entry) ;
+	void writeEntryToHeaderImmediately(S32& idx, Entry& entry, bool write_header = false) ;
 	void removeEntry(S32 idx, Entry& entry, std::string& filename);
 	void removeCachedTexture(const LLUUID& id) ;
 	S32 getHeaderCacheEntry(const LLUUID& id, Entry& entry);