Rev 4553 | Rev 4583 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
| Rev 4553 | Rev 4572 | ||
|---|---|---|---|
| Line 63... | Line 63... | ||
| 63 | fibril_mutex_t lock; |
63 | fibril_mutex_t lock; |
| 64 | size_t block_size; /**< Block size. */ |
64 | size_t block_size; /**< Block size. */ |
| 65 | unsigned block_count; /**< Total number of blocks. */ |
65 | unsigned block_count; /**< Total number of blocks. */ |
| 66 | hash_table_t block_hash; |
66 | hash_table_t block_hash; |
| 67 | link_t free_head; |
67 | link_t free_head; |
| - | 68 | enum cache_mode mode; |
|
| 68 | } cache_t; |
69 | } cache_t; |
| 69 | 70 | ||
| 70 | typedef struct { |
71 | typedef struct { |
| 71 | link_t link; |
72 | link_t link; |
| 72 | dev_handle_t dev_handle; |
73 | dev_handle_t dev_handle; |
| Line 77... | Line 78... | ||
| 77 | off_t bb_off; |
78 | off_t bb_off; |
| 78 | size_t bb_size; |
79 | size_t bb_size; |
| 79 | cache_t *cache; |
80 | cache_t *cache; |
| 80 | } devcon_t; |
81 | } devcon_t; |
| 81 | 82 | ||
| - | 83 | static int write_block(devcon_t *devcon, bn_t boff, size_t block_size, |
|
| - | 84 | const void *src); |
|
| - | 85 | ||
| 82 | static devcon_t *devcon_search(dev_handle_t dev_handle) |
86 | static devcon_t *devcon_search(dev_handle_t dev_handle) |
| 83 | { |
87 | { |
| 84 | link_t *cur; |
88 | link_t *cur; |
| 85 | 89 | ||
| 86 | fibril_mutex_lock(&dcl_lock); |
90 | fibril_mutex_lock(&dcl_lock); |
| Line 248... | Line 252... | ||
| 248 | .hash = cache_hash, |
252 | .hash = cache_hash, |
| 249 | .compare = cache_compare, |
253 | .compare = cache_compare, |
| 250 | .remove_callback = cache_remove_callback |
254 | .remove_callback = cache_remove_callback |
| 251 | }; |
255 | }; |
| 252 | 256 | ||
| 253 | int block_cache_init(dev_handle_t dev_handle, size_t size, unsigned blocks) |
257 | int block_cache_init(dev_handle_t dev_handle, size_t size, unsigned blocks, |
| - | 258 | enum cache_mode mode) |
|
| 254 | { |
259 | { |
| 255 | devcon_t *devcon = devcon_search(dev_handle); |
260 | devcon_t *devcon = devcon_search(dev_handle); |
| 256 | cache_t *cache; |
261 | cache_t *cache; |
| 257 | if (!devcon) |
262 | if (!devcon) |
| 258 | return ENOENT; |
263 | return ENOENT; |
| Line 264... | Line 269... | ||
| 264 | 269 | ||
| 265 | fibril_mutex_initialize(&cache->lock); |
270 | fibril_mutex_initialize(&cache->lock); |
| 266 | list_initialize(&cache->free_head); |
271 | list_initialize(&cache->free_head); |
| 267 | cache->block_size = size; |
272 | cache->block_size = size; |
| 268 | cache->block_count = blocks; |
273 | cache->block_count = blocks; |
| - | 274 | cache->mode = mode; |
|
| 269 | 275 | ||
| 270 | if (!hash_table_create(&cache->block_hash, CACHE_BUCKETS, 1, |
276 | if (!hash_table_create(&cache->block_hash, CACHE_BUCKETS, 1, |
| 271 | &cache_ops)) { |
277 | &cache_ops)) { |
| 272 | free(cache); |
278 | free(cache); |
| 273 | return ENOMEM; |
279 | return ENOMEM; |
| Line 411... | Line 417... | ||
| 411 | */ |
417 | */ |
| 412 | void block_put(block_t *block) |
418 | void block_put(block_t *block) |
| 413 | { |
419 | { |
| 414 | devcon_t *devcon = devcon_search(block->dev_handle); |
420 | devcon_t *devcon = devcon_search(block->dev_handle); |
| 415 | cache_t *cache; |
421 | cache_t *cache; |
| - | 422 | int rc; |
|
| 416 | 423 | ||
| 417 | assert(devcon); |
424 | assert(devcon); |
| 418 | assert(devcon->cache); |
425 | assert(devcon->cache); |
| 419 | 426 | ||
| 420 | cache = devcon->cache; |
427 | cache = devcon->cache; |
| Line 424... | Line 431... | ||
| 424 | /* |
431 | /* |
| 425 | * Last reference to the block was dropped, put the block on the |
432 | * Last reference to the block was dropped, put the block on the |
| 426 | * free list. |
433 | * free list. |
| 427 | */ |
434 | */ |
| 428 | list_append(&block->free_link, &cache->free_head); |
435 | list_append(&block->free_link, &cache->free_head); |
| - | 436 | if (cache->mode != CACHE_MODE_WB && block->dirty) { |
|
| - | 437 | rc = write_block(devcon, block->boff, block->size, |
|
| - | 438 | block->data); |
|
| - | 439 | assert(rc == EOK); |
|
| - | 440 | ||
| - | 441 | block->dirty = false; |
|
| - | 442 | } |
|
| 429 | } |
443 | } |
| 430 | fibril_mutex_unlock(&block->lock); |
444 | fibril_mutex_unlock(&block->lock); |
| 431 | fibril_mutex_unlock(&cache->lock); |
445 | fibril_mutex_unlock(&cache->lock); |
| 432 | } |
446 | } |
| 433 | 447 | ||
| Line 488... | Line 502... | ||
| 488 | } |
502 | } |
| 489 | 503 | ||
| 490 | return EOK; |
504 | return EOK; |
| 491 | } |
505 | } |
| 492 | 506 | ||
| - | 507 | /** Write block to block device. |
|
| - | 508 | * |
|
| - | 509 | * @param devcon Device connection. |
|
| - | 510 | * @param boff Block index. |
|
| - | 511 | * @param block_size Block size. |
|
| - | 512 | * @param src Buffer containing the data to write. |
|
| - | 513 | * |
|
| - | 514 | * @return EOK on success or negative error code on failure. |
|
| - | 515 | */ |
|
| - | 516 | static int write_block(devcon_t *devcon, bn_t boff, size_t block_size, |
|
| - | 517 | const void *src) |
|
| - | 518 | { |
|
| - | 519 | ipcarg_t retval; |
|
| - | 520 | int rc; |
|
| - | 521 | ||
| - | 522 | assert(devcon); |
|
| - | 523 | memcpy(devcon->com_area, src, block_size); |
|
| - | 524 | ||
| - | 525 | rc = async_req_2_1(devcon->dev_phone, BD_WRITE_BLOCK, |
|
| - | 526 | boff, block_size, &retval); |
|
| - | 527 | if ((rc != EOK) || (retval != EOK)) |
|
| - | 528 | return (rc != EOK ? rc : (int) retval); |
|
| - | 529 | ||
| - | 530 | return EOK; |
|
| - | 531 | } |
|
| - | 532 | ||
| 493 | /** @} |
533 | /** @} |
| 494 | */ |
534 | */ |