Use posix_fadvise() maybe-correctly; only use O_DIRECT for hashing, if requested; better exception handling in fspropcalc & fsdatasourceiter to prevent errors scanning individual objects from blowing up the whole init/check.

This commit is contained in:
Brian Cox 2016-05-06 11:24:24 -07:00
parent eaca9fcedf
commit b543a36d89
3 changed files with 39 additions and 17 deletions

View File

@ -174,8 +174,10 @@ void cFile::Open( const TSTRING& sFileNameC, uint32 flags )
#endif
#ifdef O_DIRECT
if (flags & OPEN_DIRECT)
perm |= O_DIRECT
//Only use O_DIRECT for scanning, since cfg/policy/report reads
// don't happen w/ a nice round block size.
if ((flags & OPEN_DIRECT) && (flags & OPEN_SCANNING))
perm |= O_DIRECT;
#endif
//
@ -212,11 +214,11 @@ void cFile::Open( const TSTRING& sFileNameC, uint32 flags )
#ifdef F_NOCACHE
if (flags & OPEN_DIRECT)
fcntl(fh, F_NOCACHE, 1);
#endif
#endif
#ifdef HAVE_POSIX_FADVISE
if (flags & OPEN_SCANNING)
posix_fadvise(fh,0,0, POSIX_FADV_DONTNEED);
posix_fadvise(fh,0,0, POSIX_FADV_SEQUENTIAL);
#endif
}
@ -227,6 +229,10 @@ void cFile::Open( const TSTRING& sFileNameC, uint32 flags )
///////////////////////////////////////////////////////////////////////////
void cFile::Close() //throw(eFile)
{
#ifdef HAVE_POSIX_FADVISE
posix_fadvise(fileno(mpData->mpCurrStream),0,0, POSIX_FADV_DONTNEED);
#endif
if(mpData->mpCurrStream != NULL)
{
fclose( mpData->mpCurrStream );

View File

@ -149,7 +149,7 @@ void cFSDataSourceIter::GetChildrenNames( const TSTRING& strParentName, std::vec
{
iFSServices::GetInstance()->ReadDir( strParentName, vChildrenNames, false );
}
catch( eFSServices& e )
catch( eError& e )
{
cDebug d("cFSDataSourceIter::GeneratePeers");
d.TraceError("**** ReadDir failed for %s\n", strParentName.c_str() );
@ -184,7 +184,7 @@ bool cFSDataSourceIter::InitializeTypeInfo(iFCO* pFCO)
{
iFSServices::GetInstance()->Stat( pTrans->ToStringAPI( pObj->GetName() ), statArgs);
}
catch(eFSServices& e)
catch(eError& e)
{
cDebug d("CreateObject");
d.TraceError( "*** Stat of %s failed!!!\n", pObj->GetName().AsString().c_str() );

View File

@ -168,7 +168,7 @@ void cFSPropCalc::VisitFSObject(cFSObject& obj)
bDidStat = true;
}
}
catch(eFSServices& e)
catch(eError& e)
{
d.TraceError("Error getting stat info for %s : %s\n", strName.c_str(), e.GetMsg().c_str());
@ -269,6 +269,8 @@ void cFSPropCalc::VisitFSObject(cFSObject& obj)
}
}
bool hash_success = false;
// if the file type is not a regular file, we will
// not try to open the file for signature generation
ASSERT( propSet.GetValidVector().ContainsItem(cFSPropSet::PROP_FILETYPE) );
@ -284,7 +286,8 @@ void cFSPropCalc::VisitFSObject(cFSObject& obj)
cFileArchive arch;
cMemoryArchive memArch;
cBidirArchive* pTheArch;
bool bInitSuccess = true;
hash_success = true;
if(propSet.GetFileType() == cFSPropSet::FT_SYMLINK)
{
pTheArch = &memArch;
@ -293,7 +296,7 @@ void cFSPropCalc::VisitFSObject(cFSObject& obj)
// add it to the bucket...
if(mpErrorBucket)
mpErrorBucket->AddError( eArchiveOpen( strName, iFSServices::GetInstance()->GetErrString(), eError::NON_FATAL ) );
bInitSuccess = false;
hash_success = false;
}
}
@ -306,19 +309,19 @@ void cFSPropCalc::VisitFSObject(cFSObject& obj)
cFileArchive::FA_SCANNING | cFileArchive::FA_DIRECT :
cFileArchive::FA_SCANNING) );
}
catch (eArchive&)
catch (eError&)
{
// add it to the bucket...
if(mpErrorBucket)
mpErrorBucket->AddError( eArchiveOpen( strName, iFSServices::GetInstance()->GetErrString(), eError::NON_FATAL ) );
bInitSuccess = false;
hash_success = false;
}
}
//
// if we have successfully initialized the archive
//
if (bInitSuccess)
if (hash_success)
{
cArchiveSigGen asg;
@ -349,13 +352,26 @@ void cFSPropCalc::VisitFSObject(cFSObject& obj)
//
// calculate the signatures
//
pTheArch->Seek( 0, cBidirArchive::BEGINNING );
asg.CalculateSignatures( *pTheArch );
arch.Close();
try
{
pTheArch->Seek( 0, cBidirArchive::BEGINNING );
asg.CalculateSignatures( *pTheArch );
arch.Close();
}
catch (eError& e)
{
d.TraceError("Error generating hashes for %s : %s\n", strName.c_str(), e.GetMsg().c_str());
e.SetFatality(false);
if(mpErrorBucket)
mpErrorBucket->AddError(e);
hash_success = false;
}
}
}
}
else
if (!hash_success)
{
// We can't calculate signatures, set them to undefined
if (propsToCheck.ContainsItem(cFSPropSet::PROP_CRC32))