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 #pragma once
7 
8 #include "rocksdb/env.h"
9 #include "rocksdb/file_system.h"
10 
11 namespace ROCKSDB_NAMESPACE {
12 
13 // The CompositeEnvWrapper class provides an interface that is compatible
14 // with the old monolithic Env API, and an implementation that wraps around
15 // the new Env that provides threading and other OS related functionality, and
16 // the new FileSystem API that provides storage functionality. By
17 // providing the old Env interface, it allows the rest of RocksDB code to
18 // be agnostic of whether the underlying Env implementation is a monolithic
19 // Env or an Env + FileSystem. In the former case, the user will specify
20 // Options::env only, whereas in the latter case, the user will specify
21 // Options::env and Options::file_system.
22 
status_to_io_status(Status && status)23 inline IOStatus status_to_io_status(Status&& status) {
24   if (status.ok()) {
25     // Fast path
26     return IOStatus::OK();
27   } else {
28     const char* state = status.getState();
29     if (state) {
30       return IOStatus(status.code(), status.subcode(),
31                       Slice(state, strlen(status.getState()) + 1),
32                       Slice());
33     } else {
34       return IOStatus(status.code(), status.subcode());
35     }
36   }
37 }
38 
39 class CompositeSequentialFileWrapper : public SequentialFile {
40  public:
CompositeSequentialFileWrapper(std::unique_ptr<FSSequentialFile> & target)41   explicit CompositeSequentialFileWrapper(
42       std::unique_ptr<FSSequentialFile>& target)
43       : target_(std::move(target)) {}
44 
Read(size_t n,Slice * result,char * scratch)45   Status Read(size_t n, Slice* result, char* scratch) override {
46     IOOptions io_opts;
47     IODebugContext dbg;
48     return target_->Read(n, io_opts, result, scratch, &dbg);
49   }
Skip(uint64_t n)50   Status Skip(uint64_t n) override { return target_->Skip(n); }
use_direct_io()51   bool use_direct_io() const override { return target_->use_direct_io(); }
GetRequiredBufferAlignment()52   size_t GetRequiredBufferAlignment() const override {
53     return target_->GetRequiredBufferAlignment();
54   }
InvalidateCache(size_t offset,size_t length)55   Status InvalidateCache(size_t offset, size_t length) override {
56     return target_->InvalidateCache(offset, length);
57   }
PositionedRead(uint64_t offset,size_t n,Slice * result,char * scratch)58   Status PositionedRead(uint64_t offset, size_t n, Slice* result,
59                         char* scratch) override {
60     IOOptions io_opts;
61     IODebugContext dbg;
62     return target_->PositionedRead(offset, n, io_opts, result, scratch, &dbg);
63   }
64 
65  private:
66   std::unique_ptr<FSSequentialFile> target_;
67 };
68 
69 class CompositeRandomAccessFileWrapper : public RandomAccessFile {
70  public:
CompositeRandomAccessFileWrapper(std::unique_ptr<FSRandomAccessFile> & target)71   explicit CompositeRandomAccessFileWrapper(
72       std::unique_ptr<FSRandomAccessFile>& target)
73       : target_(std::move(target)) {}
74 
Read(uint64_t offset,size_t n,Slice * result,char * scratch)75   Status Read(uint64_t offset, size_t n, Slice* result,
76               char* scratch) const override {
77     IOOptions io_opts;
78     IODebugContext dbg;
79     return target_->Read(offset, n, io_opts, result, scratch, &dbg);
80   }
MultiRead(ReadRequest * reqs,size_t num_reqs)81   Status MultiRead(ReadRequest* reqs, size_t num_reqs) override {
82     IOOptions io_opts;
83     IODebugContext dbg;
84     std::vector<FSReadRequest> fs_reqs;
85     Status status;
86 
87     fs_reqs.resize(num_reqs);
88     for (size_t i = 0; i < num_reqs; ++i) {
89       fs_reqs[i].offset = reqs[i].offset;
90       fs_reqs[i].len = reqs[i].len;
91       fs_reqs[i].scratch = reqs[i].scratch;
92       fs_reqs[i].status = IOStatus::OK();
93     }
94     status = target_->MultiRead(fs_reqs.data(), num_reqs, io_opts, &dbg);
95     for (size_t i = 0; i < num_reqs; ++i) {
96       reqs[i].result = fs_reqs[i].result;
97       reqs[i].status = fs_reqs[i].status;
98     }
99     return status;
100   }
Prefetch(uint64_t offset,size_t n)101   Status Prefetch(uint64_t offset, size_t n) override {
102     IOOptions io_opts;
103     IODebugContext dbg;
104     return target_->Prefetch(offset, n, io_opts, &dbg);
105   }
GetUniqueId(char * id,size_t max_size)106   size_t GetUniqueId(char* id, size_t max_size) const override {
107     return target_->GetUniqueId(id, max_size);
108   };
Hint(AccessPattern pattern)109   void Hint(AccessPattern pattern) override {
110     target_->Hint((FSRandomAccessFile::AccessPattern)pattern);
111   }
use_direct_io()112   bool use_direct_io() const override { return target_->use_direct_io(); }
GetRequiredBufferAlignment()113   size_t GetRequiredBufferAlignment() const override {
114     return target_->GetRequiredBufferAlignment();
115   }
InvalidateCache(size_t offset,size_t length)116   Status InvalidateCache(size_t offset, size_t length) override {
117     return target_->InvalidateCache(offset, length);
118   }
119 
120  private:
121   std::unique_ptr<FSRandomAccessFile> target_;
122 };
123 
124 class CompositeWritableFileWrapper : public WritableFile {
125  public:
CompositeWritableFileWrapper(std::unique_ptr<FSWritableFile> & t)126   explicit CompositeWritableFileWrapper(std::unique_ptr<FSWritableFile>& t)
127       : target_(std::move(t)) {}
128 
Append(const Slice & data)129   Status Append(const Slice& data) override {
130     IOOptions io_opts;
131     IODebugContext dbg;
132     return target_->Append(data, io_opts, &dbg);
133   }
PositionedAppend(const Slice & data,uint64_t offset)134   Status PositionedAppend(const Slice& data, uint64_t offset) override {
135     IOOptions io_opts;
136     IODebugContext dbg;
137     return target_->PositionedAppend(data, offset, io_opts, &dbg);
138   }
Truncate(uint64_t size)139   Status Truncate(uint64_t size) override {
140     IOOptions io_opts;
141     IODebugContext dbg;
142     return target_->Truncate(size, io_opts, &dbg);
143   }
Close()144   Status Close() override {
145     IOOptions io_opts;
146     IODebugContext dbg;
147     return target_->Close(io_opts, &dbg);
148   }
Flush()149   Status Flush() override {
150     IOOptions io_opts;
151     IODebugContext dbg;
152     return target_->Flush(io_opts, &dbg);
153   }
Sync()154   Status Sync() override {
155     IOOptions io_opts;
156     IODebugContext dbg;
157     return target_->Sync(io_opts, &dbg);
158   }
Fsync()159   Status Fsync() override {
160     IOOptions io_opts;
161     IODebugContext dbg;
162     return target_->Fsync(io_opts, &dbg);
163   }
IsSyncThreadSafe()164   bool IsSyncThreadSafe() const override { return target_->IsSyncThreadSafe(); }
165 
use_direct_io()166   bool use_direct_io() const override { return target_->use_direct_io(); }
167 
GetRequiredBufferAlignment()168   size_t GetRequiredBufferAlignment() const override {
169     return target_->GetRequiredBufferAlignment();
170   }
171 
SetWriteLifeTimeHint(Env::WriteLifeTimeHint hint)172   void SetWriteLifeTimeHint(Env::WriteLifeTimeHint hint) override {
173     target_->SetWriteLifeTimeHint(hint);
174   }
175 
GetWriteLifeTimeHint()176   Env::WriteLifeTimeHint GetWriteLifeTimeHint() override {
177     return target_->GetWriteLifeTimeHint();
178   }
179 
GetFileSize()180   uint64_t GetFileSize() override {
181     IOOptions io_opts;
182     IODebugContext dbg;
183     return target_->GetFileSize(io_opts, &dbg);
184   }
185 
SetPreallocationBlockSize(size_t size)186   void SetPreallocationBlockSize(size_t size) override {
187     target_->SetPreallocationBlockSize(size);
188   }
189 
GetPreallocationStatus(size_t * block_size,size_t * last_allocated_block)190   void GetPreallocationStatus(size_t* block_size,
191                               size_t* last_allocated_block) override {
192     target_->GetPreallocationStatus(block_size, last_allocated_block);
193   }
194 
GetUniqueId(char * id,size_t max_size)195   size_t GetUniqueId(char* id, size_t max_size) const override {
196     return target_->GetUniqueId(id, max_size);
197   }
198 
InvalidateCache(size_t offset,size_t length)199   Status InvalidateCache(size_t offset, size_t length) override {
200     return target_->InvalidateCache(offset, length);
201   }
202 
RangeSync(uint64_t offset,uint64_t nbytes)203   Status RangeSync(uint64_t offset, uint64_t nbytes) override {
204     IOOptions io_opts;
205     IODebugContext dbg;
206     return target_->RangeSync(offset, nbytes, io_opts, &dbg);
207   }
208 
PrepareWrite(size_t offset,size_t len)209   void PrepareWrite(size_t offset, size_t len) override {
210     IOOptions io_opts;
211     IODebugContext dbg;
212     target_->PrepareWrite(offset, len, io_opts, &dbg);
213   }
214 
Allocate(uint64_t offset,uint64_t len)215   Status Allocate(uint64_t offset, uint64_t len) override {
216     IOOptions io_opts;
217     IODebugContext dbg;
218     return target_->Allocate(offset, len, io_opts, &dbg);
219   }
220 
target()221   std::unique_ptr<FSWritableFile>* target() { return &target_; }
222 
223  private:
224   std::unique_ptr<FSWritableFile> target_;
225 };
226 
227 class CompositeRandomRWFileWrapper : public RandomRWFile {
228  public:
CompositeRandomRWFileWrapper(std::unique_ptr<FSRandomRWFile> & target)229   explicit CompositeRandomRWFileWrapper(std::unique_ptr<FSRandomRWFile>& target)
230       : target_(std::move(target)) {}
231 
use_direct_io()232   bool use_direct_io() const override { return target_->use_direct_io(); }
GetRequiredBufferAlignment()233   size_t GetRequiredBufferAlignment() const override {
234     return target_->GetRequiredBufferAlignment();
235   }
Write(uint64_t offset,const Slice & data)236   Status Write(uint64_t offset, const Slice& data) override {
237     IOOptions io_opts;
238     IODebugContext dbg;
239     return target_->Write(offset, data, io_opts, &dbg);
240   }
Read(uint64_t offset,size_t n,Slice * result,char * scratch)241   Status Read(uint64_t offset, size_t n, Slice* result,
242               char* scratch) const override {
243     IOOptions io_opts;
244     IODebugContext dbg;
245     return target_->Read(offset, n, io_opts, result, scratch, &dbg);
246   }
Flush()247   Status Flush() override {
248     IOOptions io_opts;
249     IODebugContext dbg;
250     return target_->Flush(io_opts, &dbg);
251   }
Sync()252   Status Sync() override {
253     IOOptions io_opts;
254     IODebugContext dbg;
255     return target_->Sync(io_opts, &dbg);
256   }
Fsync()257   Status Fsync() override {
258     IOOptions io_opts;
259     IODebugContext dbg;
260     return target_->Fsync(io_opts, &dbg);
261   }
Close()262   Status Close() override {
263     IOOptions io_opts;
264     IODebugContext dbg;
265     return target_->Close(io_opts, &dbg);
266   }
267 
268  private:
269   std::unique_ptr<FSRandomRWFile> target_;
270 };
271 
272 class CompositeDirectoryWrapper : public Directory {
273  public:
CompositeDirectoryWrapper(std::unique_ptr<FSDirectory> & target)274   explicit CompositeDirectoryWrapper(std::unique_ptr<FSDirectory>& target)
275       : target_(std::move(target)) {}
276 
Fsync()277   Status Fsync() override {
278     IOOptions io_opts;
279     IODebugContext dbg;
280     return target_->Fsync(io_opts, &dbg);
281   }
GetUniqueId(char * id,size_t max_size)282   size_t GetUniqueId(char* id, size_t max_size) const override {
283     return target_->GetUniqueId(id, max_size);
284   }
285 
286  private:
287   std::unique_ptr<FSDirectory> target_;
288 };
289 
290 class CompositeEnvWrapper : public Env {
291  public:
292   // Initialize a CompositeEnvWrapper that delegates all thread/time related
293   // calls to env, and all file operations to fs
CompositeEnvWrapper(Env * env,FileSystem * fs)294   explicit CompositeEnvWrapper(Env* env, FileSystem* fs)
295       : env_target_(env), fs_env_target_(fs) {}
~CompositeEnvWrapper()296   ~CompositeEnvWrapper() {}
297 
298   // Return the target to which this Env forwards all calls
env_target()299   Env* env_target() const { return env_target_; }
300 
fs_env_target()301   FileSystem* fs_env_target() const { return fs_env_target_; }
302 
303   // The following text is boilerplate that forwards all methods to target()
NewSequentialFile(const std::string & f,std::unique_ptr<SequentialFile> * r,const EnvOptions & options)304   Status NewSequentialFile(const std::string& f,
305                            std::unique_ptr<SequentialFile>* r,
306                            const EnvOptions& options) override {
307     IODebugContext dbg;
308     std::unique_ptr<FSSequentialFile> file;
309     Status status;
310     status =
311         fs_env_target_->NewSequentialFile(f, FileOptions(options), &file, &dbg);
312     if (status.ok()) {
313       r->reset(new CompositeSequentialFileWrapper(file));
314     }
315     return status;
316   }
NewRandomAccessFile(const std::string & f,std::unique_ptr<RandomAccessFile> * r,const EnvOptions & options)317   Status NewRandomAccessFile(const std::string& f,
318                              std::unique_ptr<RandomAccessFile>* r,
319                              const EnvOptions& options) override {
320     IODebugContext dbg;
321     std::unique_ptr<FSRandomAccessFile> file;
322     Status status;
323     status = fs_env_target_->NewRandomAccessFile(f, FileOptions(options), &file,
324                                                  &dbg);
325     if (status.ok()) {
326       r->reset(new CompositeRandomAccessFileWrapper(file));
327     }
328     return status;
329   }
NewWritableFile(const std::string & f,std::unique_ptr<WritableFile> * r,const EnvOptions & options)330   Status NewWritableFile(const std::string& f, std::unique_ptr<WritableFile>* r,
331                          const EnvOptions& options) override {
332     IODebugContext dbg;
333     std::unique_ptr<FSWritableFile> file;
334     Status status;
335     status =
336         fs_env_target_->NewWritableFile(f, FileOptions(options), &file, &dbg);
337     if (status.ok()) {
338       r->reset(new CompositeWritableFileWrapper(file));
339     }
340     return status;
341   }
ReopenWritableFile(const std::string & fname,std::unique_ptr<WritableFile> * result,const EnvOptions & options)342   Status ReopenWritableFile(const std::string& fname,
343                             std::unique_ptr<WritableFile>* result,
344                             const EnvOptions& options) override {
345     IODebugContext dbg;
346     Status status;
347     std::unique_ptr<FSWritableFile> file;
348     status = fs_env_target_->ReopenWritableFile(fname, FileOptions(options),
349                                                 &file, &dbg);
350     if (status.ok()) {
351       result->reset(new CompositeWritableFileWrapper(file));
352     }
353     return status;
354   }
ReuseWritableFile(const std::string & fname,const std::string & old_fname,std::unique_ptr<WritableFile> * r,const EnvOptions & options)355   Status ReuseWritableFile(const std::string& fname,
356                            const std::string& old_fname,
357                            std::unique_ptr<WritableFile>* r,
358                            const EnvOptions& options) override {
359     IODebugContext dbg;
360     Status status;
361     std::unique_ptr<FSWritableFile> file;
362     status = fs_env_target_->ReuseWritableFile(
363         fname, old_fname, FileOptions(options), &file, &dbg);
364     if (status.ok()) {
365       r->reset(new CompositeWritableFileWrapper(file));
366     }
367     return status;
368   }
NewRandomRWFile(const std::string & fname,std::unique_ptr<RandomRWFile> * result,const EnvOptions & options)369   Status NewRandomRWFile(const std::string& fname,
370                          std::unique_ptr<RandomRWFile>* result,
371                          const EnvOptions& options) override {
372     IODebugContext dbg;
373     std::unique_ptr<FSRandomRWFile> file;
374     Status status;
375     status = fs_env_target_->NewRandomRWFile(fname, FileOptions(options), &file,
376                                              &dbg);
377     if (status.ok()) {
378       result->reset(new CompositeRandomRWFileWrapper(file));
379     }
380     return status;
381   }
NewMemoryMappedFileBuffer(const std::string & fname,std::unique_ptr<MemoryMappedFileBuffer> * result)382   Status NewMemoryMappedFileBuffer(
383       const std::string& fname,
384       std::unique_ptr<MemoryMappedFileBuffer>* result) override {
385     return fs_env_target_->NewMemoryMappedFileBuffer(fname, result);
386   }
NewDirectory(const std::string & name,std::unique_ptr<Directory> * result)387   Status NewDirectory(const std::string& name,
388                       std::unique_ptr<Directory>* result) override {
389     IOOptions io_opts;
390     IODebugContext dbg;
391     std::unique_ptr<FSDirectory> dir;
392     Status status;
393     status = fs_env_target_->NewDirectory(name, io_opts, &dir, &dbg);
394     if (status.ok()) {
395       result->reset(new CompositeDirectoryWrapper(dir));
396     }
397     return status;
398   }
FileExists(const std::string & f)399   Status FileExists(const std::string& f) override {
400     IOOptions io_opts;
401     IODebugContext dbg;
402     return fs_env_target_->FileExists(f, io_opts, &dbg);
403   }
GetChildren(const std::string & dir,std::vector<std::string> * r)404   Status GetChildren(const std::string& dir,
405                      std::vector<std::string>* r) override {
406     IOOptions io_opts;
407     IODebugContext dbg;
408     return fs_env_target_->GetChildren(dir, io_opts, r, &dbg);
409   }
GetChildrenFileAttributes(const std::string & dir,std::vector<FileAttributes> * result)410   Status GetChildrenFileAttributes(
411       const std::string& dir, std::vector<FileAttributes>* result) override {
412     IOOptions io_opts;
413     IODebugContext dbg;
414     return fs_env_target_->GetChildrenFileAttributes(dir, io_opts, result,
415                                                      &dbg);
416   }
DeleteFile(const std::string & f)417   Status DeleteFile(const std::string& f) override {
418     IOOptions io_opts;
419     IODebugContext dbg;
420     return fs_env_target_->DeleteFile(f, io_opts, &dbg);
421   }
Truncate(const std::string & fname,size_t size)422   Status Truncate(const std::string& fname, size_t size) override {
423     IOOptions io_opts;
424     IODebugContext dbg;
425     return fs_env_target_->Truncate(fname, size, io_opts, &dbg);
426   }
CreateDir(const std::string & d)427   Status CreateDir(const std::string& d) override {
428     IOOptions io_opts;
429     IODebugContext dbg;
430     return fs_env_target_->CreateDir(d, io_opts, &dbg);
431   }
CreateDirIfMissing(const std::string & d)432   Status CreateDirIfMissing(const std::string& d) override {
433     IOOptions io_opts;
434     IODebugContext dbg;
435     return fs_env_target_->CreateDirIfMissing(d, io_opts, &dbg);
436   }
DeleteDir(const std::string & d)437   Status DeleteDir(const std::string& d) override {
438     IOOptions io_opts;
439     IODebugContext dbg;
440     return fs_env_target_->DeleteDir(d, io_opts, &dbg);
441   }
GetFileSize(const std::string & f,uint64_t * s)442   Status GetFileSize(const std::string& f, uint64_t* s) override {
443     IOOptions io_opts;
444     IODebugContext dbg;
445     return fs_env_target_->GetFileSize(f, io_opts, s, &dbg);
446   }
447 
GetFileModificationTime(const std::string & fname,uint64_t * file_mtime)448   Status GetFileModificationTime(const std::string& fname,
449                                  uint64_t* file_mtime) override {
450     IOOptions io_opts;
451     IODebugContext dbg;
452     return fs_env_target_->GetFileModificationTime(fname, io_opts, file_mtime,
453                                                    &dbg);
454   }
455 
RenameFile(const std::string & s,const std::string & t)456   Status RenameFile(const std::string& s, const std::string& t) override {
457     IOOptions io_opts;
458     IODebugContext dbg;
459     return fs_env_target_->RenameFile(s, t, io_opts, &dbg);
460   }
461 
LinkFile(const std::string & s,const std::string & t)462   Status LinkFile(const std::string& s, const std::string& t) override {
463     IOOptions io_opts;
464     IODebugContext dbg;
465     return fs_env_target_->LinkFile(s, t, io_opts, &dbg);
466   }
467 
NumFileLinks(const std::string & fname,uint64_t * count)468   Status NumFileLinks(const std::string& fname, uint64_t* count) override {
469     IOOptions io_opts;
470     IODebugContext dbg;
471     return fs_env_target_->NumFileLinks(fname, io_opts, count, &dbg);
472   }
473 
AreFilesSame(const std::string & first,const std::string & second,bool * res)474   Status AreFilesSame(const std::string& first, const std::string& second,
475                       bool* res) override {
476     IOOptions io_opts;
477     IODebugContext dbg;
478     return fs_env_target_->AreFilesSame(first, second, io_opts, res, &dbg);
479   }
480 
LockFile(const std::string & f,FileLock ** l)481   Status LockFile(const std::string& f, FileLock** l) override {
482     IOOptions io_opts;
483     IODebugContext dbg;
484     return fs_env_target_->LockFile(f, io_opts, l, &dbg);
485   }
486 
UnlockFile(FileLock * l)487   Status UnlockFile(FileLock* l) override {
488     IOOptions io_opts;
489     IODebugContext dbg;
490     return fs_env_target_->UnlockFile(l, io_opts, &dbg);
491   }
492 
GetAbsolutePath(const std::string & db_path,std::string * output_path)493   Status GetAbsolutePath(const std::string& db_path,
494                          std::string* output_path) override {
495     IOOptions io_opts;
496     IODebugContext dbg;
497     return fs_env_target_->GetAbsolutePath(db_path, io_opts, output_path, &dbg);
498   }
499 
500 #if !defined(OS_WIN) && !defined(ROCKSDB_NO_DYNAMIC_EXTENSION)
LoadLibrary(const std::string & lib_name,const std::string & search_path,std::shared_ptr<DynamicLibrary> * result)501   Status LoadLibrary(const std::string& lib_name,
502                      const std::string& search_path,
503                      std::shared_ptr<DynamicLibrary>* result) override {
504     return env_target_->LoadLibrary(lib_name, search_path, result);
505   }
506 #endif
507 
508   void Schedule(void (*f)(void* arg), void* a, Priority pri,
509                 void* tag = nullptr, void (*u)(void* arg) = nullptr) override {
510     return env_target_->Schedule(f, a, pri, tag, u);
511   }
512 
UnSchedule(void * tag,Priority pri)513   int UnSchedule(void* tag, Priority pri) override {
514     return env_target_->UnSchedule(tag, pri);
515   }
516 
StartThread(void (* f)(void *),void * a)517   void StartThread(void (*f)(void*), void* a) override {
518     return env_target_->StartThread(f, a);
519   }
WaitForJoin()520   void WaitForJoin() override { return env_target_->WaitForJoin(); }
521   unsigned int GetThreadPoolQueueLen(Priority pri = LOW) const override {
522     return env_target_->GetThreadPoolQueueLen(pri);
523   }
GetTestDirectory(std::string * path)524   Status GetTestDirectory(std::string* path) override {
525     return env_target_->GetTestDirectory(path);
526   }
NewLogger(const std::string & fname,std::shared_ptr<Logger> * result)527   Status NewLogger(const std::string& fname,
528                    std::shared_ptr<Logger>* result) override {
529     return env_target_->NewLogger(fname, result);
530   }
NowMicros()531   uint64_t NowMicros() override { return env_target_->NowMicros(); }
NowNanos()532   uint64_t NowNanos() override { return env_target_->NowNanos(); }
NowCPUNanos()533   uint64_t NowCPUNanos() override { return env_target_->NowCPUNanos(); }
534 
SleepForMicroseconds(int micros)535   void SleepForMicroseconds(int micros) override {
536     env_target_->SleepForMicroseconds(micros);
537   }
GetHostName(char * name,uint64_t len)538   Status GetHostName(char* name, uint64_t len) override {
539     return env_target_->GetHostName(name, len);
540   }
GetCurrentTime(int64_t * unix_time)541   Status GetCurrentTime(int64_t* unix_time) override {
542     return env_target_->GetCurrentTime(unix_time);
543   }
SetBackgroundThreads(int num,Priority pri)544   void SetBackgroundThreads(int num, Priority pri) override {
545     return env_target_->SetBackgroundThreads(num, pri);
546   }
GetBackgroundThreads(Priority pri)547   int GetBackgroundThreads(Priority pri) override {
548     return env_target_->GetBackgroundThreads(pri);
549   }
550 
SetAllowNonOwnerAccess(bool allow_non_owner_access)551   Status SetAllowNonOwnerAccess(bool allow_non_owner_access) override {
552     return env_target_->SetAllowNonOwnerAccess(allow_non_owner_access);
553   }
554 
IncBackgroundThreadsIfNeeded(int num,Priority pri)555   void IncBackgroundThreadsIfNeeded(int num, Priority pri) override {
556     return env_target_->IncBackgroundThreadsIfNeeded(num, pri);
557   }
558 
559   void LowerThreadPoolIOPriority(Priority pool = LOW) override {
560     env_target_->LowerThreadPoolIOPriority(pool);
561   }
562 
563   void LowerThreadPoolCPUPriority(Priority pool = LOW) override {
564     env_target_->LowerThreadPoolCPUPriority(pool);
565   }
566 
TimeToString(uint64_t time)567   std::string TimeToString(uint64_t time) override {
568     return env_target_->TimeToString(time);
569   }
570 
GetThreadList(std::vector<ThreadStatus> * thread_list)571   Status GetThreadList(std::vector<ThreadStatus>* thread_list) override {
572     return env_target_->GetThreadList(thread_list);
573   }
574 
GetThreadStatusUpdater()575   ThreadStatusUpdater* GetThreadStatusUpdater() const override {
576     return env_target_->GetThreadStatusUpdater();
577   }
578 
GetThreadID()579   uint64_t GetThreadID() const override { return env_target_->GetThreadID(); }
580 
GenerateUniqueId()581   std::string GenerateUniqueId() override {
582     return env_target_->GenerateUniqueId();
583   }
584 
OptimizeForLogRead(const EnvOptions & env_options)585   EnvOptions OptimizeForLogRead(const EnvOptions& env_options) const override {
586     return fs_env_target_->OptimizeForLogRead(FileOptions(env_options));
587   }
OptimizeForManifestRead(const EnvOptions & env_options)588   EnvOptions OptimizeForManifestRead(
589       const EnvOptions& env_options) const override {
590     return fs_env_target_->OptimizeForManifestRead(
591                                 FileOptions(env_options));
592   }
OptimizeForLogWrite(const EnvOptions & env_options,const DBOptions & db_options)593   EnvOptions OptimizeForLogWrite(const EnvOptions& env_options,
594                                  const DBOptions& db_options) const override {
595     return fs_env_target_->OptimizeForLogWrite(FileOptions(env_options),
596                                                db_options);
597   }
OptimizeForManifestWrite(const EnvOptions & env_options)598   EnvOptions OptimizeForManifestWrite(
599       const EnvOptions& env_options) const override {
600     return fs_env_target_->OptimizeForManifestWrite(
601                                 FileOptions(env_options));
602   }
OptimizeForCompactionTableWrite(const EnvOptions & env_options,const ImmutableDBOptions & immutable_ops)603   EnvOptions OptimizeForCompactionTableWrite(
604       const EnvOptions& env_options,
605       const ImmutableDBOptions& immutable_ops) const override {
606     return fs_env_target_->OptimizeForCompactionTableWrite(
607                                 FileOptions(env_options),
608                                 immutable_ops);
609   }
OptimizeForCompactionTableRead(const EnvOptions & env_options,const ImmutableDBOptions & db_options)610   EnvOptions OptimizeForCompactionTableRead(
611       const EnvOptions& env_options,
612       const ImmutableDBOptions& db_options) const override {
613     return fs_env_target_->OptimizeForCompactionTableRead(
614                                 FileOptions(env_options),
615                                 db_options);
616   }
GetFreeSpace(const std::string & path,uint64_t * diskfree)617   Status GetFreeSpace(const std::string& path, uint64_t* diskfree) override {
618     IOOptions io_opts;
619     IODebugContext dbg;
620     return fs_env_target_->GetFreeSpace(path, io_opts, diskfree, &dbg);
621   }
622 
623  private:
624   Env* env_target_;
625   FileSystem* fs_env_target_;
626 };
627 
628 class LegacySequentialFileWrapper : public FSSequentialFile {
629  public:
LegacySequentialFileWrapper(std::unique_ptr<SequentialFile> && _target)630   explicit LegacySequentialFileWrapper(
631       std::unique_ptr<SequentialFile>&& _target)
632       : target_(std::move(_target)) {}
633 
Read(size_t n,const IOOptions &,Slice * result,char * scratch,IODebugContext *)634   IOStatus Read(size_t n, const IOOptions& /*options*/, Slice* result,
635                 char* scratch, IODebugContext* /*dbg*/) override {
636     return status_to_io_status(target_->Read(n, result, scratch));
637   }
Skip(uint64_t n)638   IOStatus Skip(uint64_t n) override {
639     return status_to_io_status(target_->Skip(n));
640   }
use_direct_io()641   bool use_direct_io() const override { return target_->use_direct_io(); }
GetRequiredBufferAlignment()642   size_t GetRequiredBufferAlignment() const override {
643     return target_->GetRequiredBufferAlignment();
644   }
InvalidateCache(size_t offset,size_t length)645   IOStatus InvalidateCache(size_t offset, size_t length) override {
646     return status_to_io_status(target_->InvalidateCache(offset, length));
647   }
PositionedRead(uint64_t offset,size_t n,const IOOptions &,Slice * result,char * scratch,IODebugContext *)648   IOStatus PositionedRead(uint64_t offset, size_t n,
649                           const IOOptions& /*options*/, Slice* result,
650                           char* scratch, IODebugContext* /*dbg*/) override {
651     return status_to_io_status(
652         target_->PositionedRead(offset, n, result, scratch));
653   }
target()654   SequentialFile* target() { return target_.get(); }
655 
656  private:
657   std::unique_ptr<SequentialFile> target_;
658 };
659 
660 class LegacyRandomAccessFileWrapper : public FSRandomAccessFile {
661  public:
LegacyRandomAccessFileWrapper(std::unique_ptr<RandomAccessFile> && target)662   explicit LegacyRandomAccessFileWrapper(
663       std::unique_ptr<RandomAccessFile>&& target)
664       : target_(std::move(target)) {}
665 
Read(uint64_t offset,size_t n,const IOOptions &,Slice * result,char * scratch,IODebugContext *)666   IOStatus Read(uint64_t offset, size_t n, const IOOptions& /*options*/,
667                 Slice* result, char* scratch,
668                 IODebugContext* /*dbg*/) const override {
669     return status_to_io_status(target_->Read(offset, n, result, scratch));
670   }
MultiRead(FSReadRequest * fs_reqs,size_t num_reqs,const IOOptions &,IODebugContext *)671   IOStatus MultiRead(FSReadRequest* fs_reqs, size_t num_reqs,
672                      const IOOptions& /*options*/,
673                      IODebugContext* /*dbg*/) override {
674     std::vector<ReadRequest> reqs;
675     Status status;
676 
677     reqs.reserve(num_reqs);
678     for (size_t i = 0; i < num_reqs; ++i) {
679       ReadRequest req;
680 
681       req.offset = fs_reqs[i].offset;
682       req.len = fs_reqs[i].len;
683       req.scratch = fs_reqs[i].scratch;
684       req.status = Status::OK();
685 
686       reqs.emplace_back(req);
687     }
688     status = target_->MultiRead(reqs.data(), num_reqs);
689     for (size_t i = 0; i < num_reqs; ++i) {
690       fs_reqs[i].result = reqs[i].result;
691       fs_reqs[i].status = status_to_io_status(std::move(reqs[i].status));
692     }
693     return status_to_io_status(std::move(status));
694     ;
695   }
Prefetch(uint64_t offset,size_t n,const IOOptions &,IODebugContext *)696   IOStatus Prefetch(uint64_t offset, size_t n, const IOOptions& /*options*/,
697                     IODebugContext* /*dbg*/) override {
698     return status_to_io_status(target_->Prefetch(offset, n));
699   }
GetUniqueId(char * id,size_t max_size)700   size_t GetUniqueId(char* id, size_t max_size) const override {
701     return target_->GetUniqueId(id, max_size);
702   };
Hint(AccessPattern pattern)703   void Hint(AccessPattern pattern) override {
704     target_->Hint((RandomAccessFile::AccessPattern)pattern);
705   }
use_direct_io()706   bool use_direct_io() const override { return target_->use_direct_io(); }
GetRequiredBufferAlignment()707   size_t GetRequiredBufferAlignment() const override {
708     return target_->GetRequiredBufferAlignment();
709   }
InvalidateCache(size_t offset,size_t length)710   IOStatus InvalidateCache(size_t offset, size_t length) override {
711     return status_to_io_status(target_->InvalidateCache(offset, length));
712   }
713 
714  private:
715   std::unique_ptr<RandomAccessFile> target_;
716 };
717 
718 class LegacyWritableFileWrapper : public FSWritableFile {
719  public:
LegacyWritableFileWrapper(std::unique_ptr<WritableFile> && _target)720   explicit LegacyWritableFileWrapper(std::unique_ptr<WritableFile>&& _target)
721       : target_(std::move(_target)) {}
722 
Append(const Slice & data,const IOOptions &,IODebugContext *)723   IOStatus Append(const Slice& data, const IOOptions& /*options*/,
724                   IODebugContext* /*dbg*/) override {
725     return status_to_io_status(target_->Append(data));
726   }
PositionedAppend(const Slice & data,uint64_t offset,const IOOptions &,IODebugContext *)727   IOStatus PositionedAppend(const Slice& data, uint64_t offset,
728                             const IOOptions& /*options*/,
729                             IODebugContext* /*dbg*/) override {
730     return status_to_io_status(target_->PositionedAppend(data, offset));
731   }
Truncate(uint64_t size,const IOOptions &,IODebugContext *)732   IOStatus Truncate(uint64_t size, const IOOptions& /*options*/,
733                     IODebugContext* /*dbg*/) override {
734     return status_to_io_status(target_->Truncate(size));
735   }
Close(const IOOptions &,IODebugContext *)736   IOStatus Close(const IOOptions& /*options*/,
737                  IODebugContext* /*dbg*/) override {
738     return status_to_io_status(target_->Close());
739   }
Flush(const IOOptions &,IODebugContext *)740   IOStatus Flush(const IOOptions& /*options*/,
741                  IODebugContext* /*dbg*/) override {
742     return status_to_io_status(target_->Flush());
743   }
Sync(const IOOptions &,IODebugContext *)744   IOStatus Sync(const IOOptions& /*options*/,
745                 IODebugContext* /*dbg*/) override {
746     return status_to_io_status(target_->Sync());
747   }
Fsync(const IOOptions &,IODebugContext *)748   IOStatus Fsync(const IOOptions& /*options*/,
749                  IODebugContext* /*dbg*/) override {
750     return status_to_io_status(target_->Fsync());
751   }
IsSyncThreadSafe()752   bool IsSyncThreadSafe() const override { return target_->IsSyncThreadSafe(); }
753 
use_direct_io()754   bool use_direct_io() const override { return target_->use_direct_io(); }
755 
GetRequiredBufferAlignment()756   size_t GetRequiredBufferAlignment() const override {
757     return target_->GetRequiredBufferAlignment();
758   }
759 
SetWriteLifeTimeHint(Env::WriteLifeTimeHint hint)760   void SetWriteLifeTimeHint(Env::WriteLifeTimeHint hint) override {
761     target_->SetWriteLifeTimeHint(hint);
762   }
763 
GetWriteLifeTimeHint()764   Env::WriteLifeTimeHint GetWriteLifeTimeHint() override {
765     return target_->GetWriteLifeTimeHint();
766   }
767 
GetFileSize(const IOOptions &,IODebugContext *)768   uint64_t GetFileSize(const IOOptions& /*options*/,
769                        IODebugContext* /*dbg*/) override {
770     return target_->GetFileSize();
771   }
772 
SetPreallocationBlockSize(size_t size)773   void SetPreallocationBlockSize(size_t size) override {
774     target_->SetPreallocationBlockSize(size);
775   }
776 
GetPreallocationStatus(size_t * block_size,size_t * last_allocated_block)777   void GetPreallocationStatus(size_t* block_size,
778                               size_t* last_allocated_block) override {
779     target_->GetPreallocationStatus(block_size, last_allocated_block);
780   }
781 
GetUniqueId(char * id,size_t max_size)782   size_t GetUniqueId(char* id, size_t max_size) const override {
783     return target_->GetUniqueId(id, max_size);
784   }
785 
InvalidateCache(size_t offset,size_t length)786   IOStatus InvalidateCache(size_t offset, size_t length) override {
787     return status_to_io_status(target_->InvalidateCache(offset, length));
788   }
789 
RangeSync(uint64_t offset,uint64_t nbytes,const IOOptions &,IODebugContext *)790   IOStatus RangeSync(uint64_t offset, uint64_t nbytes,
791                      const IOOptions& /*options*/,
792                      IODebugContext* /*dbg*/) override {
793     return status_to_io_status(target_->RangeSync(offset, nbytes));
794   }
795 
PrepareWrite(size_t offset,size_t len,const IOOptions &,IODebugContext *)796   void PrepareWrite(size_t offset, size_t len, const IOOptions& /*options*/,
797                     IODebugContext* /*dbg*/) override {
798     target_->PrepareWrite(offset, len);
799   }
800 
Allocate(uint64_t offset,uint64_t len,const IOOptions &,IODebugContext *)801   IOStatus Allocate(uint64_t offset, uint64_t len, const IOOptions& /*options*/,
802                     IODebugContext* /*dbg*/) override {
803     return status_to_io_status(target_->Allocate(offset, len));
804   }
805 
target()806   WritableFile* target() { return target_.get(); }
807 
808  private:
809   std::unique_ptr<WritableFile> target_;
810 };
811 
812 class LegacyRandomRWFileWrapper : public FSRandomRWFile {
813  public:
LegacyRandomRWFileWrapper(std::unique_ptr<RandomRWFile> && target)814   explicit LegacyRandomRWFileWrapper(std::unique_ptr<RandomRWFile>&& target)
815       : target_(std::move(target)) {}
816 
use_direct_io()817   bool use_direct_io() const override { return target_->use_direct_io(); }
GetRequiredBufferAlignment()818   size_t GetRequiredBufferAlignment() const override {
819     return target_->GetRequiredBufferAlignment();
820   }
Write(uint64_t offset,const Slice & data,const IOOptions &,IODebugContext *)821   IOStatus Write(uint64_t offset, const Slice& data,
822                  const IOOptions& /*options*/,
823                  IODebugContext* /*dbg*/) override {
824     return status_to_io_status(target_->Write(offset, data));
825   }
Read(uint64_t offset,size_t n,const IOOptions &,Slice * result,char * scratch,IODebugContext *)826   IOStatus Read(uint64_t offset, size_t n, const IOOptions& /*options*/,
827                 Slice* result, char* scratch,
828                 IODebugContext* /*dbg*/) const override {
829     return status_to_io_status(target_->Read(offset, n, result, scratch));
830   }
Flush(const IOOptions &,IODebugContext *)831   IOStatus Flush(const IOOptions& /*options*/,
832                  IODebugContext* /*dbg*/) override {
833     return status_to_io_status(target_->Flush());
834   }
Sync(const IOOptions &,IODebugContext *)835   IOStatus Sync(const IOOptions& /*options*/,
836                 IODebugContext* /*dbg*/) override {
837     return status_to_io_status(target_->Sync());
838   }
Fsync(const IOOptions &,IODebugContext *)839   IOStatus Fsync(const IOOptions& /*options*/,
840                  IODebugContext* /*dbg*/) override {
841     return status_to_io_status(target_->Fsync());
842   }
Close(const IOOptions &,IODebugContext *)843   IOStatus Close(const IOOptions& /*options*/,
844                  IODebugContext* /*dbg*/) override {
845     return status_to_io_status(target_->Close());
846   }
847 
848  private:
849   std::unique_ptr<RandomRWFile> target_;
850 };
851 
852 class LegacyDirectoryWrapper : public FSDirectory {
853  public:
LegacyDirectoryWrapper(std::unique_ptr<Directory> && target)854   explicit LegacyDirectoryWrapper(std::unique_ptr<Directory>&& target)
855       : target_(std::move(target)) {}
856 
Fsync(const IOOptions &,IODebugContext *)857   IOStatus Fsync(const IOOptions& /*options*/,
858                  IODebugContext* /*dbg*/) override {
859     return status_to_io_status(target_->Fsync());
860   }
GetUniqueId(char * id,size_t max_size)861   size_t GetUniqueId(char* id, size_t max_size) const override {
862     return target_->GetUniqueId(id, max_size);
863   }
864 
865  private:
866   std::unique_ptr<Directory> target_;
867 };
868 
869 class LegacyFileSystemWrapper : public FileSystem {
870  public:
871   // Initialize an EnvWrapper that delegates all calls to *t
LegacyFileSystemWrapper(Env * t)872   explicit LegacyFileSystemWrapper(Env* t) : target_(t) {}
~LegacyFileSystemWrapper()873   ~LegacyFileSystemWrapper() override {}
874 
Name()875   const char* Name() const override { return "Legacy File System"; }
876 
877   // Return the target to which this Env forwards all calls
target()878   Env* target() const { return target_; }
879 
880   // The following text is boilerplate that forwards all methods to target()
NewSequentialFile(const std::string & f,const FileOptions & file_opts,std::unique_ptr<FSSequentialFile> * r,IODebugContext *)881   IOStatus NewSequentialFile(const std::string& f,
882                              const FileOptions& file_opts,
883                              std::unique_ptr<FSSequentialFile>* r,
884                              IODebugContext* /*dbg*/) override {
885     std::unique_ptr<SequentialFile> file;
886     Status s = target_->NewSequentialFile(f, &file, file_opts);
887     if (s.ok()) {
888       r->reset(new LegacySequentialFileWrapper(std::move(file)));
889     }
890     return status_to_io_status(std::move(s));
891   }
NewRandomAccessFile(const std::string & f,const FileOptions & file_opts,std::unique_ptr<FSRandomAccessFile> * r,IODebugContext *)892   IOStatus NewRandomAccessFile(const std::string& f,
893       const FileOptions& file_opts,
894                                std::unique_ptr<FSRandomAccessFile>* r,
895                                IODebugContext* /*dbg*/) override {
896     std::unique_ptr<RandomAccessFile> file;
897     Status s = target_->NewRandomAccessFile(f, &file, file_opts);
898     if (s.ok()) {
899       r->reset(new LegacyRandomAccessFileWrapper(std::move(file)));
900     }
901     return status_to_io_status(std::move(s));
902   }
NewWritableFile(const std::string & f,const FileOptions & file_opts,std::unique_ptr<FSWritableFile> * r,IODebugContext *)903   IOStatus NewWritableFile(const std::string& f, const FileOptions& file_opts,
904                            std::unique_ptr<FSWritableFile>* r,
905                            IODebugContext* /*dbg*/) override {
906     std::unique_ptr<WritableFile> file;
907     Status s = target_->NewWritableFile(f, &file, file_opts);
908     if (s.ok()) {
909       r->reset(new LegacyWritableFileWrapper(std::move(file)));
910     }
911     return status_to_io_status(std::move(s));
912   }
ReopenWritableFile(const std::string & fname,const FileOptions & file_opts,std::unique_ptr<FSWritableFile> * result,IODebugContext *)913   IOStatus ReopenWritableFile(const std::string& fname,
914                               const FileOptions& file_opts,
915                               std::unique_ptr<FSWritableFile>* result,
916                               IODebugContext* /*dbg*/) override {
917     std::unique_ptr<WritableFile> file;
918     Status s = target_->ReopenWritableFile(fname, &file, file_opts);
919     if (s.ok()) {
920       result->reset(new LegacyWritableFileWrapper(std::move(file)));
921     }
922     return status_to_io_status(std::move(s));
923   }
ReuseWritableFile(const std::string & fname,const std::string & old_fname,const FileOptions & file_opts,std::unique_ptr<FSWritableFile> * r,IODebugContext *)924   IOStatus ReuseWritableFile(const std::string& fname,
925                              const std::string& old_fname,
926                              const FileOptions& file_opts,
927                              std::unique_ptr<FSWritableFile>* r,
928                              IODebugContext* /*dbg*/) override {
929     std::unique_ptr<WritableFile> file;
930     Status s = target_->ReuseWritableFile(fname, old_fname, &file, file_opts);
931     if (s.ok()) {
932       r->reset(new LegacyWritableFileWrapper(std::move(file)));
933     }
934     return status_to_io_status(std::move(s));
935   }
NewRandomRWFile(const std::string & fname,const FileOptions & file_opts,std::unique_ptr<FSRandomRWFile> * result,IODebugContext *)936   IOStatus NewRandomRWFile(const std::string& fname,
937       const FileOptions& file_opts,
938                            std::unique_ptr<FSRandomRWFile>* result,
939                            IODebugContext* /*dbg*/) override {
940     std::unique_ptr<RandomRWFile> file;
941     Status s = target_->NewRandomRWFile(fname, &file, file_opts);
942     if (s.ok()) {
943       result->reset(new LegacyRandomRWFileWrapper(std::move(file)));
944     }
945     return status_to_io_status(std::move(s));
946   }
NewMemoryMappedFileBuffer(const std::string & fname,std::unique_ptr<MemoryMappedFileBuffer> * result)947   IOStatus NewMemoryMappedFileBuffer(
948       const std::string& fname,
949       std::unique_ptr<MemoryMappedFileBuffer>* result) override {
950     return status_to_io_status(
951         target_->NewMemoryMappedFileBuffer(fname, result));
952   }
NewDirectory(const std::string & name,const IOOptions &,std::unique_ptr<FSDirectory> * result,IODebugContext *)953   IOStatus NewDirectory(const std::string& name, const IOOptions& /*io_opts*/,
954                         std::unique_ptr<FSDirectory>* result,
955                         IODebugContext* /*dbg*/) override {
956     std::unique_ptr<Directory> dir;
957     Status s = target_->NewDirectory(name, &dir);
958     if (s.ok()) {
959       result->reset(new LegacyDirectoryWrapper(std::move(dir)));
960     }
961     return status_to_io_status(std::move(s));
962   }
FileExists(const std::string & f,const IOOptions &,IODebugContext *)963   IOStatus FileExists(const std::string& f, const IOOptions& /*io_opts*/,
964                       IODebugContext* /*dbg*/) override {
965     return status_to_io_status(target_->FileExists(f));
966   }
GetChildren(const std::string & dir,const IOOptions &,std::vector<std::string> * r,IODebugContext *)967   IOStatus GetChildren(const std::string& dir, const IOOptions& /*io_opts*/,
968                        std::vector<std::string>* r,
969                        IODebugContext* /*dbg*/) override {
970     return status_to_io_status(target_->GetChildren(dir, r));
971   }
GetChildrenFileAttributes(const std::string & dir,const IOOptions &,std::vector<FileAttributes> * result,IODebugContext *)972   IOStatus GetChildrenFileAttributes(const std::string& dir,
973                                      const IOOptions& /*options*/,
974                                      std::vector<FileAttributes>* result,
975                                      IODebugContext* /*dbg*/) override {
976     return status_to_io_status(target_->GetChildrenFileAttributes(dir, result));
977   }
DeleteFile(const std::string & f,const IOOptions &,IODebugContext *)978   IOStatus DeleteFile(const std::string& f, const IOOptions& /*options*/,
979                       IODebugContext* /*dbg*/) override {
980     return status_to_io_status(target_->DeleteFile(f));
981   }
Truncate(const std::string & fname,size_t size,const IOOptions &,IODebugContext *)982   IOStatus Truncate(const std::string& fname, size_t size,
983                     const IOOptions& /*options*/,
984                     IODebugContext* /*dbg*/) override {
985     return status_to_io_status(target_->Truncate(fname, size));
986   }
CreateDir(const std::string & d,const IOOptions &,IODebugContext *)987   IOStatus CreateDir(const std::string& d, const IOOptions& /*options*/,
988                      IODebugContext* /*dbg*/) override {
989     return status_to_io_status(target_->CreateDir(d));
990   }
CreateDirIfMissing(const std::string & d,const IOOptions &,IODebugContext *)991   IOStatus CreateDirIfMissing(const std::string& d,
992                               const IOOptions& /*options*/,
993                               IODebugContext* /*dbg*/) override {
994     return status_to_io_status(target_->CreateDirIfMissing(d));
995   }
DeleteDir(const std::string & d,const IOOptions &,IODebugContext *)996   IOStatus DeleteDir(const std::string& d, const IOOptions& /*options*/,
997                      IODebugContext* /*dbg*/) override {
998     return status_to_io_status(target_->DeleteDir(d));
999   }
GetFileSize(const std::string & f,const IOOptions &,uint64_t * s,IODebugContext *)1000   IOStatus GetFileSize(const std::string& f, const IOOptions& /*options*/,
1001                        uint64_t* s, IODebugContext* /*dbg*/) override {
1002     return status_to_io_status(target_->GetFileSize(f, s));
1003   }
1004 
GetFileModificationTime(const std::string & fname,const IOOptions &,uint64_t * file_mtime,IODebugContext *)1005   IOStatus GetFileModificationTime(const std::string& fname,
1006                                    const IOOptions& /*options*/,
1007                                    uint64_t* file_mtime,
1008                                    IODebugContext* /*dbg*/) override {
1009     return status_to_io_status(
1010         target_->GetFileModificationTime(fname, file_mtime));
1011   }
1012 
GetAbsolutePath(const std::string & db_path,const IOOptions &,std::string * output_path,IODebugContext *)1013   IOStatus GetAbsolutePath(const std::string& db_path,
1014                            const IOOptions& /*options*/,
1015                            std::string* output_path,
1016                            IODebugContext* /*dbg*/) override {
1017     return status_to_io_status(target_->GetAbsolutePath(db_path, output_path));
1018   }
1019 
RenameFile(const std::string & s,const std::string & t,const IOOptions &,IODebugContext *)1020   IOStatus RenameFile(const std::string& s, const std::string& t,
1021                       const IOOptions& /*options*/,
1022                       IODebugContext* /*dbg*/) override {
1023     return status_to_io_status(target_->RenameFile(s, t));
1024   }
1025 
LinkFile(const std::string & s,const std::string & t,const IOOptions &,IODebugContext *)1026   IOStatus LinkFile(const std::string& s, const std::string& t,
1027                     const IOOptions& /*options*/,
1028                     IODebugContext* /*dbg*/) override {
1029     return status_to_io_status(target_->LinkFile(s, t));
1030   }
1031 
NumFileLinks(const std::string & fname,const IOOptions &,uint64_t * count,IODebugContext *)1032   IOStatus NumFileLinks(const std::string& fname, const IOOptions& /*options*/,
1033                         uint64_t* count, IODebugContext* /*dbg*/) override {
1034     return status_to_io_status(target_->NumFileLinks(fname, count));
1035   }
1036 
AreFilesSame(const std::string & first,const std::string & second,const IOOptions &,bool * res,IODebugContext *)1037   IOStatus AreFilesSame(const std::string& first, const std::string& second,
1038                         const IOOptions& /*options*/, bool* res,
1039                         IODebugContext* /*dbg*/) override {
1040     return status_to_io_status(target_->AreFilesSame(first, second, res));
1041   }
1042 
LockFile(const std::string & f,const IOOptions &,FileLock ** l,IODebugContext *)1043   IOStatus LockFile(const std::string& f, const IOOptions& /*options*/,
1044                     FileLock** l, IODebugContext* /*dbg*/) override {
1045     return status_to_io_status(target_->LockFile(f, l));
1046   }
1047 
UnlockFile(FileLock * l,const IOOptions &,IODebugContext *)1048   IOStatus UnlockFile(FileLock* l, const IOOptions& /*options*/,
1049                       IODebugContext* /*dbg*/) override {
1050     return status_to_io_status(target_->UnlockFile(l));
1051   }
1052 
GetTestDirectory(const IOOptions &,std::string * path,IODebugContext *)1053   IOStatus GetTestDirectory(const IOOptions& /*options*/, std::string* path,
1054                             IODebugContext* /*dbg*/) override {
1055     return status_to_io_status(target_->GetTestDirectory(path));
1056   }
NewLogger(const std::string & fname,const IOOptions &,std::shared_ptr<Logger> * result,IODebugContext *)1057   IOStatus NewLogger(const std::string& fname, const IOOptions& /*options*/,
1058                      std::shared_ptr<Logger>* result,
1059                      IODebugContext* /*dbg*/) override {
1060     return status_to_io_status(target_->NewLogger(fname, result));
1061   }
1062 
OptimizeForLogRead(const FileOptions & file_options)1063   FileOptions OptimizeForLogRead(
1064                   const FileOptions& file_options) const override {
1065     return target_->OptimizeForLogRead(file_options);
1066   }
OptimizeForManifestRead(const FileOptions & file_options)1067   FileOptions OptimizeForManifestRead(
1068       const FileOptions& file_options) const override {
1069     return target_->OptimizeForManifestRead(file_options);
1070   }
OptimizeForLogWrite(const FileOptions & file_options,const DBOptions & db_options)1071   FileOptions OptimizeForLogWrite(const FileOptions& file_options,
1072                                  const DBOptions& db_options) const override {
1073     return target_->OptimizeForLogWrite(file_options, db_options);
1074   }
OptimizeForManifestWrite(const FileOptions & file_options)1075   FileOptions OptimizeForManifestWrite(
1076       const FileOptions& file_options) const override {
1077     return target_->OptimizeForManifestWrite(file_options);
1078   }
OptimizeForCompactionTableWrite(const FileOptions & file_options,const ImmutableDBOptions & immutable_ops)1079   FileOptions OptimizeForCompactionTableWrite(
1080       const FileOptions& file_options,
1081       const ImmutableDBOptions& immutable_ops) const override {
1082     return target_->OptimizeForCompactionTableWrite(file_options,
1083                                                      immutable_ops);
1084   }
OptimizeForCompactionTableRead(const FileOptions & file_options,const ImmutableDBOptions & db_options)1085   FileOptions OptimizeForCompactionTableRead(
1086       const FileOptions& file_options,
1087       const ImmutableDBOptions& db_options) const override {
1088     return target_->OptimizeForCompactionTableRead(file_options, db_options);
1089   }
GetFreeSpace(const std::string & path,const IOOptions &,uint64_t * diskfree,IODebugContext *)1090   IOStatus GetFreeSpace(const std::string& path, const IOOptions& /*options*/,
1091                         uint64_t* diskfree, IODebugContext* /*dbg*/) override {
1092     return status_to_io_status(target_->GetFreeSpace(path, diskfree));
1093   }
1094 
1095  private:
1096   Env* target_;
1097 };
1098 
NewLegacySequentialFileWrapper(std::unique_ptr<SequentialFile> & file)1099 inline std::unique_ptr<FSSequentialFile> NewLegacySequentialFileWrapper(
1100     std::unique_ptr<SequentialFile>& file) {
1101   return std::unique_ptr<FSSequentialFile>(
1102       new LegacySequentialFileWrapper(std::move(file)));
1103 }
1104 
NewLegacyRandomAccessFileWrapper(std::unique_ptr<RandomAccessFile> & file)1105 inline std::unique_ptr<FSRandomAccessFile> NewLegacyRandomAccessFileWrapper(
1106     std::unique_ptr<RandomAccessFile>& file) {
1107   return std::unique_ptr<FSRandomAccessFile>(
1108       new LegacyRandomAccessFileWrapper(std::move(file)));
1109 }
1110 
NewLegacyWritableFileWrapper(std::unique_ptr<WritableFile> && file)1111 inline std::unique_ptr<FSWritableFile> NewLegacyWritableFileWrapper(
1112     std::unique_ptr<WritableFile>&& file) {
1113   return std::unique_ptr<FSWritableFile>(
1114       new LegacyWritableFileWrapper(std::move(file)));
1115 }
1116 
1117 }  // namespace ROCKSDB_NAMESPACE
1118