You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
346 lines
12 KiB
346 lines
12 KiB
/*
|
|
* 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 <linux/incrementalfs.h>
|
|
#include <stdbool.h>
|
|
#include <stddef.h>
|
|
#include <stdint.h>
|
|
#include <string.h>
|
|
#include <sys/cdefs.h>
|
|
|
|
__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
|