FIRE-21669 & FIRE-11276: Fix for cross volume rename failures on Linux/Mac

Beq 2018-11-07 23:51:06 +00:00
parent cd7c6d5005
commit 22c7655573
2 changed files with 69 additions and 32 deletions

View File

@ -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());
//<FS:Beq> 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.
}
}
//</FS:Beq>
#endif
return warnif(STRINGIZE("rename to '" << newname << "' from"), filename, rc, supress_error);
}

View File

@ -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
//<FS:Beq> 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
//</FS:Beq>
LL_WARNS("Xfer") << "Rename failure - " << mTempFilename << " to "
<< mLocalFilename << LL_ENDL;
#endif
}
}