diff --git a/env/composite_env_wrapper.h b/env/composite_env_wrapper.h index 43f6ecdc5f..0c3f73977a 100644 --- a/env/composite_env_wrapper.h +++ b/env/composite_env_wrapper.h @@ -492,6 +492,12 @@ class CompositeEnvWrapper : public Env { return file_system_->NewLogger(fname, io_opts, result, &dbg); } + Status IsDirectory(const std::string& path, bool* is_dir) override { + IOOptions io_opts; + IODebugContext dbg; + return file_system_->IsDirectory(path, io_opts, is_dir, &dbg); + } + #if !defined(OS_WIN) && !defined(ROCKSDB_NO_DYNAMIC_EXTENSION) Status LoadLibrary(const std::string& lib_name, const std::string& search_path, @@ -1081,6 +1087,10 @@ class LegacyFileSystemWrapper : public FileSystem { uint64_t* diskfree, IODebugContext* /*dbg*/) override { return status_to_io_status(target_->GetFreeSpace(path, diskfree)); } + IOStatus IsDirectory(const std::string& path, const IOOptions& /*options*/, + bool* is_dir, IODebugContext* /*dbg*/) override { + return status_to_io_status(target_->IsDirectory(path, is_dir)); + } private: Env* target_; diff --git a/env/fs_posix.cc b/env/fs_posix.cc index f64a677536..92808eaa29 100644 --- a/env/fs_posix.cc +++ b/env/fs_posix.cc @@ -877,6 +877,28 @@ class PosixFileSystem : public FileSystem { return IOStatus::OK(); } + IOStatus IsDirectory(const std::string& path, const IOOptions& /*opts*/, + bool* is_dir, IODebugContext* /*dbg*/) override { + // First open + int fd = -1; + int flags = cloexec_flags(O_RDONLY, nullptr); + { + IOSTATS_TIMER_GUARD(open_nanos); + fd = open(path.c_str(), flags); + } + if (fd < 0) { + return IOError("While open for IsDirectory()", path, errno); + } + struct stat sbuf; + if (fstat(fd, &sbuf) < 0) { + return IOError("While doing stat for IsDirectory()", path, errno); + } + if (nullptr != is_dir) { + *is_dir = S_ISDIR(sbuf.st_mode); + } + return IOStatus::OK(); + } + FileOptions OptimizeForLogWrite(const FileOptions& file_options, const DBOptions& db_options) const override { FileOptions optimized = file_options;