• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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