From 4c1d7d83d0f780f735cb9111cf2b090c3aee4b57 Mon Sep 17 00:00:00 2001 From: Yanqin Jin Date: Fri, 17 Apr 2020 14:36:51 -0700 Subject: [PATCH] Add IsDirectory() to Env and FS (#6711) Summary: IsDirectory() is a common API to check whether a path is a regular file or directory. POSIX: call stat() and use S_ISDIR(st_mode) Windows: PathIsDirectoryA() and PathIsDirectoryW() HDFS: FileSystem.IsDirectory() Java: File.IsDirectory() ... Pull Request resolved: https://github.com/facebook/rocksdb/pull/6711 Test Plan: make check Reviewed By: anand1976 Differential Revision: D21053520 Pulled By: riversand963 fbshipit-source-id: 680aadfd8ce982b63689190cf31b3145d5a89e27 Signed-off-by: Changlong Chen --- env/composite_env_wrapper.h | 10 ++++++++++ env/fs_posix.cc | 22 ++++++++++++++++++++++ 2 files changed, 32 insertions(+) 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;