Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/libblock/libblock.c

    r1e4cada red903174  
    11/*
    2  * Copyright (c) 2008 Jakub Jermar 
    3  * Copyright (c) 2008 Martin Decky 
     2 * Copyright (c) 2008 Jakub Jermar
     3 * Copyright (c) 2008 Martin Decky
    44 * All rights reserved.
    55 *
     
    5252#include <macros.h>
    5353#include <mem.h>
     54#include <sys/typefmt.h>
     55#include <stacktrace.h>
    5456
    5557/** Lock protecting the device connection list */
     
    7981        size_t comm_size;
    8082        void *bb_buf;
    81         bn_t bb_addr;
     83        aoff64_t bb_addr;
    8284        size_t pblock_size;             /**< Physical block size. */
    8385        cache_t *cache;
    8486} devcon_t;
    8587
    86 static int read_blocks(devcon_t *devcon, bn_t ba, size_t cnt);
    87 static int write_blocks(devcon_t *devcon, bn_t ba, size_t cnt);
     88static int read_blocks(devcon_t *devcon, aoff64_t ba, size_t cnt);
     89static int write_blocks(devcon_t *devcon, aoff64_t ba, size_t cnt);
    8890static int get_block_size(int dev_phone, size_t *bsize);
     91static int get_num_blocks(int dev_phone, aoff64_t *nblocks);
    8992
    9093static devcon_t *devcon_search(dev_handle_t dev_handle)
     
    197200        assert(devcon);
    198201       
     202        if (devcon->cache)
     203                (void) block_cache_fini(dev_handle);
     204
    199205        devcon_remove(devcon);
    200206
     
    202208                free(devcon->bb_buf);
    203209
    204         if (devcon->cache) {
    205                 hash_table_destroy(&devcon->cache->block_hash);
    206                 free(devcon->cache);
    207         }
    208 
    209210        munmap(devcon->comm_area, devcon->comm_size);
    210211        ipc_hangup(devcon->dev_phone);
     
    213214}
    214215
    215 int block_bb_read(dev_handle_t dev_handle, bn_t ba)
     216int block_bb_read(dev_handle_t dev_handle, aoff64_t ba)
    216217{
    217218        void *bb_buf;
     
    304305}
    305306
     307int block_cache_fini(dev_handle_t dev_handle)
     308{
     309        devcon_t *devcon = devcon_search(dev_handle);
     310        cache_t *cache;
     311        int rc;
     312
     313        if (!devcon)
     314                return ENOENT;
     315        if (!devcon->cache)
     316                return EOK;
     317        cache = devcon->cache;
     318       
     319        /*
     320         * We are expecting to find all blocks for this device handle on the
     321         * free list, i.e. the block reference count should be zero. Do not
     322         * bother with the cache and block locks because we are single-threaded.
     323         */
     324        while (!list_empty(&cache->free_head)) {
     325                block_t *b = list_get_instance(cache->free_head.next,
     326                    block_t, free_link);
     327
     328                list_remove(&b->free_link);
     329                if (b->dirty) {
     330                        memcpy(devcon->comm_area, b->data, b->size);
     331                        rc = write_blocks(devcon, b->boff, 1);
     332                        if (rc != EOK)
     333                                return rc;
     334                }
     335
     336                unsigned long key = b->boff;
     337                hash_table_remove(&cache->block_hash, &key, 1);
     338               
     339                free(b->data);
     340                free(b);
     341        }
     342
     343        hash_table_destroy(&cache->block_hash);
     344        devcon->cache = NULL;
     345        free(cache);
     346
     347        return EOK;
     348}
     349
    306350#define CACHE_LO_WATERMARK      10     
    307351#define CACHE_HI_WATERMARK      20     
     
    338382 * @return                      EOK on success or a negative error code.
    339383 */
    340 int block_get(block_t **block, dev_handle_t dev_handle, bn_t boff, int flags)
     384int block_get(block_t **block, dev_handle_t dev_handle, aoff64_t boff, int flags)
    341385{
    342386        devcon_t *devcon;
     
    613657 * @return              EOK on success or a negative return code on failure.
    614658 */
    615 int block_seqread(dev_handle_t dev_handle, off_t *bufpos, size_t *buflen,
    616     off_t *pos, void *dst, size_t size)
    617 {
    618         off_t offset = 0;
     659int block_seqread(dev_handle_t dev_handle, size_t *bufpos, size_t *buflen,
     660    aoff64_t *pos, void *dst, size_t size)
     661{
     662        size_t offset = 0;
    619663        size_t left = size;
    620664        size_t block_size;
     
    646690                }
    647691               
    648                 if (*bufpos == (off_t) *buflen) {
     692                if (*bufpos == *buflen) {
    649693                        /* Refill the communication buffer with a new block. */
    650694                        int rc;
     
    674718 * @return              EOK on success or negative error code on failure.
    675719 */
    676 int block_read_direct(dev_handle_t dev_handle, bn_t ba, size_t cnt, void *buf)
     720int block_read_direct(dev_handle_t dev_handle, aoff64_t ba, size_t cnt, void *buf)
    677721{
    678722        devcon_t *devcon;
     
    702746 * @return              EOK on success or negative error code on failure.
    703747 */
    704 int block_write_direct(dev_handle_t dev_handle, bn_t ba, size_t cnt,
     748int block_write_direct(dev_handle_t dev_handle, aoff64_t ba, size_t cnt,
    705749    const void *data)
    706750{
     
    714758
    715759        memcpy(devcon->comm_area, data, devcon->pblock_size * cnt);
    716         rc = read_blocks(devcon, ba, cnt);
     760        rc = write_blocks(devcon, ba, cnt);
    717761
    718762        fibril_mutex_unlock(&devcon->comm_area_lock);
     
    736780       
    737781        return get_block_size(devcon->dev_phone, bsize);
     782}
     783
     784/** Get number of blocks on device.
     785 *
     786 * @param dev_handle    Device handle of the block device.
     787 * @param nblocks       Output number of blocks.
     788 *
     789 * @return              EOK on success or negative error code on failure.
     790 */
     791int block_get_nblocks(dev_handle_t dev_handle, aoff64_t *nblocks)
     792{
     793        devcon_t *devcon;
     794
     795        devcon = devcon_search(dev_handle);
     796        assert(devcon);
     797       
     798        return get_num_blocks(devcon->dev_phone, nblocks);
    738799}
    739800
     
    747808 * @return              EOK on success or negative error code on failure.
    748809 */
    749 static int read_blocks(devcon_t *devcon, bn_t ba, size_t cnt)
     810static int read_blocks(devcon_t *devcon, aoff64_t ba, size_t cnt)
    750811{
    751812        int rc;
     
    754815        rc = async_req_3_0(devcon->dev_phone, BD_READ_BLOCKS, LOWER32(ba),
    755816            UPPER32(ba), cnt);
     817        if (rc != EOK) {
     818                printf("Error %d reading %d blocks starting at block %" PRIuOFF64
     819                    " from device handle %d\n", rc, cnt, ba,
     820                    devcon->dev_handle);
     821#ifndef NDEBUG
     822                stacktrace_print();
     823#endif
     824        }
    756825        return rc;
    757826}
     
    766835 * @return              EOK on success or negative error code on failure.
    767836 */
    768 static int write_blocks(devcon_t *devcon, bn_t ba, size_t cnt)
     837static int write_blocks(devcon_t *devcon, aoff64_t ba, size_t cnt)
    769838{
    770839        int rc;
     
    773842        rc = async_req_3_0(devcon->dev_phone, BD_WRITE_BLOCKS, LOWER32(ba),
    774843            UPPER32(ba), cnt);
     844        if (rc != EOK) {
     845                printf("Error %d writing %d blocks starting at block %" PRIuOFF64
     846                    " to device handle %d\n", rc, cnt, ba, devcon->dev_handle);
     847#ifndef NDEBUG
     848                stacktrace_print();
     849#endif
     850        }
    775851        return rc;
    776852}
     
    789865}
    790866
     867/** Get total number of blocks on block device. */
     868static int get_num_blocks(int dev_phone, aoff64_t *nblocks)
     869{
     870        ipcarg_t nb_l, nb_h;
     871        int rc;
     872
     873        rc = async_req_0_2(dev_phone, BD_GET_NUM_BLOCKS, &nb_l, &nb_h);
     874        if (rc == EOK) {
     875                *nblocks = (aoff64_t) MERGE_LOUP32(nb_l, nb_h);
     876        }
     877
     878        return rc;
     879}
     880
    791881/** @}
    792882 */
Note: See TracChangeset for help on using the changeset viewer.