| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283 |
- // Copyright (c) 2019-present, Facebook, Inc. All rights reserved.
- // This source code is licensed under both the GPLv2 (found in the
- // COPYING file in the root directory) and Apache 2.0 License
- // (found in the LICENSE.Apache file in the root directory).
- //
- #include "rocksdb/file_system.h"
- #include "env/composite_env_wrapper.h"
- #include "env/env_chroot.h"
- #include "env/env_encryption_ctr.h"
- #include "env/fs_readonly.h"
- #include "env/mock_env.h"
- #include "logging/env_logger.h"
- #include "options/db_options.h"
- #include "rocksdb/convenience.h"
- #include "rocksdb/utilities/customizable_util.h"
- #include "rocksdb/utilities/object_registry.h"
- #include "rocksdb/utilities/options_type.h"
- #include "util/string_util.h"
- #include "utilities/counted_fs.h"
- #include "utilities/env_timed.h"
- namespace ROCKSDB_NAMESPACE {
- FileSystem::FileSystem() = default;
- FileSystem::~FileSystem() = default;
- static int RegisterBuiltinFileSystems(ObjectLibrary& library,
- const std::string& /*arg*/) {
- library.AddFactory<FileSystem>(
- TimedFileSystem::kClassName(),
- [](const std::string& /*uri*/, std::unique_ptr<FileSystem>* guard,
- std::string* /* errmsg */) {
- guard->reset(new TimedFileSystem(nullptr));
- return guard->get();
- });
- library.AddFactory<FileSystem>(
- ReadOnlyFileSystem::kClassName(),
- [](const std::string& /*uri*/, std::unique_ptr<FileSystem>* guard,
- std::string* /* errmsg */) {
- guard->reset(new ReadOnlyFileSystem(nullptr));
- return guard->get();
- });
- library.AddFactory<FileSystem>(
- EncryptedFileSystem::kClassName(),
- [](const std::string& /*uri*/, std::unique_ptr<FileSystem>* guard,
- std::string* errmsg) {
- Status s = NewEncryptedFileSystemImpl(nullptr, nullptr, guard);
- if (!s.ok()) {
- *errmsg = s.ToString();
- }
- return guard->get();
- });
- library.AddFactory<FileSystem>(
- CountedFileSystem::kClassName(),
- [](const std::string& /*uri*/, std::unique_ptr<FileSystem>* guard,
- std::string* /*errmsg*/) {
- guard->reset(new CountedFileSystem(FileSystem::Default()));
- return guard->get();
- });
- library.AddFactory<FileSystem>(
- MockFileSystem::kClassName(),
- [](const std::string& /*uri*/, std::unique_ptr<FileSystem>* guard,
- std::string* /*errmsg*/) {
- guard->reset(new MockFileSystem(SystemClock::Default()));
- return guard->get();
- });
- #ifndef OS_WIN
- library.AddFactory<FileSystem>(
- ChrootFileSystem::kClassName(),
- [](const std::string& /*uri*/, std::unique_ptr<FileSystem>* guard,
- std::string* /* errmsg */) {
- guard->reset(new ChrootFileSystem(nullptr, ""));
- return guard->get();
- });
- #endif // OS_WIN
- size_t num_types;
- return static_cast<int>(library.GetFactoryCount(&num_types));
- }
- Status FileSystem::CreateFromString(const ConfigOptions& config_options,
- const std::string& value,
- std::shared_ptr<FileSystem>* result) {
- auto default_fs = FileSystem::Default();
- if (default_fs->IsInstanceOf(value)) {
- *result = default_fs;
- return Status::OK();
- } else {
- static std::once_flag once;
- std::call_once(once, [&]() {
- RegisterBuiltinFileSystems(*(ObjectLibrary::Default().get()), "");
- });
- return LoadSharedObject<FileSystem>(config_options, value, result);
- }
- }
- IOStatus FileSystem::ReuseWritableFile(const std::string& fname,
- const std::string& old_fname,
- const FileOptions& opts,
- std::unique_ptr<FSWritableFile>* result,
- IODebugContext* dbg) {
- IOStatus s = RenameFile(old_fname, fname, opts.io_options, dbg);
- if (!s.ok()) {
- return s;
- }
- return NewWritableFile(fname, opts, result, dbg);
- }
- IOStatus FileSystem::NewLogger(const std::string& fname,
- const IOOptions& io_opts,
- std::shared_ptr<Logger>* result,
- IODebugContext* dbg) {
- FileOptions options;
- options.io_options = io_opts;
- // TODO: Tune the buffer size.
- options.writable_file_max_buffer_size = 1024 * 1024;
- std::unique_ptr<FSWritableFile> writable_file;
- const IOStatus status = NewWritableFile(fname, options, &writable_file, dbg);
- if (!status.ok()) {
- return status;
- }
- *result = std::make_shared<EnvLogger>(std::move(writable_file), fname,
- options, Env::Default());
- return IOStatus::OK();
- }
- FileOptions FileSystem::OptimizeForLogRead(
- const FileOptions& file_options) const {
- FileOptions optimized_file_options(file_options);
- optimized_file_options.use_direct_reads = false;
- return optimized_file_options;
- }
- FileOptions FileSystem::OptimizeForManifestRead(
- const FileOptions& file_options) const {
- FileOptions optimized_file_options(file_options);
- optimized_file_options.use_direct_reads = false;
- return optimized_file_options;
- }
- FileOptions FileSystem::OptimizeForLogWrite(const FileOptions& file_options,
- const DBOptions& db_options) const {
- FileOptions optimized_file_options(file_options);
- optimized_file_options.bytes_per_sync = db_options.wal_bytes_per_sync;
- optimized_file_options.writable_file_max_buffer_size =
- db_options.writable_file_max_buffer_size;
- return optimized_file_options;
- }
- FileOptions FileSystem::OptimizeForManifestWrite(
- const FileOptions& file_options) const {
- return file_options;
- }
- FileOptions FileSystem::OptimizeForCompactionTableWrite(
- const FileOptions& file_options,
- const ImmutableDBOptions& db_options) const {
- FileOptions optimized_file_options(file_options);
- optimized_file_options.use_direct_writes =
- db_options.use_direct_io_for_flush_and_compaction;
- return optimized_file_options;
- }
- FileOptions FileSystem::OptimizeForCompactionTableRead(
- const FileOptions& file_options,
- const ImmutableDBOptions& db_options) const {
- FileOptions optimized_file_options(file_options);
- optimized_file_options.use_direct_reads = db_options.use_direct_reads;
- return optimized_file_options;
- }
- FileOptions FileSystem::OptimizeForBlobFileRead(
- const FileOptions& file_options,
- const ImmutableDBOptions& db_options) const {
- FileOptions optimized_file_options(file_options);
- optimized_file_options.use_direct_reads = db_options.use_direct_reads;
- return optimized_file_options;
- }
- IOStatus WriteStringToFile(FileSystem* fs, const Slice& data,
- const std::string& fname, bool should_sync,
- const IOOptions& io_options,
- const FileOptions& file_options) {
- std::unique_ptr<FSWritableFile> file;
- IOStatus s = fs->NewWritableFile(fname, file_options, &file, nullptr);
- if (!s.ok()) {
- return s;
- }
- s = file->Append(data, io_options, nullptr);
- if (s.ok() && should_sync) {
- s = file->Sync(io_options, nullptr);
- }
- if (!s.ok()) {
- fs->DeleteFile(fname, io_options, nullptr);
- }
- return s;
- }
- IOStatus ReadFileToString(FileSystem* fs, const std::string& fname,
- std::string* data) {
- return ReadFileToString(fs, fname, IOOptions(), data);
- }
- IOStatus ReadFileToString(FileSystem* fs, const std::string& fname,
- const IOOptions& opts, std::string* data) {
- FileOptions soptions;
- data->clear();
- std::unique_ptr<FSSequentialFile> file;
- IOStatus s = status_to_io_status(
- fs->NewSequentialFile(fname, soptions, &file, nullptr));
- if (!s.ok()) {
- return s;
- }
- static const int kBufferSize = 8192;
- char* space = new char[kBufferSize];
- while (true) {
- Slice fragment;
- s = file->Read(kBufferSize, opts, &fragment, space, nullptr);
- if (!s.ok()) {
- break;
- }
- data->append(fragment.data(), fragment.size());
- if (fragment.empty()) {
- break;
- }
- }
- delete[] space;
- return s;
- }
- namespace {
- static std::unordered_map<std::string, OptionTypeInfo> fs_wrapper_type_info = {
- {"target",
- OptionTypeInfo::AsCustomSharedPtr<FileSystem>(
- 0, OptionVerificationType::kByName, OptionTypeFlags::kDontSerialize)},
- };
- } // namespace
- FileSystemWrapper::FileSystemWrapper(const std::shared_ptr<FileSystem>& t)
- : target_(t) {
- RegisterOptions("", &target_, &fs_wrapper_type_info);
- }
- Status FileSystemWrapper::PrepareOptions(const ConfigOptions& options) {
- if (target_ == nullptr) {
- target_ = FileSystem::Default();
- }
- return FileSystem::PrepareOptions(options);
- }
- std::string FileSystemWrapper::SerializeOptions(
- const ConfigOptions& config_options, const std::string& header) const {
- auto parent = FileSystem::SerializeOptions(config_options, "");
- if (config_options.IsShallow() || target_ == nullptr ||
- target_->IsInstanceOf(FileSystem::kDefaultName())) {
- return parent;
- } else {
- std::string result = header;
- if (!StartsWith(parent, OptionTypeInfo::kIdPropName())) {
- result.append(OptionTypeInfo::kIdPropName()).append("=");
- }
- result.append(parent);
- if (!EndsWith(result, config_options.delimiter)) {
- result.append(config_options.delimiter);
- }
- result.append("target=").append(target_->ToString(config_options));
- return result;
- }
- }
- DirFsyncOptions::DirFsyncOptions() { reason = kDefault; }
- DirFsyncOptions::DirFsyncOptions(std::string file_renamed_new_name) {
- reason = kFileRenamed;
- renamed_new_name = file_renamed_new_name;
- }
- DirFsyncOptions::DirFsyncOptions(FsyncReason fsync_reason) {
- assert(fsync_reason != kFileRenamed);
- reason = fsync_reason;
- }
- } // namespace ROCKSDB_NAMESPACE
|