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