]> git.proxmox.com Git - ceph.git/blame - ceph/src/rocksdb/include/rocksdb/file_system.h
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / rocksdb / include / rocksdb / file_system.h
CommitLineData
f67539c2
TL
1// Copyright (c) 2019-present, Facebook, Inc. All rights reserved.
2// This source code is licensed under both the GPLv2 (found in the
3// COPYING file in the root directory) and Apache 2.0 License
4// (found in the LICENSE.Apache file in the root directory).
5//
6// A FileSystem is an interface used by the rocksdb implementation to access
7// storage functionality like the filesystem etc. Callers
8// may wish to provide a custom FileSystem object when opening a database to
9// get fine gain control; e.g., to rate limit file system operations.
10//
11// All FileSystem implementations are safe for concurrent access from
12// multiple threads without any external synchronization.
13//
14// WARNING: Since this is a new interface, it is expected that there will be
15// some changes as storage systems are ported over.
16
17#pragma once
18
19#include <stdint.h>
1e59de90 20
f67539c2
TL
21#include <chrono>
22#include <cstdarg>
23#include <functional>
24#include <limits>
25#include <memory>
26#include <sstream>
27#include <string>
1e59de90 28#include <unordered_map>
f67539c2 29#include <vector>
1e59de90
TL
30
31#include "rocksdb/customizable.h"
f67539c2
TL
32#include "rocksdb/env.h"
33#include "rocksdb/io_status.h"
34#include "rocksdb/options.h"
1e59de90 35#include "rocksdb/table.h"
f67539c2
TL
36#include "rocksdb/thread_status.h"
37
38namespace ROCKSDB_NAMESPACE {
39
40class FileLock;
41class FSDirectory;
42class FSRandomAccessFile;
43class FSRandomRWFile;
44class FSSequentialFile;
45class FSWritableFile;
46class Logger;
47class Slice;
48struct ImmutableDBOptions;
49struct MutableDBOptions;
50class RateLimiter;
1e59de90 51struct ConfigOptions;
f67539c2
TL
52
53using AccessPattern = RandomAccessFile::AccessPattern;
54using FileAttributes = Env::FileAttributes;
55
1e59de90 56// DEPRECATED
f67539c2
TL
57// Priority of an IO request. This is a hint and does not guarantee any
58// particular QoS.
59// IO_LOW - Typically background reads/writes such as compaction/flush
60// IO_HIGH - Typically user reads/synchronous WAL writes
61enum class IOPriority : uint8_t {
62 kIOLow,
63 kIOHigh,
64 kIOTotal,
65};
66
67// Type of the data begin read/written. It can be passed down as a flag
68// for the FileSystem implementation to optionally handle different types in
69// different ways
70enum class IOType : uint8_t {
71 kData,
72 kFilter,
73 kIndex,
74 kMetadata,
75 kWAL,
76 kManifest,
77 kLog,
78 kUnknown,
79 kInvalid,
80};
81
82// Per-request options that can be passed down to the FileSystem
83// implementation. These are hints and are not necessarily guaranteed to be
84// honored. More hints can be added here in the future to indicate things like
85// storage media (HDD/SSD) to be used, replication level etc.
86struct IOOptions {
20effc67
TL
87 // Timeout for the operation in microseconds
88 std::chrono::microseconds timeout;
f67539c2 89
1e59de90 90 // DEPRECATED
f67539c2
TL
91 // Priority - high or low
92 IOPriority prio;
93
1e59de90
TL
94 // Priority used to charge rate limiter configured in file system level (if
95 // any)
96 // Limitation: right now RocksDB internal does not consider this
97 // rate_limiter_priority
98 Env::IOPriority rate_limiter_priority;
99
f67539c2
TL
100 // Type of data being read/written
101 IOType type;
20effc67 102
1e59de90
TL
103 // EXPERIMENTAL
104 // An option map that's opaque to RocksDB. It can be used to implement a
105 // custom contract between a FileSystem user and the provider. This is only
106 // useful in cases where a RocksDB user directly uses the FileSystem or file
107 // object for their own purposes, and wants to pass extra options to APIs
108 // such as NewRandomAccessFile and NewWritableFile.
109 std::unordered_map<std::string, std::string> property_bag;
110
111 // Force directory fsync, some file systems like btrfs may skip directory
112 // fsync, set this to force the fsync
113 bool force_dir_fsync;
114
115 // Can be used by underlying file systems to skip recursing through sub
116 // directories and list only files in GetChildren API.
117 bool do_not_recurse;
118
119 IOOptions() : IOOptions(false) {}
120
121 explicit IOOptions(bool force_dir_fsync_)
122 : timeout(std::chrono::microseconds::zero()),
123 prio(IOPriority::kIOLow),
124 rate_limiter_priority(Env::IO_TOTAL),
125 type(IOType::kUnknown),
126 force_dir_fsync(force_dir_fsync_),
127 do_not_recurse(false) {}
128};
129
130struct DirFsyncOptions {
131 enum FsyncReason : uint8_t {
132 kNewFileSynced,
133 kFileRenamed,
134 kDirRenamed,
135 kFileDeleted,
136 kDefault,
137 } reason;
138
139 std::string renamed_new_name; // for kFileRenamed
140 // add other options for other FsyncReason
141
142 DirFsyncOptions();
143
144 explicit DirFsyncOptions(std::string file_renamed_new_name);
145
146 explicit DirFsyncOptions(FsyncReason fsync_reason);
f67539c2
TL
147};
148
149// File scope options that control how a file is opened/created and accessed
150// while its open. We may add more options here in the future such as
151// redundancy level, media to use etc.
152struct FileOptions : EnvOptions {
153 // Embedded IOOptions to control the parameters for any IOs that need
154 // to be issued for the file open/creation
155 IOOptions io_options;
156
1e59de90
TL
157 // EXPERIMENTAL
158 // The feature is in development and is subject to change.
159 // When creating a new file, set the temperature of the file so that
160 // underlying file systems can put it with appropriate storage media and/or
161 // coding.
162 Temperature temperature = Temperature::kUnknown;
163
164 // The checksum type that is used to calculate the checksum value for
165 // handoff during file writes.
166 ChecksumType handoff_checksum_type;
167
168 FileOptions() : EnvOptions(), handoff_checksum_type(ChecksumType::kCRC32c) {}
f67539c2
TL
169
170 FileOptions(const DBOptions& opts)
1e59de90 171 : EnvOptions(opts), handoff_checksum_type(ChecksumType::kCRC32c) {}
f67539c2
TL
172
173 FileOptions(const EnvOptions& opts)
1e59de90 174 : EnvOptions(opts), handoff_checksum_type(ChecksumType::kCRC32c) {}
20effc67
TL
175
176 FileOptions(const FileOptions& opts)
1e59de90
TL
177 : EnvOptions(opts),
178 io_options(opts.io_options),
179 temperature(opts.temperature),
180 handoff_checksum_type(opts.handoff_checksum_type) {}
20effc67 181
1e59de90 182 FileOptions& operator=(const FileOptions&) = default;
f67539c2
TL
183};
184
185// A structure to pass back some debugging information from the FileSystem
186// implementation to RocksDB in case of an IO error
187struct IODebugContext {
188 // file_path to be filled in by RocksDB in case of an error
189 std::string file_path;
190
191 // A map of counter names to values - set by the FileSystem implementation
192 std::map<std::string, uint64_t> counters;
193
194 // To be set by the FileSystem implementation
195 std::string msg;
196
1e59de90
TL
197 // To be set by the underlying FileSystem implementation.
198 std::string request_id;
199
200 // In order to log required information in IO tracing for different
201 // operations, Each bit in trace_data stores which corresponding info from
202 // IODebugContext will be added in the trace. Foreg, if trace_data = 1, it
203 // means bit at position 0 is set so TraceData::kRequestID (request_id) will
204 // be logged in the trace record.
205 //
206 enum TraceData : char {
207 // The value of each enum represents the bitwise position for
208 // that information in trace_data which will be used by IOTracer for
209 // tracing. Make sure to add them sequentially.
210 kRequestID = 0,
211 };
212 uint64_t trace_data = 0;
213
f67539c2
TL
214 IODebugContext() {}
215
216 void AddCounter(std::string& name, uint64_t value) {
217 counters.emplace(name, value);
218 }
219
1e59de90
TL
220 // Called by underlying file system to set request_id and log request_id in
221 // IOTracing.
222 void SetRequestId(const std::string& _request_id) {
223 request_id = _request_id;
224 trace_data |= (1 << TraceData::kRequestID);
225 }
226
f67539c2
TL
227 std::string ToString() {
228 std::ostringstream ss;
229 ss << file_path << ", ";
230 for (auto counter : counters) {
231 ss << counter.first << " = " << counter.second << ",";
232 }
233 ss << msg;
234 return ss.str();
235 }
236};
237
1e59de90
TL
238// A function pointer type for custom destruction of void pointer passed to
239// ReadAsync API. RocksDB/caller is responsible for deleting the void pointer
240// allocated by FS in ReadAsync API.
241using IOHandleDeleter = std::function<void(void*)>;
242
f67539c2
TL
243// The FileSystem, FSSequentialFile, FSRandomAccessFile, FSWritableFile,
244// FSRandomRWFileclass, and FSDIrectory classes define the interface between
245// RocksDB and storage systems, such as Posix filesystems,
246// remote filesystems etc.
247// The interface allows for fine grained control of individual IO operations,
248// such as setting a timeout, prioritization, hints on data placement,
249// different handling based on type of IO etc.
250// This is accomplished by passing an instance of IOOptions to every
251// API call that can potentially perform IO. Additionally, each such API is
252// passed a pointer to a IODebugContext structure that can be used by the
253// storage system to include troubleshooting information. The return values
254// of the APIs is of type IOStatus, which can indicate an error code/sub-code,
255// as well as metadata about the error such as its scope and whether its
256// retryable.
1e59de90
TL
257// NewCompositeEnv can be used to create an Env with a custom FileSystem for
258// DBOptions::env.
259//
260// Exceptions MUST NOT propagate out of overridden functions into RocksDB,
261// because RocksDB is not exception-safe. This could cause undefined behavior
262// including data loss, unreported corruption, deadlocks, and more.
263class FileSystem : public Customizable {
f67539c2
TL
264 public:
265 FileSystem();
266
267 // No copying allowed
268 FileSystem(const FileSystem&) = delete;
269
270 virtual ~FileSystem();
271
f67539c2 272 static const char* Type() { return "FileSystem"; }
1e59de90 273 static const char* kDefaultName() { return "DefaultFileSystem"; }
f67539c2
TL
274
275 // Loads the FileSystem specified by the input value into the result
1e59de90
TL
276 // The CreateFromString alternative should be used; this method may be
277 // deprecated in a future release.
f67539c2
TL
278 static Status Load(const std::string& value,
279 std::shared_ptr<FileSystem>* result);
280
1e59de90
TL
281 // Loads the FileSystem specified by the input value into the result
282 // @see Customizable for a more detailed description of the parameters and
283 // return codes
284 // @param config_options Controls how the FileSystem is loaded
285 // @param value The name and optional properties describing the file system
286 // to load.
287 // @param result On success, returns the loaded FileSystem
288 // @return OK if the FileSystem was successfully loaded.
289 // @return not-OK if the load failed.
290 static Status CreateFromString(const ConfigOptions& options,
291 const std::string& value,
292 std::shared_ptr<FileSystem>* result);
293
294 // Return a default FileSystem suitable for the current operating
295 // system.
f67539c2
TL
296 static std::shared_ptr<FileSystem> Default();
297
20effc67
TL
298 // Handles the event when a new DB or a new ColumnFamily starts using the
299 // specified data paths.
300 //
301 // The data paths might be shared by different DBs or ColumnFamilies,
302 // so RegisterDbPaths might be called with the same data paths.
303 // For example, when CreateColumnFamily is called multiple times with the same
304 // data path, RegisterDbPaths will also be called with the same data path.
305 //
306 // If the return status is ok, then the paths must be correspondingly
307 // called in UnregisterDbPaths;
308 // otherwise this method should have no side effect, and UnregisterDbPaths
309 // do not need to be called for the paths.
310 //
311 // Different implementations may take different actions.
312 // By default, it's a no-op and returns Status::OK.
313 virtual Status RegisterDbPaths(const std::vector<std::string>& /*paths*/) {
314 return Status::OK();
315 }
316 // Handles the event a DB or a ColumnFamily stops using the specified data
317 // paths.
318 //
319 // It should be called corresponding to each successful RegisterDbPaths.
320 //
321 // Different implementations may take different actions.
322 // By default, it's a no-op and returns Status::OK.
323 virtual Status UnregisterDbPaths(const std::vector<std::string>& /*paths*/) {
324 return Status::OK();
325 }
326
f67539c2
TL
327 // Create a brand new sequentially-readable file with the specified name.
328 // On success, stores a pointer to the new file in *result and returns OK.
329 // On failure stores nullptr in *result and returns non-OK. If the file does
330 // not exist, returns a non-OK status.
331 //
332 // The returned file will only be accessed by one thread at a time.
333 virtual IOStatus NewSequentialFile(const std::string& fname,
334 const FileOptions& file_opts,
335 std::unique_ptr<FSSequentialFile>* result,
336 IODebugContext* dbg) = 0;
337
338 // Create a brand new random access read-only file with the
339 // specified name. On success, stores a pointer to the new file in
340 // *result and returns OK. On failure stores nullptr in *result and
341 // returns non-OK. If the file does not exist, returns a non-OK
342 // status.
343 //
344 // The returned file may be concurrently accessed by multiple threads.
345 virtual IOStatus NewRandomAccessFile(
346 const std::string& fname, const FileOptions& file_opts,
1e59de90 347 std::unique_ptr<FSRandomAccessFile>* result, IODebugContext* dbg) = 0;
f67539c2
TL
348 // These values match Linux definition
349 // https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/uapi/linux/fcntl.h#n56
350 enum WriteLifeTimeHint {
351 kWLTHNotSet = 0, // No hint information set
352 kWLTHNone, // No hints about write life time
353 kWLTHShort, // Data written has a short life time
354 kWLTHMedium, // Data written has a medium life time
355 kWLTHLong, // Data written has a long life time
356 kWLTHExtreme, // Data written has an extremely long life time
357 };
358
359 // Create an object that writes to a new file with the specified
360 // name. Deletes any existing file with the same name and creates a
361 // new file. On success, stores a pointer to the new file in
362 // *result and returns OK. On failure stores nullptr in *result and
363 // returns non-OK.
364 //
365 // The returned file will only be accessed by one thread at a time.
366 virtual IOStatus NewWritableFile(const std::string& fname,
367 const FileOptions& file_opts,
368 std::unique_ptr<FSWritableFile>* result,
369 IODebugContext* dbg) = 0;
370
1e59de90
TL
371 // Create an object that writes to a file with the specified name.
372 // `FSWritableFile::Append()`s will append after any existing content. If the
373 // file does not already exist, creates it.
374 //
375 // On success, stores a pointer to the file in *result and returns OK. On
376 // failure stores nullptr in *result and returns non-OK.
f67539c2
TL
377 //
378 // The returned file will only be accessed by one thread at a time.
379 virtual IOStatus ReopenWritableFile(
380 const std::string& /*fname*/, const FileOptions& /*options*/,
381 std::unique_ptr<FSWritableFile>* /*result*/, IODebugContext* /*dbg*/) {
20effc67 382 return IOStatus::NotSupported("ReopenWritableFile");
f67539c2
TL
383 }
384
385 // Reuse an existing file by renaming it and opening it as writable.
386 virtual IOStatus ReuseWritableFile(const std::string& fname,
387 const std::string& old_fname,
388 const FileOptions& file_opts,
389 std::unique_ptr<FSWritableFile>* result,
20effc67 390 IODebugContext* dbg);
f67539c2
TL
391
392 // Open `fname` for random read and write, if file doesn't exist the file
393 // will be created. On success, stores a pointer to the new file in
394 // *result and returns OK. On failure returns non-OK.
395 //
396 // The returned file will only be accessed by one thread at a time.
397 virtual IOStatus NewRandomRWFile(const std::string& /*fname*/,
398 const FileOptions& /*options*/,
399 std::unique_ptr<FSRandomRWFile>* /*result*/,
400 IODebugContext* /*dbg*/) {
401 return IOStatus::NotSupported(
402 "RandomRWFile is not implemented in this FileSystem");
403 }
404
405 // Opens `fname` as a memory-mapped file for read and write (in-place updates
406 // only, i.e., no appends). On success, stores a raw buffer covering the whole
407 // file in `*result`. The file must exist prior to this call.
408 virtual IOStatus NewMemoryMappedFileBuffer(
409 const std::string& /*fname*/,
410 std::unique_ptr<MemoryMappedFileBuffer>* /*result*/) {
411 return IOStatus::NotSupported(
412 "MemoryMappedFileBuffer is not implemented in this FileSystem");
413 }
414
415 // Create an object that represents a directory. Will fail if directory
416 // doesn't exist. If the directory exists, it will open the directory
417 // and create a new Directory object.
418 //
419 // On success, stores a pointer to the new Directory in
420 // *result and returns OK. On failure stores nullptr in *result and
421 // returns non-OK.
422 virtual IOStatus NewDirectory(const std::string& name,
423 const IOOptions& io_opts,
424 std::unique_ptr<FSDirectory>* result,
425 IODebugContext* dbg) = 0;
426
427 // Returns OK if the named file exists.
428 // NotFound if the named file does not exist,
429 // the calling process does not have permission to determine
430 // whether this file exists, or if the path is invalid.
431 // IOError if an IO Error was encountered
432 virtual IOStatus FileExists(const std::string& fname,
433 const IOOptions& options,
434 IODebugContext* dbg) = 0;
435
436 // Store in *result the names of the children of the specified directory.
437 // The names are relative to "dir".
438 // Original contents of *results are dropped.
439 // Returns OK if "dir" exists and "*result" contains its children.
440 // NotFound if "dir" does not exist, the calling process does not have
441 // permission to access "dir", or if "dir" is invalid.
442 // IOError if an IO Error was encountered
443 virtual IOStatus GetChildren(const std::string& dir, const IOOptions& options,
444 std::vector<std::string>* result,
445 IODebugContext* dbg) = 0;
446
447 // Store in *result the attributes of the children of the specified directory.
448 // In case the implementation lists the directory prior to iterating the files
449 // and files are concurrently deleted, the deleted files will be omitted from
450 // result.
451 // The name attributes are relative to "dir".
452 // Original contents of *results are dropped.
453 // Returns OK if "dir" exists and "*result" contains its children.
454 // NotFound if "dir" does not exist, the calling process does not have
455 // permission to access "dir", or if "dir" is invalid.
456 // IOError if an IO Error was encountered
457 virtual IOStatus GetChildrenFileAttributes(
458 const std::string& dir, const IOOptions& options,
459 std::vector<FileAttributes>* result, IODebugContext* dbg) {
460 assert(result != nullptr);
461 std::vector<std::string> child_fnames;
462 IOStatus s = GetChildren(dir, options, &child_fnames, dbg);
463 if (!s.ok()) {
464 return s;
465 }
466 result->resize(child_fnames.size());
467 size_t result_size = 0;
468 for (size_t i = 0; i < child_fnames.size(); ++i) {
469 const std::string path = dir + "/" + child_fnames[i];
470 if (!(s = GetFileSize(path, options, &(*result)[result_size].size_bytes,
471 dbg))
472 .ok()) {
473 if (FileExists(path, options, dbg).IsNotFound()) {
474 // The file may have been deleted since we listed the directory
475 continue;
476 }
477 return s;
478 }
479 (*result)[result_size].name = std::move(child_fnames[i]);
480 result_size++;
481 }
482 result->resize(result_size);
483 return IOStatus::OK();
484 }
485
1e59de90
TL
486// This seems to clash with a macro on Windows, so #undef it here
487#ifdef DeleteFile
488#undef DeleteFile
489#endif
f67539c2
TL
490 // Delete the named file.
491 virtual IOStatus DeleteFile(const std::string& fname,
492 const IOOptions& options,
493 IODebugContext* dbg) = 0;
494
495 // Truncate the named file to the specified size.
496 virtual IOStatus Truncate(const std::string& /*fname*/, size_t /*size*/,
497 const IOOptions& /*options*/,
498 IODebugContext* /*dbg*/) {
1e59de90
TL
499 return IOStatus::NotSupported(
500 "Truncate is not supported for this FileSystem");
f67539c2
TL
501 }
502
503 // Create the specified directory. Returns error if directory exists.
504 virtual IOStatus CreateDir(const std::string& dirname,
505 const IOOptions& options, IODebugContext* dbg) = 0;
506
507 // Creates directory if missing. Return Ok if it exists, or successful in
508 // Creating.
509 virtual IOStatus CreateDirIfMissing(const std::string& dirname,
510 const IOOptions& options,
511 IODebugContext* dbg) = 0;
512
513 // Delete the specified directory.
514 virtual IOStatus DeleteDir(const std::string& dirname,
515 const IOOptions& options, IODebugContext* dbg) = 0;
516
517 // Store the size of fname in *file_size.
518 virtual IOStatus GetFileSize(const std::string& fname,
519 const IOOptions& options, uint64_t* file_size,
520 IODebugContext* dbg) = 0;
521
522 // Store the last modification time of fname in *file_mtime.
523 virtual IOStatus GetFileModificationTime(const std::string& fname,
524 const IOOptions& options,
525 uint64_t* file_mtime,
526 IODebugContext* dbg) = 0;
527 // Rename file src to target.
528 virtual IOStatus RenameFile(const std::string& src, const std::string& target,
529 const IOOptions& options,
530 IODebugContext* dbg) = 0;
531
532 // Hard Link file src to target.
533 virtual IOStatus LinkFile(const std::string& /*src*/,
534 const std::string& /*target*/,
535 const IOOptions& /*options*/,
536 IODebugContext* /*dbg*/) {
1e59de90
TL
537 return IOStatus::NotSupported(
538 "LinkFile is not supported for this FileSystem");
f67539c2
TL
539 }
540
541 virtual IOStatus NumFileLinks(const std::string& /*fname*/,
542 const IOOptions& /*options*/,
543 uint64_t* /*count*/, IODebugContext* /*dbg*/) {
544 return IOStatus::NotSupported(
545 "Getting number of file links is not supported for this FileSystem");
546 }
547
548 virtual IOStatus AreFilesSame(const std::string& /*first*/,
549 const std::string& /*second*/,
550 const IOOptions& /*options*/, bool* /*res*/,
551 IODebugContext* /*dbg*/) {
1e59de90
TL
552 return IOStatus::NotSupported(
553 "AreFilesSame is not supported for this FileSystem");
f67539c2
TL
554 }
555
556 // Lock the specified file. Used to prevent concurrent access to
557 // the same db by multiple processes. On failure, stores nullptr in
558 // *lock and returns non-OK.
559 //
560 // On success, stores a pointer to the object that represents the
561 // acquired lock in *lock and returns OK. The caller should call
562 // UnlockFile(*lock) to release the lock. If the process exits,
563 // the lock will be automatically released.
564 //
565 // If somebody else already holds the lock, finishes immediately
566 // with a failure. I.e., this call does not wait for existing locks
567 // to go away.
568 //
569 // May create the named file if it does not already exist.
570 virtual IOStatus LockFile(const std::string& fname, const IOOptions& options,
571 FileLock** lock, IODebugContext* dbg) = 0;
572
573 // Release the lock acquired by a previous successful call to LockFile.
574 // REQUIRES: lock was returned by a successful LockFile() call
575 // REQUIRES: lock has not already been unlocked.
576 virtual IOStatus UnlockFile(FileLock* lock, const IOOptions& options,
577 IODebugContext* dbg) = 0;
578
579 // *path is set to a temporary directory that can be used for testing. It may
580 // or many not have just been created. The directory may or may not differ
581 // between runs of the same process, but subsequent calls will return the
582 // same directory.
583 virtual IOStatus GetTestDirectory(const IOOptions& options, std::string* path,
584 IODebugContext* dbg) = 0;
585
586 // Create and returns a default logger (an instance of EnvLogger) for storing
1e59de90 587 // informational messages. Derived classes can override to provide custom
f67539c2
TL
588 // logger.
589 virtual IOStatus NewLogger(const std::string& fname, const IOOptions& io_opts,
590 std::shared_ptr<Logger>* result,
1e59de90 591 IODebugContext* dbg);
f67539c2
TL
592
593 // Get full directory name for this db.
594 virtual IOStatus GetAbsolutePath(const std::string& db_path,
595 const IOOptions& options,
596 std::string* output_path,
597 IODebugContext* dbg) = 0;
598
20effc67
TL
599 // Sanitize the FileOptions. Typically called by a FileOptions/EnvOptions
600 // copy constructor
601 virtual void SanitizeFileOptions(FileOptions* /*opts*/) const {}
602
f67539c2
TL
603 // OptimizeForLogRead will create a new FileOptions object that is a copy of
604 // the FileOptions in the parameters, but is optimized for reading log files.
605 virtual FileOptions OptimizeForLogRead(const FileOptions& file_options) const;
606
607 // OptimizeForManifestRead will create a new FileOptions object that is a copy
608 // of the FileOptions in the parameters, but is optimized for reading manifest
609 // files.
610 virtual FileOptions OptimizeForManifestRead(
611 const FileOptions& file_options) const;
612
613 // OptimizeForLogWrite will create a new FileOptions object that is a copy of
614 // the FileOptions in the parameters, but is optimized for writing log files.
615 // Default implementation returns the copy of the same object.
616 virtual FileOptions OptimizeForLogWrite(const FileOptions& file_options,
1e59de90 617 const DBOptions& db_options) const;
f67539c2
TL
618
619 // OptimizeForManifestWrite will create a new FileOptions object that is a
620 // copy of the FileOptions in the parameters, but is optimized for writing
621 // manifest files. Default implementation returns the copy of the same
622 // object.
623 virtual FileOptions OptimizeForManifestWrite(
624 const FileOptions& file_options) const;
625
626 // OptimizeForCompactionTableWrite will create a new FileOptions object that
627 // is a copy of the FileOptions in the parameters, but is optimized for
628 // writing table files.
629 virtual FileOptions OptimizeForCompactionTableWrite(
630 const FileOptions& file_options,
631 const ImmutableDBOptions& immutable_ops) const;
632
633 // OptimizeForCompactionTableRead will create a new FileOptions object that
634 // is a copy of the FileOptions in the parameters, but is optimized for
635 // reading table files.
636 virtual FileOptions OptimizeForCompactionTableRead(
637 const FileOptions& file_options,
638 const ImmutableDBOptions& db_options) const;
639
1e59de90
TL
640 // OptimizeForBlobFileRead will create a new FileOptions object that
641 // is a copy of the FileOptions in the parameters, but is optimized for
642 // reading blob files.
643 virtual FileOptions OptimizeForBlobFileRead(
644 const FileOptions& file_options,
645 const ImmutableDBOptions& db_options) const;
646
f67539c2
TL
647// This seems to clash with a macro on Windows, so #undef it here
648#ifdef GetFreeSpace
649#undef GetFreeSpace
650#endif
651
652 // Get the amount of free disk space
653 virtual IOStatus GetFreeSpace(const std::string& /*path*/,
654 const IOOptions& /*options*/,
655 uint64_t* /*diskfree*/,
656 IODebugContext* /*dbg*/) {
20effc67 657 return IOStatus::NotSupported("GetFreeSpace");
f67539c2
TL
658 }
659
20effc67
TL
660 virtual IOStatus IsDirectory(const std::string& /*path*/,
661 const IOOptions& options, bool* is_dir,
662 IODebugContext* /*dgb*/) = 0;
663
1e59de90
TL
664 // EXPERIMENTAL
665 // Poll for completion of read IO requests. The Poll() method should call the
666 // callback functions to indicate completion of read requests.
667 // Underlying FS is required to support Poll API. Poll implementation should
668 // ensure that the callback gets called at IO completion, and return only
669 // after the callback has been called.
670 // If Poll returns partial results for any reads, its caller reponsibility to
671 // call Read or ReadAsync in order to get the remaining bytes.
672 //
673 // Default implementation is to return IOStatus::OK.
674
675 virtual IOStatus Poll(std::vector<void*>& /*io_handles*/,
676 size_t /*min_completions*/) {
677 return IOStatus::OK();
678 }
679
680 // EXPERIMENTAL
681 // Abort the read IO requests submitted asynchronously. Underlying FS is
682 // required to support AbortIO API. AbortIO implementation should ensure that
683 // the all the read requests related to io_handles should be aborted and
684 // it shouldn't call the callback for these io_handles.
685 //
686 // Default implementation is to return IOStatus::OK.
687 virtual IOStatus AbortIO(std::vector<void*>& /*io_handles*/) {
688 return IOStatus::OK();
689 }
690
f67539c2
TL
691 // If you're adding methods here, remember to add them to EnvWrapper too.
692
693 private:
694 void operator=(const FileSystem&);
695};
696
697// A file abstraction for reading sequentially through a file
698class FSSequentialFile {
699 public:
700 FSSequentialFile() {}
701
702 virtual ~FSSequentialFile() {}
703
704 // Read up to "n" bytes from the file. "scratch[0..n-1]" may be
705 // written by this routine. Sets "*result" to the data that was
706 // read (including if fewer than "n" bytes were successfully read).
707 // May set "*result" to point at data in "scratch[0..n-1]", so
708 // "scratch[0..n-1]" must be live when "*result" is used.
709 // If an error was encountered, returns a non-OK status.
710 //
1e59de90
TL
711 // After call, result->size() < n only if end of file has been
712 // reached (or non-OK status). Read might fail if called again after
713 // first result->size() < n.
714 //
f67539c2
TL
715 // REQUIRES: External synchronization
716 virtual IOStatus Read(size_t n, const IOOptions& options, Slice* result,
717 char* scratch, IODebugContext* dbg) = 0;
718
719 // Skip "n" bytes from the file. This is guaranteed to be no
720 // slower that reading the same data, but may be faster.
721 //
722 // If end of file is reached, skipping will stop at the end of the
723 // file, and Skip will return OK.
724 //
725 // REQUIRES: External synchronization
726 virtual IOStatus Skip(uint64_t n) = 0;
727
728 // Indicates the upper layers if the current SequentialFile implementation
729 // uses direct IO.
730 virtual bool use_direct_io() const { return false; }
731
732 // Use the returned alignment value to allocate
733 // aligned buffer for Direct I/O
734 virtual size_t GetRequiredBufferAlignment() const { return kDefaultPageSize; }
735
736 // Remove any kind of caching of data from the offset to offset+length
737 // of this file. If the length is 0, then it refers to the end of file.
738 // If the system is not caching the file contents, then this is a noop.
739 virtual IOStatus InvalidateCache(size_t /*offset*/, size_t /*length*/) {
740 return IOStatus::NotSupported("InvalidateCache not supported.");
741 }
742
743 // Positioned Read for direct I/O
744 // If Direct I/O enabled, offset, n, and scratch should be properly aligned
745 virtual IOStatus PositionedRead(uint64_t /*offset*/, size_t /*n*/,
746 const IOOptions& /*options*/,
747 Slice* /*result*/, char* /*scratch*/,
748 IODebugContext* /*dbg*/) {
20effc67 749 return IOStatus::NotSupported("PositionedRead");
f67539c2
TL
750 }
751
1e59de90
TL
752 // EXPERIMENTAL
753 // When available, returns the actual temperature for the file. This is
754 // useful in case some outside process moves a file from one tier to another,
755 // though the temperature is generally expected not to change while a file is
756 // open.
757 virtual Temperature GetTemperature() const { return Temperature::kUnknown; }
758
f67539c2
TL
759 // If you're adding methods here, remember to add them to
760 // SequentialFileWrapper too.
761};
762
1e59de90 763// A read IO request structure for use in MultiRead and asynchronous Read APIs.
f67539c2 764struct FSReadRequest {
1e59de90 765 // Input parameter that represents the file offset in bytes.
f67539c2
TL
766 uint64_t offset;
767
1e59de90
TL
768 // Input parameter that represents the length to read in bytes. `result` only
769 // returns fewer bytes if end of file is hit (or `status` is not OK).
f67539c2
TL
770 size_t len;
771
1e59de90
TL
772 // A buffer that MultiRead() can optionally place data in. It can
773 // ignore this and allocate its own buffer.
774 // The lifecycle of scratch will be until IO is completed.
775 //
776 // In case of asynchronous reads, its an output parameter and it will be
777 // maintained until callback has been called. Scratch is allocated by RocksDB
778 // and will be passed to underlying FileSystem.
f67539c2
TL
779 char* scratch;
780
781 // Output parameter set by MultiRead() to point to the data buffer, and
782 // the number of valid bytes
1e59de90
TL
783 //
784 // In case of asynchronous reads, this output parameter is set by Async Read
785 // APIs to point to the data buffer, and
786 // the number of valid bytes.
787 // Slice result should point to scratch i.e the data should
788 // always be read into scratch.
f67539c2
TL
789 Slice result;
790
1e59de90
TL
791 // Output parameter set by underlying FileSystem that represents status of
792 // read request.
f67539c2
TL
793 IOStatus status;
794};
795
796// A file abstraction for randomly reading the contents of a file.
797class FSRandomAccessFile {
798 public:
799 FSRandomAccessFile() {}
800
801 virtual ~FSRandomAccessFile() {}
802
803 // Read up to "n" bytes from the file starting at "offset".
804 // "scratch[0..n-1]" may be written by this routine. Sets "*result"
805 // to the data that was read (including if fewer than "n" bytes were
806 // successfully read). May set "*result" to point at data in
807 // "scratch[0..n-1]", so "scratch[0..n-1]" must be live when
808 // "*result" is used. If an error was encountered, returns a non-OK
809 // status.
810 //
1e59de90
TL
811 // After call, result->size() < n only if end of file has been
812 // reached (or non-OK status). Read might fail if called again after
813 // first result->size() < n.
814 //
f67539c2
TL
815 // Safe for concurrent use by multiple threads.
816 // If Direct I/O enabled, offset, n, and scratch should be aligned properly.
817 virtual IOStatus Read(uint64_t offset, size_t n, const IOOptions& options,
818 Slice* result, char* scratch,
819 IODebugContext* dbg) const = 0;
820
821 // Readahead the file starting from offset by n bytes for caching.
20effc67
TL
822 // If it's not implemented (default: `NotSupported`), RocksDB will create
823 // internal prefetch buffer to improve read performance.
f67539c2
TL
824 virtual IOStatus Prefetch(uint64_t /*offset*/, size_t /*n*/,
825 const IOOptions& /*options*/,
826 IODebugContext* /*dbg*/) {
20effc67 827 return IOStatus::NotSupported("Prefetch");
f67539c2
TL
828 }
829
830 // Read a bunch of blocks as described by reqs. The blocks can
831 // optionally be read in parallel. This is a synchronous call, i.e it
832 // should return after all reads have completed. The reads will be
1e59de90
TL
833 // non-overlapping but can be in any order. If the function return Status
834 // is not ok, status of individual requests will be ignored and return
835 // status will be assumed for all read requests. The function return status
836 // is only meant for errors that occur before processing individual read
837 // requests.
f67539c2
TL
838 virtual IOStatus MultiRead(FSReadRequest* reqs, size_t num_reqs,
839 const IOOptions& options, IODebugContext* dbg) {
840 assert(reqs != nullptr);
841 for (size_t i = 0; i < num_reqs; ++i) {
842 FSReadRequest& req = reqs[i];
843 req.status =
844 Read(req.offset, req.len, options, &req.result, req.scratch, dbg);
845 }
846 return IOStatus::OK();
847 }
848
849 // Tries to get an unique ID for this file that will be the same each time
850 // the file is opened (and will stay the same while the file is open).
851 // Furthermore, it tries to make this ID at most "max_size" bytes. If such an
852 // ID can be created this function returns the length of the ID and places it
853 // in "id"; otherwise, this function returns 0, in which case "id"
854 // may not have been modified.
855 //
856 // This function guarantees, for IDs from a given environment, two unique ids
857 // cannot be made equal to each other by adding arbitrary bytes to one of
858 // them. That is, no unique ID is the prefix of another.
859 //
860 // This function guarantees that the returned ID will not be interpretable as
861 // a single varint.
862 //
863 // Note: these IDs are only valid for the duration of the process.
864 virtual size_t GetUniqueId(char* /*id*/, size_t /*max_size*/) const {
865 return 0; // Default implementation to prevent issues with backwards
866 // compatibility.
867 };
868
869 enum AccessPattern { kNormal, kRandom, kSequential, kWillNeed, kWontNeed };
870
871 virtual void Hint(AccessPattern /*pattern*/) {}
872
873 // Indicates the upper layers if the current RandomAccessFile implementation
874 // uses direct IO.
875 virtual bool use_direct_io() const { return false; }
876
877 // Use the returned alignment value to allocate
878 // aligned buffer for Direct I/O
879 virtual size_t GetRequiredBufferAlignment() const { return kDefaultPageSize; }
880
881 // Remove any kind of caching of data from the offset to offset+length
882 // of this file. If the length is 0, then it refers to the end of file.
883 // If the system is not caching the file contents, then this is a noop.
884 virtual IOStatus InvalidateCache(size_t /*offset*/, size_t /*length*/) {
885 return IOStatus::NotSupported("InvalidateCache not supported.");
886 }
887
1e59de90
TL
888 // EXPERIMENTAL
889 // This API reads the requested data in FSReadRequest asynchronously. This is
890 // a asynchronous call, i.e it should return after submitting the request.
891 //
892 // When the read request is completed, callback function specified in cb
893 // should be called with arguments cb_arg and the result populated in
894 // FSReadRequest with result and status fileds updated by FileSystem.
895 // cb_arg should be used by the callback to track the original request
896 // submitted.
897 //
898 // This API should also populate io_handle which should be used by
899 // underlying FileSystem to store the context in order to distinguish the read
900 // requests at their side and provide the custom deletion function in del_fn.
901 // RocksDB guarantees that the del_fn for io_handle will be called after
902 // receiving the callback. Furthermore, RocksDB guarantees that if it calls
903 // the Poll API for this io_handle, del_fn will be called after the Poll
904 // returns. RocksDB is responsible for managing the lifetime of io_handle.
905 //
906 // req contains the request offset and size passed as input parameter of read
907 // request and result and status fields are output parameter set by underlying
908 // FileSystem. The data should always be read into scratch field.
909 //
910 // Default implementation is to read the data synchronously.
911 virtual IOStatus ReadAsync(
912 FSReadRequest& req, const IOOptions& opts,
913 std::function<void(const FSReadRequest&, void*)> cb, void* cb_arg,
914 void** /*io_handle*/, IOHandleDeleter* /*del_fn*/, IODebugContext* dbg) {
915 req.status =
916 Read(req.offset, req.len, opts, &(req.result), req.scratch, dbg);
917 cb(req, cb_arg);
918 return IOStatus::OK();
919 }
920
921 // EXPERIMENTAL
922 // When available, returns the actual temperature for the file. This is
923 // useful in case some outside process moves a file from one tier to another,
924 // though the temperature is generally expected not to change while a file is
925 // open.
926 virtual Temperature GetTemperature() const { return Temperature::kUnknown; }
927
f67539c2
TL
928 // If you're adding methods here, remember to add them to
929 // RandomAccessFileWrapper too.
930};
931
20effc67 932// A data structure brings the data verification information, which is
1e59de90 933// used together with data being written to a file.
20effc67
TL
934struct DataVerificationInfo {
935 // checksum of the data being written.
936 Slice checksum;
937};
938
f67539c2
TL
939// A file abstraction for sequential writing. The implementation
940// must provide buffering since callers may append small fragments
941// at a time to the file.
942class FSWritableFile {
943 public:
944 FSWritableFile()
945 : last_preallocated_block_(0),
946 preallocation_block_size_(0),
947 io_priority_(Env::IO_TOTAL),
948 write_hint_(Env::WLTH_NOT_SET),
949 strict_bytes_per_sync_(false) {}
950
951 explicit FSWritableFile(const FileOptions& options)
952 : last_preallocated_block_(0),
953 preallocation_block_size_(0),
954 io_priority_(Env::IO_TOTAL),
955 write_hint_(Env::WLTH_NOT_SET),
956 strict_bytes_per_sync_(options.strict_bytes_per_sync) {}
957
958 virtual ~FSWritableFile() {}
959
960 // Append data to the end of the file
1e59de90 961 // Note: A WritableFile object must support either Append or
f67539c2
TL
962 // PositionedAppend, so the users cannot mix the two.
963 virtual IOStatus Append(const Slice& data, const IOOptions& options,
964 IODebugContext* dbg) = 0;
965
1e59de90 966 // Append data with verification information.
20effc67 967 // Note that this API change is experimental and it might be changed in
1e59de90
TL
968 // the future. Currently, RocksDB only generates crc32c based checksum for
969 // the file writes when the checksum handoff option is set.
970 // Expected behavior: if the handoff_checksum_type in FileOptions (currently,
971 // ChecksumType::kCRC32C is set as default) is not supported by this
972 // FSWritableFile, the information in DataVerificationInfo can be ignored
973 // (i.e. does not perform checksum verification).
20effc67
TL
974 virtual IOStatus Append(const Slice& data, const IOOptions& options,
975 const DataVerificationInfo& /* verification_info */,
976 IODebugContext* dbg) {
977 return Append(data, options, dbg);
978 }
979
f67539c2
TL
980 // PositionedAppend data to the specified offset. The new EOF after append
981 // must be larger than the previous EOF. This is to be used when writes are
982 // not backed by OS buffers and hence has to always start from the start of
983 // the sector. The implementation thus needs to also rewrite the last
984 // partial sector.
985 // Note: PositionAppend does not guarantee moving the file offset after the
986 // write. A WritableFile object must support either Append or
987 // PositionedAppend, so the users cannot mix the two.
988 //
989 // PositionedAppend() can only happen on the page/sector boundaries. For that
990 // reason, if the last write was an incomplete sector we still need to rewind
991 // back to the nearest sector/page and rewrite the portion of it with whatever
992 // we need to add. We need to keep where we stop writing.
993 //
994 // PositionedAppend() can only write whole sectors. For that reason we have to
995 // pad with zeros for the last write and trim the file when closing according
996 // to the position we keep in the previous step.
997 //
998 // PositionedAppend() requires aligned buffer to be passed in. The alignment
999 // required is queried via GetRequiredBufferAlignment()
1000 virtual IOStatus PositionedAppend(const Slice& /* data */,
1001 uint64_t /* offset */,
1002 const IOOptions& /*options*/,
1003 IODebugContext* /*dbg*/) {
20effc67
TL
1004 return IOStatus::NotSupported("PositionedAppend");
1005 }
1006
20effc67
TL
1007 // PositionedAppend data with verification information.
1008 // Note that this API change is experimental and it might be changed in
1e59de90
TL
1009 // the future. Currently, RocksDB only generates crc32c based checksum for
1010 // the file writes when the checksum handoff option is set.
1011 // Expected behavior: if the handoff_checksum_type in FileOptions (currently,
1012 // ChecksumType::kCRC32C is set as default) is not supported by this
1013 // FSWritableFile, the information in DataVerificationInfo can be ignored
1014 // (i.e. does not perform checksum verification).
20effc67
TL
1015 virtual IOStatus PositionedAppend(
1016 const Slice& /* data */, uint64_t /* offset */,
1017 const IOOptions& /*options*/,
1018 const DataVerificationInfo& /* verification_info */,
1019 IODebugContext* /*dbg*/) {
1020 return IOStatus::NotSupported("PositionedAppend");
f67539c2
TL
1021 }
1022
1023 // Truncate is necessary to trim the file to the correct size
1024 // before closing. It is not always possible to keep track of the file
1025 // size due to whole pages writes. The behavior is undefined if called
1026 // with other writes to follow.
1027 virtual IOStatus Truncate(uint64_t /*size*/, const IOOptions& /*options*/,
1028 IODebugContext* /*dbg*/) {
1029 return IOStatus::OK();
1030 }
1e59de90
TL
1031 virtual IOStatus Close(const IOOptions& /*options*/,
1032 IODebugContext* /*dbg*/) = 0;
1033
f67539c2
TL
1034 virtual IOStatus Flush(const IOOptions& options, IODebugContext* dbg) = 0;
1035 virtual IOStatus Sync(const IOOptions& options,
1036 IODebugContext* dbg) = 0; // sync data
1037
1038 /*
1039 * Sync data and/or metadata as well.
1040 * By default, sync only data.
1041 * Override this method for environments where we need to sync
1042 * metadata as well.
1043 */
1044 virtual IOStatus Fsync(const IOOptions& options, IODebugContext* dbg) {
1045 return Sync(options, dbg);
1046 }
1047
1048 // true if Sync() and Fsync() are safe to call concurrently with Append()
1049 // and Flush().
1050 virtual bool IsSyncThreadSafe() const { return false; }
1051
1052 // Indicates the upper layers if the current WritableFile implementation
1053 // uses direct IO.
1054 virtual bool use_direct_io() const { return false; }
1055
1056 // Use the returned alignment value to allocate
1057 // aligned buffer for Direct I/O
1058 virtual size_t GetRequiredBufferAlignment() const { return kDefaultPageSize; }
1059
1060 virtual void SetWriteLifeTimeHint(Env::WriteLifeTimeHint hint) {
1061 write_hint_ = hint;
1062 }
1063
1e59de90
TL
1064 /*
1065 * If rate limiting is enabled, change the file-granularity priority used in
1066 * rate-limiting writes.
1067 *
1068 * In the presence of finer-granularity priority such as
1069 * `WriteOptions::rate_limiter_priority`, this file-granularity priority may
1070 * be overridden by a non-Env::IO_TOTAL finer-granularity priority and used as
1071 * a fallback for Env::IO_TOTAL finer-granularity priority.
1072 *
1073 * If rate limiting is not enabled, this call has no effect.
1074 */
f67539c2
TL
1075 virtual void SetIOPriority(Env::IOPriority pri) { io_priority_ = pri; }
1076
1077 virtual Env::IOPriority GetIOPriority() { return io_priority_; }
1078
1079 virtual Env::WriteLifeTimeHint GetWriteLifeTimeHint() { return write_hint_; }
1080 /*
1081 * Get the size of valid data in the file.
1082 */
1083 virtual uint64_t GetFileSize(const IOOptions& /*options*/,
1084 IODebugContext* /*dbg*/) {
1085 return 0;
1086 }
1087
1088 /*
1089 * Get and set the default pre-allocation block size for writes to
1090 * this file. If non-zero, then Allocate will be used to extend the
1091 * underlying storage of a file (generally via fallocate) if the Env
1092 * instance supports it.
1093 */
1094 virtual void SetPreallocationBlockSize(size_t size) {
1095 preallocation_block_size_ = size;
1096 }
1097
1098 virtual void GetPreallocationStatus(size_t* block_size,
1099 size_t* last_allocated_block) {
1100 *last_allocated_block = last_preallocated_block_;
1101 *block_size = preallocation_block_size_;
1102 }
1103
1104 // For documentation, refer to RandomAccessFile::GetUniqueId()
1105 virtual size_t GetUniqueId(char* /*id*/, size_t /*max_size*/) const {
1106 return 0; // Default implementation to prevent issues with backwards
1107 }
1108
1109 // Remove any kind of caching of data from the offset to offset+length
1110 // of this file. If the length is 0, then it refers to the end of file.
1111 // If the system is not caching the file contents, then this is a noop.
1112 // This call has no effect on dirty pages in the cache.
1113 virtual IOStatus InvalidateCache(size_t /*offset*/, size_t /*length*/) {
1114 return IOStatus::NotSupported("InvalidateCache not supported.");
1115 }
1116
1117 // Sync a file range with disk.
1118 // offset is the starting byte of the file range to be synchronized.
1119 // nbytes specifies the length of the range to be synchronized.
1120 // This asks the OS to initiate flushing the cached data to disk,
1121 // without waiting for completion.
1122 // Default implementation does nothing.
1123 virtual IOStatus RangeSync(uint64_t /*offset*/, uint64_t /*nbytes*/,
1124 const IOOptions& options, IODebugContext* dbg) {
1125 if (strict_bytes_per_sync_) {
1126 return Sync(options, dbg);
1127 }
1128 return IOStatus::OK();
1129 }
1130
1131 // PrepareWrite performs any necessary preparation for a write
1132 // before the write actually occurs. This allows for pre-allocation
1133 // of space on devices where it can result in less file
1134 // fragmentation and/or less waste from over-zealous filesystem
1135 // pre-allocation.
1136 virtual void PrepareWrite(size_t offset, size_t len, const IOOptions& options,
1137 IODebugContext* dbg) {
1138 if (preallocation_block_size_ == 0) {
1139 return;
1140 }
1141 // If this write would cross one or more preallocation blocks,
1142 // determine what the last preallocation block necessary to
1143 // cover this write would be and Allocate to that point.
1144 const auto block_size = preallocation_block_size_;
1145 size_t new_last_preallocated_block =
1146 (offset + len + block_size - 1) / block_size;
1147 if (new_last_preallocated_block > last_preallocated_block_) {
1148 size_t num_spanned_blocks =
1149 new_last_preallocated_block - last_preallocated_block_;
1150 Allocate(block_size * last_preallocated_block_,
20effc67
TL
1151 block_size * num_spanned_blocks, options, dbg)
1152 .PermitUncheckedError();
f67539c2
TL
1153 last_preallocated_block_ = new_last_preallocated_block;
1154 }
1155 }
1156
1157 // Pre-allocates space for a file.
1158 virtual IOStatus Allocate(uint64_t /*offset*/, uint64_t /*len*/,
1159 const IOOptions& /*options*/,
1160 IODebugContext* /*dbg*/) {
1161 return IOStatus::OK();
1162 }
1163
1164 // If you're adding methods here, remember to add them to
1165 // WritableFileWrapper too.
1166
1167 protected:
1168 size_t preallocation_block_size() { return preallocation_block_size_; }
1169
1170 private:
1171 size_t last_preallocated_block_;
1172 size_t preallocation_block_size_;
1173 // No copying allowed
1174 FSWritableFile(const FSWritableFile&);
1175 void operator=(const FSWritableFile&);
1176
1177 protected:
1178 Env::IOPriority io_priority_;
1179 Env::WriteLifeTimeHint write_hint_;
1180 const bool strict_bytes_per_sync_;
1181};
1182
1183// A file abstraction for random reading and writing.
1184class FSRandomRWFile {
1185 public:
1186 FSRandomRWFile() {}
1187
1188 virtual ~FSRandomRWFile() {}
1189
1190 // Indicates if the class makes use of direct I/O
1191 // If false you must pass aligned buffer to Write()
1192 virtual bool use_direct_io() const { return false; }
1193
1194 // Use the returned alignment value to allocate
1195 // aligned buffer for Direct I/O
1196 virtual size_t GetRequiredBufferAlignment() const { return kDefaultPageSize; }
1197
1198 // Write bytes in `data` at offset `offset`, Returns Status::OK() on success.
1199 // Pass aligned buffer when use_direct_io() returns true.
1200 virtual IOStatus Write(uint64_t offset, const Slice& data,
1201 const IOOptions& options, IODebugContext* dbg) = 0;
1202
1203 // Read up to `n` bytes starting from offset `offset` and store them in
1204 // result, provided `scratch` size should be at least `n`.
1e59de90
TL
1205 //
1206 // After call, result->size() < n only if end of file has been
1207 // reached (or non-OK status). Read might fail if called again after
1208 // first result->size() < n.
1209 //
f67539c2
TL
1210 // Returns Status::OK() on success.
1211 virtual IOStatus Read(uint64_t offset, size_t n, const IOOptions& options,
1212 Slice* result, char* scratch,
1213 IODebugContext* dbg) const = 0;
1214
1215 virtual IOStatus Flush(const IOOptions& options, IODebugContext* dbg) = 0;
1216
1217 virtual IOStatus Sync(const IOOptions& options, IODebugContext* dbg) = 0;
1218
1219 virtual IOStatus Fsync(const IOOptions& options, IODebugContext* dbg) {
1220 return Sync(options, dbg);
1221 }
1222
1223 virtual IOStatus Close(const IOOptions& options, IODebugContext* dbg) = 0;
1224
1e59de90
TL
1225 // EXPERIMENTAL
1226 // When available, returns the actual temperature for the file. This is
1227 // useful in case some outside process moves a file from one tier to another,
1228 // though the temperature is generally expected not to change while a file is
1229 // open.
1230 virtual Temperature GetTemperature() const { return Temperature::kUnknown; }
1231
f67539c2
TL
1232 // If you're adding methods here, remember to add them to
1233 // RandomRWFileWrapper too.
1234
1235 // No copying allowed
1236 FSRandomRWFile(const RandomRWFile&) = delete;
1237 FSRandomRWFile& operator=(const RandomRWFile&) = delete;
1238};
1239
1240// MemoryMappedFileBuffer object represents a memory-mapped file's raw buffer.
1241// Subclasses should release the mapping upon destruction.
1242class FSMemoryMappedFileBuffer {
1243 public:
1244 FSMemoryMappedFileBuffer(void* _base, size_t _length)
1245 : base_(_base), length_(_length) {}
1246
1247 virtual ~FSMemoryMappedFileBuffer() = 0;
1248
1249 // We do not want to unmap this twice. We can make this class
1250 // movable if desired, however, since
1251 FSMemoryMappedFileBuffer(const FSMemoryMappedFileBuffer&) = delete;
1252 FSMemoryMappedFileBuffer& operator=(const FSMemoryMappedFileBuffer&) = delete;
1253
1254 void* GetBase() const { return base_; }
1255 size_t GetLen() const { return length_; }
1256
1257 protected:
1258 void* base_;
1259 const size_t length_;
1260};
1261
1262// Directory object represents collection of files and implements
1263// filesystem operations that can be executed on directories.
1264class FSDirectory {
1265 public:
1266 virtual ~FSDirectory() {}
1267 // Fsync directory. Can be called concurrently from multiple threads.
1268 virtual IOStatus Fsync(const IOOptions& options, IODebugContext* dbg) = 0;
1269
1e59de90
TL
1270 // FsyncWithDirOptions after renaming a file. Depends on the filesystem, it
1271 // may fsync directory or just the renaming file (e.g. btrfs). By default, it
1272 // just calls directory fsync.
1273 virtual IOStatus FsyncWithDirOptions(
1274 const IOOptions& options, IODebugContext* dbg,
1275 const DirFsyncOptions& /*dir_fsync_options*/) {
1276 return Fsync(options, dbg);
1277 }
1278
1279 // Close directory
1280 virtual IOStatus Close(const IOOptions& /*options*/,
1281 IODebugContext* /*dbg*/) {
1282 return IOStatus::NotSupported("Close");
1283 }
1284
f67539c2
TL
1285 virtual size_t GetUniqueId(char* /*id*/, size_t /*max_size*/) const {
1286 return 0;
1287 }
1288
1289 // If you're adding methods here, remember to add them to
1290 // DirectoryWrapper too.
1291};
1292
1293// Below are helpers for wrapping most of the classes in this file.
1294// They forward all calls to another instance of the class.
1295// Useful when wrapping the default implementations.
1296// Typical usage is to inherit your wrapper from *Wrapper, e.g.:
1297//
1298// class MySequentialFileWrapper : public
1299// ROCKSDB_NAMESPACE::FSSequentialFileWrapper {
1300// public:
1301// MySequentialFileWrapper(ROCKSDB_NAMESPACE::FSSequentialFile* target):
1302// ROCKSDB_NAMESPACE::FSSequentialFileWrapper(target) {}
1303// Status Read(size_t n, FileSystem::IOOptions& options, Slice* result,
1304// char* scratch, FileSystem::IODebugContext* dbg) override {
1305// cout << "Doing a read of size " << n << "!" << endl;
1306// return ROCKSDB_NAMESPACE::FSSequentialFileWrapper::Read(n, options,
1307// result,
1308// scratch, dbg);
1309// }
1310// // All other methods are forwarded to target_ automatically.
1311// };
1312//
1313// This is often more convenient than inheriting the class directly because
1314// (a) Don't have to override and forward all methods - the Wrapper will
1315// forward everything you're not explicitly overriding.
1316// (b) Don't need to update the wrapper when more methods are added to the
1317// rocksdb class. Unless you actually want to override the behavior.
1318// (And unless rocksdb people forgot to update the *Wrapper class.)
1319
1320// An implementation of Env that forwards all calls to another Env.
1321// May be useful to clients who wish to override just part of the
1322// functionality of another Env.
1323class FileSystemWrapper : public FileSystem {
1324 public:
1325 // Initialize an EnvWrapper that delegates all calls to *t
1e59de90 1326 explicit FileSystemWrapper(const std::shared_ptr<FileSystem>& t);
f67539c2
TL
1327 ~FileSystemWrapper() override {}
1328
1329 // Return the target to which this Env forwards all calls
20effc67 1330 FileSystem* target() const { return target_.get(); }
f67539c2
TL
1331
1332 // The following text is boilerplate that forwards all methods to target()
1e59de90 1333 IOStatus NewSequentialFile(const std::string& f, const FileOptions& file_opts,
f67539c2
TL
1334 std::unique_ptr<FSSequentialFile>* r,
1335 IODebugContext* dbg) override {
1336 return target_->NewSequentialFile(f, file_opts, r, dbg);
1337 }
1338 IOStatus NewRandomAccessFile(const std::string& f,
1339 const FileOptions& file_opts,
1340 std::unique_ptr<FSRandomAccessFile>* r,
1341 IODebugContext* dbg) override {
1342 return target_->NewRandomAccessFile(f, file_opts, r, dbg);
1343 }
1344 IOStatus NewWritableFile(const std::string& f, const FileOptions& file_opts,
1345 std::unique_ptr<FSWritableFile>* r,
1346 IODebugContext* dbg) override {
1347 return target_->NewWritableFile(f, file_opts, r, dbg);
1348 }
1349 IOStatus ReopenWritableFile(const std::string& fname,
1350 const FileOptions& file_opts,
1351 std::unique_ptr<FSWritableFile>* result,
1352 IODebugContext* dbg) override {
1353 return target_->ReopenWritableFile(fname, file_opts, result, dbg);
1354 }
1355 IOStatus ReuseWritableFile(const std::string& fname,
1356 const std::string& old_fname,
1357 const FileOptions& file_opts,
1358 std::unique_ptr<FSWritableFile>* r,
1359 IODebugContext* dbg) override {
1e59de90 1360 return target_->ReuseWritableFile(fname, old_fname, file_opts, r, dbg);
f67539c2
TL
1361 }
1362 IOStatus NewRandomRWFile(const std::string& fname,
1363 const FileOptions& file_opts,
1364 std::unique_ptr<FSRandomRWFile>* result,
1365 IODebugContext* dbg) override {
1366 return target_->NewRandomRWFile(fname, file_opts, result, dbg);
1367 }
1368 IOStatus NewMemoryMappedFileBuffer(
1369 const std::string& fname,
1370 std::unique_ptr<MemoryMappedFileBuffer>* result) override {
1371 return target_->NewMemoryMappedFileBuffer(fname, result);
1372 }
1373 IOStatus NewDirectory(const std::string& name, const IOOptions& io_opts,
1374 std::unique_ptr<FSDirectory>* result,
1375 IODebugContext* dbg) override {
1376 return target_->NewDirectory(name, io_opts, result, dbg);
1377 }
1378 IOStatus FileExists(const std::string& f, const IOOptions& io_opts,
1379 IODebugContext* dbg) override {
1380 return target_->FileExists(f, io_opts, dbg);
1381 }
1382 IOStatus GetChildren(const std::string& dir, const IOOptions& io_opts,
1383 std::vector<std::string>* r,
1384 IODebugContext* dbg) override {
1385 return target_->GetChildren(dir, io_opts, r, dbg);
1386 }
1387 IOStatus GetChildrenFileAttributes(const std::string& dir,
1388 const IOOptions& options,
1389 std::vector<FileAttributes>* result,
1390 IODebugContext* dbg) override {
1391 return target_->GetChildrenFileAttributes(dir, options, result, dbg);
1392 }
1393 IOStatus DeleteFile(const std::string& f, const IOOptions& options,
1394 IODebugContext* dbg) override {
1395 return target_->DeleteFile(f, options, dbg);
1396 }
1397 IOStatus Truncate(const std::string& fname, size_t size,
1398 const IOOptions& options, IODebugContext* dbg) override {
1399 return target_->Truncate(fname, size, options, dbg);
1400 }
1401 IOStatus CreateDir(const std::string& d, const IOOptions& options,
1402 IODebugContext* dbg) override {
1403 return target_->CreateDir(d, options, dbg);
1404 }
1405 IOStatus CreateDirIfMissing(const std::string& d, const IOOptions& options,
1406 IODebugContext* dbg) override {
1407 return target_->CreateDirIfMissing(d, options, dbg);
1408 }
1409 IOStatus DeleteDir(const std::string& d, const IOOptions& options,
1410 IODebugContext* dbg) override {
1411 return target_->DeleteDir(d, options, dbg);
1412 }
1413 IOStatus GetFileSize(const std::string& f, const IOOptions& options,
1414 uint64_t* s, IODebugContext* dbg) override {
1415 return target_->GetFileSize(f, options, s, dbg);
1416 }
1417
1418 IOStatus GetFileModificationTime(const std::string& fname,
1419 const IOOptions& options,
1420 uint64_t* file_mtime,
1421 IODebugContext* dbg) override {
1422 return target_->GetFileModificationTime(fname, options, file_mtime, dbg);
1423 }
1424
1425 IOStatus GetAbsolutePath(const std::string& db_path, const IOOptions& options,
1426 std::string* output_path,
1427 IODebugContext* dbg) override {
1428 return target_->GetAbsolutePath(db_path, options, output_path, dbg);
1429 }
1430
1431 IOStatus RenameFile(const std::string& s, const std::string& t,
1432 const IOOptions& options, IODebugContext* dbg) override {
1433 return target_->RenameFile(s, t, options, dbg);
1434 }
1435
1436 IOStatus LinkFile(const std::string& s, const std::string& t,
1437 const IOOptions& options, IODebugContext* dbg) override {
1438 return target_->LinkFile(s, t, options, dbg);
1439 }
1440
1441 IOStatus NumFileLinks(const std::string& fname, const IOOptions& options,
1442 uint64_t* count, IODebugContext* dbg) override {
1443 return target_->NumFileLinks(fname, options, count, dbg);
1444 }
1445
1446 IOStatus AreFilesSame(const std::string& first, const std::string& second,
1447 const IOOptions& options, bool* res,
1448 IODebugContext* dbg) override {
1449 return target_->AreFilesSame(first, second, options, res, dbg);
1450 }
1451
1452 IOStatus LockFile(const std::string& f, const IOOptions& options,
1453 FileLock** l, IODebugContext* dbg) override {
1454 return target_->LockFile(f, options, l, dbg);
1455 }
1456
1457 IOStatus UnlockFile(FileLock* l, const IOOptions& options,
1458 IODebugContext* dbg) override {
1459 return target_->UnlockFile(l, options, dbg);
1460 }
1461
1462 IOStatus GetTestDirectory(const IOOptions& options, std::string* path,
1463 IODebugContext* dbg) override {
1464 return target_->GetTestDirectory(options, path, dbg);
1465 }
1466 IOStatus NewLogger(const std::string& fname, const IOOptions& options,
1467 std::shared_ptr<Logger>* result,
1468 IODebugContext* dbg) override {
1469 return target_->NewLogger(fname, options, result, dbg);
1470 }
1471
20effc67
TL
1472 void SanitizeFileOptions(FileOptions* opts) const override {
1473 target_->SanitizeFileOptions(opts);
1474 }
1475
f67539c2 1476 FileOptions OptimizeForLogRead(
1e59de90 1477 const FileOptions& file_options) const override {
f67539c2
TL
1478 return target_->OptimizeForLogRead(file_options);
1479 }
1480 FileOptions OptimizeForManifestRead(
1481 const FileOptions& file_options) const override {
1482 return target_->OptimizeForManifestRead(file_options);
1483 }
1484 FileOptions OptimizeForLogWrite(const FileOptions& file_options,
1e59de90 1485 const DBOptions& db_options) const override {
f67539c2
TL
1486 return target_->OptimizeForLogWrite(file_options, db_options);
1487 }
1488 FileOptions OptimizeForManifestWrite(
1489 const FileOptions& file_options) const override {
1490 return target_->OptimizeForManifestWrite(file_options);
1491 }
1492 FileOptions OptimizeForCompactionTableWrite(
1493 const FileOptions& file_options,
1494 const ImmutableDBOptions& immutable_ops) const override {
1495 return target_->OptimizeForCompactionTableWrite(file_options,
1496 immutable_ops);
1497 }
1498 FileOptions OptimizeForCompactionTableRead(
1499 const FileOptions& file_options,
1500 const ImmutableDBOptions& db_options) const override {
1501 return target_->OptimizeForCompactionTableRead(file_options, db_options);
1502 }
1e59de90
TL
1503 FileOptions OptimizeForBlobFileRead(
1504 const FileOptions& file_options,
1505 const ImmutableDBOptions& db_options) const override {
1506 return target_->OptimizeForBlobFileRead(file_options, db_options);
1507 }
f67539c2
TL
1508 IOStatus GetFreeSpace(const std::string& path, const IOOptions& options,
1509 uint64_t* diskfree, IODebugContext* dbg) override {
1510 return target_->GetFreeSpace(path, options, diskfree, dbg);
1511 }
20effc67
TL
1512 IOStatus IsDirectory(const std::string& path, const IOOptions& options,
1513 bool* is_dir, IODebugContext* dbg) override {
1514 return target_->IsDirectory(path, options, is_dir, dbg);
1515 }
f67539c2 1516
1e59de90
TL
1517 const Customizable* Inner() const override { return target_.get(); }
1518 Status PrepareOptions(const ConfigOptions& options) override;
1519#ifndef ROCKSDB_LITE
1520 std::string SerializeOptions(const ConfigOptions& config_options,
1521 const std::string& header) const override;
1522#endif // ROCKSDB_LITE
1523
1524 virtual IOStatus Poll(std::vector<void*>& io_handles,
1525 size_t min_completions) override {
1526 return target_->Poll(io_handles, min_completions);
1527 }
1528
1529 virtual IOStatus AbortIO(std::vector<void*>& io_handles) override {
1530 return target_->AbortIO(io_handles);
1531 }
1532
1533 protected:
20effc67 1534 std::shared_ptr<FileSystem> target_;
f67539c2
TL
1535};
1536
1537class FSSequentialFileWrapper : public FSSequentialFile {
1538 public:
1e59de90
TL
1539 // Creates a FileWrapper around the input File object and without
1540 // taking ownership of the object
20effc67
TL
1541 explicit FSSequentialFileWrapper(FSSequentialFile* t) : target_(t) {}
1542
1543 FSSequentialFile* target() const { return target_; }
f67539c2
TL
1544
1545 IOStatus Read(size_t n, const IOOptions& options, Slice* result,
1546 char* scratch, IODebugContext* dbg) override {
1547 return target_->Read(n, options, result, scratch, dbg);
1548 }
1549 IOStatus Skip(uint64_t n) override { return target_->Skip(n); }
1550 bool use_direct_io() const override { return target_->use_direct_io(); }
1551 size_t GetRequiredBufferAlignment() const override {
1552 return target_->GetRequiredBufferAlignment();
1553 }
1554 IOStatus InvalidateCache(size_t offset, size_t length) override {
1555 return target_->InvalidateCache(offset, length);
1556 }
1557 IOStatus PositionedRead(uint64_t offset, size_t n, const IOOptions& options,
1558 Slice* result, char* scratch,
1559 IODebugContext* dbg) override {
1560 return target_->PositionedRead(offset, n, options, result, scratch, dbg);
1561 }
1e59de90
TL
1562 Temperature GetTemperature() const override {
1563 return target_->GetTemperature();
1564 }
f67539c2
TL
1565
1566 private:
1567 FSSequentialFile* target_;
1568};
1569
1e59de90
TL
1570class FSSequentialFileOwnerWrapper : public FSSequentialFileWrapper {
1571 public:
1572 // Creates a FileWrapper around the input File object and takes
1573 // ownership of the object
1574 explicit FSSequentialFileOwnerWrapper(std::unique_ptr<FSSequentialFile>&& t)
1575 : FSSequentialFileWrapper(t.get()), guard_(std::move(t)) {}
1576
1577 private:
1578 std::unique_ptr<FSSequentialFile> guard_;
1579};
1580
f67539c2
TL
1581class FSRandomAccessFileWrapper : public FSRandomAccessFile {
1582 public:
1e59de90
TL
1583 // Creates a FileWrapper around the input File object and without
1584 // taking ownership of the object
20effc67
TL
1585 explicit FSRandomAccessFileWrapper(FSRandomAccessFile* t) : target_(t) {}
1586
1587 FSRandomAccessFile* target() const { return target_; }
f67539c2
TL
1588
1589 IOStatus Read(uint64_t offset, size_t n, const IOOptions& options,
1590 Slice* result, char* scratch,
1591 IODebugContext* dbg) const override {
1592 return target_->Read(offset, n, options, result, scratch, dbg);
1593 }
1594 IOStatus MultiRead(FSReadRequest* reqs, size_t num_reqs,
1595 const IOOptions& options, IODebugContext* dbg) override {
1596 return target_->MultiRead(reqs, num_reqs, options, dbg);
1597 }
1598 IOStatus Prefetch(uint64_t offset, size_t n, const IOOptions& options,
1599 IODebugContext* dbg) override {
1600 return target_->Prefetch(offset, n, options, dbg);
1601 }
1602 size_t GetUniqueId(char* id, size_t max_size) const override {
1603 return target_->GetUniqueId(id, max_size);
1604 };
1605 void Hint(AccessPattern pattern) override { target_->Hint(pattern); }
1606 bool use_direct_io() const override { return target_->use_direct_io(); }
1607 size_t GetRequiredBufferAlignment() const override {
1608 return target_->GetRequiredBufferAlignment();
1609 }
1610 IOStatus InvalidateCache(size_t offset, size_t length) override {
1611 return target_->InvalidateCache(offset, length);
1612 }
1e59de90
TL
1613 IOStatus ReadAsync(FSReadRequest& req, const IOOptions& opts,
1614 std::function<void(const FSReadRequest&, void*)> cb,
1615 void* cb_arg, void** io_handle, IOHandleDeleter* del_fn,
1616 IODebugContext* dbg) override {
1617 return target()->ReadAsync(req, opts, cb, cb_arg, io_handle, del_fn, dbg);
1618 }
1619 Temperature GetTemperature() const override {
1620 return target_->GetTemperature();
1621 }
f67539c2
TL
1622
1623 private:
1e59de90 1624 std::unique_ptr<FSRandomAccessFile> guard_;
f67539c2
TL
1625 FSRandomAccessFile* target_;
1626};
1627
1e59de90
TL
1628class FSRandomAccessFileOwnerWrapper : public FSRandomAccessFileWrapper {
1629 public:
1630 // Creates a FileWrapper around the input File object and takes
1631 // ownership of the object
1632 explicit FSRandomAccessFileOwnerWrapper(
1633 std::unique_ptr<FSRandomAccessFile>&& t)
1634 : FSRandomAccessFileWrapper(t.get()), guard_(std::move(t)) {}
1635
1636 private:
1637 std::unique_ptr<FSRandomAccessFile> guard_;
1638};
1639
f67539c2
TL
1640class FSWritableFileWrapper : public FSWritableFile {
1641 public:
1e59de90
TL
1642 // Creates a FileWrapper around the input File object and without
1643 // taking ownership of the object
f67539c2
TL
1644 explicit FSWritableFileWrapper(FSWritableFile* t) : target_(t) {}
1645
20effc67
TL
1646 FSWritableFile* target() const { return target_; }
1647
f67539c2
TL
1648 IOStatus Append(const Slice& data, const IOOptions& options,
1649 IODebugContext* dbg) override {
1650 return target_->Append(data, options, dbg);
1651 }
20effc67
TL
1652 IOStatus Append(const Slice& data, const IOOptions& options,
1653 const DataVerificationInfo& verification_info,
1654 IODebugContext* dbg) override {
1655 return target_->Append(data, options, verification_info, dbg);
1656 }
f67539c2
TL
1657 IOStatus PositionedAppend(const Slice& data, uint64_t offset,
1658 const IOOptions& options,
1659 IODebugContext* dbg) override {
1660 return target_->PositionedAppend(data, offset, options, dbg);
1661 }
20effc67
TL
1662 IOStatus PositionedAppend(const Slice& data, uint64_t offset,
1663 const IOOptions& options,
1664 const DataVerificationInfo& verification_info,
1665 IODebugContext* dbg) override {
1666 return target_->PositionedAppend(data, offset, options, verification_info,
1667 dbg);
1668 }
f67539c2
TL
1669 IOStatus Truncate(uint64_t size, const IOOptions& options,
1670 IODebugContext* dbg) override {
1671 return target_->Truncate(size, options, dbg);
1672 }
1673 IOStatus Close(const IOOptions& options, IODebugContext* dbg) override {
1674 return target_->Close(options, dbg);
1675 }
1676 IOStatus Flush(const IOOptions& options, IODebugContext* dbg) override {
1677 return target_->Flush(options, dbg);
1678 }
1679 IOStatus Sync(const IOOptions& options, IODebugContext* dbg) override {
1680 return target_->Sync(options, dbg);
1681 }
1682 IOStatus Fsync(const IOOptions& options, IODebugContext* dbg) override {
1683 return target_->Fsync(options, dbg);
1684 }
1685 bool IsSyncThreadSafe() const override { return target_->IsSyncThreadSafe(); }
1686
1687 bool use_direct_io() const override { return target_->use_direct_io(); }
1688
1689 size_t GetRequiredBufferAlignment() const override {
1690 return target_->GetRequiredBufferAlignment();
1691 }
1692
1693 void SetWriteLifeTimeHint(Env::WriteLifeTimeHint hint) override {
1694 target_->SetWriteLifeTimeHint(hint);
1695 }
1696
1697 Env::WriteLifeTimeHint GetWriteLifeTimeHint() override {
1698 return target_->GetWriteLifeTimeHint();
1699 }
1700
1701 uint64_t GetFileSize(const IOOptions& options, IODebugContext* dbg) override {
1702 return target_->GetFileSize(options, dbg);
1703 }
1704
1705 void SetPreallocationBlockSize(size_t size) override {
1706 target_->SetPreallocationBlockSize(size);
1707 }
1708
1709 void GetPreallocationStatus(size_t* block_size,
1710 size_t* last_allocated_block) override {
1711 target_->GetPreallocationStatus(block_size, last_allocated_block);
1712 }
1713
1714 size_t GetUniqueId(char* id, size_t max_size) const override {
1715 return target_->GetUniqueId(id, max_size);
1716 }
1717
1718 IOStatus InvalidateCache(size_t offset, size_t length) override {
1719 return target_->InvalidateCache(offset, length);
1720 }
1721
1722 IOStatus RangeSync(uint64_t offset, uint64_t nbytes, const IOOptions& options,
1723 IODebugContext* dbg) override {
1724 return target_->RangeSync(offset, nbytes, options, dbg);
1725 }
1726
1727 void PrepareWrite(size_t offset, size_t len, const IOOptions& options,
1728 IODebugContext* dbg) override {
1729 target_->PrepareWrite(offset, len, options, dbg);
1730 }
1731
1732 IOStatus Allocate(uint64_t offset, uint64_t len, const IOOptions& options,
1733 IODebugContext* dbg) override {
1734 return target_->Allocate(offset, len, options, dbg);
1735 }
1736
1737 private:
1738 FSWritableFile* target_;
1739};
1740
1e59de90
TL
1741class FSWritableFileOwnerWrapper : public FSWritableFileWrapper {
1742 public:
1743 // Creates a FileWrapper around the input File object and takes
1744 // ownership of the object
1745 explicit FSWritableFileOwnerWrapper(std::unique_ptr<FSWritableFile>&& t)
1746 : FSWritableFileWrapper(t.get()), guard_(std::move(t)) {}
1747
1748 private:
1749 std::unique_ptr<FSWritableFile> guard_;
1750};
1751
f67539c2
TL
1752class FSRandomRWFileWrapper : public FSRandomRWFile {
1753 public:
1e59de90
TL
1754 // Creates a FileWrapper around the input File object and without
1755 // taking ownership of the object
20effc67
TL
1756 explicit FSRandomRWFileWrapper(FSRandomRWFile* t) : target_(t) {}
1757
1758 FSRandomRWFile* target() const { return target_; }
f67539c2
TL
1759
1760 bool use_direct_io() const override { return target_->use_direct_io(); }
1761 size_t GetRequiredBufferAlignment() const override {
1762 return target_->GetRequiredBufferAlignment();
1763 }
1764 IOStatus Write(uint64_t offset, const Slice& data, const IOOptions& options,
1765 IODebugContext* dbg) override {
1766 return target_->Write(offset, data, options, dbg);
1767 }
1768 IOStatus Read(uint64_t offset, size_t n, const IOOptions& options,
1769 Slice* result, char* scratch,
1770 IODebugContext* dbg) const override {
1771 return target_->Read(offset, n, options, result, scratch, dbg);
1772 }
1773 IOStatus Flush(const IOOptions& options, IODebugContext* dbg) override {
1774 return target_->Flush(options, dbg);
1775 }
1776 IOStatus Sync(const IOOptions& options, IODebugContext* dbg) override {
1777 return target_->Sync(options, dbg);
1778 }
1779 IOStatus Fsync(const IOOptions& options, IODebugContext* dbg) override {
1780 return target_->Fsync(options, dbg);
1781 }
1782 IOStatus Close(const IOOptions& options, IODebugContext* dbg) override {
1783 return target_->Close(options, dbg);
1784 }
1e59de90
TL
1785 Temperature GetTemperature() const override {
1786 return target_->GetTemperature();
1787 }
f67539c2
TL
1788
1789 private:
1790 FSRandomRWFile* target_;
1791};
1792
1e59de90
TL
1793class FSRandomRWFileOwnerWrapper : public FSRandomRWFileWrapper {
1794 public:
1795 // Creates a FileWrapper around the input File object and takes
1796 // ownership of the object
1797 explicit FSRandomRWFileOwnerWrapper(std::unique_ptr<FSRandomRWFile>&& t)
1798 : FSRandomRWFileWrapper(t.get()), guard_(std::move(t)) {}
1799
1800 private:
1801 std::unique_ptr<FSRandomRWFile> guard_;
1802};
1803
f67539c2
TL
1804class FSDirectoryWrapper : public FSDirectory {
1805 public:
1e59de90
TL
1806 // Creates a FileWrapper around the input File object and takes
1807 // ownership of the object
1808 explicit FSDirectoryWrapper(std::unique_ptr<FSDirectory>&& t)
1809 : guard_(std::move(t)) {
1810 target_ = guard_.get();
1811 }
1812
1813 // Creates a FileWrapper around the input File object and without
1814 // taking ownership of the object
20effc67 1815 explicit FSDirectoryWrapper(FSDirectory* t) : target_(t) {}
f67539c2
TL
1816
1817 IOStatus Fsync(const IOOptions& options, IODebugContext* dbg) override {
1818 return target_->Fsync(options, dbg);
1819 }
1e59de90
TL
1820
1821 IOStatus FsyncWithDirOptions(
1822 const IOOptions& options, IODebugContext* dbg,
1823 const DirFsyncOptions& dir_fsync_options) override {
1824 return target_->FsyncWithDirOptions(options, dbg, dir_fsync_options);
1825 }
1826
1827 IOStatus Close(const IOOptions& options, IODebugContext* dbg) override {
1828 return target_->Close(options, dbg);
1829 }
1830
f67539c2
TL
1831 size_t GetUniqueId(char* id, size_t max_size) const override {
1832 return target_->GetUniqueId(id, max_size);
1833 }
1834
1835 private:
1e59de90 1836 std::unique_ptr<FSDirectory> guard_;
f67539c2
TL
1837 FSDirectory* target_;
1838};
1839
20effc67
TL
1840// A utility routine: write "data" to the named file.
1841extern IOStatus WriteStringToFile(FileSystem* fs, const Slice& data,
1842 const std::string& fname,
1843 bool should_sync = false);
1844
f67539c2 1845// A utility routine: read contents of named file into *data
20effc67
TL
1846extern IOStatus ReadFileToString(FileSystem* fs, const std::string& fname,
1847 std::string* data);
f67539c2
TL
1848
1849} // namespace ROCKSDB_NAMESPACE