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