Changeset b5e68c8 in mainline for uspace/lib/block/libblock.c


Ignore:
Timestamp:
2011-05-12T16:49:44Z (14 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
f36787d7
Parents:
e80329d6 (diff), 750636a (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge mainline changes.

File:
1 edited

Legend:

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

    re80329d6 rb5e68c8  
    4444#include <sys/mman.h>
    4545#include <async.h>
    46 #include <ipc/ipc.h>
    4746#include <as.h>
    4847#include <assert.h>
     
    5251#include <macros.h>
    5352#include <mem.h>
     53#include <malloc.h>
     54#include <stdio.h>
    5455#include <sys/typefmt.h>
    5556#include <stacktrace.h>
     
    6667        fibril_mutex_t lock;
    6768        size_t lblock_size;             /**< Logical block size. */
     69        unsigned blocks_cluster;        /**< Physical blocks per block_t */
    6870        unsigned block_count;           /**< Total number of blocks. */
    6971        unsigned blocks_cached;         /**< Number of cached blocks. */
     
    7577typedef struct {
    7678        link_t link;
    77         dev_handle_t dev_handle;
     79        devmap_handle_t devmap_handle;
    7880        int dev_phone;
    7981        fibril_mutex_t comm_area_lock;
     
    9092static int get_block_size(int dev_phone, size_t *bsize);
    9193static int get_num_blocks(int dev_phone, aoff64_t *nblocks);
    92 
    93 static devcon_t *devcon_search(dev_handle_t dev_handle)
     94static aoff64_t ba_ltop(devcon_t *devcon, aoff64_t lba);
     95
     96static devcon_t *devcon_search(devmap_handle_t devmap_handle)
    9497{
    9598        link_t *cur;
     
    98101        for (cur = dcl_head.next; cur != &dcl_head; cur = cur->next) {
    99102                devcon_t *devcon = list_get_instance(cur, devcon_t, link);
    100                 if (devcon->dev_handle == dev_handle) {
     103                if (devcon->devmap_handle == devmap_handle) {
    101104                        fibril_mutex_unlock(&dcl_lock);
    102105                        return devcon;
     
    107110}
    108111
    109 static int devcon_add(dev_handle_t dev_handle, int dev_phone, size_t bsize,
     112static int devcon_add(devmap_handle_t devmap_handle, int dev_phone, size_t bsize,
    110113    void *comm_area, size_t comm_size)
    111114{
     
    121124       
    122125        link_initialize(&devcon->link);
    123         devcon->dev_handle = dev_handle;
     126        devcon->devmap_handle = devmap_handle;
    124127        devcon->dev_phone = dev_phone;
    125128        fibril_mutex_initialize(&devcon->comm_area_lock);
     
    134137        for (cur = dcl_head.next; cur != &dcl_head; cur = cur->next) {
    135138                devcon_t *d = list_get_instance(cur, devcon_t, link);
    136                 if (d->dev_handle == dev_handle) {
     139                if (d->devmap_handle == devmap_handle) {
    137140                        fibril_mutex_unlock(&dcl_lock);
    138141                        free(devcon);
     
    152155}
    153156
    154 int block_init(dev_handle_t dev_handle, size_t comm_size)
     157int block_init(devmap_handle_t devmap_handle, size_t comm_size)
    155158{
    156159        int rc;
     
    165168        }
    166169
    167         dev_phone = devmap_device_connect(dev_handle, IPC_FLAG_BLOCKING);
     170        dev_phone = devmap_device_connect(devmap_handle, IPC_FLAG_BLOCKING);
    168171        if (dev_phone < 0) {
    169172                munmap(comm_area, comm_size);
     
    175178        if (rc != EOK) {
    176179                munmap(comm_area, comm_size);
    177                 ipc_hangup(dev_phone);
     180                async_hangup(dev_phone);
    178181                return rc;
    179182        }
     
    181184        if (get_block_size(dev_phone, &bsize) != EOK) {
    182185                munmap(comm_area, comm_size);
    183                 ipc_hangup(dev_phone);
     186                async_hangup(dev_phone);
    184187                return rc;
    185188        }
    186189       
    187         rc = devcon_add(dev_handle, dev_phone, bsize, comm_area, comm_size);
     190        rc = devcon_add(devmap_handle, dev_phone, bsize, comm_area, comm_size);
    188191        if (rc != EOK) {
    189192                munmap(comm_area, comm_size);
    190                 ipc_hangup(dev_phone);
     193                async_hangup(dev_phone);
    191194                return rc;
    192195        }
     
    195198}
    196199
    197 void block_fini(dev_handle_t dev_handle)
    198 {
    199         devcon_t *devcon = devcon_search(dev_handle);
     200void block_fini(devmap_handle_t devmap_handle)
     201{
     202        devcon_t *devcon = devcon_search(devmap_handle);
    200203        assert(devcon);
    201204       
    202205        if (devcon->cache)
    203                 (void) block_cache_fini(dev_handle);
     206                (void) block_cache_fini(devmap_handle);
    204207
    205208        devcon_remove(devcon);
     
    209212
    210213        munmap(devcon->comm_area, devcon->comm_size);
    211         ipc_hangup(devcon->dev_phone);
     214        async_hangup(devcon->dev_phone);
    212215
    213216        free(devcon);   
    214217}
    215218
    216 int block_bb_read(dev_handle_t dev_handle, aoff64_t ba)
     219int block_bb_read(devmap_handle_t devmap_handle, aoff64_t ba)
    217220{
    218221        void *bb_buf;
    219222        int rc;
    220223
    221         devcon_t *devcon = devcon_search(dev_handle);
     224        devcon_t *devcon = devcon_search(devmap_handle);
    222225        if (!devcon)
    223226                return ENOENT;
     
    244247}
    245248
    246 void *block_bb_get(dev_handle_t dev_handle)
    247 {
    248         devcon_t *devcon = devcon_search(dev_handle);
     249void *block_bb_get(devmap_handle_t devmap_handle)
     250{
     251        devcon_t *devcon = devcon_search(devmap_handle);
    249252        assert(devcon);
    250253        return devcon->bb_buf;
     
    259262{
    260263        block_t *b = hash_table_get_instance(item, block_t, hash_link);
    261         return b->boff == *key;
     264        return b->lba == *key;
    262265}
    263266
     
    272275};
    273276
    274 int block_cache_init(dev_handle_t dev_handle, size_t size, unsigned blocks,
     277int block_cache_init(devmap_handle_t devmap_handle, size_t size, unsigned blocks,
    275278    enum cache_mode mode)
    276279{
    277         devcon_t *devcon = devcon_search(dev_handle);
     280        devcon_t *devcon = devcon_search(devmap_handle);
    278281        cache_t *cache;
    279282        if (!devcon)
     
    292295        cache->mode = mode;
    293296
    294         /* No block size translation a.t.m. */
    295         assert(cache->lblock_size == devcon->pblock_size);
     297        /* Allow 1:1 or small-to-large block size translation */
     298        if (cache->lblock_size % devcon->pblock_size != 0) {
     299                free(cache);
     300                return ENOTSUP;
     301        }
     302
     303        cache->blocks_cluster = cache->lblock_size / devcon->pblock_size;
    296304
    297305        if (!hash_table_create(&cache->block_hash, CACHE_BUCKETS, 1,
     
    305313}
    306314
    307 int block_cache_fini(dev_handle_t dev_handle)
    308 {
    309         devcon_t *devcon = devcon_search(dev_handle);
     315int block_cache_fini(devmap_handle_t devmap_handle)
     316{
     317        devcon_t *devcon = devcon_search(devmap_handle);
    310318        cache_t *cache;
    311319        int rc;
     
    329337                if (b->dirty) {
    330338                        memcpy(devcon->comm_area, b->data, b->size);
    331                         rc = write_blocks(devcon, b->boff, 1);
     339                        rc = write_blocks(devcon, b->pba, cache->blocks_cluster);
    332340                        if (rc != EOK)
    333341                                return rc;
    334342                }
    335343
    336                 unsigned long key = b->boff;
     344                unsigned long key = b->lba;
    337345                hash_table_remove(&cache->block_hash, &key, 1);
    338346               
     
    374382 * @param block                 Pointer to where the function will store the
    375383 *                              block pointer on success.
    376  * @param dev_handle            Device handle of the block device.
    377  * @param boff                  Block offset.
     384 * @param devmap_handle         Device handle of the block device.
     385 * @param ba                    Block address (logical).
    378386 * @param flags                 If BLOCK_FLAGS_NOREAD is specified, block_get()
    379387 *                              will not read the contents of the block from the
     
    382390 * @return                      EOK on success or a negative error code.
    383391 */
    384 int block_get(block_t **block, dev_handle_t dev_handle, aoff64_t boff, int flags)
     392int block_get(block_t **block, devmap_handle_t devmap_handle, aoff64_t ba, int flags)
    385393{
    386394        devcon_t *devcon;
     
    388396        block_t *b;
    389397        link_t *l;
    390         unsigned long key = boff;
     398        unsigned long key = ba;
    391399        int rc;
    392400       
    393         devcon = devcon_search(dev_handle);
     401        devcon = devcon_search(devmap_handle);
    394402
    395403        assert(devcon);
     
    405413        l = hash_table_find(&cache->block_hash, &key);
    406414        if (l) {
     415found:
    407416                /*
    408417                 * We found the block in the cache.
     
    432441                        if (!b->data) {
    433442                                free(b);
     443                                b = NULL;
    434444                                goto recycle;
    435445                        }
     
    465475                                fibril_mutex_lock(&devcon->comm_area_lock);
    466476                                memcpy(devcon->comm_area, b->data, b->size);
    467                                 rc = write_blocks(devcon, b->boff, 1);
     477                                rc = write_blocks(devcon, b->pba,
     478                                    cache->blocks_cluster);
    468479                                fibril_mutex_unlock(&devcon->comm_area_lock);
    469480                                if (rc != EOK) {
     
    486497                                        goto retry;
    487498                                }
     499                                l = hash_table_find(&cache->block_hash, &key);
     500                                if (l) {
     501                                        /*
     502                                         * Someone else must have already
     503                                         * instantiated the block while we were
     504                                         * not holding the cache lock.
     505                                         * Leave the recycled block on the
     506                                         * freelist and continue as if we
     507                                         * found the block of interest during
     508                                         * the first try.
     509                                         */
     510                                        fibril_mutex_unlock(&b->lock);
     511                                        goto found;
     512                                }
    488513
    489514                        }
     
    495520                         */
    496521                        list_remove(&b->free_link);
    497                         temp_key = b->boff;
     522                        temp_key = b->lba;
    498523                        hash_table_remove(&cache->block_hash, &temp_key, 1);
    499524                }
    500525
    501526                block_initialize(b);
    502                 b->dev_handle = dev_handle;
     527                b->devmap_handle = devmap_handle;
    503528                b->size = cache->lblock_size;
    504                 b->boff = boff;
     529                b->lba = ba;
     530                b->pba = ba_ltop(devcon, b->lba);
    505531                hash_table_insert(&cache->block_hash, &key, &b->hash_link);
    506532
     
    519545                         */
    520546                        fibril_mutex_lock(&devcon->comm_area_lock);
    521                         rc = read_blocks(devcon, b->boff, 1);
     547                        rc = read_blocks(devcon, b->pba, cache->blocks_cluster);
    522548                        memcpy(b->data, devcon->comm_area, cache->lblock_size);
    523549                        fibril_mutex_unlock(&devcon->comm_area_lock);
     
    549575int block_put(block_t *block)
    550576{
    551         devcon_t *devcon = devcon_search(block->dev_handle);
     577        devcon_t *devcon = devcon_search(block->devmap_handle);
    552578        cache_t *cache;
    553579        unsigned blocks_cached;
     
    557583        assert(devcon);
    558584        assert(devcon->cache);
     585        assert(block->refcnt >= 1);
    559586
    560587        cache = devcon->cache;
     
    580607                fibril_mutex_lock(&devcon->comm_area_lock);
    581608                memcpy(devcon->comm_area, block->data, block->size);
    582                 rc = write_blocks(devcon, block->boff, 1);
     609                rc = write_blocks(devcon, block->pba, cache->blocks_cluster);
    583610                fibril_mutex_unlock(&devcon->comm_area_lock);
    584611                block->dirty = false;
     
    614641                         * Take the block out of the cache and free it.
    615642                         */
    616                         unsigned long key = block->boff;
     643                        unsigned long key = block->lba;
    617644                        hash_table_remove(&cache->block_hash, &key, 1);
     645                        fibril_mutex_unlock(&block->lock);
     646                        free(block->data);
    618647                        free(block);
    619                         free(block->data);
    620648                        cache->blocks_cached--;
    621649                        fibril_mutex_unlock(&cache->lock);
     
    645673/** Read sequential data from a block device.
    646674 *
    647  * @param dev_handle    Device handle of the block device.
     675 * @param devmap_handle Device handle of the block device.
    648676 * @param bufpos        Pointer to the first unread valid offset within the
    649677 *                      communication buffer.
     
    657685 * @return              EOK on success or a negative return code on failure.
    658686 */
    659 int block_seqread(dev_handle_t dev_handle, size_t *bufpos, size_t *buflen,
     687int block_seqread(devmap_handle_t devmap_handle, size_t *bufpos, size_t *buflen,
    660688    aoff64_t *pos, void *dst, size_t size)
    661689{
     
    665693        devcon_t *devcon;
    666694
    667         devcon = devcon_search(dev_handle);
     695        devcon = devcon_search(devmap_handle);
    668696        assert(devcon);
    669697        block_size = devcon->pblock_size;
     
    711739/** Read blocks directly from device (bypass cache).
    712740 *
    713  * @param dev_handle    Device handle of the block device.
    714  * @param ba            Address of first block.
     741 * @param devmap_handle Device handle of the block device.
     742 * @param ba            Address of first block (physical).
    715743 * @param cnt           Number of blocks.
    716744 * @param src           Buffer for storing the data.
     
    718746 * @return              EOK on success or negative error code on failure.
    719747 */
    720 int block_read_direct(dev_handle_t dev_handle, aoff64_t ba, size_t cnt, void *buf)
     748int block_read_direct(devmap_handle_t devmap_handle, aoff64_t ba, size_t cnt, void *buf)
    721749{
    722750        devcon_t *devcon;
    723751        int rc;
    724752
    725         devcon = devcon_search(dev_handle);
     753        devcon = devcon_search(devmap_handle);
    726754        assert(devcon);
    727755       
     
    739767/** Write blocks directly to device (bypass cache).
    740768 *
    741  * @param dev_handle    Device handle of the block device.
    742  * @param ba            Address of first block.
     769 * @param devmap_handle Device handle of the block device.
     770 * @param ba            Address of first block (physical).
    743771 * @param cnt           Number of blocks.
    744772 * @param src           The data to be written.
     
    746774 * @return              EOK on success or negative error code on failure.
    747775 */
    748 int block_write_direct(dev_handle_t dev_handle, aoff64_t ba, size_t cnt,
     776int block_write_direct(devmap_handle_t devmap_handle, aoff64_t ba, size_t cnt,
    749777    const void *data)
    750778{
     
    752780        int rc;
    753781
    754         devcon = devcon_search(dev_handle);
     782        devcon = devcon_search(devmap_handle);
    755783        assert(devcon);
    756784       
     
    767795/** Get device block size.
    768796 *
    769  * @param dev_handle    Device handle of the block device.
     797 * @param devmap_handle Device handle of the block device.
    770798 * @param bsize         Output block size.
    771799 *
    772800 * @return              EOK on success or negative error code on failure.
    773801 */
    774 int block_get_bsize(dev_handle_t dev_handle, size_t *bsize)
     802int block_get_bsize(devmap_handle_t devmap_handle, size_t *bsize)
    775803{
    776804        devcon_t *devcon;
    777805
    778         devcon = devcon_search(dev_handle);
     806        devcon = devcon_search(devmap_handle);
    779807        assert(devcon);
    780808       
     
    784812/** Get number of blocks on device.
    785813 *
    786  * @param dev_handle    Device handle of the block device.
     814 * @param devmap_handle Device handle of the block device.
    787815 * @param nblocks       Output number of blocks.
    788816 *
    789817 * @return              EOK on success or negative error code on failure.
    790818 */
    791 int block_get_nblocks(dev_handle_t dev_handle, aoff64_t *nblocks)
     819int block_get_nblocks(devmap_handle_t devmap_handle, aoff64_t *nblocks)
    792820{
    793821        devcon_t *devcon;
    794822
    795         devcon = devcon_search(dev_handle);
     823        devcon = devcon_search(devmap_handle);
    796824        assert(devcon);
    797825       
     
    816844            UPPER32(ba), cnt);
    817845        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);
     846                printf("Error %d reading %zu blocks starting at block %" PRIuOFF64
     847                    " from device handle %" PRIun "\n", rc, cnt, ba,
     848                    devcon->devmap_handle);
    821849#ifndef NDEBUG
    822850                stacktrace_print();
     
    843871            UPPER32(ba), cnt);
    844872        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);
     873                printf("Error %d writing %zu blocks starting at block %" PRIuOFF64
     874                    " to device handle %" PRIun "\n", rc, cnt, ba, devcon->devmap_handle);
    847875#ifndef NDEBUG
    848876                stacktrace_print();
     
    855883static int get_block_size(int dev_phone, size_t *bsize)
    856884{
    857         ipcarg_t bs;
     885        sysarg_t bs;
    858886        int rc;
    859887
     
    868896static int get_num_blocks(int dev_phone, aoff64_t *nblocks)
    869897{
    870         ipcarg_t nb_l, nb_h;
     898        sysarg_t nb_l, nb_h;
    871899        int rc;
    872900
     
    879907}
    880908
     909/** Convert logical block address to physical block address. */
     910static aoff64_t ba_ltop(devcon_t *devcon, aoff64_t lba)
     911{
     912        assert(devcon->cache != NULL);
     913        return lba * devcon->cache->blocks_cluster;
     914}
     915
    881916/** @}
    882917 */
Note: See TracChangeset for help on using the changeset viewer.