/* * Copyright (C) 2019 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef ANDROID_INCREMENTAL_FILE_SYSTEM_NDK_H #define ANDROID_INCREMENTAL_FILE_SYSTEM_NDK_H #include #include #include #include #include #include __BEGIN_DECLS #define INCFS_LIBRARY_NAME "libincfs.so" typedef struct { union { char data[16]; int64_t for_alignment; }; } IncFsFileId; static const IncFsFileId kIncFsInvalidFileId = { {{(char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1, (char)-1}}}; static const int kIncFsFileIdStringLength = sizeof(IncFsFileId) * 2; typedef enum { INCFS_FEATURE_NONE = 0, INCFS_FEATURE_CORE = 1, INCFS_FEATURE_V2 = 2, } IncFsFeatures; typedef int IncFsErrorCode; typedef int64_t IncFsSize; typedef int32_t IncFsBlockIndex; typedef int IncFsFd; typedef struct IncFsControl IncFsControl; typedef int IncFsUid; static const IncFsUid kIncFsNoUid = -1; typedef struct { const char* data; IncFsSize size; } IncFsSpan; typedef enum { CMD, PENDING_READS, LOGS, BLOCKS_WRITTEN, FDS_COUNT, } IncFsFdType; typedef enum { INCFS_DEFAULT_READ_TIMEOUT_MS = 10000, INCFS_DEFAULT_PENDING_READ_BUFFER_SIZE = 24, INCFS_DEFAULT_PAGE_READ_BUFFER_PAGES = 4, } IncFsDefaults; typedef enum { INCFS_MOUNT_CREATE_ONLY = 1, INCFS_MOUNT_TRUNCATE = 2, } IncFsMountFlags; typedef enum { INCFS_HASH_NONE, INCFS_HASH_SHA256, } IncFsHashAlgortithm; typedef struct { IncFsMountFlags flags; int32_t defaultReadTimeoutMs; int32_t readLogBufferPages; int32_t readLogDisableAfterTimeoutMs; const char* sysfsName; } IncFsMountOptions; typedef enum { INCFS_COMPRESSION_KIND_NONE, INCFS_COMPRESSION_KIND_LZ4, INCFS_COMPRESSION_KIND_ZSTD, } IncFsCompressionKind; typedef enum { INCFS_BLOCK_KIND_DATA, INCFS_BLOCK_KIND_HASH, } IncFsBlockKind; typedef struct { IncFsFd fileFd; IncFsBlockIndex pageIndex; IncFsCompressionKind compression; IncFsBlockKind kind; uint32_t dataSize; const char* data; } IncFsDataBlock; typedef struct { IncFsSize size; IncFsSpan metadata; IncFsSpan signature; } IncFsNewFileParams; typedef struct { IncFsFileId sourceId; IncFsSize sourceOffset; IncFsSize size; } IncFsNewMappedFileParams; typedef struct { IncFsFileId id; uint64_t bootClockTsUs; IncFsBlockIndex block; uint32_t serialNo; } IncFsReadInfo; typedef struct { IncFsFileId id; uint64_t bootClockTsUs; IncFsBlockIndex block; uint32_t serialNo; IncFsUid uid; } IncFsReadInfoWithUid; typedef struct { IncFsBlockIndex begin; IncFsBlockIndex end; } IncFsBlockRange; typedef struct { IncFsBlockRange* dataRanges; IncFsBlockRange* hashRanges; int32_t dataRangesCount; int32_t hashRangesCount; IncFsBlockIndex endIndex; } IncFsFilledRanges; typedef struct { IncFsSize totalDataBlocks; IncFsSize filledDataBlocks; IncFsSize totalHashBlocks; IncFsSize filledHashBlocks; } IncFsBlockCounts; typedef struct { IncFsUid uid; uint32_t minTimeUs; uint32_t minPendingTimeUs; uint32_t maxPendingTimeUs; } IncFsUidReadTimeouts; typedef struct { uint32_t readsDelayedMin; uint64_t readsDelayedMinUs; uint32_t readsDelayedPending; uint64_t readsDelayedPendingUs; uint32_t readsFailedHashVerification; uint32_t readsFailedOther; uint32_t readsFailedTimedOut; uint64_t reserved; uint64_t reserved1; } IncFsMetrics; typedef struct { IncFsFileId id; uint64_t timestampUs; IncFsBlockIndex block; uint32_t errorNo; IncFsUid uid; } IncFsLastReadError; // All functions return -errno in case of failure. // All IncFsFd functions return >=0 in case of success. // All IncFsFileId functions return invalid IncFsFileId on error. // All IncFsErrorCode functions return 0 in case of success. bool IncFs_IsEnabled(); IncFsFeatures IncFs_Features(); bool IncFs_IsIncFsFd(int fd); bool IncFs_IsIncFsPath(const char* path); static inline bool IncFs_IsValidFileId(IncFsFileId fileId) { return memcmp(&fileId, &kIncFsInvalidFileId, sizeof(fileId)) != 0; } int IncFs_FileIdToString(IncFsFileId id, char* out); IncFsFileId IncFs_FileIdFromString(const char* in); IncFsFileId IncFs_FileIdFromMetadata(IncFsSpan metadata); IncFsControl* IncFs_Mount(const char* backingPath, const char* targetDir, IncFsMountOptions options); IncFsControl* IncFs_Open(const char* dir); IncFsControl* IncFs_CreateControl(IncFsFd cmd, IncFsFd pendingReads, IncFsFd logs, IncFsFd blocksWritten); void IncFs_DeleteControl(IncFsControl* control); IncFsFd IncFs_GetControlFd(const IncFsControl* control, IncFsFdType type); IncFsSize IncFs_ReleaseControlFds(IncFsControl* control, IncFsFd out[], IncFsSize outSize); IncFsErrorCode IncFs_SetOptions(const IncFsControl* control, IncFsMountOptions options); IncFsErrorCode IncFs_BindMount(const char* sourceDir, const char* targetDir); IncFsErrorCode IncFs_Unmount(const char* dir); IncFsErrorCode IncFs_Root(const IncFsControl* control, char buffer[], size_t* bufferSize); IncFsErrorCode IncFs_MakeFile(const IncFsControl* control, const char* path, int32_t mode, IncFsFileId id, IncFsNewFileParams params); IncFsErrorCode IncFs_MakeMappedFile(const IncFsControl* control, const char* path, int32_t mode, IncFsNewMappedFileParams params); IncFsErrorCode IncFs_MakeDir(const IncFsControl* control, const char* path, int32_t mode); IncFsErrorCode IncFs_MakeDirs(const IncFsControl* control, const char* path, int32_t mode); IncFsErrorCode IncFs_GetMetadataById(const IncFsControl* control, IncFsFileId id, char buffer[], size_t* bufferSize); IncFsErrorCode IncFs_GetMetadataByPath(const IncFsControl* control, const char* path, char buffer[], size_t* bufferSize); IncFsErrorCode IncFs_GetSignatureById(const IncFsControl* control, IncFsFileId id, char buffer[], size_t* bufferSize); IncFsErrorCode IncFs_GetSignatureByPath(const IncFsControl* control, const char* path, char buffer[], size_t* bufferSize); IncFsErrorCode IncFs_UnsafeGetSignatureByPath(const char* path, char buffer[], size_t* bufferSize); IncFsFileId IncFs_GetId(const IncFsControl* control, const char* path); IncFsErrorCode IncFs_Link(const IncFsControl* control, const char* sourcePath, const char* targetPath); IncFsErrorCode IncFs_Unlink(const IncFsControl* control, const char* path); IncFsErrorCode IncFs_WaitForPendingReads(const IncFsControl* control, int32_t timeoutMs, IncFsReadInfo buffer[], size_t* bufferSize); IncFsErrorCode IncFs_WaitForPageReads(const IncFsControl* control, int32_t timeoutMs, IncFsReadInfo buffer[], size_t* bufferSize); IncFsErrorCode IncFs_WaitForPendingReadsWithUid(const IncFsControl* control, int32_t timeoutMs, IncFsReadInfoWithUid buffer[], size_t* bufferSize); IncFsErrorCode IncFs_WaitForPageReadsWithUid(const IncFsControl* control, int32_t timeoutMs, IncFsReadInfoWithUid buffer[], size_t* bufferSize); IncFsErrorCode IncFs_WaitForFsWrittenBlocksChange(const IncFsControl* control, int32_t timeoutMs, IncFsSize* count); IncFsFd IncFs_OpenForSpecialOpsByPath(const IncFsControl* control, const char* path); IncFsFd IncFs_OpenForSpecialOpsById(const IncFsControl* control, IncFsFileId id); IncFsErrorCode IncFs_WriteBlocks(const IncFsDataBlock blocks[], size_t blocksCount); IncFsErrorCode IncFs_SetUidReadTimeouts(const IncFsControl* control, const IncFsUidReadTimeouts timeouts[], size_t count); IncFsErrorCode IncFs_GetUidReadTimeouts(const IncFsControl* control, IncFsUidReadTimeouts timeoutsBuffer[], size_t* bufferSize); IncFsErrorCode IncFs_GetFileBlockCountByPath(const IncFsControl* control, const char* path, IncFsBlockCounts* blockCount); IncFsErrorCode IncFs_GetFileBlockCountById(const IncFsControl* control, IncFsFileId id, IncFsBlockCounts* blockCount); IncFsErrorCode IncFs_ListIncompleteFiles(const IncFsControl* control, IncFsFileId ids[], size_t* bufferSize); // Calls a passed callback for each file on the mounted filesystem, or, in the second case, // for each incomplete file (only for v2 IncFS). // Callback can stop the iteration early by returning |false|. // Return codes: // >=0 - number of files iterated, // <0 - -errno typedef bool (*FileCallback)(void* context, const IncFsControl* control, IncFsFileId fileId); IncFsErrorCode IncFs_ForEachFile(const IncFsControl* control, void* context, FileCallback cb); IncFsErrorCode IncFs_ForEachIncompleteFile(const IncFsControl* control, void* context, FileCallback cb); IncFsErrorCode IncFs_WaitForLoadingComplete(const IncFsControl* control, int32_t timeoutMs); // Gets a collection of filled ranges in the file from IncFS. Uses the |outBuffer| memory, it has // to be big enough to fit all the ranges the caller is expecting. // Return codes: // 0 - success, // -ERANGE - input buffer is too small. filledRanges are still valid up to the outBuffer.size, // but there are more, // <0 - error, |filledRanges| is not valid. IncFsErrorCode IncFs_GetFilledRanges(int fd, IncFsSpan outBuffer, IncFsFilledRanges* filledRanges); IncFsErrorCode IncFs_GetFilledRangesStartingFrom(int fd, int startBlockIndex, IncFsSpan outBuffer, IncFsFilledRanges* filledRanges); // Check if the file is fully loaded. Return codes: // 0 - fully loaded, // -ENODATA - some blocks are missing, // <0 - error from the syscall. IncFsErrorCode IncFs_IsFullyLoaded(int fd); IncFsErrorCode IncFs_IsFullyLoadedByPath(const IncFsControl* control, const char* path); IncFsErrorCode IncFs_IsFullyLoadedById(const IncFsControl* control, IncFsFileId fileId); // Check if all files on the mount are fully loaded. Return codes: // 0 - fully loaded, // -ENODATA - some blocks are missing, // <0 - error from the syscall. IncFsErrorCode IncFs_IsEverythingFullyLoaded(const IncFsControl* control); // Reserve |size| bytes for the file. Trims reserved space to the current file size when |size = -1| static const IncFsSize kIncFsTrimReservedSpace = -1; IncFsErrorCode IncFs_ReserveSpaceByPath(const IncFsControl* control, const char* path, IncFsSize size); IncFsErrorCode IncFs_ReserveSpaceById(const IncFsControl* control, IncFsFileId id, IncFsSize size); // Gets the metrics of a mount by specifying the corresponding sysfs subpath. // Return codes: // =0 - success // <0 - -errno IncFsErrorCode IncFs_GetMetrics(const char* sysfsName, IncFsMetrics* metrics); // Gets information about the last read error of a mount. // Return codes: // =0 - success // <0 - -errno // When there is no read error, still returns success. Fields in IncFsLastReadError will be all 0. // Possible values of IncFsLastReadError.errorNo: // -ETIME for read timeout; // -EBADMSG for hash verification failure; // Other negative values for other types of errors. IncFsErrorCode IncFs_GetLastReadError(const IncFsControl* control, IncFsLastReadError* lastReadError); __END_DECLS #endif // ANDROID_INCREMENTAL_FILE_SYSTEM_NDK_H