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