in SLOW_FLUSH, flush the dir after the rename; this won't prevent corruption, but avoid returning to the caller until the change is fully committed to disk (before, we could reboot after returning and return to a previous version of the file)

This commit is contained in:
Glenn Maynard
2008-10-28 08:39:50 +00:00
parent 935b188e29
commit 1b98e724ba
+46 -17
View File
@@ -232,6 +232,38 @@ RageFileObjDirect::RageFileObjDirect( const RString &sPath, int iFD, int iMode )
this->EnableWriteBuffering( BUFSIZE );
}
namespace
{
#if !defined(WIN32)
bool FlushDir( RString sPath, RString &sError )
{
/* Wait for the directory to be flushed. */
int dirfd = open( sPath, O_RDONLY );
if( dirfd == -1 )
{
sError = strerror(errno);
return false;
}
if( fsync( dirfd ) == -1 )
{
sError = strerror(errno);
close( dirfd );
return false;
}
close( dirfd );
return true;
}
#else
bool FlushDir( RString sPath, RString &sError )
{
return true;
}
#endif
}
bool RageFileObjDirect::FinalFlush()
{
if( !(m_iMode & RageFile::WRITE) )
@@ -253,27 +285,14 @@ bool RageFileObjDirect::FinalFlush()
return false;
}
#if !defined(WIN32)
/* Wait for the directory to be flushed. */
int dirfd = open( Dirname(m_sPath), O_RDONLY );
if( dirfd == -1 )
RString sError;
if( !FlushDir(Dirname(m_sPath), sError) )
{
WARN( ssprintf("Error synchronizing open(%s dir): %s", this->m_sPath.c_str(), strerror(errno)) );
SetError( strerror(errno) );
WARN( ssprintf("Error synchronizing fsync(%s dir): %s", this->m_sPath.c_str(), sError.c_str()) );
SetError( sError );
return false;
}
if( fsync( dirfd ) == -1 )
{
WARN( ssprintf("Error synchronizing fsync(%s dir): %s", this->m_sPath.c_str(), strerror(errno)) );
SetError( strerror(errno) );
close( dirfd );
return false;
}
close( dirfd );
#endif
return true;
}
@@ -333,6 +352,16 @@ RageFileObjDirect::~RageFileObjDirect()
}
#endif
if( m_iMode & RageFile::SLOW_FLUSH )
{
RString sError;
if( !FlushDir(Dirname(m_sPath), sError) )
{
WARN( ssprintf("Error synchronizing fsync(%s dir): %s", this->m_sPath.c_str(), sError.c_str()) );
SetError( sError );
}
}
/* Success. */
return;
} while(0);