1 /* SPDX-License-Identifier: GPL-2.0-only */ 2 /* 3 * Copyright 2023 Red Hat 4 */ 5 6 #ifndef DATA_VIO_H 7 #define DATA_VIO_H 8 9 #include <linux/atomic.h> 10 #include <linux/bio.h> 11 #include <linux/list.h> 12 13 #include "permassert.h" 14 15 #include "indexer.h" 16 17 #include "block-map.h" 18 #include "completion.h" 19 #include "constants.h" 20 #include "dedupe.h" 21 #include "encodings.h" 22 #include "logical-zone.h" 23 #include "physical-zone.h" 24 #include "types.h" 25 #include "vdo.h" 26 #include "vio.h" 27 #include "wait-queue.h" 28 29 /* Codes for describing the last asynchronous operation performed on a vio. */ 30 enum async_operation_number { 31 MIN_VIO_ASYNC_OPERATION_NUMBER, 32 VIO_ASYNC_OP_LAUNCH = MIN_VIO_ASYNC_OPERATION_NUMBER, 33 VIO_ASYNC_OP_ACKNOWLEDGE_WRITE, 34 VIO_ASYNC_OP_ACQUIRE_VDO_HASH_LOCK, 35 VIO_ASYNC_OP_ATTEMPT_LOGICAL_BLOCK_LOCK, 36 VIO_ASYNC_OP_LOCK_DUPLICATE_PBN, 37 VIO_ASYNC_OP_CHECK_FOR_DUPLICATION, 38 VIO_ASYNC_OP_CLEANUP, 39 VIO_ASYNC_OP_COMPRESS_DATA_VIO, 40 VIO_ASYNC_OP_FIND_BLOCK_MAP_SLOT, 41 VIO_ASYNC_OP_GET_MAPPED_BLOCK_FOR_READ, 42 VIO_ASYNC_OP_GET_MAPPED_BLOCK_FOR_WRITE, 43 VIO_ASYNC_OP_HASH_DATA_VIO, 44 VIO_ASYNC_OP_JOURNAL_REMAPPING, 45 VIO_ASYNC_OP_ATTEMPT_PACKING, 46 VIO_ASYNC_OP_PUT_MAPPED_BLOCK, 47 VIO_ASYNC_OP_READ_DATA_VIO, 48 VIO_ASYNC_OP_UPDATE_DEDUPE_INDEX, 49 VIO_ASYNC_OP_UPDATE_REFERENCE_COUNTS, 50 VIO_ASYNC_OP_VERIFY_DUPLICATION, 51 VIO_ASYNC_OP_WRITE_DATA_VIO, 52 MAX_VIO_ASYNC_OPERATION_NUMBER, 53 } __packed; 54 55 struct lbn_lock { 56 logical_block_number_t lbn; 57 bool locked; 58 struct vdo_wait_queue waiters; 59 struct logical_zone *zone; 60 }; 61 62 /* A position in the arboreal block map at a specific level. */ 63 struct block_map_tree_slot { 64 page_number_t page_index; 65 struct block_map_slot block_map_slot; 66 }; 67 68 /* Fields for using the arboreal block map. */ 69 struct tree_lock { 70 /* The current height at which this data_vio is operating */ 71 height_t height; 72 /* The block map tree for this LBN */ 73 root_count_t root_index; 74 /* Whether we hold a page lock */ 75 bool locked; 76 /* The key for the lock map */ 77 u64 key; 78 /* The queue of waiters for the page this vio is allocating or loading */ 79 struct vdo_wait_queue waiters; 80 /* The block map tree slots for this LBN */ 81 struct block_map_tree_slot tree_slots[VDO_BLOCK_MAP_TREE_HEIGHT + 1]; 82 }; 83 84 struct zoned_pbn { 85 physical_block_number_t pbn; 86 enum block_mapping_state state; 87 struct physical_zone *zone; 88 }; 89 90 /* 91 * Where a data_vio is on the compression path; advance_compression_stage() depends on the order of 92 * this enum. 93 */ 94 enum data_vio_compression_stage { 95 /* A data_vio which has not yet entered the compression path */ 96 DATA_VIO_PRE_COMPRESSOR, 97 /* A data_vio which is in the compressor */ 98 DATA_VIO_COMPRESSING, 99 /* A data_vio which is blocked in the packer */ 100 DATA_VIO_PACKING, 101 /* A data_vio which is no longer on the compression path (and never will be) */ 102 DATA_VIO_POST_PACKER, 103 }; 104 105 struct data_vio_compression_status { 106 enum data_vio_compression_stage stage; 107 bool may_not_compress; 108 }; 109 110 struct compression_state { 111 /* 112 * The current compression status of this data_vio. This field contains a value which 113 * consists of a data_vio_compression_stage and a flag indicating whether a request has 114 * been made to cancel (or prevent) compression for this data_vio. 115 * 116 * This field should be accessed through the get_data_vio_compression_status() and 117 * set_data_vio_compression_status() methods. It should not be accessed directly. 118 */ 119 atomic_t status; 120 121 /* The compressed size of this block */ 122 u16 size; 123 124 /* The packer input or output bin slot which holds the enclosing data_vio */ 125 slot_number_t slot; 126 127 /* The packer bin to which the enclosing data_vio has been assigned */ 128 struct packer_bin *bin; 129 130 /* A link in the chain of data_vios which have been packed together */ 131 struct data_vio *next_in_batch; 132 133 /* A vio which is blocked in the packer while holding a lock this vio needs. */ 134 struct data_vio *lock_holder; 135 136 /* 137 * The compressed block used to hold the compressed form of this block and that of any 138 * other blocks for which this data_vio is the compressed write agent. 139 */ 140 struct compressed_block *block; 141 }; 142 143 /* Fields supporting allocation of data blocks. */ 144 struct allocation { 145 /* The physical zone in which to allocate a physical block */ 146 struct physical_zone *zone; 147 148 /* The block allocated to this vio */ 149 physical_block_number_t pbn; 150 151 /* 152 * If non-NULL, the pooled PBN lock held on the allocated block. Must be a write lock until 153 * the block has been written, after which it will become a read lock. 154 */ 155 struct pbn_lock *lock; 156 157 /* The type of write lock to obtain on the allocated block */ 158 enum pbn_lock_type write_lock_type; 159 160 /* The zone which was the start of the current allocation cycle */ 161 zone_count_t first_allocation_zone; 162 163 /* Whether this vio should wait for a clean slab */ 164 bool wait_for_clean_slab; 165 }; 166 167 struct reference_updater { 168 enum journal_operation operation; 169 bool increment; 170 struct zoned_pbn zpbn; 171 struct pbn_lock *lock; 172 struct vdo_waiter waiter; 173 }; 174 175 /* A vio for processing user data requests. */ 176 struct data_vio { 177 /* The vdo_wait_queue entry structure */ 178 struct vdo_waiter waiter; 179 180 /* The logical block of this request */ 181 struct lbn_lock logical; 182 183 /* The state for traversing the block map tree */ 184 struct tree_lock tree_lock; 185 186 /* The current partition address of this block */ 187 struct zoned_pbn mapped; 188 189 /* The hash of this vio (if not zero) */ 190 struct uds_record_name record_name; 191 192 /* Used for logging and debugging */ 193 enum async_operation_number last_async_operation; 194 195 /* The operations to record in the recovery and slab journals */ 196 struct reference_updater increment_updater; 197 struct reference_updater decrement_updater; 198 199 u16 read : 1; 200 u16 write : 1; 201 u16 fua : 1; 202 u16 is_zero : 1; 203 u16 is_discard : 1; 204 u16 is_partial : 1; 205 u16 is_duplicate : 1; 206 u16 first_reference_operation_complete : 1; 207 u16 downgrade_allocation_lock : 1; 208 209 struct allocation allocation; 210 211 /* 212 * Whether this vio has received an allocation. This field is examined from threads not in 213 * the allocation zone. 214 */ 215 bool allocation_succeeded; 216 217 /* The new partition address of this block after the vio write completes */ 218 struct zoned_pbn new_mapped; 219 220 /* The hash zone responsible for the name (NULL if is_zero_block) */ 221 struct hash_zone *hash_zone; 222 223 /* The lock this vio holds or shares with other vios with the same data */ 224 struct hash_lock *hash_lock; 225 226 /* All data_vios sharing a hash lock are kept in a list linking these list entries */ 227 struct list_head hash_lock_entry; 228 229 /* The block number in the partition of the UDS deduplication advice */ 230 struct zoned_pbn duplicate; 231 232 /* 233 * The sequence number of the recovery journal block containing the increment entry for 234 * this vio. 235 */ 236 sequence_number_t recovery_sequence_number; 237 238 /* The point in the recovery journal where this write last made an entry */ 239 struct journal_point recovery_journal_point; 240 241 /* The list of vios in user initiated write requests */ 242 struct list_head write_entry; 243 244 /* The generation number of the VDO that this vio belongs to */ 245 sequence_number_t flush_generation; 246 247 /* The completion to use for fetching block map pages for this vio */ 248 struct vdo_page_completion page_completion; 249 250 /* The user bio that initiated this VIO */ 251 struct bio *user_bio; 252 253 /* partial block support */ 254 block_size_t offset; 255 256 /* 257 * The number of bytes to be discarded. For discards, this field will always be positive, 258 * whereas for non-discards it will always be 0. Hence it can be used to determine whether 259 * a data_vio is processing a discard, even after the user_bio has been acknowledged. 260 */ 261 u32 remaining_discard; 262 263 struct dedupe_context *dedupe_context; 264 265 /* Fields beyond this point will not be reset when a pooled data_vio is reused. */ 266 267 struct vio vio; 268 269 /* The completion for making reference count decrements */ 270 struct vdo_completion decrement_completion; 271 272 /* All of the fields necessary for the compression path */ 273 struct compression_state compression; 274 275 /* A block used as output during compression or uncompression */ 276 char *scratch_block; 277 278 struct list_head pool_entry; 279 }; 280 281 static inline struct data_vio *vio_as_data_vio(struct vio *vio) 282 { 283 VDO_ASSERT_LOG_ONLY((vio->type == VIO_TYPE_DATA), "vio is a data_vio"); 284 return container_of(vio, struct data_vio, vio); 285 } 286 287 static inline struct data_vio *as_data_vio(struct vdo_completion *completion) 288 { 289 return vio_as_data_vio(as_vio(completion)); 290 } 291 292 static inline struct data_vio *vdo_waiter_as_data_vio(struct vdo_waiter *waiter) 293 { 294 if (waiter == NULL) 295 return NULL; 296 297 return container_of(waiter, struct data_vio, waiter); 298 } 299 300 static inline struct data_vio *data_vio_from_reference_updater(struct reference_updater *updater) 301 { 302 if (updater->increment) 303 return container_of(updater, struct data_vio, increment_updater); 304 305 return container_of(updater, struct data_vio, decrement_updater); 306 } 307 308 static inline bool data_vio_has_flush_generation_lock(struct data_vio *data_vio) 309 { 310 return !list_empty(&data_vio->write_entry); 311 } 312 313 static inline struct vdo *vdo_from_data_vio(struct data_vio *data_vio) 314 { 315 return data_vio->vio.completion.vdo; 316 } 317 318 static inline bool data_vio_has_allocation(struct data_vio *data_vio) 319 { 320 return (data_vio->allocation.pbn != VDO_ZERO_BLOCK); 321 } 322 323 struct data_vio_compression_status __must_check 324 advance_data_vio_compression_stage(struct data_vio *data_vio); 325 struct data_vio_compression_status __must_check 326 get_data_vio_compression_status(struct data_vio *data_vio); 327 bool cancel_data_vio_compression(struct data_vio *data_vio); 328 329 struct data_vio_pool; 330 331 int make_data_vio_pool(struct vdo *vdo, data_vio_count_t pool_size, 332 data_vio_count_t discard_limit, struct data_vio_pool **pool_ptr); 333 void free_data_vio_pool(struct data_vio_pool *pool); 334 void vdo_launch_bio(struct data_vio_pool *pool, struct bio *bio); 335 void drain_data_vio_pool(struct data_vio_pool *pool, struct vdo_completion *completion); 336 void resume_data_vio_pool(struct data_vio_pool *pool, struct vdo_completion *completion); 337 338 void dump_data_vio_pool(struct data_vio_pool *pool, bool dump_vios); 339 data_vio_count_t get_data_vio_pool_active_discards(struct data_vio_pool *pool); 340 data_vio_count_t get_data_vio_pool_discard_limit(struct data_vio_pool *pool); 341 data_vio_count_t get_data_vio_pool_maximum_discards(struct data_vio_pool *pool); 342 int __must_check set_data_vio_pool_discard_limit(struct data_vio_pool *pool, 343 data_vio_count_t limit); 344 data_vio_count_t get_data_vio_pool_active_requests(struct data_vio_pool *pool); 345 data_vio_count_t get_data_vio_pool_request_limit(struct data_vio_pool *pool); 346 data_vio_count_t get_data_vio_pool_maximum_requests(struct data_vio_pool *pool); 347 348 void complete_data_vio(struct vdo_completion *completion); 349 void handle_data_vio_error(struct vdo_completion *completion); 350 351 static inline void continue_data_vio(struct data_vio *data_vio) 352 { 353 vdo_launch_completion(&data_vio->vio.completion); 354 } 355 356 /** 357 * continue_data_vio_with_error() - Set an error code and then continue processing a data_vio. 358 * 359 * This will not mask older errors. This function can be called with a success code, but it is more 360 * efficient to call continue_data_vio() if the caller knows the result was a success. 361 */ 362 static inline void continue_data_vio_with_error(struct data_vio *data_vio, int result) 363 { 364 vdo_continue_completion(&data_vio->vio.completion, result); 365 } 366 367 const char * __must_check get_data_vio_operation_name(struct data_vio *data_vio); 368 369 static inline void assert_data_vio_in_hash_zone(struct data_vio *data_vio) 370 { 371 thread_id_t expected = data_vio->hash_zone->thread_id; 372 thread_id_t thread_id = vdo_get_callback_thread_id(); 373 /* 374 * It's odd to use the LBN, but converting the record name to hex is a bit clunky for an 375 * inline, and the LBN better than nothing as an identifier. 376 */ 377 VDO_ASSERT_LOG_ONLY((expected == thread_id), 378 "data_vio for logical block %llu on thread %u, should be on hash zone thread %u", 379 (unsigned long long) data_vio->logical.lbn, thread_id, expected); 380 } 381 382 static inline void set_data_vio_hash_zone_callback(struct data_vio *data_vio, 383 vdo_action_fn callback) 384 { 385 vdo_set_completion_callback(&data_vio->vio.completion, callback, 386 data_vio->hash_zone->thread_id); 387 } 388 389 /** 390 * launch_data_vio_hash_zone_callback() - Set a callback as a hash zone operation and invoke it 391 * immediately. 392 */ 393 static inline void launch_data_vio_hash_zone_callback(struct data_vio *data_vio, 394 vdo_action_fn callback) 395 { 396 set_data_vio_hash_zone_callback(data_vio, callback); 397 vdo_launch_completion(&data_vio->vio.completion); 398 } 399 400 static inline void assert_data_vio_in_logical_zone(struct data_vio *data_vio) 401 { 402 thread_id_t expected = data_vio->logical.zone->thread_id; 403 thread_id_t thread_id = vdo_get_callback_thread_id(); 404 405 VDO_ASSERT_LOG_ONLY((expected == thread_id), 406 "data_vio for logical block %llu on thread %u, should be on thread %u", 407 (unsigned long long) data_vio->logical.lbn, thread_id, expected); 408 } 409 410 static inline void set_data_vio_logical_callback(struct data_vio *data_vio, 411 vdo_action_fn callback) 412 { 413 vdo_set_completion_callback(&data_vio->vio.completion, callback, 414 data_vio->logical.zone->thread_id); 415 } 416 417 /** 418 * launch_data_vio_logical_callback() - Set a callback as a logical block operation and invoke it 419 * immediately. 420 */ 421 static inline void launch_data_vio_logical_callback(struct data_vio *data_vio, 422 vdo_action_fn callback) 423 { 424 set_data_vio_logical_callback(data_vio, callback); 425 vdo_launch_completion(&data_vio->vio.completion); 426 } 427 428 static inline void assert_data_vio_in_allocated_zone(struct data_vio *data_vio) 429 { 430 thread_id_t expected = data_vio->allocation.zone->thread_id; 431 thread_id_t thread_id = vdo_get_callback_thread_id(); 432 433 VDO_ASSERT_LOG_ONLY((expected == thread_id), 434 "struct data_vio for allocated physical block %llu on thread %u, should be on thread %u", 435 (unsigned long long) data_vio->allocation.pbn, thread_id, 436 expected); 437 } 438 439 static inline void set_data_vio_allocated_zone_callback(struct data_vio *data_vio, 440 vdo_action_fn callback) 441 { 442 vdo_set_completion_callback(&data_vio->vio.completion, callback, 443 data_vio->allocation.zone->thread_id); 444 } 445 446 /** 447 * launch_data_vio_allocated_zone_callback() - Set a callback as a physical block operation in a 448 * data_vio's allocated zone and queue the data_vio and 449 * invoke it immediately. 450 */ 451 static inline void launch_data_vio_allocated_zone_callback(struct data_vio *data_vio, 452 vdo_action_fn callback) 453 { 454 set_data_vio_allocated_zone_callback(data_vio, callback); 455 vdo_launch_completion(&data_vio->vio.completion); 456 } 457 458 static inline void assert_data_vio_in_duplicate_zone(struct data_vio *data_vio) 459 { 460 thread_id_t expected = data_vio->duplicate.zone->thread_id; 461 thread_id_t thread_id = vdo_get_callback_thread_id(); 462 463 VDO_ASSERT_LOG_ONLY((expected == thread_id), 464 "data_vio for duplicate physical block %llu on thread %u, should be on thread %u", 465 (unsigned long long) data_vio->duplicate.pbn, thread_id, 466 expected); 467 } 468 469 static inline void set_data_vio_duplicate_zone_callback(struct data_vio *data_vio, 470 vdo_action_fn callback) 471 { 472 vdo_set_completion_callback(&data_vio->vio.completion, callback, 473 data_vio->duplicate.zone->thread_id); 474 } 475 476 /** 477 * launch_data_vio_duplicate_zone_callback() - Set a callback as a physical block operation in a 478 * data_vio's duplicate zone and queue the data_vio and 479 * invoke it immediately. 480 */ 481 static inline void launch_data_vio_duplicate_zone_callback(struct data_vio *data_vio, 482 vdo_action_fn callback) 483 { 484 set_data_vio_duplicate_zone_callback(data_vio, callback); 485 vdo_launch_completion(&data_vio->vio.completion); 486 } 487 488 static inline void assert_data_vio_in_mapped_zone(struct data_vio *data_vio) 489 { 490 thread_id_t expected = data_vio->mapped.zone->thread_id; 491 thread_id_t thread_id = vdo_get_callback_thread_id(); 492 493 VDO_ASSERT_LOG_ONLY((expected == thread_id), 494 "data_vio for mapped physical block %llu on thread %u, should be on thread %u", 495 (unsigned long long) data_vio->mapped.pbn, thread_id, expected); 496 } 497 498 static inline void set_data_vio_mapped_zone_callback(struct data_vio *data_vio, 499 vdo_action_fn callback) 500 { 501 vdo_set_completion_callback(&data_vio->vio.completion, callback, 502 data_vio->mapped.zone->thread_id); 503 } 504 505 static inline void assert_data_vio_in_new_mapped_zone(struct data_vio *data_vio) 506 { 507 thread_id_t expected = data_vio->new_mapped.zone->thread_id; 508 thread_id_t thread_id = vdo_get_callback_thread_id(); 509 510 VDO_ASSERT_LOG_ONLY((expected == thread_id), 511 "data_vio for new_mapped physical block %llu on thread %u, should be on thread %u", 512 (unsigned long long) data_vio->new_mapped.pbn, thread_id, 513 expected); 514 } 515 516 static inline void set_data_vio_new_mapped_zone_callback(struct data_vio *data_vio, 517 vdo_action_fn callback) 518 { 519 vdo_set_completion_callback(&data_vio->vio.completion, callback, 520 data_vio->new_mapped.zone->thread_id); 521 } 522 523 static inline void assert_data_vio_in_journal_zone(struct data_vio *data_vio) 524 { 525 thread_id_t journal_thread = vdo_from_data_vio(data_vio)->thread_config.journal_thread; 526 thread_id_t thread_id = vdo_get_callback_thread_id(); 527 528 VDO_ASSERT_LOG_ONLY((journal_thread == thread_id), 529 "data_vio for logical block %llu on thread %u, should be on journal thread %u", 530 (unsigned long long) data_vio->logical.lbn, thread_id, 531 journal_thread); 532 } 533 534 static inline void set_data_vio_journal_callback(struct data_vio *data_vio, 535 vdo_action_fn callback) 536 { 537 thread_id_t journal_thread = vdo_from_data_vio(data_vio)->thread_config.journal_thread; 538 539 vdo_set_completion_callback(&data_vio->vio.completion, callback, journal_thread); 540 } 541 542 /** 543 * launch_data_vio_journal_callback() - Set a callback as a journal operation and invoke it 544 * immediately. 545 */ 546 static inline void launch_data_vio_journal_callback(struct data_vio *data_vio, 547 vdo_action_fn callback) 548 { 549 set_data_vio_journal_callback(data_vio, callback); 550 vdo_launch_completion(&data_vio->vio.completion); 551 } 552 553 static inline void assert_data_vio_in_packer_zone(struct data_vio *data_vio) 554 { 555 thread_id_t packer_thread = vdo_from_data_vio(data_vio)->thread_config.packer_thread; 556 thread_id_t thread_id = vdo_get_callback_thread_id(); 557 558 VDO_ASSERT_LOG_ONLY((packer_thread == thread_id), 559 "data_vio for logical block %llu on thread %u, should be on packer thread %u", 560 (unsigned long long) data_vio->logical.lbn, thread_id, 561 packer_thread); 562 } 563 564 static inline void set_data_vio_packer_callback(struct data_vio *data_vio, 565 vdo_action_fn callback) 566 { 567 thread_id_t packer_thread = vdo_from_data_vio(data_vio)->thread_config.packer_thread; 568 569 vdo_set_completion_callback(&data_vio->vio.completion, callback, packer_thread); 570 } 571 572 /** 573 * launch_data_vio_packer_callback() - Set a callback as a packer operation and invoke it 574 * immediately. 575 */ 576 static inline void launch_data_vio_packer_callback(struct data_vio *data_vio, 577 vdo_action_fn callback) 578 { 579 set_data_vio_packer_callback(data_vio, callback); 580 vdo_launch_completion(&data_vio->vio.completion); 581 } 582 583 static inline void assert_data_vio_on_cpu_thread(struct data_vio *data_vio) 584 { 585 thread_id_t cpu_thread = vdo_from_data_vio(data_vio)->thread_config.cpu_thread; 586 thread_id_t thread_id = vdo_get_callback_thread_id(); 587 588 VDO_ASSERT_LOG_ONLY((cpu_thread == thread_id), 589 "data_vio for logical block %llu on thread %u, should be on cpu thread %u", 590 (unsigned long long) data_vio->logical.lbn, thread_id, 591 cpu_thread); 592 } 593 594 static inline void set_data_vio_cpu_callback(struct data_vio *data_vio, 595 vdo_action_fn callback) 596 { 597 thread_id_t cpu_thread = vdo_from_data_vio(data_vio)->thread_config.cpu_thread; 598 599 vdo_set_completion_callback(&data_vio->vio.completion, callback, cpu_thread); 600 } 601 602 /** 603 * launch_data_vio_cpu_callback() - Set a callback to run on the CPU queues and invoke it 604 * immediately. 605 */ 606 static inline void launch_data_vio_cpu_callback(struct data_vio *data_vio, 607 vdo_action_fn callback, 608 enum vdo_completion_priority priority) 609 { 610 set_data_vio_cpu_callback(data_vio, callback); 611 vdo_launch_completion_with_priority(&data_vio->vio.completion, priority); 612 } 613 614 static inline void set_data_vio_bio_zone_callback(struct data_vio *data_vio, 615 vdo_action_fn callback) 616 { 617 vdo_set_completion_callback(&data_vio->vio.completion, callback, 618 get_vio_bio_zone_thread_id(&data_vio->vio)); 619 } 620 621 /** 622 * launch_data_vio_bio_zone_callback() - Set a callback as a bio zone operation and invoke it 623 * immediately. 624 */ 625 static inline void launch_data_vio_bio_zone_callback(struct data_vio *data_vio, 626 vdo_action_fn callback) 627 { 628 set_data_vio_bio_zone_callback(data_vio, callback); 629 vdo_launch_completion_with_priority(&data_vio->vio.completion, 630 BIO_Q_DATA_PRIORITY); 631 } 632 633 /** 634 * launch_data_vio_on_bio_ack_queue() - If the vdo uses a bio_ack queue, set a callback to run on 635 * it and invoke it immediately, otherwise, just run the 636 * callback on the current thread. 637 */ 638 static inline void launch_data_vio_on_bio_ack_queue(struct data_vio *data_vio, 639 vdo_action_fn callback) 640 { 641 struct vdo_completion *completion = &data_vio->vio.completion; 642 struct vdo *vdo = completion->vdo; 643 644 if (!vdo_uses_bio_ack_queue(vdo)) { 645 callback(completion); 646 return; 647 } 648 649 vdo_set_completion_callback(completion, callback, 650 vdo->thread_config.bio_ack_thread); 651 vdo_launch_completion_with_priority(completion, BIO_ACK_Q_ACK_PRIORITY); 652 } 653 654 void data_vio_allocate_data_block(struct data_vio *data_vio, 655 enum pbn_lock_type write_lock_type, 656 vdo_action_fn callback, vdo_action_fn error_handler); 657 658 void release_data_vio_allocation_lock(struct data_vio *data_vio, bool reset); 659 660 int __must_check uncompress_data_vio(struct data_vio *data_vio, 661 enum block_mapping_state mapping_state, 662 char *buffer); 663 664 void update_metadata_for_data_vio_write(struct data_vio *data_vio, 665 struct pbn_lock *lock); 666 void write_data_vio(struct data_vio *data_vio); 667 void launch_compress_data_vio(struct data_vio *data_vio); 668 void continue_data_vio_with_block_map_slot(struct vdo_completion *completion); 669 670 #endif /* DATA_VIO_H */ 671