Subversion Repositories HelenOS

Rev

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
 */