| 2381 | */ |
| 2382 | |
| 2383 | static void read_block(KEY_CACHE *keycache, |
| 2384 | BLOCK_LINK *block, uint read_length, |
| 2385 | uint min_length, my_bool primary) |
| 2386 | { |
| 2387 | size_t got_length; |
| 2388 | |
| 2389 | /* On entry cache_lock is locked */ |
| 2390 | |
| 2391 | KEYCACHE_THREAD_TRACE("read_block"); |
| 2392 | if (primary) |
| 2393 | { |
| 2394 | /* |
| 2395 | This code is executed only by threads that submitted primary |
| 2396 | requests. Until block->status contains BLOCK_READ, all other |
| 2397 | request for the block become secondary requests. For a primary |
| 2398 | request the block must be properly initialized. |
| 2399 | */ |
| 2400 | DBUG_ASSERT(((block->status & ~BLOCK_FOR_UPDATE) == BLOCK_IN_USE) || |
| 2401 | fail_block(block)); |
| 2402 | DBUG_ASSERT((block->length == 0) || fail_block(block)); |
| 2403 | DBUG_ASSERT((block->offset == keycache->key_cache_block_size) || |
| 2404 | fail_block(block)); |
| 2405 | DBUG_ASSERT((block->requests > 0) || fail_block(block)); |
| 2406 | |
| 2407 | KEYCACHE_DBUG_PRINT("read_block", |
| 2408 | ("page to be read by primary request")); |
| 2409 | |
| 2410 | keycache->global_cache_read++; |
| 2411 | /* Page is not in buffer yet, is to be read from disk */ |
| 2412 | keycache_pthread_mutex_unlock(&keycache->cache_lock); |
| 2413 | /* |
| 2414 | Here other threads may step in and register as secondary readers. |
| 2415 | They will register in block->wqueue[COND_FOR_REQUESTED]. |
| 2416 | */ |
| 2417 | got_length= my_pread(block->hash_link->file, block->buffer, |
| 2418 | read_length, block->hash_link->diskpos, MYF(0)); |
| 2419 | keycache_pthread_mutex_lock(&keycache->cache_lock); |
| 2420 | /* |
| 2421 | The block can now have been marked for free (in case of |
| 2422 | FLUSH_RELEASE). Otherwise the state must be unchanged. |
| 2423 | */ |
| 2424 | DBUG_ASSERT(((block->status & ~(BLOCK_REASSIGNED | |
| 2425 | BLOCK_FOR_UPDATE)) == BLOCK_IN_USE) || |
| 2426 | fail_block(block)); |
| 2427 | DBUG_ASSERT((block->length == 0) || fail_block(block)); |
| 2428 | DBUG_ASSERT((block->offset == keycache->key_cache_block_size) || |
| 2429 | fail_block(block)); |
| 2430 | DBUG_ASSERT((block->requests > 0) || fail_block(block)); |
| 2431 | |
| 2432 | if (got_length < min_length) |
| 2433 | block->status|= BLOCK_ERROR; |
| 2434 | else |
| 2435 | { |
| 2436 | block->status|= BLOCK_READ; |
| 2437 | block->length= got_length; |
| 2438 | /* |
| 2439 | Do not set block->offset here. If this block is marked |
| 2440 | BLOCK_CHANGED later, we want to flush only the modified part. So |
no test coverage detected