Skip to content

Commit

Permalink
Handle "NotSupported" status by default implementation of Close() in … (
Browse files Browse the repository at this point in the history
#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: #10127

Reviewed By: ajkr

Differential Revision: D36971112

Pulled By: littlepig2013

fbshipit-source-id: 100f0e6ad1191e1acc1ba6458c566a11724cf466
  • Loading branch information
zczhu authored and facebook-github-bot committed Jun 7, 2022
1 parent 3ee6c9b commit b6de139
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 8 deletions.
2 changes: 0 additions & 2 deletions db/column_family.cc
Original file line number Diff line number Diff line change
Expand Up @@ -683,8 +683,6 @@ ColumnFamilyData::~ColumnFamilyData() {
s = data_dir_ptr->Close(IOOptions(), nullptr);
if (!s.ok()) {
// TODO(zichen): add `Status Close()` and `CloseDirectories()
ROCKS_LOG_WARN(ioptions_.logger, "Ignoring error %s",
s.ToString().c_str());
s.PermitUncheckedError();
}
}
Expand Down
12 changes: 11 additions & 1 deletion db/db_impl/db_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4408,7 +4408,17 @@ Status DBImpl::RenameTempFileToOptionsFile(const std::string& file_name) {
DirFsyncOptions(options_file_name));
}
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()) {
Expand Down
37 changes: 33 additions & 4 deletions db/db_impl/db_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -116,8 +116,23 @@ class Directories {
IOStatus Close(const IOOptions& options, IODebugContext* dbg) {
// close all directories for all database paths
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_) {
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()) {
Expand All @@ -126,6 +141,13 @@ class Directories {

if (wal_dir_) {
s = wal_dir_->Close(options, dbg);
if (!temp_s.ok()) {
if (temp_s.IsNotSupported()) {
temp_s.PermitUncheckedError();
} else {
s = temp_s;
}
}
}

if (!s.ok()) {
Expand All @@ -135,14 +157,21 @@ class Directories {
if (data_dirs_.size() > 0 && s.ok()) {
for (auto& data_dir_ptr : data_dirs_) {
if (data_dir_ptr) {
s = data_dir_ptr->Close(options, dbg);
if (!s.ok()) {
return s;
temp_s = data_dir_ptr->Close(options, dbg);
if (!temp_s.ok()) {
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;
}

Expand Down
13 changes: 12 additions & 1 deletion file/filename.cc
Original file line number Diff line number Diff line change
Expand Up @@ -443,8 +443,19 @@ Status SetIdentityFile(Env* env, const std::string& dbname,
s = dir_obj->FsyncWithDirOptions(IOOptions(), nullptr,
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()) {
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()) {
env->DeleteFile(tmp).PermitUncheckedError();
Expand Down

0 comments on commit b6de139

Please sign in to comment.