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 } IncFsFeatures;
48 
49 typedef int IncFsErrorCode;
50 typedef int64_t IncFsSize;
51 typedef int32_t IncFsBlockIndex;
52 typedef int IncFsFd;
53 typedef struct IncFsControl IncFsControl;
54 
55 typedef struct {
56     const char* data;
57     IncFsSize size;
58 } IncFsSpan;
59 
60 typedef enum {
61     CMD,
62     PENDING_READS,
63     LOGS,
64     FDS_COUNT,
65 } IncFsFdType;
66 
67 typedef enum {
68     INCFS_DEFAULT_READ_TIMEOUT_MS = 10000,
69     INCFS_DEFAULT_PENDING_READ_BUFFER_SIZE = 24,
70     INCFS_DEFAULT_PAGE_READ_BUFFER_PAGES = 4,
71 } IncFsDefaults;
72 
73 typedef enum {
74     INCFS_MOUNT_CREATE_ONLY = 1,
75     INCFS_MOUNT_TRUNCATE = 2,
76 } IncFsMountFlags;
77 
78 typedef enum {
79     INCFS_HASH_NONE,
80     INCFS_HASH_SHA256,
81 } IncFsHashAlgortithm;
82 
83 typedef struct {
84     IncFsMountFlags flags;
85     int32_t defaultReadTimeoutMs;
86     int32_t readLogBufferPages;
87     int32_t readLogDisableAfterTimeoutMs;
88 } IncFsMountOptions;
89 
90 typedef enum {
91     INCFS_COMPRESSION_KIND_NONE,
92     INCFS_COMPRESSION_KIND_LZ4,
93 } IncFsCompressionKind;
94 
95 typedef enum {
96     INCFS_BLOCK_KIND_DATA,
97     INCFS_BLOCK_KIND_HASH,
98 } IncFsBlockKind;
99 
100 typedef struct {
101     IncFsFd fileFd;
102     IncFsBlockIndex pageIndex;
103     IncFsCompressionKind compression;
104     IncFsBlockKind kind;
105     uint32_t dataSize;
106     const char* data;
107 } IncFsDataBlock;
108 
109 typedef struct {
110     IncFsSize size;
111     IncFsSpan metadata;
112     IncFsSpan signature;
113 } IncFsNewFileParams;
114 
115 typedef struct {
116     IncFsFileId id;
117     uint64_t bootClockTsUs;
118     IncFsBlockIndex block;
119     uint32_t serialNo;
120 } IncFsReadInfo;
121 
122 typedef struct {
123     IncFsBlockIndex begin;
124     IncFsBlockIndex end;
125 } IncFsBlockRange;
126 
127 typedef struct {
128     IncFsBlockRange* dataRanges;
129     IncFsBlockRange* hashRanges;
130     int32_t dataRangesCount;
131     int32_t hashRangesCount;
132     IncFsBlockIndex endIndex;
133 } IncFsFilledRanges;
134 
135 // All functions return -errno in case of failure.
136 // All IncFsFd functions return >=0 in case of success.
137 // All IncFsFileId functions return invalid IncFsFileId on error.
138 // All IncFsErrorCode functions return 0 in case of success.
139 
140 bool IncFs_IsEnabled();
141 IncFsFeatures IncFs_Features();
142 
143 bool IncFs_IsIncFsPath(const char* path);
144 
IncFs_IsValidFileId(IncFsFileId fileId)145 static inline bool IncFs_IsValidFileId(IncFsFileId fileId) {
146     return memcmp(&fileId, &kIncFsInvalidFileId, sizeof(fileId)) != 0;
147 }
148 
149 int IncFs_FileIdToString(IncFsFileId id, char* out);
150 IncFsFileId IncFs_FileIdFromString(const char* in);
151 
152 IncFsFileId IncFs_FileIdFromMetadata(IncFsSpan metadata);
153 
154 IncFsControl* IncFs_Mount(const char* backingPath, const char* targetDir,
155                           IncFsMountOptions options);
156 IncFsControl* IncFs_Open(const char* dir);
157 IncFsControl* IncFs_CreateControl(IncFsFd cmd, IncFsFd pendingReads, IncFsFd logs);
158 void IncFs_DeleteControl(IncFsControl* control);
159 IncFsFd IncFs_GetControlFd(const IncFsControl* control, IncFsFdType type);
160 IncFsSize IncFs_ReleaseControlFds(IncFsControl* control, IncFsFd out[], IncFsSize outSize);
161 
162 IncFsErrorCode IncFs_SetOptions(const IncFsControl* control, IncFsMountOptions options);
163 
164 IncFsErrorCode IncFs_BindMount(const char* sourceDir, const char* targetDir);
165 IncFsErrorCode IncFs_Unmount(const char* dir);
166 
167 IncFsErrorCode IncFs_Root(const IncFsControl* control, char buffer[], size_t* bufferSize);
168 
169 IncFsErrorCode IncFs_MakeFile(const IncFsControl* control, const char* path, int32_t mode,
170                               IncFsFileId id, IncFsNewFileParams params);
171 IncFsErrorCode IncFs_MakeDir(const IncFsControl* control, const char* path, int32_t mode);
172 IncFsErrorCode IncFs_MakeDirs(const IncFsControl* control, const char* path, int32_t mode);
173 
174 IncFsErrorCode IncFs_GetMetadataById(const IncFsControl* control, IncFsFileId id, char buffer[],
175                                      size_t* bufferSize);
176 IncFsErrorCode IncFs_GetMetadataByPath(const IncFsControl* control, const char* path, char buffer[],
177                                        size_t* bufferSize);
178 
179 IncFsErrorCode IncFs_GetSignatureById(const IncFsControl* control, IncFsFileId id, char buffer[],
180                                       size_t* bufferSize);
181 IncFsErrorCode IncFs_GetSignatureByPath(const IncFsControl* control, const char* path,
182                                         char buffer[], size_t* bufferSize);
183 IncFsErrorCode IncFs_UnsafeGetSignatureByPath(const char* path, char buffer[], size_t* bufferSize);
184 
185 IncFsFileId IncFs_GetId(const IncFsControl* control, const char* path);
186 
187 IncFsErrorCode IncFs_Link(const IncFsControl* control, const char* sourcePath,
188                           const char* targetPath);
189 IncFsErrorCode IncFs_Unlink(const IncFsControl* control, const char* path);
190 
191 IncFsErrorCode IncFs_WaitForPendingReads(const IncFsControl* control, int32_t timeoutMs,
192                                          IncFsReadInfo buffer[], size_t* bufferSize);
193 IncFsErrorCode IncFs_WaitForPageReads(const IncFsControl* control, int32_t timeoutMs,
194                                       IncFsReadInfo buffer[], size_t* bufferSize);
195 
196 IncFsFd IncFs_OpenForSpecialOpsByPath(const IncFsControl* control, const char* path);
197 IncFsFd IncFs_OpenForSpecialOpsById(const IncFsControl* control, IncFsFileId id);
198 
199 IncFsErrorCode IncFs_WriteBlocks(const IncFsDataBlock blocks[], size_t blocksCount);
200 
201 // Gets a collection of filled ranges in the file from IncFS. Uses the |outBuffer| memory, it has
202 // to be big enough to fit all the ranges the caller is expecting.
203 // Return codes:
204 //  0       - success,
205 //  -ERANGE - input buffer is too small. filledRanges are still valid up to the outBuffer.size,
206 //            but there are more,
207 //  <0      - error, |filledRanges| is not valid.
208 IncFsErrorCode IncFs_GetFilledRanges(int fd, IncFsSpan outBuffer, IncFsFilledRanges* filledRanges);
209 IncFsErrorCode IncFs_GetFilledRangesStartingFrom(int fd, int startBlockIndex, IncFsSpan outBuffer,
210                                                  IncFsFilledRanges* filledRanges);
211 // Check if the file is fully loaded. Return codes:
212 //  0        - fully loaded,
213 //  -ENODATA - some blocks are missing,
214 //  <0       - error from the syscall.
215 IncFsErrorCode IncFs_IsFullyLoaded(int fd);
216 
217 __END_DECLS
218 
219 #endif // ANDROID_INCREMENTAL_FILE_SYSTEM_NDK_H
220