Ignore:
File:
1 edited

Legend:

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

    r0da4e41 r64bc4b6  
    4747#include <as.h>
    4848#include <assert.h>
    49 #include <fibril_sync.h>
     49#include <fibril_synch.h>
    5050#include <adt/list.h>
    5151#include <adt/hash_table.h>
     
    8787static int write_blocks(devcon_t *devcon, bn_t ba, size_t cnt);
    8888static int get_block_size(int dev_phone, size_t *bsize);
     89static int get_num_blocks(int dev_phone, bn_t *nblocks);
    8990
    9091static devcon_t *devcon_search(dev_handle_t dev_handle)
     
    197198        assert(devcon);
    198199       
     200        if (devcon->cache)
     201                (void) block_cache_fini(dev_handle);
     202
    199203        devcon_remove(devcon);
    200204
    201205        if (devcon->bb_buf)
    202206                free(devcon->bb_buf);
    203 
    204         if (devcon->cache) {
    205                 hash_table_destroy(&devcon->cache->block_hash);
    206                 free(devcon->cache);
    207         }
    208207
    209208        munmap(devcon->comm_area, devcon->comm_size);
     
    301300
    302301        devcon->cache = cache;
     302        return EOK;
     303}
     304
     305int block_cache_fini(dev_handle_t dev_handle)
     306{
     307        devcon_t *devcon = devcon_search(dev_handle);
     308        cache_t *cache;
     309        int rc;
     310
     311        if (!devcon)
     312                return ENOENT;
     313        if (!devcon->cache)
     314                return EOK;
     315        cache = devcon->cache;
     316       
     317        /*
     318         * We are expecting to find all blocks for this device handle on the
     319         * free list, i.e. the block reference count should be zero. Do not
     320         * bother with the cache and block locks because we are single-threaded.
     321         */
     322        while (!list_empty(&cache->free_head)) {
     323                block_t *b = list_get_instance(cache->free_head.next,
     324                    block_t, free_link);
     325
     326                list_remove(&b->free_link);
     327                if (b->dirty) {
     328                        memcpy(devcon->comm_area, b->data, b->size);
     329                        rc = write_blocks(devcon, b->boff, 1);
     330                        if (rc != EOK)
     331                                return rc;
     332                }
     333
     334                long key = b->boff;
     335                hash_table_remove(&cache->block_hash, &key, 1);
     336               
     337                free(b->data);
     338                free(b);
     339        }
     340
     341        hash_table_destroy(&cache->block_hash);
     342        devcon->cache = NULL;
     343        free(cache);
     344
    303345        return EOK;
    304346}
     
    714756
    715757        memcpy(devcon->comm_area, data, devcon->pblock_size * cnt);
    716         rc = read_blocks(devcon, ba, cnt);
     758        rc = write_blocks(devcon, ba, cnt);
    717759
    718760        fibril_mutex_unlock(&devcon->comm_area_lock);
     
    736778       
    737779        return get_block_size(devcon->dev_phone, bsize);
     780}
     781
     782/** Get number of blocks on device.
     783 *
     784 * @param dev_handle    Device handle of the block device.
     785 * @param nblocks       Output number of blocks.
     786 *
     787 * @return              EOK on success or negative error code on failure.
     788 */
     789int block_get_nblocks(dev_handle_t dev_handle, bn_t *nblocks)
     790{
     791        devcon_t *devcon;
     792
     793        devcon = devcon_search(dev_handle);
     794        assert(devcon);
     795       
     796        return get_num_blocks(devcon->dev_phone, nblocks);
    738797}
    739798
     
    789848}
    790849
     850/** Get total number of blocks on block device. */
     851static int get_num_blocks(int dev_phone, bn_t *nblocks)
     852{
     853        ipcarg_t nb_l, nb_h;
     854        int rc;
     855
     856        rc = async_req_0_2(dev_phone, BD_GET_NUM_BLOCKS, &nb_l, &nb_h);
     857        if (rc == EOK) {
     858                *nblocks = (bn_t) MERGE_LOUP32(nb_l, nb_h);
     859        }
     860
     861        return rc;
     862}
     863
    791864/** @}
    792865 */
Note: See TracChangeset for help on using the changeset viewer.