diff --git a/indra/llcommon/llfile.cpp b/indra/llcommon/llfile.cpp
index b539a69ad6..ce0d87ae05 100644
--- a/indra/llcommon/llfile.cpp
+++ b/indra/llcommon/llfile.cpp
@@ -268,6 +268,39 @@ int LLFile::rename(const std::string& filename, const std::string& newname, int
int rc = _wrename(utf16filename.c_str(),utf16newname.c_str());
#else
int rc = ::rename(filename.c_str(),newname.c_str());
+ // FIRE-21669 & FIRE-11276 cross volume link rename workaround.
+ // Note: This workaround generalises the solution previously applied in llxfer_file.
+ // In doing this we add more failure modes to the operation, the copy can fail, the unlink can fail, in fact the copy can fail for multiple reasons.
+ // "A common mistake that people make when trying to design something completely foolproof is to underestimate the ingenuity of complete fools." - Douglas Adams, Mostly harmless
+ if (rc)
+ {
+ S32 error_number = errno;
+ LL_INFOS("LLFile") << "Rename failure (" << error_number << ") - " << filename << " to " << newname << LL_ENDL;
+ if (EXDEV == error_number)
+ {
+ if (copy(filename, newname) == 0)
+ {
+ LL_INFOS("LLFile") << "Rename across mounts not supported; copying+unlinking the file instead." << LL_ENDL;
+ rc = LLFile::remove(filename);
+ if (rc)
+ {
+ LL_WARNS("LLFile") << "unlink failed during copy/unlink workaround. Please check for stray file: " << filename << LL_ENDL;
+ }
+ }
+ else
+ {
+ LL_WARNS("LLFile") << "Copy failure during rename workaround for rename " << filename << " to " << newname << " (check both filenames and maunally rectify)" << LL_ENDL;
+ }
+ rc=0; // We need to reset rc here to avoid the higher level function taking corrective action on what could be bad files.
+ }
+ else
+ {
+ LL_WARNS("LLFile") << "Rename fatally failed, no workaround attempted for errno="
+ << errno << "." << LL_ENDL;
+ // rc will propogate alllowing corrective action above. Not entirely happy with this but it is what already happens so we're not making it worse.
+ }
+ }
+ //
#endif
return warnif(STRINGIZE("rename to '" << newname << "' from"), filename, rc, supress_error);
}
diff --git a/indra/llmessage/llxfer_file.cpp b/indra/llmessage/llxfer_file.cpp
index 7fd4222fb7..2483be99c3 100644
--- a/indra/llmessage/llxfer_file.cpp
+++ b/indra/llmessage/llxfer_file.cpp
@@ -362,40 +362,44 @@ S32 LLXfer_File::processEOF()
{
if (LLFile::rename(mTempFilename,mLocalFilename))
{
-#if !LL_WINDOWS
- S32 error_number = errno;
- LL_INFOS("Xfer") << "Rename failure (" << error_number << ") - "
- << mTempFilename << " to " << mLocalFilename << LL_ENDL;
- if(EXDEV == error_number)
- {
- if(copy_file(mTempFilename, mLocalFilename) == 0)
- {
- LL_INFOS("Xfer") << "Rename across mounts; copying+unlinking the file instead." << LL_ENDL;
- unlink(mTempFilename.c_str());
- }
- else
- {
- LL_WARNS("Xfer") << "Copy failure - " << mTempFilename << " to "
- << mLocalFilename << LL_ENDL;
- }
- }
- else
- {
- //LLFILE* fp = LLFile::fopen(mTempFilename, "r");
- //LL_WARNS() << "File " << mTempFilename << " does "
- // << (!fp ? "not" : "" ) << " exit." << LL_ENDL;
- //if(fp) fclose(fp);
- //fp = LLFile::fopen(mLocalFilename, "r");
- //LL_WARNS() << "File " << mLocalFilename << " does "
- // << (!fp ? "not" : "" ) << " exit." << LL_ENDL;
- //if(fp) fclose(fp);
- LL_WARNS("Xfer") << "Rename fatally failed, can only handle EXDEV ("
- << EXDEV << ")" << LL_ENDL;
- }
-#else
+// FIRE-21669/FIRE-11276 : move similar fucntionality down into LLFile
+//#if !LL_WINDOWS
+// S32 error_number = errno;
+// LL_INFOS("Xfer") << "Rename failure (" << error_number << ") - "
+// << mTempFilename << " to " << mLocalFilename << LL_ENDL;
+// if(EXDEV == error_number)
+// {
+// if(copy_file(mTempFilename, mLocalFilename) == 0)
+// {
+// LL_INFOS("Xfer") << "Rename across mounts; copying+unlinking the file instead." << LL_ENDL;
+// unlink(mTempFilename.c_str());
+// }
+// else
+// {
+// LL_WARNS("Xfer") << "Copy failure - " << mTempFilename << " to "
+// << mLocalFilename << LL_ENDL;
+// }
+// }
+// else
+// {
+// //LLFILE* fp = LLFile::fopen(mTempFilename, "r");
+// //LL_WARNS() << "File " << mTempFilename << " does "
+// // << (!fp ? "not" : "" ) << " exit." << LL_ENDL;
+// //if(fp) fclose(fp);
+// //fp = LLFile::fopen(mLocalFilename, "r");
+// //LL_WARNS() << "File " << mLocalFilename << " does "
+// // << (!fp ? "not" : "" ) << " exit." << LL_ENDL;
+// //if(fp) fclose(fp);
+// LL_WARNS("Xfer") << "Rename fatally failed, can only handle EXDEV ("
+// << EXDEV << ")" << LL_ENDL;
+// }
+//#else
+// LL_WARNS("Xfer") << "Rename failure - " << mTempFilename << " to "
+// << mLocalFilename << LL_ENDL;
+//#endif
+//
LL_WARNS("Xfer") << "Rename failure - " << mTempFilename << " to "
<< mLocalFilename << LL_ENDL;
-#endif
}
}