^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /* SPDX-License-Identifier: GPL-2.0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright 2018 Google LLC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Overview
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * --------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * The backbone of the incremental-fs ondisk format is an append only linked
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * list of metadata blocks. Each metadata block contains an offset of the next
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * one. These blocks describe files and directories on the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * file system. They also represent actions of adding and removing file names
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * (hard links).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * Every time incremental-fs instance is mounted, it reads through this list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * to recreate filesystem's state in memory. An offset of the first record in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * the metadata list is stored in the superblock at the beginning of the backing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * file.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * Most of the backing file is taken by data areas and blockmaps.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * Since data blocks can be compressed and have different sizes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) * single per-file data area can't be pre-allocated. That's why blockmaps are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) * needed in order to find a location and size of each data block in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) * the backing file. Each time a file is created, a corresponding block map is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) * allocated to store future offsets of data blocks.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) * Whenever a data block is given by data loader to incremental-fs:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) * - A data area with the given block is appended to the end of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) * the backing file.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) * - A record in the blockmap for the given block index is updated to reflect
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) * its location, size, and compression algorithm.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) * Metadata records
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) * ----------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) * incfs_blockmap - metadata record that specifies size and location
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) * of a blockmap area for a given file. This area
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) * contains an array of incfs_blockmap_entry-s.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) * incfs_file_signature - metadata record that specifies where file signature
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) * and its hash tree can be found in the backing file.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) * incfs_file_attr - metadata record that specifies where additional file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) * attributes blob can be found.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) * Metadata header
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) * ---------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) * incfs_md_header - header of a metadata record. It's always a part
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) * of other structures and served purpose of metadata
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) * bookkeeping.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) * +-----------------------------------------------+ ^
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) * | incfs_md_header | |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) * | 1. type of body(BLOCKMAP, FILE_ATTR..) | |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) * | 2. size of the whole record header + body | |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) * | 3. CRC the whole record header + body | |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) * | 4. offset of the previous md record |]------+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) * | 5. offset of the next md record (md link) |]---+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) * +-----------------------------------------------+ |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) * | Metadata record body with useful data | |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) * +-----------------------------------------------+ |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) * +--->
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) * Other ondisk structures
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) * -----------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) * incfs_super_block - backing file header
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) * incfs_blockmap_entry - a record in a blockmap area that describes size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) * and location of a data block.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) * Data blocks dont have any particular structure, they are written to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) * backing file in a raw form as they come from a data loader.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) * Backing file layout
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) * -------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) * +-------------------------------------------+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) * | incfs_file_header |]---+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) * +-------------------------------------------+ |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) * | metadata |<---+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) * | incfs_file_signature |]---+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) * +-------------------------------------------+ |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) * ......................... |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) * +-------------------------------------------+ | metadata
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) * +------->| blockmap area | | list links
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) * | | [incfs_blockmap_entry] | |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) * | | [incfs_blockmap_entry] | |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) * | | [incfs_blockmap_entry] | |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) * | +--[| [incfs_blockmap_entry] | |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) * | | | [incfs_blockmap_entry] | |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) * | | | [incfs_blockmap_entry] | |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) * | | +-------------------------------------------+ |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) * | | ......................... |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) * | | +-------------------------------------------+ |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) * | | | metadata |<---+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) * +----|--[| incfs_blockmap |]---+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) * | +-------------------------------------------+ |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) * | ......................... |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) * | +-------------------------------------------+ |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) * +-->| data block | |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) * +-------------------------------------------+ |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) * ......................... |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) * +-------------------------------------------+ |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) * | metadata |<---+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) * | incfs_file_attr |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) * +-------------------------------------------+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) #ifndef _INCFS_FORMAT_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) #define _INCFS_FORMAT_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) #include <uapi/linux/incrementalfs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) #include "internal.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) #define INCFS_MAX_NAME_LEN 255
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) #define INCFS_FORMAT_V1 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) #define INCFS_FORMAT_CURRENT_VER INCFS_FORMAT_V1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) enum incfs_metadata_type {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) INCFS_MD_NONE = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) INCFS_MD_BLOCK_MAP = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) INCFS_MD_FILE_ATTR = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) INCFS_MD_SIGNATURE = 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) INCFS_MD_STATUS = 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) INCFS_MD_VERITY_SIGNATURE = 5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) enum incfs_file_header_flags {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) INCFS_FILE_MAPPED = 1 << 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) /* Header included at the beginning of all metadata records on the disk. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) struct incfs_md_header {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) __u8 h_md_entry_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) * Size of the metadata record.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) * (e.g. inode, dir entry etc) not just this struct.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) __le16 h_record_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) * Was: CRC32 of the metadata record.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) * (e.g. inode, dir entry etc) not just this struct.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) __le32 h_unused1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) /* Offset of the next metadata entry if any */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) __le64 h_next_md_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) /* Was: Offset of the previous metadata entry if any */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) __le64 h_unused2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) } __packed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) /* Backing file header */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) struct incfs_file_header {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) /* Magic number: INCFS_MAGIC_NUMBER */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) __le64 fh_magic;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) /* Format version: INCFS_FORMAT_CURRENT_VER */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) __le64 fh_version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) /* sizeof(incfs_file_header) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) __le16 fh_header_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) /* INCFS_DATA_FILE_BLOCK_SIZE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) __le16 fh_data_block_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) /* File flags, from incfs_file_header_flags */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) __le32 fh_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) union {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) /* Standard incfs file */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) /* Offset of the first metadata record */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) __le64 fh_first_md_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) /* Full size of the file's content */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) __le64 fh_file_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) /* File uuid */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) incfs_uuid_t fh_uuid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) /* Mapped file - INCFS_FILE_MAPPED set in fh_flags */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) /* Offset in original file */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) __le64 fh_original_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) /* Full size of the file's content */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) __le64 fh_mapped_file_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) /* Original file's uuid */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) incfs_uuid_t fh_original_uuid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) } __packed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) enum incfs_block_map_entry_flags {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) INCFS_BLOCK_COMPRESSED_LZ4 = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) INCFS_BLOCK_COMPRESSED_ZSTD = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) /* Reserve 3 bits for compression alg */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) INCFS_BLOCK_COMPRESSED_MASK = 7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) /* Block map entry pointing to an actual location of the data block. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) struct incfs_blockmap_entry {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) /* Offset of the actual data block. Lower 32 bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) __le32 me_data_offset_lo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) /* Offset of the actual data block. Higher 16 bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) __le16 me_data_offset_hi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) /* How many bytes the data actually occupies in the backing file */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) __le16 me_data_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) /* Block flags from incfs_block_map_entry_flags */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) __le16 me_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) } __packed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) /* Metadata record for locations of file blocks. Type = INCFS_MD_BLOCK_MAP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) struct incfs_blockmap {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) struct incfs_md_header m_header;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) /* Base offset of the array of incfs_blockmap_entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) __le64 m_base_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) /* Size of the map entry array in blocks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) __le32 m_block_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) } __packed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) * Metadata record for file signature. Type = INCFS_MD_SIGNATURE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) * The signature stored here is the APK V4 signature data blob. See the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) * definition of incfs_new_file_args::signature_info for an explanation of this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) * blob. Specifically, it contains the root hash, but it does *not* contain
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) * anything that the kernel treats as a signature.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) * When FS_IOC_ENABLE_VERITY is called on a file without this record, an APK V4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) * signature blob and a hash tree are added to the file, and then this metadata
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) * record is created to record their locations.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) struct incfs_file_signature {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) struct incfs_md_header sg_header;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) __le32 sg_sig_size; /* The size of the signature. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) __le64 sg_sig_offset; /* Signature's offset in the backing file */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) __le32 sg_hash_tree_size; /* The size of the hash tree. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) __le64 sg_hash_tree_offset; /* Hash tree offset in the backing file */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) } __packed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) /* In memory version of above */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) struct incfs_df_signature {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) u32 sig_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) u64 sig_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) u32 hash_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) u64 hash_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) struct incfs_status {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) struct incfs_md_header is_header;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) __le32 is_data_blocks_written; /* Number of data blocks written */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) __le32 is_hash_blocks_written; /* Number of hash blocks written */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) __le32 is_dummy[6]; /* Spare fields */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) } __packed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) * Metadata record for verity signature. Type = INCFS_MD_VERITY_SIGNATURE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) * This record will only exist for verity-enabled files with signatures. Verity
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) * enabled files without signatures do not have this record. This signature is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) * checked by fs-verity identically to any other fs-verity signature.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) struct incfs_file_verity_signature {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) struct incfs_md_header vs_header;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) /* The size of the signature */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) __le32 vs_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) /* Signature's offset in the backing file */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) __le64 vs_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) } __packed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) /* In memory version of above */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) struct incfs_df_verity_signature {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) u32 size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) u64 offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) /* State of the backing file. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) struct backing_file_context {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) /* Protects writes to bc_file */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) struct mutex bc_mutex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) /* File object to read data from */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) struct file *bc_file;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) * Offset of the last known metadata record in the backing file.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) * 0 means there are no metadata records.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) loff_t bc_last_md_record_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) * Credentials to set before reads/writes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) * Note that this is a pointer to the mount_info mi_owner field so
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) * there is no need to get/put the creds
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) const struct cred *bc_cred;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) struct metadata_handler {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) loff_t md_record_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) loff_t md_prev_record_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) void *context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) union {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) struct incfs_md_header md_header;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) struct incfs_blockmap blockmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) struct incfs_file_signature signature;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) struct incfs_status status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) struct incfs_file_verity_signature verity_signature;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) } md_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) int (*handle_blockmap)(struct incfs_blockmap *bm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) struct metadata_handler *handler);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) int (*handle_signature)(struct incfs_file_signature *sig,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) struct metadata_handler *handler);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) int (*handle_status)(struct incfs_status *sig,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) struct metadata_handler *handler);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) int (*handle_verity_signature)(struct incfs_file_verity_signature *s,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) struct metadata_handler *handler);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) #define INCFS_MAX_METADATA_RECORD_SIZE \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) sizeof_field(struct metadata_handler, md_buffer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) /* Backing file context management */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) struct mount_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) struct backing_file_context *incfs_alloc_bfc(struct mount_info *mi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) struct file *backing_file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) void incfs_free_bfc(struct backing_file_context *bfc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) /* Writing stuff */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) int incfs_write_blockmap_to_backing_file(struct backing_file_context *bfc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) u32 block_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) int incfs_write_fh_to_backing_file(struct backing_file_context *bfc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) incfs_uuid_t *uuid, u64 file_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) int incfs_write_mapping_fh_to_backing_file(struct backing_file_context *bfc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) incfs_uuid_t *uuid, u64 file_size, u64 offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) int incfs_write_data_block_to_backing_file(struct backing_file_context *bfc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) struct mem_range block,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) int block_index, loff_t bm_base_off,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) u16 flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) int incfs_write_hash_block_to_backing_file(struct backing_file_context *bfc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) struct mem_range block,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) int block_index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) loff_t hash_area_off,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) loff_t bm_base_off,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) loff_t file_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) int incfs_write_signature_to_backing_file(struct backing_file_context *bfc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) struct mem_range sig, u32 tree_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) loff_t *tree_offset, loff_t *sig_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) int incfs_write_status_to_backing_file(struct backing_file_context *bfc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) loff_t status_offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) u32 data_blocks_written,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) u32 hash_blocks_written);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) int incfs_write_verity_signature_to_backing_file(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) struct backing_file_context *bfc, struct mem_range signature,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) loff_t *offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) /* Reading stuff */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) int incfs_read_file_header(struct backing_file_context *bfc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) loff_t *first_md_off, incfs_uuid_t *uuid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) u64 *file_size, u32 *flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) int incfs_read_blockmap_entry(struct backing_file_context *bfc, int block_index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) loff_t bm_base_off,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) struct incfs_blockmap_entry *bm_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) int incfs_read_blockmap_entries(struct backing_file_context *bfc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) struct incfs_blockmap_entry *entries,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) int start_index, int blocks_number,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) loff_t bm_base_off);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) int incfs_read_next_metadata_record(struct backing_file_context *bfc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) struct metadata_handler *handler);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) ssize_t incfs_kread(struct backing_file_context *bfc, void *buf, size_t size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) loff_t pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) ssize_t incfs_kwrite(struct backing_file_context *bfc, const void *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) size_t size, loff_t pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) #endif /* _INCFS_FORMAT_H */