1 /*
2 * Copyright (C) 2019 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #ifndef ANDROID_INCREMENTAL_FILE_SYSTEM_NDK_H
18 #define ANDROID_INCREMENTAL_FILE_SYSTEM_NDK_H
19
20 #include <linux/incrementalfs.h>
21 #include <stdbool.h>
22 #include <stddef.h>
23 #include <stdint.h>
24 #include <string.h>
25 #include <sys/cdefs.h>
26
27 __BEGIN_DECLS
28
29 #define INCFS_LIBRARY_NAME "libincfs.so"
30
31 typedef struct {
32 union {
33 char data[16];
34 int64_t for_alignment;
35 };
36 } IncFsFileId;
37
38 static const IncFsFileId kIncFsInvalidFileId = {
39 {{(char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1,
40 (char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1}}};
41
42 static const int kIncFsFileIdStringLength = sizeof(IncFsFileId) * 2;
43
44 typedef enum {
45 INCFS_FEATURE_NONE = 0,
46 INCFS_FEATURE_CORE = 1 << 0,
47 INCFS_FEATURE_V2 = 1 << 1,
48 INCFS_FEATURE_MAPPING_FILES_PROGRESS_FIXED = 1 << 2,
49
50 } IncFsFeatures;
51
52 typedef int IncFsErrorCode;
53 typedef int64_t IncFsSize;
54 typedef int32_t IncFsBlockIndex;
55 typedef int IncFsFd;
56 typedef struct IncFsControl IncFsControl;
57 typedef int IncFsUid;
58
59 static const IncFsUid kIncFsNoUid = -1;
60
61 typedef struct {
62 const char* data;
63 IncFsSize size;
64 } IncFsSpan;
65
66 typedef enum {
67 CMD,
68 PENDING_READS,
69 LOGS,
70 BLOCKS_WRITTEN,
71 FDS_COUNT,
72 } IncFsFdType;
73
74 typedef enum {
75 INCFS_DEFAULT_READ_TIMEOUT_MS = 10000,
76 INCFS_DEFAULT_PENDING_READ_BUFFER_SIZE = 24,
77 INCFS_DEFAULT_PAGE_READ_BUFFER_PAGES = 4,
78 } IncFsDefaults;
79
80 typedef enum {
81 INCFS_MOUNT_CREATE_ONLY = 1,
82 INCFS_MOUNT_TRUNCATE = 2,
83 } IncFsMountFlags;
84
85 typedef enum {
86 INCFS_HASH_NONE,
87 INCFS_HASH_SHA256,
88 } IncFsHashAlgortithm;
89
90 typedef struct {
91 IncFsMountFlags flags;
92 int32_t defaultReadTimeoutMs;
93 int32_t readLogBufferPages;
94 int32_t readLogDisableAfterTimeoutMs;
95 const char* sysfsName;
96 } IncFsMountOptions;
97
98 typedef enum {
99 INCFS_COMPRESSION_KIND_NONE,
100 INCFS_COMPRESSION_KIND_LZ4,
101 INCFS_COMPRESSION_KIND_ZSTD,
102 } IncFsCompressionKind;
103
104 typedef enum {
105 INCFS_BLOCK_KIND_DATA,
106 INCFS_BLOCK_KIND_HASH,
107 } IncFsBlockKind;
108
109 typedef struct {
110 IncFsFd fileFd;
111 IncFsBlockIndex pageIndex;
112 IncFsCompressionKind compression;
113 IncFsBlockKind kind;
114 uint32_t dataSize;
115 const char* data;
116 } IncFsDataBlock;
117
118 typedef struct {
119 IncFsSize size;
120 IncFsSpan metadata;
121 IncFsSpan signature;
122 } IncFsNewFileParams;
123
124 typedef struct {
125 IncFsFileId sourceId;
126 IncFsSize sourceOffset;
127 IncFsSize size;
128 } IncFsNewMappedFileParams;
129
130 typedef struct {
131 IncFsFileId id;
132 uint64_t bootClockTsUs;
133 IncFsBlockIndex block;
134 uint32_t serialNo;
135 } IncFsReadInfo;
136
137 typedef struct {
138 IncFsFileId id;
139 uint64_t bootClockTsUs;
140 IncFsBlockIndex block;
141 uint32_t serialNo;
142 IncFsUid uid;
143 } IncFsReadInfoWithUid;
144
145 typedef struct {
146 IncFsBlockIndex begin;
147 IncFsBlockIndex end;
148 } IncFsBlockRange;
149
150 typedef struct {
151 IncFsBlockRange* dataRanges;
152 IncFsBlockRange* hashRanges;
153 int32_t dataRangesCount;
154 int32_t hashRangesCount;
155 IncFsBlockIndex endIndex;
156 } IncFsFilledRanges;
157
158 typedef struct {
159 IncFsSize totalDataBlocks;
160 IncFsSize filledDataBlocks;
161 IncFsSize totalHashBlocks;
162 IncFsSize filledHashBlocks;
163 } IncFsBlockCounts;
164
165 typedef struct {
166 IncFsUid uid;
167 uint32_t minTimeUs;
168 uint32_t minPendingTimeUs;
169 uint32_t maxPendingTimeUs;
170 } IncFsUidReadTimeouts;
171
172 typedef struct {
173 uint32_t readsDelayedMin;
174 uint64_t readsDelayedMinUs;
175 uint32_t readsDelayedPending;
176 uint64_t readsDelayedPendingUs;
177 uint32_t readsFailedHashVerification;
178 uint32_t readsFailedOther;
179 uint32_t readsFailedTimedOut;
180 uint64_t reserved;
181 uint64_t reserved1;
182 } IncFsMetrics;
183
184 typedef struct {
185 IncFsFileId id;
186 uint64_t timestampUs;
187 IncFsBlockIndex block;
188 uint32_t errorNo;
189 IncFsUid uid;
190 } IncFsLastReadError;
191
192 // All functions return -errno in case of failure.
193 // All IncFsFd functions return >=0 in case of success.
194 // All IncFsFileId functions return invalid IncFsFileId on error.
195 // All IncFsErrorCode functions return 0 in case of success.
196
197 bool IncFs_IsEnabled();
198 IncFsFeatures IncFs_Features();
199
200 bool IncFs_IsIncFsFd(int fd);
201 bool IncFs_IsIncFsPath(const char* path);
202
IncFs_IsValidFileId(IncFsFileId fileId)203 static inline bool IncFs_IsValidFileId(IncFsFileId fileId) {
204 return memcmp(&fileId, &kIncFsInvalidFileId, sizeof(fileId)) != 0;
205 }
206
207 int IncFs_FileIdToString(IncFsFileId id, char* out);
208 IncFsFileId IncFs_FileIdFromString(const char* in);
209
210 IncFsFileId IncFs_FileIdFromMetadata(IncFsSpan metadata);
211
212 IncFsControl* IncFs_Mount(const char* backingPath, const char* targetDir,
213 IncFsMountOptions options);
214 IncFsControl* IncFs_Open(const char* dir);
215 IncFsControl* IncFs_CreateControl(IncFsFd cmd, IncFsFd pendingReads, IncFsFd logs,
216 IncFsFd blocksWritten);
217 void IncFs_DeleteControl(IncFsControl* control);
218 IncFsFd IncFs_GetControlFd(const IncFsControl* control, IncFsFdType type);
219 IncFsSize IncFs_ReleaseControlFds(IncFsControl* control, IncFsFd out[], IncFsSize outSize);
220
221 IncFsErrorCode IncFs_SetOptions(const IncFsControl* control, IncFsMountOptions options);
222
223 IncFsErrorCode IncFs_BindMount(const char* sourceDir, const char* targetDir);
224 IncFsErrorCode IncFs_Unmount(const char* dir);
225
226 IncFsErrorCode IncFs_Root(const IncFsControl* control, char buffer[], size_t* bufferSize);
227
228 IncFsErrorCode IncFs_MakeFile(const IncFsControl* control, const char* path, int32_t mode,
229 IncFsFileId id, IncFsNewFileParams params);
230 IncFsErrorCode IncFs_MakeMappedFile(const IncFsControl* control, const char* path, int32_t mode,
231 IncFsNewMappedFileParams params);
232
233 IncFsErrorCode IncFs_MakeDir(const IncFsControl* control, const char* path, int32_t mode);
234 IncFsErrorCode IncFs_MakeDirs(const IncFsControl* control, const char* path, int32_t mode);
235
236 IncFsErrorCode IncFs_GetMetadataById(const IncFsControl* control, IncFsFileId id, char buffer[],
237 size_t* bufferSize);
238 IncFsErrorCode IncFs_GetMetadataByPath(const IncFsControl* control, const char* path, char buffer[],
239 size_t* bufferSize);
240
241 IncFsErrorCode IncFs_GetSignatureById(const IncFsControl* control, IncFsFileId id, char buffer[],
242 size_t* bufferSize);
243 IncFsErrorCode IncFs_GetSignatureByPath(const IncFsControl* control, const char* path,
244 char buffer[], size_t* bufferSize);
245 IncFsErrorCode IncFs_UnsafeGetSignatureByPath(const char* path, char buffer[], size_t* bufferSize);
246
247 IncFsFileId IncFs_GetId(const IncFsControl* control, const char* path);
248
249 IncFsErrorCode IncFs_Link(const IncFsControl* control, const char* sourcePath,
250 const char* targetPath);
251 IncFsErrorCode IncFs_Unlink(const IncFsControl* control, const char* path);
252
253 IncFsErrorCode IncFs_WaitForPendingReads(const IncFsControl* control, int32_t timeoutMs,
254 IncFsReadInfo buffer[], size_t* bufferSize);
255 IncFsErrorCode IncFs_WaitForPageReads(const IncFsControl* control, int32_t timeoutMs,
256 IncFsReadInfo buffer[], size_t* bufferSize);
257
258 IncFsErrorCode IncFs_WaitForPendingReadsWithUid(const IncFsControl* control, int32_t timeoutMs,
259 IncFsReadInfoWithUid buffer[], size_t* bufferSize);
260 IncFsErrorCode IncFs_WaitForPageReadsWithUid(const IncFsControl* control, int32_t timeoutMs,
261 IncFsReadInfoWithUid buffer[], size_t* bufferSize);
262
263 IncFsErrorCode IncFs_WaitForFsWrittenBlocksChange(const IncFsControl* control, int32_t timeoutMs,
264 IncFsSize* count);
265
266 IncFsFd IncFs_OpenForSpecialOpsByPath(const IncFsControl* control, const char* path);
267 IncFsFd IncFs_OpenForSpecialOpsById(const IncFsControl* control, IncFsFileId id);
268
269 IncFsErrorCode IncFs_WriteBlocks(const IncFsDataBlock blocks[], size_t blocksCount);
270
271 IncFsErrorCode IncFs_SetUidReadTimeouts(const IncFsControl* control,
272 const IncFsUidReadTimeouts timeouts[], size_t count);
273 IncFsErrorCode IncFs_GetUidReadTimeouts(const IncFsControl* control,
274 IncFsUidReadTimeouts timeoutsBuffer[], size_t* bufferSize);
275
276 IncFsErrorCode IncFs_GetFileBlockCountByPath(const IncFsControl* control, const char* path,
277 IncFsBlockCounts* blockCount);
278 IncFsErrorCode IncFs_GetFileBlockCountById(const IncFsControl* control, IncFsFileId id,
279 IncFsBlockCounts* blockCount);
280
281 IncFsErrorCode IncFs_ListIncompleteFiles(const IncFsControl* control, IncFsFileId ids[],
282 size_t* bufferSize);
283
284 // Calls a passed callback for each file on the mounted filesystem, or, in the second case,
285 // for each incomplete file (only for v2 IncFS).
286 // Callback can stop the iteration early by returning |false|.
287 // Return codes:
288 // >=0 - number of files iterated,
289 // <0 - -errno
290 typedef bool (*FileCallback)(void* context, const IncFsControl* control, IncFsFileId fileId);
291 IncFsErrorCode IncFs_ForEachFile(const IncFsControl* control, void* context, FileCallback cb);
292 IncFsErrorCode IncFs_ForEachIncompleteFile(const IncFsControl* control, void* context,
293 FileCallback cb);
294
295 IncFsErrorCode IncFs_WaitForLoadingComplete(const IncFsControl* control, int32_t timeoutMs);
296
297 // Gets a collection of filled ranges in the file from IncFS. Uses the |outBuffer| memory, it has
298 // to be big enough to fit all the ranges the caller is expecting.
299 // Return codes:
300 // 0 - success,
301 // -ERANGE - input buffer is too small. filledRanges are still valid up to the outBuffer.size,
302 // but there are more,
303 // <0 - error, |filledRanges| is not valid.
304 IncFsErrorCode IncFs_GetFilledRanges(int fd, IncFsSpan outBuffer, IncFsFilledRanges* filledRanges);
305 IncFsErrorCode IncFs_GetFilledRangesStartingFrom(int fd, int startBlockIndex, IncFsSpan outBuffer,
306 IncFsFilledRanges* filledRanges);
307 // Check if the file is fully loaded. Return codes:
308 // 0 - fully loaded,
309 // -ENODATA - some blocks are missing,
310 // <0 - error from the syscall.
311 IncFsErrorCode IncFs_IsFullyLoaded(int fd);
312 IncFsErrorCode IncFs_IsFullyLoadedByPath(const IncFsControl* control, const char* path);
313 IncFsErrorCode IncFs_IsFullyLoadedById(const IncFsControl* control, IncFsFileId fileId);
314
315 // Check if all files on the mount are fully loaded. Return codes:
316 // 0 - fully loaded,
317 // -ENODATA - some blocks are missing,
318 // <0 - error from the syscall.
319 IncFsErrorCode IncFs_IsEverythingFullyLoaded(const IncFsControl* control);
320
321 // Reserve |size| bytes for the file. Trims reserved space to the current file size when |size = -1|
322 static const IncFsSize kIncFsTrimReservedSpace = -1;
323 IncFsErrorCode IncFs_ReserveSpaceByPath(const IncFsControl* control, const char* path,
324 IncFsSize size);
325 IncFsErrorCode IncFs_ReserveSpaceById(const IncFsControl* control, IncFsFileId id, IncFsSize size);
326
327 // Gets the metrics of a mount by specifying the corresponding sysfs subpath.
328 // Return codes:
329 // =0 - success
330 // <0 - -errno
331 IncFsErrorCode IncFs_GetMetrics(const char* sysfsName, IncFsMetrics* metrics);
332
333 // Gets information about the last read error of a mount.
334 // Return codes:
335 // =0 - success
336 // <0 - -errno
337 // When there is no read error, still returns success. Fields in IncFsLastReadError will be all 0.
338 // Possible values of IncFsLastReadError.errorNo:
339 // -ETIME for read timeout;
340 // -EBADMSG for hash verification failure;
341 // Other negative values for other types of errors.
342 IncFsErrorCode IncFs_GetLastReadError(const IncFsControl* control,
343 IncFsLastReadError* lastReadError);
344
345 __END_DECLS
346
347 #endif // ANDROID_INCREMENTAL_FILE_SYSTEM_NDK_H
348