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