| 3457 | */ |
| 3458 | |
| 3459 | static int flush_cached_blocks(KEY_CACHE *keycache, |
| 3460 | File file, BLOCK_LINK **cache, |
| 3461 | BLOCK_LINK **end, |
| 3462 | enum flush_type type) |
| 3463 | { |
| 3464 | int error; |
| 3465 | int last_errno= 0; |
| 3466 | uint count= (uint) (end-cache); |
| 3467 | |
| 3468 | /* Don't lock the cache during the flush */ |
| 3469 | keycache_pthread_mutex_unlock(&keycache->cache_lock); |
| 3470 | /* |
| 3471 | As all blocks referred in 'cache' are marked by BLOCK_IN_FLUSH |
| 3472 | we are guarunteed no thread will change them |
| 3473 | */ |
| 3474 | my_qsort((uchar*) cache, count, sizeof(*cache), (qsort_cmp) cmp_sec_link); |
| 3475 | |
| 3476 | keycache_pthread_mutex_lock(&keycache->cache_lock); |
| 3477 | /* |
| 3478 | Note: Do not break the loop. We have registered a request on every |
| 3479 | block in 'cache'. These must be unregistered by free_block() or |
| 3480 | unreg_request(). |
| 3481 | */ |
| 3482 | for ( ; cache != end ; cache++) |
| 3483 | { |
| 3484 | BLOCK_LINK *block= *cache; |
| 3485 | |
| 3486 | KEYCACHE_DBUG_PRINT("flush_cached_blocks", |
| 3487 | ("block %u to be flushed", BLOCK_NUMBER(block))); |
| 3488 | /* |
| 3489 | If the block contents is going to be changed, we abandon the flush |
| 3490 | for this block. flush_key_blocks_int() will restart its search and |
| 3491 | handle the block properly. |
| 3492 | */ |
| 3493 | if (!(block->status & BLOCK_FOR_UPDATE)) |
| 3494 | { |
| 3495 | /* Blocks coming here must have a certain status. */ |
| 3496 | DBUG_ASSERT(block->hash_link); |
| 3497 | DBUG_ASSERT(block->hash_link->block == block); |
| 3498 | DBUG_ASSERT(block->hash_link->file == file); |
| 3499 | DBUG_ASSERT((block->status & ~BLOCK_IN_EVICTION) == |
| 3500 | (BLOCK_READ | BLOCK_IN_FLUSH | BLOCK_CHANGED | BLOCK_IN_USE)); |
| 3501 | block->status|= BLOCK_IN_FLUSHWRITE; |
| 3502 | keycache_pthread_mutex_unlock(&keycache->cache_lock); |
| 3503 | error= my_pwrite(file, block->buffer+block->offset, |
| 3504 | block->length - block->offset, |
| 3505 | block->hash_link->diskpos+ block->offset, |
| 3506 | MYF(MY_NABP | MY_WAIT_IF_FULL)); |
| 3507 | keycache_pthread_mutex_lock(&keycache->cache_lock); |
| 3508 | keycache->global_cache_write++; |
| 3509 | if (error) |
| 3510 | { |
| 3511 | block->status|= BLOCK_ERROR; |
| 3512 | if (!last_errno) |
| 3513 | last_errno= errno ? errno : -1; |
| 3514 | } |
| 3515 | block->status&= ~BLOCK_IN_FLUSHWRITE; |
| 3516 | /* Block must not have changed status except BLOCK_FOR_UPDATE. */ |
no test coverage detected