@ -87,8 +87,21 @@ IOStatus TestFSDirectory::Fsync(const IOOptions& options, IODebugContext* dbg) {
if ( ! fs_ - > IsFilesystemActive ( ) ) {
if ( ! fs_ - > IsFilesystemActive ( ) ) {
return fs_ - > GetError ( ) ;
return fs_ - > GetError ( ) ;
}
}
{
IOStatus in_s = fs_ - > InjectMetadataWriteError ( ) ;
if ( ! in_s . ok ( ) ) {
return in_s ;
}
}
fs_ - > SyncDir ( dirname_ ) ;
fs_ - > SyncDir ( dirname_ ) ;
return dir_ - > Fsync ( options , dbg ) ;
IOStatus s = dir_ - > Fsync ( options , dbg ) ;
{
IOStatus in_s = fs_ - > InjectMetadataWriteError ( ) ;
if ( ! in_s . ok ( ) ) {
return in_s ;
}
}
return s ;
}
}
TestFSWritableFile : : TestFSWritableFile ( const std : : string & fname ,
TestFSWritableFile : : TestFSWritableFile ( const std : : string & fname ,
@ -159,6 +172,12 @@ IOStatus TestFSWritableFile::Close(const IOOptions& options,
if ( ! fs_ - > IsFilesystemActive ( ) ) {
if ( ! fs_ - > IsFilesystemActive ( ) ) {
return fs_ - > GetError ( ) ;
return fs_ - > GetError ( ) ;
}
}
{
IOStatus in_s = fs_ - > InjectMetadataWriteError ( ) ;
if ( ! in_s . ok ( ) ) {
return in_s ;
}
}
writable_file_opened_ = false ;
writable_file_opened_ = false ;
IOStatus io_s ;
IOStatus io_s ;
io_s = target_ - > Append ( state_ . buffer_ , options , dbg ) ;
io_s = target_ - > Append ( state_ . buffer_ , options , dbg ) ;
@ -170,6 +189,10 @@ IOStatus TestFSWritableFile::Close(const IOOptions& options,
}
}
if ( io_s . ok ( ) ) {
if ( io_s . ok ( ) ) {
fs_ - > WritableFileClosed ( state_ ) ;
fs_ - > WritableFileClosed ( state_ ) ;
IOStatus in_s = fs_ - > InjectMetadataWriteError ( ) ;
if ( ! in_s . ok ( ) ) {
return in_s ;
}
}
}
return io_s ;
return io_s ;
}
}
@ -294,6 +317,12 @@ IOStatus FaultInjectionTestFS::NewWritableFile(
if ( ! IsFilesystemActive ( ) ) {
if ( ! IsFilesystemActive ( ) ) {
return GetError ( ) ;
return GetError ( ) ;
}
}
{
IOStatus in_s = InjectMetadataWriteError ( ) ;
if ( ! in_s . ok ( ) ) {
return in_s ;
}
}
if ( IsFilesystemDirectWritable ( ) ) {
if ( IsFilesystemDirectWritable ( ) ) {
return target ( ) - > NewWritableFile ( fname , file_opts , result , dbg ) ;
return target ( ) - > NewWritableFile ( fname , file_opts , result , dbg ) ;
}
}
@ -305,11 +334,19 @@ IOStatus FaultInjectionTestFS::NewWritableFile(
// WritableFileWriter* file is opened
// WritableFileWriter* file is opened
// again then it will be truncated - so forget our saved state.
// again then it will be truncated - so forget our saved state.
UntrackFile ( fname ) ;
UntrackFile ( fname ) ;
MutexLock l ( & mutex_ ) ;
{
open_files_ . insert ( fname ) ;
MutexLock l ( & mutex_ ) ;
auto dir_and_name = TestFSGetDirAndName ( fname ) ;
open_files_ . insert ( fname ) ;
auto & list = dir_to_new_files_since_last_sync_ [ dir_and_name . first ] ;
auto dir_and_name = TestFSGetDirAndName ( fname ) ;
list . insert ( dir_and_name . second ) ;
auto & list = dir_to_new_files_since_last_sync_ [ dir_and_name . first ] ;
list . insert ( dir_and_name . second ) ;
}
{
IOStatus in_s = InjectMetadataWriteError ( ) ;
if ( ! in_s . ok ( ) ) {
return in_s ;
}
}
}
}
return io_s ;
return io_s ;
}
}
@ -323,6 +360,12 @@ IOStatus FaultInjectionTestFS::ReopenWritableFile(
if ( IsFilesystemDirectWritable ( ) ) {
if ( IsFilesystemDirectWritable ( ) ) {
return target ( ) - > ReopenWritableFile ( fname , file_opts , result , dbg ) ;
return target ( ) - > ReopenWritableFile ( fname , file_opts , result , dbg ) ;
}
}
{
IOStatus in_s = InjectMetadataWriteError ( ) ;
if ( ! in_s . ok ( ) ) {
return in_s ;
}
}
IOStatus io_s = target ( ) - > ReopenWritableFile ( fname , file_opts , result , dbg ) ;
IOStatus io_s = target ( ) - > ReopenWritableFile ( fname , file_opts , result , dbg ) ;
if ( io_s . ok ( ) ) {
if ( io_s . ok ( ) ) {
result - > reset (
result - > reset (
@ -330,11 +373,19 @@ IOStatus FaultInjectionTestFS::ReopenWritableFile(
// WritableFileWriter* file is opened
// WritableFileWriter* file is opened
// again then it will be truncated - so forget our saved state.
// again then it will be truncated - so forget our saved state.
UntrackFile ( fname ) ;
UntrackFile ( fname ) ;
MutexLock l ( & mutex_ ) ;
{
open_files_ . insert ( fname ) ;
MutexLock l ( & mutex_ ) ;
auto dir_and_name = TestFSGetDirAndName ( fname ) ;
open_files_ . insert ( fname ) ;
auto & list = dir_to_new_files_since_last_sync_ [ dir_and_name . first ] ;
auto dir_and_name = TestFSGetDirAndName ( fname ) ;
list . insert ( dir_and_name . second ) ;
auto & list = dir_to_new_files_since_last_sync_ [ dir_and_name . first ] ;
list . insert ( dir_and_name . second ) ;
}
{
IOStatus in_s = InjectMetadataWriteError ( ) ;
if ( ! in_s . ok ( ) ) {
return in_s ;
}
}
}
}
return io_s ;
return io_s ;
}
}
@ -348,17 +399,31 @@ IOStatus FaultInjectionTestFS::NewRandomRWFile(
if ( IsFilesystemDirectWritable ( ) ) {
if ( IsFilesystemDirectWritable ( ) ) {
return target ( ) - > NewRandomRWFile ( fname , file_opts , result , dbg ) ;
return target ( ) - > NewRandomRWFile ( fname , file_opts , result , dbg ) ;
}
}
{
IOStatus in_s = InjectMetadataWriteError ( ) ;
if ( ! in_s . ok ( ) ) {
return in_s ;
}
}
IOStatus io_s = target ( ) - > NewRandomRWFile ( fname , file_opts , result , dbg ) ;
IOStatus io_s = target ( ) - > NewRandomRWFile ( fname , file_opts , result , dbg ) ;
if ( io_s . ok ( ) ) {
if ( io_s . ok ( ) ) {
result - > reset ( new TestFSRandomRWFile ( fname , std : : move ( * result ) , this ) ) ;
result - > reset ( new TestFSRandomRWFile ( fname , std : : move ( * result ) , this ) ) ;
// WritableFileWriter* file is opened
// WritableFileWriter* file is opened
// again then it will be truncated - so forget our saved state.
// again then it will be truncated - so forget our saved state.
UntrackFile ( fname ) ;
UntrackFile ( fname ) ;
MutexLock l ( & mutex_ ) ;
{
open_files_ . insert ( fname ) ;
MutexLock l ( & mutex_ ) ;
auto dir_and_name = TestFSGetDirAndName ( fname ) ;
open_files_ . insert ( fname ) ;
auto & list = dir_to_new_files_since_last_sync_ [ dir_and_name . first ] ;
auto dir_and_name = TestFSGetDirAndName ( fname ) ;
list . insert ( dir_and_name . second ) ;
auto & list = dir_to_new_files_since_last_sync_ [ dir_and_name . first ] ;
list . insert ( dir_and_name . second ) ;
}
{
IOStatus in_s = InjectMetadataWriteError ( ) ;
if ( ! in_s . ok ( ) ) {
return in_s ;
}
}
}
}
return io_s ;
return io_s ;
}
}
@ -385,9 +450,21 @@ IOStatus FaultInjectionTestFS::DeleteFile(const std::string& f,
if ( ! IsFilesystemActive ( ) ) {
if ( ! IsFilesystemActive ( ) ) {
return GetError ( ) ;
return GetError ( ) ;
}
}
{
IOStatus in_s = InjectMetadataWriteError ( ) ;
if ( ! in_s . ok ( ) ) {
return in_s ;
}
}
IOStatus io_s = FileSystemWrapper : : DeleteFile ( f , options , dbg ) ;
IOStatus io_s = FileSystemWrapper : : DeleteFile ( f , options , dbg ) ;
if ( io_s . ok ( ) ) {
if ( io_s . ok ( ) ) {
UntrackFile ( f ) ;
UntrackFile ( f ) ;
{
IOStatus in_s = InjectMetadataWriteError ( ) ;
if ( ! in_s . ok ( ) ) {
return in_s ;
}
}
}
}
return io_s ;
return io_s ;
}
}
@ -399,21 +476,33 @@ IOStatus FaultInjectionTestFS::RenameFile(const std::string& s,
if ( ! IsFilesystemActive ( ) ) {
if ( ! IsFilesystemActive ( ) ) {
return GetError ( ) ;
return GetError ( ) ;
}
}
{
IOStatus in_s = InjectMetadataWriteError ( ) ;
if ( ! in_s . ok ( ) ) {
return in_s ;
}
}
IOStatus io_s = FileSystemWrapper : : RenameFile ( s , t , options , dbg ) ;
IOStatus io_s = FileSystemWrapper : : RenameFile ( s , t , options , dbg ) ;
if ( io_s . ok ( ) ) {
if ( io_s . ok ( ) ) {
MutexLock l ( & mutex_ ) ;
{
if ( db_file_state_ . find ( s ) ! = db_file_state_ . end ( ) ) {
MutexLock l ( & mutex_ ) ;
db_file_state_ [ t ] = db_file_state_ [ s ] ;
if ( db_file_state_ . find ( s ) ! = db_file_state_ . end ( ) ) {
db_file_state_ . erase ( s ) ;
db_file_state_ [ t ] = db_file_state_ [ s ] ;
}
db_file_state_ . erase ( s ) ;
}
auto sdn = TestFSGetDirAndName ( s ) ;
auto sdn = TestFSGetDirAndName ( s ) ;
auto tdn = TestFSGetDirAndName ( t ) ;
auto tdn = TestFSGetDirAndName ( t ) ;
if ( dir_to_new_files_since_last_sync_ [ sdn . first ] . erase ( sdn . second ) ! = 0 ) {
if ( dir_to_new_files_since_last_sync_ [ sdn . first ] . erase ( sdn . second ) ! = 0 ) {
auto & tlist = dir_to_new_files_since_last_sync_ [ tdn . first ] ;
auto & tlist = dir_to_new_files_since_last_sync_ [ tdn . first ] ;
assert ( tlist . find ( tdn . second ) = = tlist . end ( ) ) ;
assert ( tlist . find ( tdn . second ) = = tlist . end ( ) ) ;
tlist . insert ( tdn . second ) ;
tlist . insert ( tdn . second ) ;
}
}
IOStatus in_s = InjectMetadataWriteError ( ) ;
if ( ! in_s . ok ( ) ) {
return in_s ;
}
}
}
}
@ -618,6 +707,16 @@ IOStatus FaultInjectionTestFS::InjectWriteError(const std::string& file_name) {
return IOStatus : : OK ( ) ;
return IOStatus : : OK ( ) ;
}
}
IOStatus FaultInjectionTestFS : : InjectMetadataWriteError ( ) {
MutexLock l ( & mutex_ ) ;
if ( ! enable_metadata_write_error_injection_ | |
! metadata_write_error_one_in_ | |
! write_error_rand_ . OneIn ( metadata_write_error_one_in_ ) ) {
return IOStatus : : OK ( ) ;
}
return IOStatus : : IOError ( ) ;
}
void FaultInjectionTestFS : : PrintFaultBacktrace ( ) {
void FaultInjectionTestFS : : PrintFaultBacktrace ( ) {
# if defined(OS_LINUX)
# if defined(OS_LINUX)
ErrorContext * ctx =
ErrorContext * ctx =