return dir_->Fsync();
}
+Status TestDirectory::Close() {
+ if (!env_->IsFilesystemActive()) {
+ return env_->GetError();
+ }
+ return dir_->Close();
+}
+
TestRandomAccessFile::TestRandomAccessFile(
std::unique_ptr<RandomAccessFile>&& target, FaultInjectionTestEnv* env)
: target_(std::move(target)), env_(env) {
TestWritableFile::~TestWritableFile() {
if (writable_file_opened_) {
- Close();
+ Close().PermitUncheckedError();
}
}
TestRandomRWFile::~TestRandomRWFile() {
if (file_opened_) {
- Close();
+ Close().PermitUncheckedError();
}
}
// again then it will be truncated - so forget our saved state.
UntrackFile(fname);
MutexLock l(&mutex_);
- open_files_.insert(fname);
+ open_managed_files_.insert(fname);
auto dir_and_name = GetDirAndName(fname);
auto& list = dir_to_new_files_since_last_sync_[dir_and_name.first];
list.insert(dir_and_name.second);
if (!IsFilesystemActive()) {
return GetError();
}
- Status s = target()->ReopenWritableFile(fname, result, soptions);
+
+ bool exists;
+ Status s, exists_s = target()->FileExists(fname);
+ if (exists_s.IsNotFound()) {
+ exists = false;
+ } else if (exists_s.ok()) {
+ exists = true;
+ } else {
+ s = exists_s;
+ exists = false;
+ }
+
if (s.ok()) {
- result->reset(new TestWritableFile(fname, std::move(*result), this));
- // WritableFileWriter* file is opened
- // again then it will be truncated - so forget our saved state.
- UntrackFile(fname);
- MutexLock l(&mutex_);
- open_files_.insert(fname);
- auto dir_and_name = GetDirAndName(fname);
- auto& list = dir_to_new_files_since_last_sync_[dir_and_name.first];
- list.insert(dir_and_name.second);
+ s = target()->ReopenWritableFile(fname, result, soptions);
+ }
+
+ // Only track files we created. Files created outside of this
+ // `FaultInjectionTestEnv` are not eligible for tracking/data dropping
+ // (for example, they may contain data a previous db_stress run expects to
+ // be recovered). This could be extended to track/drop data appended once
+ // the file is under `FaultInjectionTestEnv`'s control.
+ if (s.ok()) {
+ bool should_track;
+ {
+ MutexLock l(&mutex_);
+ if (db_file_state_.find(fname) != db_file_state_.end()) {
+ // It was written by this `Env` earlier.
+ assert(exists);
+ should_track = true;
+ } else if (!exists) {
+ // It was created by this `Env` just now.
+ should_track = true;
+ open_managed_files_.insert(fname);
+ auto dir_and_name = GetDirAndName(fname);
+ auto& list = dir_to_new_files_since_last_sync_[dir_and_name.first];
+ list.insert(dir_and_name.second);
+ } else {
+ should_track = false;
+ }
+ }
+ if (should_track) {
+ result->reset(new TestWritableFile(fname, std::move(*result), this));
+ }
}
return s;
}
// again then it will be truncated - so forget our saved state.
UntrackFile(fname);
MutexLock l(&mutex_);
- open_files_.insert(fname);
+ open_managed_files_.insert(fname);
auto dir_and_name = GetDirAndName(fname);
auto& list = dir_to_new_files_since_last_sync_[dir_and_name.first];
list.insert(dir_and_name.second);
return ret;
}
+Status FaultInjectionTestEnv::LinkFile(const std::string& s,
+ const std::string& t) {
+ if (!IsFilesystemActive()) {
+ return GetError();
+ }
+ Status ret = EnvWrapper::LinkFile(s, t);
+
+ if (ret.ok()) {
+ MutexLock l(&mutex_);
+ if (db_file_state_.find(s) != db_file_state_.end()) {
+ db_file_state_[t] = db_file_state_[s];
+ }
+
+ auto sdn = GetDirAndName(s);
+ auto tdn = GetDirAndName(t);
+ if (dir_to_new_files_since_last_sync_[sdn.first].find(sdn.second) !=
+ dir_to_new_files_since_last_sync_[sdn.first].end()) {
+ auto& tlist = dir_to_new_files_since_last_sync_[tdn.first];
+ assert(tlist.find(tdn.second) == tlist.end());
+ tlist.insert(tdn.second);
+ }
+ }
+
+ return ret;
+}
+
void FaultInjectionTestEnv::WritableFileClosed(const FileState& state) {
MutexLock l(&mutex_);
- if (open_files_.find(state.filename_) != open_files_.end()) {
+ if (open_managed_files_.find(state.filename_) != open_managed_files_.end()) {
db_file_state_[state.filename_] = state;
- open_files_.erase(state.filename_);
+ open_managed_files_.erase(state.filename_);
}
}
void FaultInjectionTestEnv::WritableFileSynced(const FileState& state) {
MutexLock l(&mutex_);
- if (open_files_.find(state.filename_) != open_files_.end()) {
+ if (open_managed_files_.find(state.filename_) != open_managed_files_.end()) {
if (db_file_state_.find(state.filename_) == db_file_state_.end()) {
db_file_state_.insert(std::make_pair(state.filename_, state));
} else {
void FaultInjectionTestEnv::WritableFileAppended(const FileState& state) {
MutexLock l(&mutex_);
- if (open_files_.find(state.filename_) != open_files_.end()) {
+ if (open_managed_files_.find(state.filename_) != open_managed_files_.end()) {
if (db_file_state_.find(state.filename_) == db_file_state_.end()) {
db_file_state_.insert(std::make_pair(state.filename_, state));
} else {
dir_to_new_files_since_last_sync_[dir_and_name.first].erase(
dir_and_name.second);
db_file_state_.erase(f);
- open_files_.erase(f);
+ open_managed_files_.erase(f);
}
} // namespace ROCKSDB_NAMESPACE