Skip to content

Commit

Permalink
Add PathNotFound subcode to IOError
Browse files Browse the repository at this point in the history
Summary: As titled. Returning error about non-existing path can help user
better handle them.

Test Plan:
```
$make clean && make -j32 all check
```

Reviewers:

Subscribers:

Tasks:

Tags:
  • Loading branch information
riversand963 committed Jan 8, 2019
1 parent cd227d7 commit 6034b95
Show file tree
Hide file tree
Showing 6 changed files with 32 additions and 9 deletions.
1 change: 1 addition & 0 deletions HISTORY.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
* Enabled checkpoint on readonly db (DBImplReadOnly).
* Make DB ignore dropped column families while committing results of atomic flush.
* RocksDB may choose to preopen some files even if options.max_open_files != -1. This may make DB open slightly longer.
* Introduce a new IOError subcode, PathNotFound, to indicate trying to open a nonexistent file or directory for read.

### Public API Change
* Transaction::GetForUpdate is extended with a do_validate parameter with default value of true. If false it skips validating the snapshot before doing the read. Similarly ::Merge, ::Put, ::Delete, and ::SingleDelete are extended with assume_tracked with default value of false. If true it indicates that call is assumed to be after a ::GetForUpdate.
Expand Down
8 changes: 5 additions & 3 deletions env/env_hdfs.cc
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,11 @@ namespace {

// Log error message
static Status IOError(const std::string& context, int err_number) {
return (err_number == ENOSPC) ?
Status::NoSpace(context, strerror(err_number)) :
Status::IOError(context, strerror(err_number));
return (err_number == ENOSPC)
? Status::NoSpace(context, strerror(err_number))
: (err_number == ENOENT)
? Status::PathNotFound(context, strerror(err_number))
: Status::IOError(context, strerror(err_number));
}

// assume that there is one global logger for now. It is not thread-safe,
Expand Down
3 changes: 3 additions & 0 deletions env/io_posix.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ static Status IOError(const std::string& context, const std::string& file_name,
strerror(err_number));
case ESTALE:
return Status::IOError(Status::kStaleFile);
case ENOENT:
return Status::PathNotFound(IOErrorMsg(context, file_name),
strerror(err_number));
default:
return Status::IOError(IOErrorMsg(context, file_name),
strerror(err_number));
Expand Down
14 changes: 14 additions & 0 deletions include/rocksdb/status.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ class Status {
kStaleFile = 6,
kMemoryLimit = 7,
kSpaceLimit = 8,
kPathNotFound = 9,
kMaxSubCode
};

Expand Down Expand Up @@ -198,6 +199,11 @@ class Status {
return Status(kIOError, kSpaceLimit, msg, msg2);
}

static Status PathNotFound() { return Status(kIOError, kPathNotFound); }
static Status PathNotFound(const Slice& msg, const Slice& msg2 = Slice()) {
return Status(kIOError, kPathNotFound, msg, msg2);
}

// Returns true iff the status indicates success.
bool ok() const { return code() == kOk; }

Expand Down Expand Up @@ -266,6 +272,14 @@ class Status {
return (code() == kAborted) && (subcode() == kMemoryLimit);
}

// Returns true iff the status indicates a PathNotFound error
// This is caused by an I/O error returning the specific "no such file or
// directory" error condition. A PathNotFound error is an I/O error with
// a specific subcode, enabling users to take appropriate action if necessary
bool IsPathNotFound() const {
return (code() == kIOError) && (subcode() == kPathNotFound);
}

// Return a string representation of this status suitable for printing.
// Returns the string "OK" for success.
std::string ToString() const;
Expand Down
12 changes: 7 additions & 5 deletions port/win/io_win.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@ std::string GetWindowsErrSz(DWORD err);
inline Status IOErrorFromWindowsError(const std::string& context, DWORD err) {
return ((err == ERROR_HANDLE_DISK_FULL) || (err == ERROR_DISK_FULL))
? Status::NoSpace(context, GetWindowsErrSz(err))
: Status::IOError(context, GetWindowsErrSz(err));
: ((err == ERROR_FILE_NOT_FOUND) || (err == ERROR_PATH_NOT_FOUND))
? Status::PathNotFound(context, GetWindowsErrSz(err))
: Status::IOError(context, GetWindowsErrSz(err));
}

inline Status IOErrorFromLastWindowsError(const std::string& context) {
Expand All @@ -37,7 +39,9 @@ inline Status IOErrorFromLastWindowsError(const std::string& context) {
inline Status IOError(const std::string& context, int err_number) {
return (err_number == ENOSPC)
? Status::NoSpace(context, strerror(err_number))
: Status::IOError(context, strerror(err_number));
: (err_number == ENOENT)
? Status::PathNotFound(context, strerror(err_number))
: Status::IOError(context, strerror(err_number));
}

class WinFileData;
Expand Down Expand Up @@ -426,9 +430,7 @@ class WinMemoryMappedBuffer : public MemoryMappedFileBuffer {
class WinDirectory : public Directory {
HANDLE handle_;
public:
explicit
WinDirectory(HANDLE h) noexcept :
handle_(h) {
explicit WinDirectory(HANDLE h) noexcept : handle_(h) {
assert(handle_ != INVALID_HANDLE_VALUE);
}
~WinDirectory() {
Expand Down
3 changes: 2 additions & 1 deletion util/status.cc
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ static const char* msgs[static_cast<int>(Status::kMaxSubCode)] = {
"Deadlock", // kDeadlock
"Stale file handle", // kStaleFile
"Memory limit reached", // kMemoryLimit
"Space limit reached" // kSpaceLimit
"Space limit reached", // kSpaceLimit
"No such file or directory", // kPathNotFound
};

Status::Status(Code _code, SubCode _subcode, const Slice& msg,
Expand Down

0 comments on commit 6034b95

Please sign in to comment.