1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ 2*4882a593Smuzhiyun /* 3*4882a593Smuzhiyun * Userspace interface for Incremental FS. 4*4882a593Smuzhiyun * 5*4882a593Smuzhiyun * Incremental FS is special-purpose Linux virtual file system that allows 6*4882a593Smuzhiyun * execution of a program while its binary and resource files are still being 7*4882a593Smuzhiyun * lazily downloaded over the network, USB etc. 8*4882a593Smuzhiyun * 9*4882a593Smuzhiyun * Copyright 2019 Google LLC 10*4882a593Smuzhiyun */ 11*4882a593Smuzhiyun #ifndef _UAPI_LINUX_INCREMENTALFS_H 12*4882a593Smuzhiyun #define _UAPI_LINUX_INCREMENTALFS_H 13*4882a593Smuzhiyun 14*4882a593Smuzhiyun #include <linux/limits.h> 15*4882a593Smuzhiyun #include <linux/ioctl.h> 16*4882a593Smuzhiyun #include <linux/types.h> 17*4882a593Smuzhiyun #include <linux/xattr.h> 18*4882a593Smuzhiyun 19*4882a593Smuzhiyun /* ===== constants ===== */ 20*4882a593Smuzhiyun #define INCFS_NAME "incremental-fs" 21*4882a593Smuzhiyun 22*4882a593Smuzhiyun /* 23*4882a593Smuzhiyun * Magic number used in file header and in memory superblock 24*4882a593Smuzhiyun * Note that it is a 5 byte unsigned long. Thus on 32 bit kernels, it is 25*4882a593Smuzhiyun * truncated to a 4 byte number 26*4882a593Smuzhiyun */ 27*4882a593Smuzhiyun #define INCFS_MAGIC_NUMBER (0x5346434e49ul & ULONG_MAX) 28*4882a593Smuzhiyun 29*4882a593Smuzhiyun #define INCFS_DATA_FILE_BLOCK_SIZE 4096 30*4882a593Smuzhiyun #define INCFS_HEADER_VER 1 31*4882a593Smuzhiyun 32*4882a593Smuzhiyun /* TODO: This value is assumed in incfs_copy_signature_info_from_user to be the 33*4882a593Smuzhiyun * actual signature length. Set back to 64 when fixed. 34*4882a593Smuzhiyun */ 35*4882a593Smuzhiyun #define INCFS_MAX_HASH_SIZE 32 36*4882a593Smuzhiyun #define INCFS_MAX_FILE_ATTR_SIZE 512 37*4882a593Smuzhiyun 38*4882a593Smuzhiyun #define INCFS_INDEX_NAME ".index" 39*4882a593Smuzhiyun #define INCFS_INCOMPLETE_NAME ".incomplete" 40*4882a593Smuzhiyun #define INCFS_PENDING_READS_FILENAME ".pending_reads" 41*4882a593Smuzhiyun #define INCFS_LOG_FILENAME ".log" 42*4882a593Smuzhiyun #define INCFS_BLOCKS_WRITTEN_FILENAME ".blocks_written" 43*4882a593Smuzhiyun #define INCFS_XATTR_ID_NAME (XATTR_USER_PREFIX "incfs.id") 44*4882a593Smuzhiyun #define INCFS_XATTR_SIZE_NAME (XATTR_USER_PREFIX "incfs.size") 45*4882a593Smuzhiyun #define INCFS_XATTR_METADATA_NAME (XATTR_USER_PREFIX "incfs.metadata") 46*4882a593Smuzhiyun #define INCFS_XATTR_VERITY_NAME (XATTR_USER_PREFIX "incfs.verity") 47*4882a593Smuzhiyun 48*4882a593Smuzhiyun #define INCFS_MAX_SIGNATURE_SIZE 8096 49*4882a593Smuzhiyun #define INCFS_SIGNATURE_VERSION 2 50*4882a593Smuzhiyun #define INCFS_SIGNATURE_SECTIONS 2 51*4882a593Smuzhiyun 52*4882a593Smuzhiyun #define INCFS_IOCTL_BASE_CODE 'g' 53*4882a593Smuzhiyun 54*4882a593Smuzhiyun /* ===== ioctl requests on the command dir ===== */ 55*4882a593Smuzhiyun 56*4882a593Smuzhiyun /* 57*4882a593Smuzhiyun * Create a new file 58*4882a593Smuzhiyun * May only be called on .pending_reads file 59*4882a593Smuzhiyun */ 60*4882a593Smuzhiyun #define INCFS_IOC_CREATE_FILE \ 61*4882a593Smuzhiyun _IOWR(INCFS_IOCTL_BASE_CODE, 30, struct incfs_new_file_args) 62*4882a593Smuzhiyun 63*4882a593Smuzhiyun /* Read file signature */ 64*4882a593Smuzhiyun #define INCFS_IOC_READ_FILE_SIGNATURE \ 65*4882a593Smuzhiyun _IOR(INCFS_IOCTL_BASE_CODE, 31, struct incfs_get_file_sig_args) 66*4882a593Smuzhiyun 67*4882a593Smuzhiyun /* 68*4882a593Smuzhiyun * Fill in one or more data block. This may only be called on a handle 69*4882a593Smuzhiyun * passed as a parameter to INCFS_IOC_PERMIT_FILLING 70*4882a593Smuzhiyun * 71*4882a593Smuzhiyun * Returns number of blocks filled in, or error if none were 72*4882a593Smuzhiyun */ 73*4882a593Smuzhiyun #define INCFS_IOC_FILL_BLOCKS \ 74*4882a593Smuzhiyun _IOR(INCFS_IOCTL_BASE_CODE, 32, struct incfs_fill_blocks) 75*4882a593Smuzhiyun 76*4882a593Smuzhiyun /* 77*4882a593Smuzhiyun * Permit INCFS_IOC_FILL_BLOCKS on the given file descriptor 78*4882a593Smuzhiyun * May only be called on .pending_reads file 79*4882a593Smuzhiyun * 80*4882a593Smuzhiyun * Returns 0 on success or error 81*4882a593Smuzhiyun */ 82*4882a593Smuzhiyun #define INCFS_IOC_PERMIT_FILL \ 83*4882a593Smuzhiyun _IOW(INCFS_IOCTL_BASE_CODE, 33, struct incfs_permit_fill) 84*4882a593Smuzhiyun 85*4882a593Smuzhiyun /* 86*4882a593Smuzhiyun * Fills buffer with ranges of populated blocks 87*4882a593Smuzhiyun * 88*4882a593Smuzhiyun * Returns 0 if all ranges written 89*4882a593Smuzhiyun * error otherwise 90*4882a593Smuzhiyun * 91*4882a593Smuzhiyun * Either way, range_buffer_size_out is set to the number 92*4882a593Smuzhiyun * of bytes written. Should be set to 0 by caller. The ranges 93*4882a593Smuzhiyun * filled are valid, but if an error was returned there might 94*4882a593Smuzhiyun * be more ranges to come. 95*4882a593Smuzhiyun * 96*4882a593Smuzhiyun * Ranges are ranges of filled blocks: 97*4882a593Smuzhiyun * 98*4882a593Smuzhiyun * 1 2 7 9 99*4882a593Smuzhiyun * 100*4882a593Smuzhiyun * means blocks 1, 2, 7, 8, 9 are filled, 0, 3, 4, 5, 6 and 10 on 101*4882a593Smuzhiyun * are not 102*4882a593Smuzhiyun * 103*4882a593Smuzhiyun * If hashing is enabled for the file, the hash blocks are simply 104*4882a593Smuzhiyun * treated as though they immediately followed the data blocks. 105*4882a593Smuzhiyun */ 106*4882a593Smuzhiyun #define INCFS_IOC_GET_FILLED_BLOCKS \ 107*4882a593Smuzhiyun _IOR(INCFS_IOCTL_BASE_CODE, 34, struct incfs_get_filled_blocks_args) 108*4882a593Smuzhiyun 109*4882a593Smuzhiyun /* 110*4882a593Smuzhiyun * Creates a new mapped file 111*4882a593Smuzhiyun * May only be called on .pending_reads file 112*4882a593Smuzhiyun */ 113*4882a593Smuzhiyun #define INCFS_IOC_CREATE_MAPPED_FILE \ 114*4882a593Smuzhiyun _IOWR(INCFS_IOCTL_BASE_CODE, 35, struct incfs_create_mapped_file_args) 115*4882a593Smuzhiyun 116*4882a593Smuzhiyun /* 117*4882a593Smuzhiyun * Get number of blocks, total and filled 118*4882a593Smuzhiyun * May only be called on .pending_reads file 119*4882a593Smuzhiyun */ 120*4882a593Smuzhiyun #define INCFS_IOC_GET_BLOCK_COUNT \ 121*4882a593Smuzhiyun _IOR(INCFS_IOCTL_BASE_CODE, 36, struct incfs_get_block_count_args) 122*4882a593Smuzhiyun 123*4882a593Smuzhiyun /* 124*4882a593Smuzhiyun * Get per UID read timeouts 125*4882a593Smuzhiyun * May only be called on .pending_reads file 126*4882a593Smuzhiyun */ 127*4882a593Smuzhiyun #define INCFS_IOC_GET_READ_TIMEOUTS \ 128*4882a593Smuzhiyun _IOR(INCFS_IOCTL_BASE_CODE, 37, struct incfs_get_read_timeouts_args) 129*4882a593Smuzhiyun 130*4882a593Smuzhiyun /* 131*4882a593Smuzhiyun * Set per UID read timeouts 132*4882a593Smuzhiyun * May only be called on .pending_reads file 133*4882a593Smuzhiyun */ 134*4882a593Smuzhiyun #define INCFS_IOC_SET_READ_TIMEOUTS \ 135*4882a593Smuzhiyun _IOW(INCFS_IOCTL_BASE_CODE, 38, struct incfs_set_read_timeouts_args) 136*4882a593Smuzhiyun 137*4882a593Smuzhiyun /* 138*4882a593Smuzhiyun * Get last read error 139*4882a593Smuzhiyun * May only be called on .pending_reads file 140*4882a593Smuzhiyun */ 141*4882a593Smuzhiyun #define INCFS_IOC_GET_LAST_READ_ERROR \ 142*4882a593Smuzhiyun _IOW(INCFS_IOCTL_BASE_CODE, 39, struct incfs_get_last_read_error_args) 143*4882a593Smuzhiyun 144*4882a593Smuzhiyun /* ===== sysfs feature flags ===== */ 145*4882a593Smuzhiyun /* 146*4882a593Smuzhiyun * Each flag is represented by a file in /sys/fs/incremental-fs/features 147*4882a593Smuzhiyun * If the file exists the feature is supported 148*4882a593Smuzhiyun * Also the file contents will be the line "supported" 149*4882a593Smuzhiyun */ 150*4882a593Smuzhiyun 151*4882a593Smuzhiyun /* 152*4882a593Smuzhiyun * Basic flag stating that the core incfs file system is available 153*4882a593Smuzhiyun */ 154*4882a593Smuzhiyun #define INCFS_FEATURE_FLAG_COREFS "corefs" 155*4882a593Smuzhiyun 156*4882a593Smuzhiyun /* 157*4882a593Smuzhiyun * zstd compression support 158*4882a593Smuzhiyun */ 159*4882a593Smuzhiyun #define INCFS_FEATURE_FLAG_ZSTD "zstd" 160*4882a593Smuzhiyun 161*4882a593Smuzhiyun /* 162*4882a593Smuzhiyun * v2 feature set support. Covers: 163*4882a593Smuzhiyun * INCFS_IOC_CREATE_MAPPED_FILE 164*4882a593Smuzhiyun * INCFS_IOC_GET_BLOCK_COUNT 165*4882a593Smuzhiyun * INCFS_IOC_GET_READ_TIMEOUTS/INCFS_IOC_SET_READ_TIMEOUTS 166*4882a593Smuzhiyun * .blocks_written status file 167*4882a593Smuzhiyun * .incomplete folder 168*4882a593Smuzhiyun * report_uid mount option 169*4882a593Smuzhiyun */ 170*4882a593Smuzhiyun #define INCFS_FEATURE_FLAG_V2 "v2" 171*4882a593Smuzhiyun 172*4882a593Smuzhiyun enum incfs_compression_alg { 173*4882a593Smuzhiyun COMPRESSION_NONE = 0, 174*4882a593Smuzhiyun COMPRESSION_LZ4 = 1, 175*4882a593Smuzhiyun COMPRESSION_ZSTD = 2, 176*4882a593Smuzhiyun }; 177*4882a593Smuzhiyun 178*4882a593Smuzhiyun enum incfs_block_flags { 179*4882a593Smuzhiyun INCFS_BLOCK_FLAGS_NONE = 0, 180*4882a593Smuzhiyun INCFS_BLOCK_FLAGS_HASH = 1, 181*4882a593Smuzhiyun }; 182*4882a593Smuzhiyun 183*4882a593Smuzhiyun typedef struct { 184*4882a593Smuzhiyun __u8 bytes[16]; 185*4882a593Smuzhiyun } incfs_uuid_t __attribute__((aligned (8))); 186*4882a593Smuzhiyun 187*4882a593Smuzhiyun /* 188*4882a593Smuzhiyun * Description of a pending read. A pending read - a read call by 189*4882a593Smuzhiyun * a userspace program for which the filesystem currently doesn't have data. 190*4882a593Smuzhiyun * 191*4882a593Smuzhiyun * Reads from .pending_reads and .log return an array of these structure 192*4882a593Smuzhiyun */ 193*4882a593Smuzhiyun struct incfs_pending_read_info { 194*4882a593Smuzhiyun /* Id of a file that is being read from. */ 195*4882a593Smuzhiyun incfs_uuid_t file_id; 196*4882a593Smuzhiyun 197*4882a593Smuzhiyun /* A number of microseconds since system boot to the read. */ 198*4882a593Smuzhiyun __aligned_u64 timestamp_us; 199*4882a593Smuzhiyun 200*4882a593Smuzhiyun /* Index of a file block that is being read. */ 201*4882a593Smuzhiyun __u32 block_index; 202*4882a593Smuzhiyun 203*4882a593Smuzhiyun /* A serial number of this pending read. */ 204*4882a593Smuzhiyun __u32 serial_number; 205*4882a593Smuzhiyun }; 206*4882a593Smuzhiyun 207*4882a593Smuzhiyun /* 208*4882a593Smuzhiyun * Description of a pending read. A pending read - a read call by 209*4882a593Smuzhiyun * a userspace program for which the filesystem currently doesn't have data. 210*4882a593Smuzhiyun * 211*4882a593Smuzhiyun * This version of incfs_pending_read_info is used whenever the file system is 212*4882a593Smuzhiyun * mounted with the report_uid flag 213*4882a593Smuzhiyun */ 214*4882a593Smuzhiyun struct incfs_pending_read_info2 { 215*4882a593Smuzhiyun /* Id of a file that is being read from. */ 216*4882a593Smuzhiyun incfs_uuid_t file_id; 217*4882a593Smuzhiyun 218*4882a593Smuzhiyun /* A number of microseconds since system boot to the read. */ 219*4882a593Smuzhiyun __aligned_u64 timestamp_us; 220*4882a593Smuzhiyun 221*4882a593Smuzhiyun /* Index of a file block that is being read. */ 222*4882a593Smuzhiyun __u32 block_index; 223*4882a593Smuzhiyun 224*4882a593Smuzhiyun /* A serial number of this pending read. */ 225*4882a593Smuzhiyun __u32 serial_number; 226*4882a593Smuzhiyun 227*4882a593Smuzhiyun /* The UID of the reading process */ 228*4882a593Smuzhiyun __u32 uid; 229*4882a593Smuzhiyun 230*4882a593Smuzhiyun __u32 reserved; 231*4882a593Smuzhiyun }; 232*4882a593Smuzhiyun 233*4882a593Smuzhiyun /* 234*4882a593Smuzhiyun * Description of a data or hash block to add to a data file. 235*4882a593Smuzhiyun */ 236*4882a593Smuzhiyun struct incfs_fill_block { 237*4882a593Smuzhiyun /* Index of a data block. */ 238*4882a593Smuzhiyun __u32 block_index; 239*4882a593Smuzhiyun 240*4882a593Smuzhiyun /* Length of data */ 241*4882a593Smuzhiyun __u32 data_len; 242*4882a593Smuzhiyun 243*4882a593Smuzhiyun /* 244*4882a593Smuzhiyun * A pointer to an actual data for the block. 245*4882a593Smuzhiyun * 246*4882a593Smuzhiyun * Equivalent to: __u8 *data; 247*4882a593Smuzhiyun */ 248*4882a593Smuzhiyun __aligned_u64 data; 249*4882a593Smuzhiyun 250*4882a593Smuzhiyun /* 251*4882a593Smuzhiyun * Compression algorithm used to compress the data block. 252*4882a593Smuzhiyun * Values from enum incfs_compression_alg. 253*4882a593Smuzhiyun */ 254*4882a593Smuzhiyun __u8 compression; 255*4882a593Smuzhiyun 256*4882a593Smuzhiyun /* Values from enum incfs_block_flags */ 257*4882a593Smuzhiyun __u8 flags; 258*4882a593Smuzhiyun 259*4882a593Smuzhiyun __u16 reserved1; 260*4882a593Smuzhiyun 261*4882a593Smuzhiyun __u32 reserved2; 262*4882a593Smuzhiyun 263*4882a593Smuzhiyun __aligned_u64 reserved3; 264*4882a593Smuzhiyun }; 265*4882a593Smuzhiyun 266*4882a593Smuzhiyun /* 267*4882a593Smuzhiyun * Description of a number of blocks to add to a data file 268*4882a593Smuzhiyun * 269*4882a593Smuzhiyun * Argument for INCFS_IOC_FILL_BLOCKS 270*4882a593Smuzhiyun */ 271*4882a593Smuzhiyun struct incfs_fill_blocks { 272*4882a593Smuzhiyun /* Number of blocks */ 273*4882a593Smuzhiyun __u64 count; 274*4882a593Smuzhiyun 275*4882a593Smuzhiyun /* A pointer to an array of incfs_fill_block structs */ 276*4882a593Smuzhiyun __aligned_u64 fill_blocks; 277*4882a593Smuzhiyun }; 278*4882a593Smuzhiyun 279*4882a593Smuzhiyun /* 280*4882a593Smuzhiyun * Permit INCFS_IOC_FILL_BLOCKS on the given file descriptor 281*4882a593Smuzhiyun * May only be called on .pending_reads file 282*4882a593Smuzhiyun * 283*4882a593Smuzhiyun * Argument for INCFS_IOC_PERMIT_FILL 284*4882a593Smuzhiyun */ 285*4882a593Smuzhiyun struct incfs_permit_fill { 286*4882a593Smuzhiyun /* File to permit fills on */ 287*4882a593Smuzhiyun __u32 file_descriptor; 288*4882a593Smuzhiyun }; 289*4882a593Smuzhiyun 290*4882a593Smuzhiyun enum incfs_hash_tree_algorithm { 291*4882a593Smuzhiyun INCFS_HASH_TREE_NONE = 0, 292*4882a593Smuzhiyun INCFS_HASH_TREE_SHA256 = 1 293*4882a593Smuzhiyun }; 294*4882a593Smuzhiyun 295*4882a593Smuzhiyun /* 296*4882a593Smuzhiyun * Create a new file or directory. 297*4882a593Smuzhiyun */ 298*4882a593Smuzhiyun struct incfs_new_file_args { 299*4882a593Smuzhiyun /* Id of a file to create. */ 300*4882a593Smuzhiyun incfs_uuid_t file_id; 301*4882a593Smuzhiyun 302*4882a593Smuzhiyun /* 303*4882a593Smuzhiyun * Total size of the new file. Ignored if S_ISDIR(mode). 304*4882a593Smuzhiyun */ 305*4882a593Smuzhiyun __aligned_u64 size; 306*4882a593Smuzhiyun 307*4882a593Smuzhiyun /* 308*4882a593Smuzhiyun * File mode. Permissions and dir flag. 309*4882a593Smuzhiyun */ 310*4882a593Smuzhiyun __u16 mode; 311*4882a593Smuzhiyun 312*4882a593Smuzhiyun __u16 reserved1; 313*4882a593Smuzhiyun 314*4882a593Smuzhiyun __u32 reserved2; 315*4882a593Smuzhiyun 316*4882a593Smuzhiyun /* 317*4882a593Smuzhiyun * A pointer to a null-terminated relative path to the file's parent 318*4882a593Smuzhiyun * dir. 319*4882a593Smuzhiyun * Max length: PATH_MAX 320*4882a593Smuzhiyun * 321*4882a593Smuzhiyun * Equivalent to: char *directory_path; 322*4882a593Smuzhiyun */ 323*4882a593Smuzhiyun __aligned_u64 directory_path; 324*4882a593Smuzhiyun 325*4882a593Smuzhiyun /* 326*4882a593Smuzhiyun * A pointer to a null-terminated file's name. 327*4882a593Smuzhiyun * Max length: PATH_MAX 328*4882a593Smuzhiyun * 329*4882a593Smuzhiyun * Equivalent to: char *file_name; 330*4882a593Smuzhiyun */ 331*4882a593Smuzhiyun __aligned_u64 file_name; 332*4882a593Smuzhiyun 333*4882a593Smuzhiyun /* 334*4882a593Smuzhiyun * A pointer to a file attribute to be set on creation. 335*4882a593Smuzhiyun * 336*4882a593Smuzhiyun * Equivalent to: u8 *file_attr; 337*4882a593Smuzhiyun */ 338*4882a593Smuzhiyun __aligned_u64 file_attr; 339*4882a593Smuzhiyun 340*4882a593Smuzhiyun /* 341*4882a593Smuzhiyun * Length of the data buffer specfied by file_attr. 342*4882a593Smuzhiyun * Max value: INCFS_MAX_FILE_ATTR_SIZE 343*4882a593Smuzhiyun */ 344*4882a593Smuzhiyun __u32 file_attr_len; 345*4882a593Smuzhiyun 346*4882a593Smuzhiyun __u32 reserved4; 347*4882a593Smuzhiyun 348*4882a593Smuzhiyun /* 349*4882a593Smuzhiyun * Points to an APK V4 Signature data blob 350*4882a593Smuzhiyun * Signature must have two sections 351*4882a593Smuzhiyun * Format is: 352*4882a593Smuzhiyun * u32 version 353*4882a593Smuzhiyun * u32 size_of_hash_info_section 354*4882a593Smuzhiyun * u8 hash_info_section[] 355*4882a593Smuzhiyun * u32 size_of_signing_info_section 356*4882a593Smuzhiyun * u8 signing_info_section[] 357*4882a593Smuzhiyun * 358*4882a593Smuzhiyun * Note that incfs does not care about what is in signing_info_section 359*4882a593Smuzhiyun * 360*4882a593Smuzhiyun * hash_info_section has following format: 361*4882a593Smuzhiyun * u32 hash_algorithm; // Must be SHA256 == 1 362*4882a593Smuzhiyun * u8 log2_blocksize; // Must be 12 for 4096 byte blocks 363*4882a593Smuzhiyun * u32 salt_size; 364*4882a593Smuzhiyun * u8 salt[]; 365*4882a593Smuzhiyun * u32 hash_size; 366*4882a593Smuzhiyun * u8 root_hash[]; 367*4882a593Smuzhiyun */ 368*4882a593Smuzhiyun __aligned_u64 signature_info; 369*4882a593Smuzhiyun 370*4882a593Smuzhiyun /* Size of signature_info */ 371*4882a593Smuzhiyun __aligned_u64 signature_size; 372*4882a593Smuzhiyun 373*4882a593Smuzhiyun __aligned_u64 reserved6; 374*4882a593Smuzhiyun }; 375*4882a593Smuzhiyun 376*4882a593Smuzhiyun /* 377*4882a593Smuzhiyun * Request a digital signature blob for a given file. 378*4882a593Smuzhiyun * Argument for INCFS_IOC_READ_FILE_SIGNATURE ioctl 379*4882a593Smuzhiyun */ 380*4882a593Smuzhiyun struct incfs_get_file_sig_args { 381*4882a593Smuzhiyun /* 382*4882a593Smuzhiyun * A pointer to the data buffer to save an signature blob to. 383*4882a593Smuzhiyun * 384*4882a593Smuzhiyun * Equivalent to: u8 *file_signature; 385*4882a593Smuzhiyun */ 386*4882a593Smuzhiyun __aligned_u64 file_signature; 387*4882a593Smuzhiyun 388*4882a593Smuzhiyun /* Size of the buffer at file_signature. */ 389*4882a593Smuzhiyun __u32 file_signature_buf_size; 390*4882a593Smuzhiyun 391*4882a593Smuzhiyun /* 392*4882a593Smuzhiyun * Number of bytes save file_signature buffer. 393*4882a593Smuzhiyun * It is set after ioctl done. 394*4882a593Smuzhiyun */ 395*4882a593Smuzhiyun __u32 file_signature_len_out; 396*4882a593Smuzhiyun }; 397*4882a593Smuzhiyun 398*4882a593Smuzhiyun struct incfs_filled_range { 399*4882a593Smuzhiyun __u32 begin; 400*4882a593Smuzhiyun __u32 end; 401*4882a593Smuzhiyun }; 402*4882a593Smuzhiyun 403*4882a593Smuzhiyun /* 404*4882a593Smuzhiyun * Request ranges of filled blocks 405*4882a593Smuzhiyun * Argument for INCFS_IOC_GET_FILLED_BLOCKS 406*4882a593Smuzhiyun */ 407*4882a593Smuzhiyun struct incfs_get_filled_blocks_args { 408*4882a593Smuzhiyun /* 409*4882a593Smuzhiyun * A buffer to populate with ranges of filled blocks 410*4882a593Smuzhiyun * 411*4882a593Smuzhiyun * Equivalent to struct incfs_filled_ranges *range_buffer 412*4882a593Smuzhiyun */ 413*4882a593Smuzhiyun __aligned_u64 range_buffer; 414*4882a593Smuzhiyun 415*4882a593Smuzhiyun /* Size of range_buffer */ 416*4882a593Smuzhiyun __u32 range_buffer_size; 417*4882a593Smuzhiyun 418*4882a593Smuzhiyun /* Start index to read from */ 419*4882a593Smuzhiyun __u32 start_index; 420*4882a593Smuzhiyun 421*4882a593Smuzhiyun /* 422*4882a593Smuzhiyun * End index to read to. 0 means read to end. This is a range, 423*4882a593Smuzhiyun * so incfs will read from start_index to end_index - 1 424*4882a593Smuzhiyun */ 425*4882a593Smuzhiyun __u32 end_index; 426*4882a593Smuzhiyun 427*4882a593Smuzhiyun /* Actual number of blocks in file */ 428*4882a593Smuzhiyun __u32 total_blocks_out; 429*4882a593Smuzhiyun 430*4882a593Smuzhiyun /* The number of data blocks in file */ 431*4882a593Smuzhiyun __u32 data_blocks_out; 432*4882a593Smuzhiyun 433*4882a593Smuzhiyun /* Number of bytes written to range buffer */ 434*4882a593Smuzhiyun __u32 range_buffer_size_out; 435*4882a593Smuzhiyun 436*4882a593Smuzhiyun /* Sector scanned up to, if the call was interrupted */ 437*4882a593Smuzhiyun __u32 index_out; 438*4882a593Smuzhiyun }; 439*4882a593Smuzhiyun 440*4882a593Smuzhiyun /* 441*4882a593Smuzhiyun * Create a new mapped file 442*4882a593Smuzhiyun * Argument for INCFS_IOC_CREATE_MAPPED_FILE 443*4882a593Smuzhiyun */ 444*4882a593Smuzhiyun struct incfs_create_mapped_file_args { 445*4882a593Smuzhiyun /* 446*4882a593Smuzhiyun * Total size of the new file. 447*4882a593Smuzhiyun */ 448*4882a593Smuzhiyun __aligned_u64 size; 449*4882a593Smuzhiyun 450*4882a593Smuzhiyun /* 451*4882a593Smuzhiyun * File mode. Permissions and dir flag. 452*4882a593Smuzhiyun */ 453*4882a593Smuzhiyun __u16 mode; 454*4882a593Smuzhiyun 455*4882a593Smuzhiyun __u16 reserved1; 456*4882a593Smuzhiyun 457*4882a593Smuzhiyun __u32 reserved2; 458*4882a593Smuzhiyun 459*4882a593Smuzhiyun /* 460*4882a593Smuzhiyun * A pointer to a null-terminated relative path to the incfs mount 461*4882a593Smuzhiyun * point 462*4882a593Smuzhiyun * Max length: PATH_MAX 463*4882a593Smuzhiyun * 464*4882a593Smuzhiyun * Equivalent to: char *directory_path; 465*4882a593Smuzhiyun */ 466*4882a593Smuzhiyun __aligned_u64 directory_path; 467*4882a593Smuzhiyun 468*4882a593Smuzhiyun /* 469*4882a593Smuzhiyun * A pointer to a null-terminated file name. 470*4882a593Smuzhiyun * Max length: PATH_MAX 471*4882a593Smuzhiyun * 472*4882a593Smuzhiyun * Equivalent to: char *file_name; 473*4882a593Smuzhiyun */ 474*4882a593Smuzhiyun __aligned_u64 file_name; 475*4882a593Smuzhiyun 476*4882a593Smuzhiyun /* Id of source file to map. */ 477*4882a593Smuzhiyun incfs_uuid_t source_file_id; 478*4882a593Smuzhiyun 479*4882a593Smuzhiyun /* 480*4882a593Smuzhiyun * Offset in source file to start mapping. Must be a multiple of 481*4882a593Smuzhiyun * INCFS_DATA_FILE_BLOCK_SIZE 482*4882a593Smuzhiyun */ 483*4882a593Smuzhiyun __aligned_u64 source_offset; 484*4882a593Smuzhiyun }; 485*4882a593Smuzhiyun 486*4882a593Smuzhiyun /* 487*4882a593Smuzhiyun * Get information about the blocks in this file 488*4882a593Smuzhiyun * Argument for INCFS_IOC_GET_BLOCK_COUNT 489*4882a593Smuzhiyun */ 490*4882a593Smuzhiyun struct incfs_get_block_count_args { 491*4882a593Smuzhiyun /* Total number of data blocks in the file */ 492*4882a593Smuzhiyun __u32 total_data_blocks_out; 493*4882a593Smuzhiyun 494*4882a593Smuzhiyun /* Number of filled data blocks in the file */ 495*4882a593Smuzhiyun __u32 filled_data_blocks_out; 496*4882a593Smuzhiyun 497*4882a593Smuzhiyun /* Total number of hash blocks in the file */ 498*4882a593Smuzhiyun __u32 total_hash_blocks_out; 499*4882a593Smuzhiyun 500*4882a593Smuzhiyun /* Number of filled hash blocks in the file */ 501*4882a593Smuzhiyun __u32 filled_hash_blocks_out; 502*4882a593Smuzhiyun }; 503*4882a593Smuzhiyun 504*4882a593Smuzhiyun /* Description of timeouts for one UID */ 505*4882a593Smuzhiyun struct incfs_per_uid_read_timeouts { 506*4882a593Smuzhiyun /* UID to apply these timeouts to */ 507*4882a593Smuzhiyun __u32 uid; 508*4882a593Smuzhiyun 509*4882a593Smuzhiyun /* 510*4882a593Smuzhiyun * Min time in microseconds to read any block. Note that this doesn't 511*4882a593Smuzhiyun * apply to reads which are satisfied from the page cache. 512*4882a593Smuzhiyun */ 513*4882a593Smuzhiyun __u32 min_time_us; 514*4882a593Smuzhiyun 515*4882a593Smuzhiyun /* 516*4882a593Smuzhiyun * Min time in microseconds to satisfy a pending read. Any pending read 517*4882a593Smuzhiyun * which is filled before this time will be delayed so that the total 518*4882a593Smuzhiyun * read time >= this value. 519*4882a593Smuzhiyun */ 520*4882a593Smuzhiyun __u32 min_pending_time_us; 521*4882a593Smuzhiyun 522*4882a593Smuzhiyun /* 523*4882a593Smuzhiyun * Max time in microseconds to satisfy a pending read before the read 524*4882a593Smuzhiyun * times out. If set to U32_MAX, defaults to mount options 525*4882a593Smuzhiyun * read_timeout_ms * 1000. Must be >= min_pending_time_us 526*4882a593Smuzhiyun */ 527*4882a593Smuzhiyun __u32 max_pending_time_us; 528*4882a593Smuzhiyun }; 529*4882a593Smuzhiyun 530*4882a593Smuzhiyun /* 531*4882a593Smuzhiyun * Get the read timeouts array 532*4882a593Smuzhiyun * Argument for INCFS_IOC_GET_READ_TIMEOUTS 533*4882a593Smuzhiyun */ 534*4882a593Smuzhiyun struct incfs_get_read_timeouts_args { 535*4882a593Smuzhiyun /* 536*4882a593Smuzhiyun * A pointer to a buffer to fill with the current timeouts 537*4882a593Smuzhiyun * 538*4882a593Smuzhiyun * Equivalent to struct incfs_per_uid_read_timeouts * 539*4882a593Smuzhiyun */ 540*4882a593Smuzhiyun __aligned_u64 timeouts_array; 541*4882a593Smuzhiyun 542*4882a593Smuzhiyun /* Size of above buffer in bytes */ 543*4882a593Smuzhiyun __u32 timeouts_array_size; 544*4882a593Smuzhiyun 545*4882a593Smuzhiyun /* Size used in bytes, or size needed if -ENOMEM returned */ 546*4882a593Smuzhiyun __u32 timeouts_array_size_out; 547*4882a593Smuzhiyun }; 548*4882a593Smuzhiyun 549*4882a593Smuzhiyun /* 550*4882a593Smuzhiyun * Set the read timeouts array 551*4882a593Smuzhiyun * Arguments for INCFS_IOC_SET_READ_TIMEOUTS 552*4882a593Smuzhiyun */ 553*4882a593Smuzhiyun struct incfs_set_read_timeouts_args { 554*4882a593Smuzhiyun /* 555*4882a593Smuzhiyun * A pointer to an array containing the new timeouts 556*4882a593Smuzhiyun * This will replace any existing timeouts 557*4882a593Smuzhiyun * 558*4882a593Smuzhiyun * Equivalent to struct incfs_per_uid_read_timeouts * 559*4882a593Smuzhiyun */ 560*4882a593Smuzhiyun __aligned_u64 timeouts_array; 561*4882a593Smuzhiyun 562*4882a593Smuzhiyun /* Size of above array in bytes. Must be < 256 */ 563*4882a593Smuzhiyun __u32 timeouts_array_size; 564*4882a593Smuzhiyun }; 565*4882a593Smuzhiyun 566*4882a593Smuzhiyun /* 567*4882a593Smuzhiyun * Get last read error struct 568*4882a593Smuzhiyun * Arguments for INCFS_IOC_GET_LAST_READ_ERROR 569*4882a593Smuzhiyun */ 570*4882a593Smuzhiyun struct incfs_get_last_read_error_args { 571*4882a593Smuzhiyun /* File id of last file that had a read error */ 572*4882a593Smuzhiyun incfs_uuid_t file_id_out; 573*4882a593Smuzhiyun 574*4882a593Smuzhiyun /* Time of last read error, in us, from CLOCK_MONOTONIC */ 575*4882a593Smuzhiyun __u64 time_us_out; 576*4882a593Smuzhiyun 577*4882a593Smuzhiyun /* Index of page that was being read at last read error */ 578*4882a593Smuzhiyun __u32 page_out; 579*4882a593Smuzhiyun 580*4882a593Smuzhiyun /* errno of last read error */ 581*4882a593Smuzhiyun __u32 errno_out; 582*4882a593Smuzhiyun 583*4882a593Smuzhiyun /* uid of last read error */ 584*4882a593Smuzhiyun __u32 uid_out; 585*4882a593Smuzhiyun 586*4882a593Smuzhiyun __u32 reserved1; 587*4882a593Smuzhiyun __u64 reserved2; 588*4882a593Smuzhiyun }; 589*4882a593Smuzhiyun 590*4882a593Smuzhiyun #endif /* _UAPI_LINUX_INCREMENTALFS_H */ 591