| 2496 | */ |
| 2497 | |
| 2498 | uchar *key_cache_read(KEY_CACHE *keycache, |
| 2499 | File file, my_off_t filepos, int level, |
| 2500 | uchar *buff, uint length, |
| 2501 | uint block_length __attribute__((unused)), |
| 2502 | int return_buffer __attribute__((unused))) |
| 2503 | { |
| 2504 | my_bool locked_and_incremented= FALSE; |
| 2505 | int error=0; |
| 2506 | uchar *start= buff; |
| 2507 | DBUG_ENTER("key_cache_read"); |
| 2508 | DBUG_PRINT("enter", ("fd: %u pos: %lu length: %u", |
| 2509 | (uint) file, (ulong) filepos, length)); |
| 2510 | |
| 2511 | if (keycache->key_cache_inited) |
| 2512 | { |
| 2513 | /* Key cache is used */ |
| 2514 | reg1 BLOCK_LINK *block; |
| 2515 | uint read_length; |
| 2516 | uint offset; |
| 2517 | int page_st; |
| 2518 | |
| 2519 | if (MYSQL_KEYCACHE_READ_START_ENABLED()) |
| 2520 | { |
| 2521 | MYSQL_KEYCACHE_READ_START(my_filename(file), length, |
| 2522 | (ulong) (keycache->blocks_used * |
| 2523 | keycache->key_cache_block_size), |
| 2524 | (ulong) (keycache->blocks_unused * |
| 2525 | keycache->key_cache_block_size)); |
| 2526 | } |
| 2527 | |
| 2528 | /* |
| 2529 | When the key cache is once initialized, we use the cache_lock to |
| 2530 | reliably distinguish the cases of normal operation, resizing, and |
| 2531 | disabled cache. We always increment and decrement |
| 2532 | 'cnt_for_resize_op' so that a resizer can wait for pending I/O. |
| 2533 | */ |
| 2534 | keycache_pthread_mutex_lock(&keycache->cache_lock); |
| 2535 | /* |
| 2536 | Cache resizing has two phases: Flushing and re-initializing. In |
| 2537 | the flush phase read requests are allowed to bypass the cache for |
| 2538 | blocks not in the cache. find_key_block() returns NULL in this |
| 2539 | case. |
| 2540 | |
| 2541 | After the flush phase new I/O requests must wait until the |
| 2542 | re-initialization is done. The re-initialization can be done only |
| 2543 | if no I/O request is in progress. The reason is that |
| 2544 | key_cache_block_size can change. With enabled cache, I/O is done |
| 2545 | in chunks of key_cache_block_size. Every chunk tries to use a |
| 2546 | cache block first. If the block size changes in the middle, a |
| 2547 | block could be missed and old data could be read. |
| 2548 | */ |
| 2549 | while (keycache->in_resize && !keycache->resize_in_flush) |
| 2550 | wait_on_queue(&keycache->resize_queue, &keycache->cache_lock); |
| 2551 | /* Register the I/O for the next resize. */ |
| 2552 | inc_counter_for_resize_op(keycache); |
| 2553 | locked_and_incremented= TRUE; |
| 2554 | /* Requested data may not always be aligned to cache blocks. */ |
| 2555 | offset= (uint) (filepos % keycache->key_cache_block_size); |
nothing calls this directly
no test coverage detected