Handle "NotSupported" status by default implementation of Close() in … (#10127)

Summary:
The default implementation of Close() function in Directory/FSDirectory classes returns `NotSupported` status. However, we don't want operations that worked in older versions to begin failing after upgrading when run on FileSystems that have not implemented Directory::Close() yet. So we require the upper level that calls Close() function should properly handle "NotSupported" status instead of treating it as an error status.

Pull Request resolved: https://github.com/facebook/rocksdb/pull/10127

Reviewed By: ajkr

Differential Revision: D36971112

Pulled By: littlepig2013

fbshipit-source-id: 100f0e6ad1191e1acc1ba6458c566a11724cf466
main
zczhu 3 years ago committed by Facebook GitHub Bot
parent 3ee6c9baec
commit b6de139df5
  1. 2
      db/column_family.cc
  2. 12
      db/db_impl/db_impl.cc
  3. 37
      db/db_impl/db_impl.h
  4. 13
      file/filename.cc

@ -683,8 +683,6 @@ ColumnFamilyData::~ColumnFamilyData() {
s = data_dir_ptr->Close(IOOptions(), nullptr); s = data_dir_ptr->Close(IOOptions(), nullptr);
if (!s.ok()) { if (!s.ok()) {
// TODO(zichen): add `Status Close()` and `CloseDirectories() // TODO(zichen): add `Status Close()` and `CloseDirectories()
ROCKS_LOG_WARN(ioptions_.logger, "Ignoring error %s",
s.ToString().c_str());
s.PermitUncheckedError(); s.PermitUncheckedError();
} }
} }

@ -4408,7 +4408,17 @@ Status DBImpl::RenameTempFileToOptionsFile(const std::string& file_name) {
DirFsyncOptions(options_file_name)); DirFsyncOptions(options_file_name));
} }
if (s.ok()) { if (s.ok()) {
s = dir_obj->Close(IOOptions(), nullptr); Status temp_s = dir_obj->Close(IOOptions(), nullptr);
// The default Close() could return "NotSupproted" and we bypass it
// if it is not impelmented. Detailed explanations can be found in
// db/db_impl/db_impl.h
if (!temp_s.ok()) {
if (temp_s.IsNotSupported()) {
temp_s.PermitUncheckedError();
} else {
s = temp_s;
}
}
} }
} }
if (s.ok()) { if (s.ok()) {

@ -116,8 +116,23 @@ class Directories {
IOStatus Close(const IOOptions& options, IODebugContext* dbg) { IOStatus Close(const IOOptions& options, IODebugContext* dbg) {
// close all directories for all database paths // close all directories for all database paths
IOStatus s = IOStatus::OK(); IOStatus s = IOStatus::OK();
IOStatus temp_s = IOStatus::OK();
// The default implementation for Close() in Directory/FSDirectory class
// "NotSupported" status, the upper level interface should be able to
// handle this error so that Close() does not fail after upgrading when
// run on FileSystems that have not implemented `Directory::Close()` or
// `FSDirectory::Close()` yet
if (db_dir_) { if (db_dir_) {
s = db_dir_->Close(options, dbg); temp_s = db_dir_->Close(options, dbg);
if (!temp_s.ok()) {
if (temp_s.IsNotSupported()) {
temp_s.PermitUncheckedError();
} else {
s = temp_s;
}
}
} }
if (!s.ok()) { if (!s.ok()) {
@ -126,6 +141,13 @@ class Directories {
if (wal_dir_) { if (wal_dir_) {
s = wal_dir_->Close(options, dbg); s = wal_dir_->Close(options, dbg);
if (!temp_s.ok()) {
if (temp_s.IsNotSupported()) {
temp_s.PermitUncheckedError();
} else {
s = temp_s;
}
}
} }
if (!s.ok()) { if (!s.ok()) {
@ -135,14 +157,21 @@ class Directories {
if (data_dirs_.size() > 0 && s.ok()) { if (data_dirs_.size() > 0 && s.ok()) {
for (auto& data_dir_ptr : data_dirs_) { for (auto& data_dir_ptr : data_dirs_) {
if (data_dir_ptr) { if (data_dir_ptr) {
s = data_dir_ptr->Close(options, dbg); temp_s = data_dir_ptr->Close(options, dbg);
if (!s.ok()) { if (!temp_s.ok()) {
return s; if (temp_s.IsNotSupported()) {
temp_s.PermitUncheckedError();
} else {
return temp_s;
}
} }
} }
} }
} }
// Mark temp_s as checked when temp_s is still the initial status
// (IOStatus::OK(), not checked yet)
temp_s.PermitUncheckedError();
return s; return s;
} }

@ -443,8 +443,19 @@ Status SetIdentityFile(Env* env, const std::string& dbname,
s = dir_obj->FsyncWithDirOptions(IOOptions(), nullptr, s = dir_obj->FsyncWithDirOptions(IOOptions(), nullptr,
DirFsyncOptions(identify_file_name)); DirFsyncOptions(identify_file_name));
} }
// The default Close() could return "NotSupported" and we bypass it
// if it is not impelmented. Detailed explanations can be found in
// db/db_impl/db_impl.h
if (s.ok()) { if (s.ok()) {
s = dir_obj->Close(IOOptions(), nullptr); Status temp_s = dir_obj->Close(IOOptions(), nullptr);
if (!temp_s.ok()) {
if (temp_s.IsNotSupported()) {
temp_s.PermitUncheckedError();
} else {
s = temp_s;
}
}
} }
if (!s.ok()) { if (!s.ok()) {
env->DeleteFile(tmp).PermitUncheckedError(); env->DeleteFile(tmp).PermitUncheckedError();

Loading…
Cancel
Save