Ignore:
File:
1 edited

Legend:

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

    r7a72ce1a r79ae36dd  
    3939#include "libblock.h"
    4040#include "../../srv/vfs/vfs.h"
    41 #include <ipc/loc.h>
     41#include <ipc/devmap.h>
    4242#include <ipc/bd.h>
    4343#include <ipc/services.h>
     
    6060static FIBRIL_MUTEX_INITIALIZE(dcl_lock);
    6161/** Device connection list head. */
    62 static LIST_INITIALIZE(dcl);
     62static LIST_INITIALIZE(dcl_head);
    6363
    6464#define CACHE_BUCKETS_LOG2  10
     
    7272        unsigned blocks_cached;   /**< Number of cached blocks. */
    7373        hash_table_t block_hash;
    74         list_t free_list;
     74        link_t free_head;
    7575        enum cache_mode mode;
    7676} cache_t;
     
    7878typedef struct {
    7979        link_t link;
    80         service_id_t service_id;
     80        devmap_handle_t devmap_handle;
    8181        async_sess_t *sess;
    8282        fibril_mutex_t comm_area_lock;
     
    9393static int get_block_size(async_sess_t *, size_t *);
    9494static int get_num_blocks(async_sess_t *, aoff64_t *);
    95 static int read_toc(async_sess_t *, uint8_t);
    9695static aoff64_t ba_ltop(devcon_t *, aoff64_t);
    9796
    98 static devcon_t *devcon_search(service_id_t service_id)
    99 {
     97static devcon_t *devcon_search(devmap_handle_t devmap_handle)
     98{
     99        link_t *cur;
     100       
    100101        fibril_mutex_lock(&dcl_lock);
    101102       
    102         list_foreach(dcl, cur) {
     103        for (cur = dcl_head.next; cur != &dcl_head; cur = cur->next) {
    103104                devcon_t *devcon = list_get_instance(cur, devcon_t, link);
    104                 if (devcon->service_id == service_id) {
     105                if (devcon->devmap_handle == devmap_handle) {
    105106                        fibril_mutex_unlock(&dcl_lock);
    106107                        return devcon;
     
    112113}
    113114
    114 static int devcon_add(service_id_t service_id, async_sess_t *sess,
     115static int devcon_add(devmap_handle_t devmap_handle, async_sess_t *sess,
    115116    size_t bsize, void *comm_area, size_t comm_size)
    116117{
     118        link_t *cur;
    117119        devcon_t *devcon;
    118120       
     
    125127       
    126128        link_initialize(&devcon->link);
    127         devcon->service_id = service_id;
     129        devcon->devmap_handle = devmap_handle;
    128130        devcon->sess = sess;
    129131        fibril_mutex_initialize(&devcon->comm_area_lock);
     
    136138       
    137139        fibril_mutex_lock(&dcl_lock);
    138         list_foreach(dcl, cur) {
     140        for (cur = dcl_head.next; cur != &dcl_head; cur = cur->next) {
    139141                devcon_t *d = list_get_instance(cur, devcon_t, link);
    140                 if (d->service_id == service_id) {
     142                if (d->devmap_handle == devmap_handle) {
    141143                        fibril_mutex_unlock(&dcl_lock);
    142144                        free(devcon);
     
    144146                }
    145147        }
    146         list_append(&devcon->link, &dcl);
     148        list_append(&devcon->link, &dcl_head);
    147149        fibril_mutex_unlock(&dcl_lock);
    148150        return EOK;
     
    156158}
    157159
    158 int block_init(exch_mgmt_t mgmt, service_id_t service_id,
     160int block_init(exch_mgmt_t mgmt, devmap_handle_t devmap_handle,
    159161    size_t comm_size)
    160162{
     
    164166                return ENOMEM;
    165167       
    166         async_sess_t *sess = loc_service_connect(mgmt, service_id,
     168        async_sess_t *sess = devmap_device_connect(mgmt, devmap_handle,
    167169            IPC_FLAG_BLOCKING);
    168170        if (!sess) {
     
    191193        }
    192194       
    193         rc = devcon_add(service_id, sess, bsize, comm_area, comm_size);
     195        rc = devcon_add(devmap_handle, sess, bsize, comm_area, comm_size);
    194196        if (rc != EOK) {
    195197                munmap(comm_area, comm_size);
     
    201203}
    202204
    203 void block_fini(service_id_t service_id)
    204 {
    205         devcon_t *devcon = devcon_search(service_id);
     205void block_fini(devmap_handle_t devmap_handle)
     206{
     207        devcon_t *devcon = devcon_search(devmap_handle);
    206208        assert(devcon);
    207209       
    208210        if (devcon->cache)
    209                 (void) block_cache_fini(service_id);
     211                (void) block_cache_fini(devmap_handle);
    210212       
    211213        devcon_remove(devcon);
     
    220222}
    221223
    222 int block_bb_read(service_id_t service_id, aoff64_t ba)
     224int block_bb_read(devmap_handle_t devmap_handle, aoff64_t ba)
    223225{
    224226        void *bb_buf;
    225227        int rc;
    226228
    227         devcon_t *devcon = devcon_search(service_id);
     229        devcon_t *devcon = devcon_search(devmap_handle);
    228230        if (!devcon)
    229231                return ENOENT;
     
    250252}
    251253
    252 void *block_bb_get(service_id_t service_id)
    253 {
    254         devcon_t *devcon = devcon_search(service_id);
     254void *block_bb_get(devmap_handle_t devmap_handle)
     255{
     256        devcon_t *devcon = devcon_search(devmap_handle);
    255257        assert(devcon);
    256258        return devcon->bb_buf;
     
    259261static hash_index_t cache_hash(unsigned long *key)
    260262{
    261         return MERGE_LOUP32(key[0], key[1]) & (CACHE_BUCKETS - 1);
     263        return *key & (CACHE_BUCKETS - 1);
    262264}
    263265
     
    265267{
    266268        block_t *b = hash_table_get_instance(item, block_t, hash_link);
    267         return b->lba == MERGE_LOUP32(key[0], key[1]);
     269        return b->lba == *key;
    268270}
    269271
     
    278280};
    279281
    280 int block_cache_init(service_id_t service_id, size_t size, unsigned blocks,
     282int block_cache_init(devmap_handle_t devmap_handle, size_t size, unsigned blocks,
    281283    enum cache_mode mode)
    282284{
    283         devcon_t *devcon = devcon_search(service_id);
     285        devcon_t *devcon = devcon_search(devmap_handle);
    284286        cache_t *cache;
    285287        if (!devcon)
     
    292294       
    293295        fibril_mutex_initialize(&cache->lock);
    294         list_initialize(&cache->free_list);
     296        list_initialize(&cache->free_head);
    295297        cache->lblock_size = size;
    296298        cache->block_count = blocks;
     
    306308        cache->blocks_cluster = cache->lblock_size / devcon->pblock_size;
    307309
    308         if (!hash_table_create(&cache->block_hash, CACHE_BUCKETS, 2,
     310        if (!hash_table_create(&cache->block_hash, CACHE_BUCKETS, 1,
    309311            &cache_ops)) {
    310312                free(cache);
     
    316318}
    317319
    318 int block_cache_fini(service_id_t service_id)
    319 {
    320         devcon_t *devcon = devcon_search(service_id);
     320int block_cache_fini(devmap_handle_t devmap_handle)
     321{
     322        devcon_t *devcon = devcon_search(devmap_handle);
    321323        cache_t *cache;
    322324        int rc;
     
    333335         * bother with the cache and block locks because we are single-threaded.
    334336         */
    335         while (!list_empty(&cache->free_list)) {
    336                 block_t *b = list_get_instance(list_first(&cache->free_list),
     337        while (!list_empty(&cache->free_head)) {
     338                block_t *b = list_get_instance(cache->free_head.next,
    337339                    block_t, free_link);
    338340
     
    345347                }
    346348
    347                 unsigned long key[2] = {
    348                         LOWER32(b->lba),
    349                         UPPER32(b->lba)
    350                 };
    351                 hash_table_remove(&cache->block_hash, key, 2);
     349                unsigned long key = b->lba;
     350                hash_table_remove(&cache->block_hash, &key, 1);
    352351               
    353352                free(b->data);
     
    368367        if (cache->blocks_cached < CACHE_LO_WATERMARK)
    369368                return true;
    370         if (!list_empty(&cache->free_list))
     369        if (!list_empty(&cache->free_head))
    371370                return false;
    372371        return true;
     
    388387 * @param block                 Pointer to where the function will store the
    389388 *                              block pointer on success.
    390  * @param service_id            Service ID of the block device.
     389 * @param devmap_handle         Device handle of the block device.
    391390 * @param ba                    Block address (logical).
    392391 * @param flags                 If BLOCK_FLAGS_NOREAD is specified, block_get()
     
    396395 * @return                      EOK on success or a negative error code.
    397396 */
    398 int block_get(block_t **block, service_id_t service_id, aoff64_t ba, int flags)
     397int block_get(block_t **block, devmap_handle_t devmap_handle, aoff64_t ba, int flags)
    399398{
    400399        devcon_t *devcon;
     
    402401        block_t *b;
    403402        link_t *l;
    404         unsigned long key[2] = {
    405                 LOWER32(ba),
    406                 UPPER32(ba)
    407         };
    408 
     403        unsigned long key = ba;
    409404        int rc;
    410405       
    411         devcon = devcon_search(service_id);
     406        devcon = devcon_search(devmap_handle);
    412407
    413408        assert(devcon);
     
    421416
    422417        fibril_mutex_lock(&cache->lock);
    423         l = hash_table_find(&cache->block_hash, key);
     418        l = hash_table_find(&cache->block_hash, &key);
    424419        if (l) {
    425420found:
     
    459454                         * Try to recycle a block from the free list.
    460455                         */
     456                        unsigned long temp_key;
    461457recycle:
    462                         if (list_empty(&cache->free_list)) {
     458                        if (list_empty(&cache->free_head)) {
    463459                                fibril_mutex_unlock(&cache->lock);
    464460                                rc = ENOMEM;
    465461                                goto out;
    466462                        }
    467                         l = list_first(&cache->free_list);
     463                        l = cache->free_head.next;
    468464                        b = list_get_instance(l, block_t, free_link);
    469465
     
    480476                                 */
    481477                                list_remove(&b->free_link);
    482                                 list_append(&b->free_link, &cache->free_list);
     478                                list_append(&b->free_link, &cache->free_head);
    483479                                fibril_mutex_unlock(&cache->lock);
    484480                                fibril_mutex_lock(&devcon->comm_area_lock);
     
    506502                                        goto retry;
    507503                                }
    508                                 l = hash_table_find(&cache->block_hash, key);
     504                                l = hash_table_find(&cache->block_hash, &key);
    509505                                if (l) {
    510506                                        /*
     
    529525                         */
    530526                        list_remove(&b->free_link);
    531                         unsigned long temp_key[2] = {
    532                                 LOWER32(b->lba),
    533                                 UPPER32(b->lba)
    534                         };
    535                         hash_table_remove(&cache->block_hash, temp_key, 2);
     527                        temp_key = b->lba;
     528                        hash_table_remove(&cache->block_hash, &temp_key, 1);
    536529                }
    537530
    538531                block_initialize(b);
    539                 b->service_id = service_id;
     532                b->devmap_handle = devmap_handle;
    540533                b->size = cache->lblock_size;
    541534                b->lba = ba;
    542535                b->pba = ba_ltop(devcon, b->lba);
    543                 hash_table_insert(&cache->block_hash, key, &b->hash_link);
     536                hash_table_insert(&cache->block_hash, &key, &b->hash_link);
    544537
    545538                /*
     
    587580int block_put(block_t *block)
    588581{
    589         devcon_t *devcon = devcon_search(block->service_id);
     582        devcon_t *devcon = devcon_search(block->devmap_handle);
    590583        cache_t *cache;
    591584        unsigned blocks_cached;
     
    653646                         * Take the block out of the cache and free it.
    654647                         */
    655                         unsigned long key[2] = {
    656                                 LOWER32(block->lba),
    657                                 UPPER32(block->lba)
    658                         };
    659                         hash_table_remove(&cache->block_hash, key, 2);
     648                        unsigned long key = block->lba;
     649                        hash_table_remove(&cache->block_hash, &key, 1);
    660650                        fibril_mutex_unlock(&block->lock);
    661651                        free(block->data);
     
    678668                        goto retry;
    679669                }
    680                 list_append(&block->free_link, &cache->free_list);
     670                list_append(&block->free_link, &cache->free_head);
    681671        }
    682672        fibril_mutex_unlock(&block->lock);
     
    688678/** Read sequential data from a block device.
    689679 *
    690  * @param service_id    Service ID of the block device.
     680 * @param devmap_handle Device handle of the block device.
    691681 * @param bufpos        Pointer to the first unread valid offset within the
    692682 *                      communication buffer.
     
    700690 * @return              EOK on success or a negative return code on failure.
    701691 */
    702 int block_seqread(service_id_t service_id, size_t *bufpos, size_t *buflen,
     692int block_seqread(devmap_handle_t devmap_handle, size_t *bufpos, size_t *buflen,
    703693    aoff64_t *pos, void *dst, size_t size)
    704694{
     
    708698        devcon_t *devcon;
    709699
    710         devcon = devcon_search(service_id);
     700        devcon = devcon_search(devmap_handle);
    711701        assert(devcon);
    712702        block_size = devcon->pblock_size;
     
    754744/** Read blocks directly from device (bypass cache).
    755745 *
    756  * @param service_id    Service ID of the block device.
     746 * @param devmap_handle Device handle of the block device.
    757747 * @param ba            Address of first block (physical).
    758748 * @param cnt           Number of blocks.
     
    761751 * @return              EOK on success or negative error code on failure.
    762752 */
    763 int block_read_direct(service_id_t service_id, aoff64_t ba, size_t cnt, void *buf)
     753int block_read_direct(devmap_handle_t devmap_handle, aoff64_t ba, size_t cnt, void *buf)
    764754{
    765755        devcon_t *devcon;
    766756        int rc;
    767757
    768         devcon = devcon_search(service_id);
     758        devcon = devcon_search(devmap_handle);
    769759        assert(devcon);
    770760       
     
    782772/** Write blocks directly to device (bypass cache).
    783773 *
    784  * @param service_id    Service ID of the block device.
     774 * @param devmap_handle Device handle of the block device.
    785775 * @param ba            Address of first block (physical).
    786776 * @param cnt           Number of blocks.
     
    789779 * @return              EOK on success or negative error code on failure.
    790780 */
    791 int block_write_direct(service_id_t service_id, aoff64_t ba, size_t cnt,
     781int block_write_direct(devmap_handle_t devmap_handle, aoff64_t ba, size_t cnt,
    792782    const void *data)
    793783{
     
    795785        int rc;
    796786
    797         devcon = devcon_search(service_id);
     787        devcon = devcon_search(devmap_handle);
    798788        assert(devcon);
    799789       
     
    810800/** Get device block size.
    811801 *
    812  * @param service_id    Service ID of the block device.
     802 * @param devmap_handle Device handle of the block device.
    813803 * @param bsize         Output block size.
    814804 *
    815805 * @return              EOK on success or negative error code on failure.
    816806 */
    817 int block_get_bsize(service_id_t service_id, size_t *bsize)
     807int block_get_bsize(devmap_handle_t devmap_handle, size_t *bsize)
    818808{
    819809        devcon_t *devcon;
    820810
    821         devcon = devcon_search(service_id);
     811        devcon = devcon_search(devmap_handle);
    822812        assert(devcon);
    823813       
     
    827817/** Get number of blocks on device.
    828818 *
    829  * @param service_id    Service ID of the block device.
     819 * @param devmap_handle Device handle of the block device.
    830820 * @param nblocks       Output number of blocks.
    831821 *
    832822 * @return              EOK on success or negative error code on failure.
    833823 */
    834 int block_get_nblocks(service_id_t service_id, aoff64_t *nblocks)
    835 {
    836         devcon_t *devcon = devcon_search(service_id);
     824int block_get_nblocks(devmap_handle_t devmap_handle, aoff64_t *nblocks)
     825{
     826        devcon_t *devcon = devcon_search(devmap_handle);
    837827        assert(devcon);
    838828       
     
    842832/** Read bytes directly from the device (bypass cache)
    843833 *
    844  * @param service_id    Service ID of the block device.
     834 * @param devmap_handle Device handle of the block device.
    845835 * @param abs_offset    Absolute offset in bytes where to start reading
    846836 * @param bytes                 Number of bytes to read
     
    849839 * @return              EOK on success or negative error code on failure.
    850840 */
    851 int block_read_bytes_direct(service_id_t service_id, aoff64_t abs_offset,
     841int block_read_bytes_direct(devmap_handle_t devmap_handle, aoff64_t abs_offset,
    852842    size_t bytes, void *data)
    853843{
     
    861851        size_t offset;
    862852       
    863         rc = block_get_bsize(service_id, &phys_block_size);
     853        rc = block_get_bsize(devmap_handle, &phys_block_size);
    864854        if (rc != EOK) {
    865855                return rc;
     
    879869        }
    880870       
    881         rc = block_read_direct(service_id, first_block, blocks, buffer);
     871        rc = block_read_direct(devmap_handle, first_block, blocks, buffer);
    882872        if (rc != EOK) {
    883873                free(buffer);
     
    890880       
    891881        return EOK;
    892 }
    893 
    894 /** Get TOC from device.
    895  *
    896  * @param service_id Service ID of the block device.
    897  * @param session    Starting session.
    898  * @param data       Buffer to read TOC into.
    899  *
    900  * @return EOK on success.
    901  * @return Error code on failure.
    902  *
    903  */
    904 int block_get_toc(service_id_t service_id, uint8_t session, void *data)
    905 {
    906         devcon_t *devcon = devcon_search(service_id);
    907         assert(devcon);
    908        
    909         fibril_mutex_lock(&devcon->comm_area_lock);
    910        
    911         int rc = read_toc(devcon->sess, session);
    912         if (rc == EOK)
    913                 memcpy(data, devcon->comm_area, devcon->pblock_size);
    914        
    915         fibril_mutex_unlock(&devcon->comm_area_lock);
    916        
    917         return rc;
    918882}
    919883
     
    939903                printf("Error %d reading %zu blocks starting at block %" PRIuOFF64
    940904                    " from device handle %" PRIun "\n", rc, cnt, ba,
    941                     devcon->service_id);
     905                    devcon->devmap_handle);
    942906#ifndef NDEBUG
    943907                stacktrace_print();
     
    968932        if (rc != EOK) {
    969933                printf("Error %d writing %zu blocks starting at block %" PRIuOFF64
    970                     " to device handle %" PRIun "\n", rc, cnt, ba, devcon->service_id);
     934                    " to device handle %" PRIun "\n", rc, cnt, ba, devcon->devmap_handle);
    971935#ifndef NDEBUG
    972936                stacktrace_print();
     
    1008972}
    1009973
    1010 /** Get TOC from block device. */
    1011 static int read_toc(async_sess_t *sess, uint8_t session)
    1012 {
    1013         async_exch_t *exch = async_exchange_begin(sess);
    1014         int rc = async_req_1_0(exch, BD_READ_TOC, session);
    1015         async_exchange_end(exch);
    1016 
    1017         return rc;
    1018 }
    1019 
    1020974/** Convert logical block address to physical block address. */
    1021975static aoff64_t ba_ltop(devcon_t *devcon, aoff64_t lba)
Note: See TracChangeset for help on using the changeset viewer.