-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathfsLogic.h
348 lines (290 loc) · 12 KB
/
fsLogic.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
/**
* @file fsLogic.h
* @author Konrad Zemek
* @copyright (C) 2016 ACK CYFRONET AGH
* @copyright This software is released under the MIT license cited in
* 'LICENSE.txt'
*/
#pragma once
#include "fuseFileHandle.h"
#include "attrs.h"
#include "cache/forceProxyIOCache.h"
#include "cache/helpersCache.h"
#include "cache/lruMetadataCache.h"
#include "cache/readdirCache.h"
#include "events/events.h"
#include "fsSubscriptions.h"
#include "ioTraceLogger.h"
#include <asio/buffer.hpp>
#include <boost/icl/discrete_interval.hpp>
#include <folly/FBString.h>
#include <folly/FBVector.h>
#include <folly/Function.h>
#include <folly/io/IOBufQueue.h>
#include <functional>
#include <memory>
#include <random>
#include <unordered_map>
#include <unordered_set>
constexpr auto ONE_XATTR_PREFIX = "org.onedata.";
namespace one {
namespace messages {
class Configuration;
namespace fuse {
class FileBlock;
class FuseResponse;
class SyncResponse;
} // namespace fuse
} // namespace messages
namespace client {
class Context;
namespace fslogic {
constexpr auto FSLOGIC_RETRY_COUNT = 4;
const std::array<std::pair<int, int>, FSLOGIC_RETRY_COUNT> FSLOGIC_RETRY_DELAYS{
{{100, 1000}, {1000, 5000}, {5000, 10'000}, {10'000, 30'000}}};
constexpr auto SYNCHRONIZE_BLOCK_PRIORITY_IMMEDIATE = 32;
constexpr auto SYNCHRONIZE_BLOCK_PRIORITY_LINEAR_PREFETCH = 96;
constexpr auto SYNCHRONIZE_BLOCK_PRIORITY_CLUSTER_PREFETCH = 160;
/**
* The FsLogic main class.
* This class contains FUSE all callbacks, so it basically is an heart of the
* filesystem. Technically FsLogic is an singleton created on program start and
* registered in FUSE daemon.
*/
class FsLogic {
public:
using BlocksMap =
std::map<folly::fbstring, folly::fbvector<std::pair<off_t, off_t>>>;
/**
* Constructor.
* @param context Shared pointer to application context instance.
* @param configuration Starting configuration from server.
* @param helpersCache Cache from which helpers will be fetched.
* @param readEventsDisabled Specifies if FileRead event should be emitted.
* @param providerTimeout Timeout for provider connection.
* @param runInFiber A function that runs callback inside a main fiber.
*/
FsLogic(std::shared_ptr<Context> context,
std::shared_ptr<messages::Configuration> configuration,
std::unique_ptr<cache::HelpersCache> helpersCache,
unsigned int metadataCacheSize, bool readEventsDisabled,
bool forceFullblockRead, const std::chrono::seconds providerTimeout,
std::function<void(folly::Function<void()>)> runInFiber);
~FsLogic();
/**
* FUSE @c lookup callback.
* @see https://libfuse.github.io/doxygen/structfuse__lowlevel__ops.html
*/
FileAttrPtr lookup(
const folly::fbstring &uuid, const folly::fbstring &name);
/**
* FUSE @c getattr callback.
* @see https://libfuse.github.io/doxygen/structfuse__lowlevel__ops.html
*/
FileAttrPtr getattr(const folly::fbstring &uuid);
/**
* FUSE @c readdir callback.
* @see https://libfuse.github.io/doxygen/structfuse__lowlevel__ops.html
*/
folly::fbvector<folly::fbstring> readdir(
const folly::fbstring &uuid, const size_t maxSize, const off_t off);
/**
* FUSE @c open callback.
* @see https://libfuse.github.io/doxygen/structfuse__lowlevel__ops.html
*/
std::uint64_t open(const folly::fbstring &uuid, const int flags);
/**
* FUSE @c release callback.
* @see https://libfuse.github.io/doxygen/structfuse__lowlevel__ops.html
*/
void release(const folly::fbstring &uuid, const std::uint64_t fileHandleId);
/**
* FUSE @c read callback.
* @see https://libfuse.github.io/doxygen/structfuse__lowlevel__ops.html
*/
folly::IOBufQueue read(const folly::fbstring &uuid,
const std::uint64_t fileHandleId, const off_t offset,
const std::size_t size, folly::Optional<folly::fbstring> checksum,
const int retriesLeft = FSLOGIC_RETRY_COUNT,
std::unique_ptr<IOTraceRead> ioTraceEntry = {});
/**
* FUSE @c write callback.
* @see https://libfuse.github.io/doxygen/structfuse__lowlevel__ops.html
*/
std::size_t write(const folly::fbstring &uuid,
const std::uint64_t fuseFileHandleId, const off_t offset,
std::shared_ptr<folly::IOBuf> buf,
const int retriesLeft = FSLOGIC_RETRY_COUNT,
std::unique_ptr<IOTraceWrite> ioTraceEntry = {});
/**
* FUSE @c mkdir callback.
* @see https://libfuse.github.io/doxygen/structfuse__lowlevel__ops.html
*/
FileAttrPtr mkdir(const folly::fbstring &parentUuid,
const folly::fbstring &name, const mode_t mode);
/**
* FUSE @c mknod callback.
* @see https://libfuse.github.io/doxygen/structfuse__lowlevel__ops.html
*/
FileAttrPtr mknod(const folly::fbstring &parentUuid,
const folly::fbstring &name, const mode_t mode);
/**
* FUSE @c unlink callback.
* @see https://libfuse.github.io/doxygen/structfuse__lowlevel__ops.html
*/
void unlink(const folly::fbstring &parentUuid, const folly::fbstring &name);
/**
* FUSE @c rename callback.
* @see https://libfuse.github.io/doxygen/structfuse__lowlevel__ops.html
*/
void rename(const folly::fbstring &parentUuid, const folly::fbstring &name,
const folly::fbstring &newParentUuid, const folly::fbstring &newName);
/**
* FUSE @c setattr callback.
* @see https://libfuse.github.io/doxygen/structfuse__lowlevel__ops.html
*/
FileAttrPtr setattr(
const folly::fbstring &uuid, const struct stat &attr, const int toSet);
/**
* FUSE @c create callback.
* @see https://libfuse.github.io/doxygen/structfuse__lowlevel__ops.html
*/
std::pair<FileAttrPtr, std::uint64_t> create(
const folly::fbstring &parentUuid, const folly::fbstring &name,
const mode_t mode, const int flags);
/**
* FUSE @c flush callback.
* @see https://libfuse.github.io/doxygen/structfuse__lowlevel__ops.html
*/
void flush(const folly::fbstring &uuid, const std::uint64_t fileHandleId);
/**
* FUSE @c fsync callback.
* @see https://libfuse.github.io/doxygen/structfuse__lowlevel__ops.html
*/
void fsync(const folly::fbstring &uuid, const std::uint64_t fileHandleId,
const bool dataOnly);
/**
* FUSE @c getxattr callback.
* @see https://libfuse.github.io/doxygen/structfuse__lowlevel__ops.html
*/
folly::fbstring getxattr(
const folly::fbstring &uuid, const folly::fbstring &name);
/**
* FUSE @c setxattr callback.
* @see https://libfuse.github.io/doxygen/structfuse__lowlevel__ops.html
*/
void setxattr(const folly::fbstring &uuid, const folly::fbstring &name,
const folly::fbstring &value, bool create, bool replace);
/**
* FUSE @c removexattr callback.
* @see https://libfuse.github.io/doxygen/structfuse__lowlevel__ops.html
*/
void removexattr(const folly::fbstring &uuid, const folly::fbstring &name);
/**
* FUSE @c listxattr callback.
* @see https://libfuse.github.io/doxygen/structfuse__lowlevel__ops.html
*/
folly::fbvector<folly::fbstring> listxattr(const folly::fbstring &uuid);
/**
* Sets a callback to be called when a file is marked as deleted.
* @param cb The callback function that takes file's uuid as parameter.
*/
void onMarkDeleted(std::function<void(const folly::fbstring &)> cb)
{
m_onMarkDeleted = std::move(cb);
}
/**
* Sets a callback to be called when a file is marked as deleted.
* @param cb The callback function that takes file's old uuid and new uuid
* as parameters.
*/
void onRename(
std::function<void(const folly::fbstring &, const folly::fbstring &)>
cb)
{
m_onRename = std::move(cb);
}
/**
* Returns true if full block reads are forced.
*/
bool isFullBlockReadForced() const { return m_forceFullblockRead; }
std::shared_ptr<IOTraceLogger> ioTraceLogger() { return m_ioTraceLogger; }
std::shared_ptr<FuseFileHandle> getFuseFileHandle(std::uint64_t handleId)
{
return m_fuseFileHandles.at(handleId);
}
std::map<folly::fbstring, folly::fbvector<std::pair<off_t, off_t>>>
getFileLocalBlocks(const folly::fbstring &uuid);
private:
template <typename SrvMsg = messages::fuse::FuseResponse, typename CliMsg>
SrvMsg communicate(CliMsg &&msg, const std::chrono::seconds timeout);
folly::fbstring syncAndFetchChecksum(const folly::fbstring &uuid,
const boost::icl::discrete_interval<off_t> &range);
void sync(const folly::fbstring &uuid,
const boost::icl::discrete_interval<off_t> &range);
bool dataCorrupted(const folly::fbstring &uuid,
const folly::IOBufQueue &buf, const folly::fbstring &serverChecksum,
const boost::icl::discrete_interval<off_t> &availableRange,
const boost::icl::discrete_interval<off_t> &wantedRange);
folly::fbstring computeHash(const folly::IOBufQueue &buf);
FileAttrPtr makeFile(const folly::fbstring &parentUuid,
const folly::fbstring &name, const mode_t mode,
const helpers::Flag flag);
bool isSpaceDisabled(const folly::fbstring &spaceId);
void disableSpaces(const std::vector<std::string> &spaces);
std::shared_ptr<IOTraceLogger> createIOTraceLogger();
std::pair<size_t, IOTraceLogger::PrefetchType> prefetchAsync(
std::shared_ptr<FuseFileHandle> fuseFileHandle,
helpers::FileHandlePtr helperHandle, const off_t offset,
const std::size_t size, const folly::fbstring &uuid,
const boost::icl::discrete_interval<off_t> possibleRange,
const boost::icl::discrete_interval<off_t> availableRange);
/**
* Suspends current fiber for a random timed delay depending
* on current retry number.
* @param retriesLeft Current number of retries left
*/
void fiberRetryDelay(int retriesLeft);
std::shared_ptr<Context> m_context;
events::Manager m_eventManager{m_context};
cache::LRUMetadataCache m_metadataCache;
cache::ForceProxyIOCache m_forceProxyIOCache;
std::unique_ptr<cache::HelpersCache> m_helpersCache;
std::shared_ptr<cache::ReaddirCache> m_readdirCache;
bool m_readEventsDisabled = false;
// Determines whether the read requests should return full requested
// size, or can return partial byte range if it is immediately
// available
bool m_forceFullblockRead;
FsSubscriptions m_fsSubscriptions;
std::unordered_set<folly::fbstring> m_disabledSpaces;
std::unordered_map<std::uint64_t, std::shared_ptr<FuseFileHandle>>
m_fuseFileHandles;
std::unordered_map<std::uint64_t, folly::fbstring> m_fuseDirectoryHandles;
std::atomic<std::uint64_t> m_nextFuseHandleId;
std::function<void(const folly::fbstring &)> m_onMarkDeleted = [](auto) {};
std::function<void(const folly::fbstring &, const folly::fbstring &)>
m_onRename = [](auto, auto) {};
const std::chrono::seconds m_providerTimeout;
std::function<void(folly::Function<void()>)> m_runInFiber;
const bool m_prefetchModeAsync;
const double m_linearReadPrefetchThreshold;
const double m_randomReadPrefetchThreshold;
const unsigned int m_randomReadPrefetchBlockThreshold;
const int m_randomReadPrefetchClusterWindow;
const unsigned int m_randomReadPrefetchClusterBlockThreshold;
const unsigned int m_randomReadPrefetchEvaluationFrequency;
const double m_randomReadPrefetchClusterWindowGrowFactor;
const bool m_clusterPrefetchThresholdRandom;
const bool m_ioTraceLoggerEnabled;
const boost::optional<std::pair<std::string, std::string>> m_tagOnCreate;
const boost::optional<std::pair<std::string, std::string>> m_tagOnModify;
const folly::fbstring m_rootUuid;
std::shared_ptr<IOTraceLogger> m_ioTraceLogger;
std::random_device m_clusterPrefetchRD{};
std::mt19937 m_clusterPrefetchRandomGenerator{m_clusterPrefetchRD()};
std::uniform_int_distribution<> m_clusterPrefetchDistribution;
};
} // namespace fslogic
} // namespace client
} // namespace one