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