Coverage Report

Created: 2024-07-27 06:53

/src/rocksdb/env/fs_remap.cc
Line
Count
Source (jump to first uncovered line)
1
//  Copyright (c) Facebook, Inc. and its affiliates. 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
7
#include "env/fs_remap.h"
8
9
namespace ROCKSDB_NAMESPACE {
10
11
RemapFileSystem::RemapFileSystem(const std::shared_ptr<FileSystem>& base)
12
0
    : FileSystemWrapper(base) {}
13
14
std::pair<IOStatus, std::string> RemapFileSystem::EncodePathWithNewBasename(
15
0
    const std::string& path) {
16
  // No difference by default
17
0
  return EncodePath(path);
18
0
}
19
20
0
Status RemapFileSystem::RegisterDbPaths(const std::vector<std::string>& paths) {
21
0
  std::vector<std::string> encoded_paths;
22
0
  encoded_paths.reserve(paths.size());
23
0
  for (auto& path : paths) {
24
0
    auto status_and_enc_path = EncodePathWithNewBasename(path);
25
0
    if (!status_and_enc_path.first.ok()) {
26
0
      return status_and_enc_path.first;
27
0
    }
28
0
    encoded_paths.emplace_back(status_and_enc_path.second);
29
0
  }
30
0
  return FileSystemWrapper::RegisterDbPaths(encoded_paths);
31
0
}
32
33
Status RemapFileSystem::UnregisterDbPaths(
34
0
    const std::vector<std::string>& paths) {
35
0
  std::vector<std::string> encoded_paths;
36
0
  encoded_paths.reserve(paths.size());
37
0
  for (auto& path : paths) {
38
0
    auto status_and_enc_path = EncodePathWithNewBasename(path);
39
0
    if (!status_and_enc_path.first.ok()) {
40
0
      return status_and_enc_path.first;
41
0
    }
42
0
    encoded_paths.emplace_back(status_and_enc_path.second);
43
0
  }
44
0
  return FileSystemWrapper::UnregisterDbPaths(encoded_paths);
45
0
}
46
47
IOStatus RemapFileSystem::NewSequentialFile(
48
    const std::string& fname, const FileOptions& options,
49
0
    std::unique_ptr<FSSequentialFile>* result, IODebugContext* dbg) {
50
0
  auto status_and_enc_path = EncodePathWithNewBasename(fname);
51
0
  if (!status_and_enc_path.first.ok()) {
52
0
    return status_and_enc_path.first;
53
0
  }
54
0
  return FileSystemWrapper::NewSequentialFile(status_and_enc_path.second,
55
0
                                              options, result, dbg);
56
0
}
57
58
IOStatus RemapFileSystem::NewRandomAccessFile(
59
    const std::string& fname, const FileOptions& options,
60
0
    std::unique_ptr<FSRandomAccessFile>* result, IODebugContext* dbg) {
61
0
  auto status_and_enc_path = EncodePathWithNewBasename(fname);
62
0
  if (!status_and_enc_path.first.ok()) {
63
0
    return status_and_enc_path.first;
64
0
  }
65
0
  return FileSystemWrapper::NewRandomAccessFile(status_and_enc_path.second,
66
0
                                                options, result, dbg);
67
0
}
68
69
IOStatus RemapFileSystem::NewWritableFile(
70
    const std::string& fname, const FileOptions& options,
71
0
    std::unique_ptr<FSWritableFile>* result, IODebugContext* dbg) {
72
0
  auto status_and_enc_path = EncodePathWithNewBasename(fname);
73
0
  if (!status_and_enc_path.first.ok()) {
74
0
    return status_and_enc_path.first;
75
0
  }
76
0
  return FileSystemWrapper::NewWritableFile(status_and_enc_path.second, options,
77
0
                                            result, dbg);
78
0
}
79
80
IOStatus RemapFileSystem::ReuseWritableFile(
81
    const std::string& fname, const std::string& old_fname,
82
    const FileOptions& options, std::unique_ptr<FSWritableFile>* result,
83
0
    IODebugContext* dbg) {
84
0
  auto status_and_enc_path = EncodePathWithNewBasename(fname);
85
0
  if (!status_and_enc_path.first.ok()) {
86
0
    return status_and_enc_path.first;
87
0
  }
88
0
  auto status_and_old_enc_path = EncodePath(old_fname);
89
0
  if (!status_and_old_enc_path.first.ok()) {
90
0
    return status_and_old_enc_path.first;
91
0
  }
92
0
  return FileSystemWrapper::ReuseWritableFile(status_and_old_enc_path.second,
93
0
                                              status_and_old_enc_path.second,
94
0
                                              options, result, dbg);
95
0
}
96
97
IOStatus RemapFileSystem::NewRandomRWFile(
98
    const std::string& fname, const FileOptions& options,
99
0
    std::unique_ptr<FSRandomRWFile>* result, IODebugContext* dbg) {
100
0
  auto status_and_enc_path = EncodePathWithNewBasename(fname);
101
0
  if (!status_and_enc_path.first.ok()) {
102
0
    return status_and_enc_path.first;
103
0
  }
104
0
  return FileSystemWrapper::NewRandomRWFile(status_and_enc_path.second, options,
105
0
                                            result, dbg);
106
0
}
107
108
IOStatus RemapFileSystem::NewDirectory(const std::string& dir,
109
                                       const IOOptions& options,
110
                                       std::unique_ptr<FSDirectory>* result,
111
0
                                       IODebugContext* dbg) {
112
  // A hassle to remap DirFsyncOptions::renamed_new_name
113
0
  class RemapFSDirectory : public FSDirectoryWrapper {
114
0
   public:
115
0
    RemapFSDirectory(RemapFileSystem* fs, std::unique_ptr<FSDirectory>&& t)
116
0
        : FSDirectoryWrapper(std::move(t)), fs_(fs) {}
117
0
    IOStatus FsyncWithDirOptions(
118
0
        const IOOptions& options, IODebugContext* dbg,
119
0
        const DirFsyncOptions& dir_fsync_options) override {
120
0
      if (dir_fsync_options.renamed_new_name.empty()) {
121
0
        return FSDirectoryWrapper::FsyncWithDirOptions(options, dbg,
122
0
                                                       dir_fsync_options);
123
0
      } else {
124
0
        auto status_and_enc_path =
125
0
            fs_->EncodePath(dir_fsync_options.renamed_new_name);
126
0
        if (status_and_enc_path.first.ok()) {
127
0
          DirFsyncOptions mapped_options = dir_fsync_options;
128
0
          mapped_options.renamed_new_name = status_and_enc_path.second;
129
0
          return FSDirectoryWrapper::FsyncWithDirOptions(options, dbg,
130
0
                                                         mapped_options);
131
0
        } else {
132
0
          return status_and_enc_path.first;
133
0
        }
134
0
      }
135
0
    }
136
137
0
   private:
138
0
    RemapFileSystem* const fs_;
139
0
  };
140
141
0
  auto status_and_enc_path = EncodePathWithNewBasename(dir);
142
0
  if (!status_and_enc_path.first.ok()) {
143
0
    return status_and_enc_path.first;
144
0
  }
145
0
  IOStatus ios = FileSystemWrapper::NewDirectory(status_and_enc_path.second,
146
0
                                                 options, result, dbg);
147
0
  if (ios.ok()) {
148
0
    *result = std::make_unique<RemapFSDirectory>(this, std::move(*result));
149
0
  }
150
0
  return ios;
151
0
}
152
153
IOStatus RemapFileSystem::FileExists(const std::string& fname,
154
                                     const IOOptions& options,
155
0
                                     IODebugContext* dbg) {
156
0
  auto status_and_enc_path = EncodePathWithNewBasename(fname);
157
0
  if (!status_and_enc_path.first.ok()) {
158
0
    return status_and_enc_path.first;
159
0
  }
160
0
  return FileSystemWrapper::FileExists(status_and_enc_path.second, options,
161
0
                                       dbg);
162
0
}
163
164
IOStatus RemapFileSystem::GetChildren(const std::string& dir,
165
                                      const IOOptions& options,
166
                                      std::vector<std::string>* result,
167
0
                                      IODebugContext* dbg) {
168
0
  auto status_and_enc_path = EncodePath(dir);
169
0
  if (!status_and_enc_path.first.ok()) {
170
0
    return status_and_enc_path.first;
171
0
  }
172
0
  return FileSystemWrapper::GetChildren(status_and_enc_path.second, options,
173
0
                                        result, dbg);
174
0
}
175
176
IOStatus RemapFileSystem::GetChildrenFileAttributes(
177
    const std::string& dir, const IOOptions& options,
178
0
    std::vector<FileAttributes>* result, IODebugContext* dbg) {
179
0
  auto status_and_enc_path = EncodePath(dir);
180
0
  if (!status_and_enc_path.first.ok()) {
181
0
    return status_and_enc_path.first;
182
0
  }
183
0
  return FileSystemWrapper::GetChildrenFileAttributes(
184
0
      status_and_enc_path.second, options, result, dbg);
185
0
}
186
187
IOStatus RemapFileSystem::DeleteFile(const std::string& fname,
188
                                     const IOOptions& options,
189
0
                                     IODebugContext* dbg) {
190
0
  auto status_and_enc_path = EncodePath(fname);
191
0
  if (!status_and_enc_path.first.ok()) {
192
0
    return status_and_enc_path.first;
193
0
  }
194
0
  return FileSystemWrapper::DeleteFile(status_and_enc_path.second, options,
195
0
                                       dbg);
196
0
}
197
198
IOStatus RemapFileSystem::CreateDir(const std::string& dirname,
199
                                    const IOOptions& options,
200
0
                                    IODebugContext* dbg) {
201
0
  auto status_and_enc_path = EncodePathWithNewBasename(dirname);
202
0
  if (!status_and_enc_path.first.ok()) {
203
0
    return status_and_enc_path.first;
204
0
  }
205
0
  return FileSystemWrapper::CreateDir(status_and_enc_path.second, options, dbg);
206
0
}
207
208
IOStatus RemapFileSystem::CreateDirIfMissing(const std::string& dirname,
209
                                             const IOOptions& options,
210
0
                                             IODebugContext* dbg) {
211
0
  auto status_and_enc_path = EncodePathWithNewBasename(dirname);
212
0
  if (!status_and_enc_path.first.ok()) {
213
0
    return status_and_enc_path.first;
214
0
  }
215
0
  return FileSystemWrapper::CreateDirIfMissing(status_and_enc_path.second,
216
0
                                               options, dbg);
217
0
}
218
219
IOStatus RemapFileSystem::DeleteDir(const std::string& dirname,
220
                                    const IOOptions& options,
221
0
                                    IODebugContext* dbg) {
222
0
  auto status_and_enc_path = EncodePath(dirname);
223
0
  if (!status_and_enc_path.first.ok()) {
224
0
    return status_and_enc_path.first;
225
0
  }
226
0
  return FileSystemWrapper::DeleteDir(status_and_enc_path.second, options, dbg);
227
0
}
228
229
IOStatus RemapFileSystem::GetFileSize(const std::string& fname,
230
                                      const IOOptions& options,
231
                                      uint64_t* file_size,
232
0
                                      IODebugContext* dbg) {
233
0
  auto status_and_enc_path = EncodePath(fname);
234
0
  if (!status_and_enc_path.first.ok()) {
235
0
    return status_and_enc_path.first;
236
0
  }
237
0
  return FileSystemWrapper::GetFileSize(status_and_enc_path.second, options,
238
0
                                        file_size, dbg);
239
0
}
240
241
IOStatus RemapFileSystem::GetFileModificationTime(const std::string& fname,
242
                                                  const IOOptions& options,
243
                                                  uint64_t* file_mtime,
244
0
                                                  IODebugContext* dbg) {
245
0
  auto status_and_enc_path = EncodePath(fname);
246
0
  if (!status_and_enc_path.first.ok()) {
247
0
    return status_and_enc_path.first;
248
0
  }
249
0
  return FileSystemWrapper::GetFileModificationTime(status_and_enc_path.second,
250
0
                                                    options, file_mtime, dbg);
251
0
}
252
253
IOStatus RemapFileSystem::IsDirectory(const std::string& path,
254
                                      const IOOptions& options, bool* is_dir,
255
0
                                      IODebugContext* dbg) {
256
0
  auto status_and_enc_path = EncodePath(path);
257
0
  if (!status_and_enc_path.first.ok()) {
258
0
    return status_and_enc_path.first;
259
0
  }
260
0
  return FileSystemWrapper::IsDirectory(status_and_enc_path.second, options,
261
0
                                        is_dir, dbg);
262
0
}
263
264
IOStatus RemapFileSystem::RenameFile(const std::string& src,
265
                                     const std::string& dest,
266
                                     const IOOptions& options,
267
0
                                     IODebugContext* dbg) {
268
0
  auto status_and_src_enc_path = EncodePath(src);
269
0
  if (!status_and_src_enc_path.first.ok()) {
270
0
    if (status_and_src_enc_path.first.IsNotFound()) {
271
0
      const IOStatus& s = status_and_src_enc_path.first;
272
0
      status_and_src_enc_path.first = IOStatus::PathNotFound(s.ToString());
273
0
    }
274
0
    return status_and_src_enc_path.first;
275
0
  }
276
0
  auto status_and_dest_enc_path = EncodePathWithNewBasename(dest);
277
0
  if (!status_and_dest_enc_path.first.ok()) {
278
0
    return status_and_dest_enc_path.first;
279
0
  }
280
0
  return FileSystemWrapper::RenameFile(status_and_src_enc_path.second,
281
0
                                       status_and_dest_enc_path.second, options,
282
0
                                       dbg);
283
0
}
284
285
IOStatus RemapFileSystem::LinkFile(const std::string& src,
286
                                   const std::string& dest,
287
                                   const IOOptions& options,
288
0
                                   IODebugContext* dbg) {
289
0
  auto status_and_src_enc_path = EncodePath(src);
290
0
  if (!status_and_src_enc_path.first.ok()) {
291
0
    return status_and_src_enc_path.first;
292
0
  }
293
0
  auto status_and_dest_enc_path = EncodePathWithNewBasename(dest);
294
0
  if (!status_and_dest_enc_path.first.ok()) {
295
0
    return status_and_dest_enc_path.first;
296
0
  }
297
0
  return FileSystemWrapper::LinkFile(status_and_src_enc_path.second,
298
0
                                     status_and_dest_enc_path.second, options,
299
0
                                     dbg);
300
0
}
301
302
IOStatus RemapFileSystem::LockFile(const std::string& fname,
303
                                   const IOOptions& options, FileLock** lock,
304
0
                                   IODebugContext* dbg) {
305
0
  auto status_and_enc_path = EncodePathWithNewBasename(fname);
306
0
  if (!status_and_enc_path.first.ok()) {
307
0
    return status_and_enc_path.first;
308
0
  }
309
  // FileLock subclasses may store path (e.g., PosixFileLock stores it). We
310
  // can skip stripping the chroot directory from this path because callers
311
  // shouldn't use it.
312
0
  return FileSystemWrapper::LockFile(status_and_enc_path.second, options, lock,
313
0
                                     dbg);
314
0
}
315
316
IOStatus RemapFileSystem::NewLogger(const std::string& fname,
317
                                    const IOOptions& options,
318
                                    std::shared_ptr<Logger>* result,
319
0
                                    IODebugContext* dbg) {
320
0
  auto status_and_enc_path = EncodePathWithNewBasename(fname);
321
0
  if (!status_and_enc_path.first.ok()) {
322
0
    return status_and_enc_path.first;
323
0
  }
324
0
  return FileSystemWrapper::NewLogger(status_and_enc_path.second, options,
325
0
                                      result, dbg);
326
0
}
327
328
IOStatus RemapFileSystem::GetAbsolutePath(const std::string& db_path,
329
                                          const IOOptions& options,
330
                                          std::string* output_path,
331
0
                                          IODebugContext* dbg) {
332
0
  auto status_and_enc_path = EncodePathWithNewBasename(db_path);
333
0
  if (!status_and_enc_path.first.ok()) {
334
0
    return status_and_enc_path.first;
335
0
  }
336
0
  return FileSystemWrapper::GetAbsolutePath(status_and_enc_path.second, options,
337
0
                                            output_path, dbg);
338
0
}
339
340
}  // namespace ROCKSDB_NAMESPACE
341