Ignore:
File:
1 edited

Legend:

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

    r00b1d20e r7a56b1ed  
    5050#include <adt/list.h>
    5151#include <adt/hash_table.h>
    52 #include <macros.h>
    5352#include <mem.h>
    5453
     
    6362typedef struct {
    6463        fibril_mutex_t lock;
    65         size_t lblock_size;             /**< Logical block size. */
     64        size_t block_size;              /**< Block size. */
    6665        unsigned block_count;           /**< Total number of blocks. */
    6766        unsigned blocks_cached;         /**< Number of cached blocks. */
     
    7574        dev_handle_t dev_handle;
    7675        int dev_phone;
    77         fibril_mutex_t comm_area_lock;
    78         void *comm_area;
    79         size_t comm_size;
     76        fibril_mutex_t com_area_lock;
     77        void *com_area;
     78        size_t com_size;
    8079        void *bb_buf;
    81         bn_t bb_addr;
    82         size_t pblock_size;             /**< Physical block size. */
     80        off_t bb_off;
     81        size_t bb_size;
    8382        cache_t *cache;
    8483} devcon_t;
    8584
    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);
    88 static int get_block_size(int dev_phone, size_t *bsize);
     85static int read_block(devcon_t *devcon, bn_t boff, size_t block_size);
     86static int write_block(devcon_t *devcon, bn_t boff, size_t block_size);
    8987
    9088static devcon_t *devcon_search(dev_handle_t dev_handle)
     
    104102}
    105103
    106 static int devcon_add(dev_handle_t dev_handle, int dev_phone, size_t bsize,
    107     void *comm_area, size_t comm_size)
     104static int devcon_add(dev_handle_t dev_handle, int dev_phone, void *com_area,
     105   size_t com_size)
    108106{
    109107        link_t *cur;
    110108        devcon_t *devcon;
    111 
    112         if (comm_size < bsize)
    113                 return EINVAL;
    114109
    115110        devcon = malloc(sizeof(devcon_t));
     
    120115        devcon->dev_handle = dev_handle;
    121116        devcon->dev_phone = dev_phone;
    122         fibril_mutex_initialize(&devcon->comm_area_lock);
    123         devcon->comm_area = comm_area;
    124         devcon->comm_size = comm_size;
     117        fibril_mutex_initialize(&devcon->com_area_lock);
     118        devcon->com_area = com_area;
     119        devcon->com_size = com_size;
    125120        devcon->bb_buf = NULL;
    126         devcon->bb_addr = 0;
    127         devcon->pblock_size = bsize;
     121        devcon->bb_off = 0;
     122        devcon->bb_size = 0;
    128123        devcon->cache = NULL;
    129124
     
    149144}
    150145
    151 int block_init(dev_handle_t dev_handle, size_t comm_size)
     146int block_init(dev_handle_t dev_handle, size_t com_size)
    152147{
    153148        int rc;
    154149        int dev_phone;
    155         void *comm_area;
    156         size_t bsize;
    157 
    158         comm_area = mmap(NULL, comm_size, PROTO_READ | PROTO_WRITE,
     150        void *com_area;
     151       
     152        com_area = mmap(NULL, com_size, PROTO_READ | PROTO_WRITE,
    159153            MAP_ANONYMOUS | MAP_PRIVATE, 0, 0);
    160         if (!comm_area) {
     154        if (!com_area) {
    161155                return ENOMEM;
    162156        }
     
    164158        dev_phone = devmap_device_connect(dev_handle, IPC_FLAG_BLOCKING);
    165159        if (dev_phone < 0) {
    166                 munmap(comm_area, comm_size);
     160                munmap(com_area, com_size);
    167161                return dev_phone;
    168162        }
    169163
    170         rc = ipc_share_out_start(dev_phone, comm_area,
     164        rc = ipc_share_out_start(dev_phone, com_area,
    171165            AS_AREA_READ | AS_AREA_WRITE);
    172166        if (rc != EOK) {
    173                 munmap(comm_area, comm_size);
     167                munmap(com_area, com_size);
    174168                ipc_hangup(dev_phone);
    175169                return rc;
    176170        }
    177 
    178         if (get_block_size(dev_phone, &bsize) != EOK) {
    179                 munmap(comm_area, comm_size);
    180                 ipc_hangup(dev_phone);
    181                 return rc;
    182         }
    183        
    184         rc = devcon_add(dev_handle, dev_phone, bsize, comm_area, comm_size);
     171       
     172        rc = devcon_add(dev_handle, dev_phone, com_area, com_size);
    185173        if (rc != EOK) {
    186                 munmap(comm_area, comm_size);
     174                munmap(com_area, com_size);
    187175                ipc_hangup(dev_phone);
    188176                return rc;
     
    207195        }
    208196
    209         munmap(devcon->comm_area, devcon->comm_size);
     197        munmap(devcon->com_area, devcon->com_size);
    210198        ipc_hangup(devcon->dev_phone);
    211199
     
    213201}
    214202
    215 int block_bb_read(dev_handle_t dev_handle, bn_t ba)
     203int block_bb_read(dev_handle_t dev_handle, off_t off, size_t size)
    216204{
    217205        void *bb_buf;
     
    223211        if (devcon->bb_buf)
    224212                return EEXIST;
    225         bb_buf = malloc(devcon->pblock_size);
     213        bb_buf = malloc(size);
    226214        if (!bb_buf)
    227215                return ENOMEM;
    228 
    229         fibril_mutex_lock(&devcon->comm_area_lock);
    230         rc = read_blocks(devcon, 0, 1);
     216       
     217        fibril_mutex_lock(&devcon->com_area_lock);
     218        rc = read_block(devcon, 0, size);
    231219        if (rc != EOK) {
    232                 fibril_mutex_unlock(&devcon->comm_area_lock);
     220                fibril_mutex_unlock(&devcon->com_area_lock);
    233221                free(bb_buf);
    234222                return rc;
    235223        }
    236         memcpy(bb_buf, devcon->comm_area, devcon->pblock_size);
    237         fibril_mutex_unlock(&devcon->comm_area_lock);
     224        memcpy(bb_buf, devcon->com_area, size);
     225        fibril_mutex_unlock(&devcon->com_area_lock);
    238226
    239227        devcon->bb_buf = bb_buf;
    240         devcon->bb_addr = ba;
     228        devcon->bb_off = off;
     229        devcon->bb_size = size;
    241230
    242231        return EOK;
     
    286275        fibril_mutex_initialize(&cache->lock);
    287276        list_initialize(&cache->free_head);
    288         cache->lblock_size = size;
     277        cache->block_size = size;
    289278        cache->block_count = blocks;
    290279        cache->blocks_cached = 0;
    291280        cache->mode = mode;
    292 
    293         /* No block size translation a.t.m. */
    294         assert(cache->lblock_size == devcon->pblock_size);
    295281
    296282        if (!hash_table_create(&cache->block_hash, CACHE_BUCKETS, 1,
     
    345331        link_t *l;
    346332        unsigned long key = boff;
    347         int rc = EOK;
     333        int rc;
    348334       
    349335        devcon = devcon_search(dev_handle);
     
    355341
    356342retry:
     343        rc = EOK;
     344        b = NULL;
     345
    357346        fibril_mutex_lock(&cache->lock);
    358347        l = hash_table_find(&cache->block_hash, &key);
     
    382371                        if (!b)
    383372                                goto recycle;
    384                         b->data = malloc(cache->lblock_size);
     373                        b->data = malloc(cache->block_size);
    385374                        if (!b->data) {
    386375                                free(b);
     
    394383                        unsigned long temp_key;
    395384recycle:
    396                         assert(!list_empty(&cache->free_head));
     385                        if (list_empty(&cache->free_head)) {
     386                                fibril_mutex_unlock(&cache->lock);
     387                                rc = ENOMEM;
     388                                goto out;
     389                        }
    397390                        l = cache->free_head.next;
    398391                        b = list_get_instance(l, block_t, free_link);
     
    412405                                list_append(&b->free_link, &cache->free_head);
    413406                                fibril_mutex_unlock(&cache->lock);
    414                                 fibril_mutex_lock(&devcon->comm_area_lock);
    415                                 memcpy(devcon->comm_area, b->data, b->size);
    416                                 rc = write_blocks(devcon, b->boff, 1);
    417                                 fibril_mutex_unlock(&devcon->comm_area_lock);
     407                                fibril_mutex_lock(&devcon->com_area_lock);
     408                                memcpy(devcon->com_area, b->data, b->size);
     409                                rc = write_block(devcon, b->boff,
     410                                    cache->block_size);
     411                                fibril_mutex_unlock(&devcon->com_area_lock);
    418412                                if (rc != EOK) {
    419413                                        /*
     
    450444                block_initialize(b);
    451445                b->dev_handle = dev_handle;
    452                 b->size = cache->lblock_size;
     446                b->size = cache->block_size;
    453447                b->boff = boff;
    454448                hash_table_insert(&cache->block_hash, &key, &b->hash_link);
     
    467461                         * the new contents from the device.
    468462                         */
    469                         fibril_mutex_lock(&devcon->comm_area_lock);
    470                         rc = read_blocks(devcon, b->boff, 1);
    471                         memcpy(b->data, devcon->comm_area, cache->lblock_size);
    472                         fibril_mutex_unlock(&devcon->comm_area_lock);
     463                        fibril_mutex_lock(&devcon->com_area_lock);
     464                        rc = read_block(devcon, b->boff, cache->block_size);
     465                        memcpy(b->data, devcon->com_area, cache->block_size);
     466                        fibril_mutex_unlock(&devcon->com_area_lock);
    473467                        if (rc != EOK)
    474468                                b->toxic = true;
     
    477471
    478472                fibril_mutex_unlock(&b->lock);
     473        }
     474out:
     475        if ((rc != EOK) && b) {
     476                assert(b->toxic);
     477                (void) block_put(b);
     478                b = NULL;
    479479        }
    480480        *block = b;
     
    521521        if (block->dirty && (block->refcnt == 1) &&
    522522            (blocks_cached > CACHE_HI_WATERMARK || mode != CACHE_MODE_WB)) {
    523                 fibril_mutex_lock(&devcon->comm_area_lock);
    524                 memcpy(devcon->comm_area, block->data, block->size);
    525                 rc = write_blocks(devcon, block->boff, 1);
    526                 fibril_mutex_unlock(&devcon->comm_area_lock);
     523                fibril_mutex_lock(&devcon->com_area_lock);
     524                memcpy(devcon->com_area, block->data, block->size);
     525                rc = write_block(devcon, block->boff, block->size);
     526                fibril_mutex_unlock(&devcon->com_area_lock);
    527527                block->dirty = false;
    528528        }
     
    601601 */
    602602int block_seqread(dev_handle_t dev_handle, off_t *bufpos, size_t *buflen,
    603     off_t *pos, void *dst, size_t size)
     603    off_t *pos, void *dst, size_t size, size_t block_size)
    604604{
    605605        off_t offset = 0;
    606606        size_t left = size;
    607         size_t block_size;
    608         devcon_t *devcon;
    609 
    610         devcon = devcon_search(dev_handle);
     607        devcon_t *devcon = devcon_search(dev_handle);
    611608        assert(devcon);
    612         block_size = devcon->pblock_size;
    613        
    614         fibril_mutex_lock(&devcon->comm_area_lock);
     609       
     610        fibril_mutex_lock(&devcon->com_area_lock);
    615611        while (left > 0) {
    616612                size_t rd;
     
    626622                         * destination buffer.
    627623                         */
    628                         memcpy(dst + offset, devcon->comm_area + *bufpos, rd);
     624                        memcpy(dst + offset, devcon->com_area + *bufpos, rd);
    629625                        offset += rd;
    630626                        *bufpos += rd;
     
    637633                        int rc;
    638634
    639                         rc = read_blocks(devcon, *pos / block_size, 1);
     635                        rc = read_block(devcon, *pos / block_size, block_size);
    640636                        if (rc != EOK) {
    641                                 fibril_mutex_unlock(&devcon->comm_area_lock);
     637                                fibril_mutex_unlock(&devcon->com_area_lock);
    642638                                return rc;
    643639                        }
     
    647643                }
    648644        }
    649         fibril_mutex_unlock(&devcon->comm_area_lock);
     645        fibril_mutex_unlock(&devcon->com_area_lock);
    650646       
    651647        return EOK;
    652648}
    653649
    654 /** Read blocks directly from device (bypass cache).
    655  *
    656  * @param dev_handle    Device handle of the block device.
    657  * @param ba            Address of first block.
    658  * @param cnt           Number of blocks.
     650/** Read block from block device.
     651 *
     652 * @param devcon        Device connection.
     653 * @param boff          Block index.
     654 * @param block_size    Block size.
    659655 * @param src           Buffer for storing the data.
    660656 *
    661657 * @return              EOK on success or negative error code on failure.
    662658 */
    663 int block_read_direct(dev_handle_t dev_handle, bn_t ba, size_t cnt, void *buf)
    664 {
    665         devcon_t *devcon;
     659static int read_block(devcon_t *devcon, bn_t boff, size_t block_size)
     660{
     661        ipcarg_t retval;
    666662        int rc;
    667663
    668         devcon = devcon_search(dev_handle);
    669664        assert(devcon);
    670        
    671         fibril_mutex_lock(&devcon->comm_area_lock);
    672 
    673         rc = read_blocks(devcon, ba, cnt);
    674         if (rc == EOK)
    675                 memcpy(buf, devcon->comm_area, devcon->pblock_size * cnt);
    676 
    677         fibril_mutex_unlock(&devcon->comm_area_lock);
    678 
    679         return rc;
    680 }
    681 
    682 /** Write blocks directly to device (bypass cache).
    683  *
    684  * @param dev_handle    Device handle of the block device.
    685  * @param ba            Address of first block.
    686  * @param cnt           Number of blocks.
    687  * @param src           The data to be written.
     665        rc = async_req_2_1(devcon->dev_phone, BD_READ_BLOCK, boff, block_size,
     666            &retval);
     667        if ((rc != EOK) || (retval != EOK))
     668                return (rc != EOK ? rc : (int) retval);
     669
     670        return EOK;
     671}
     672
     673/** Write block to block device.
     674 *
     675 * @param devcon        Device connection.
     676 * @param boff          Block index.
     677 * @param block_size    Block size.
     678 * @param src           Buffer containing the data to write.
    688679 *
    689680 * @return              EOK on success or negative error code on failure.
    690681 */
    691 int block_write_direct(dev_handle_t dev_handle, bn_t ba, size_t cnt,
    692     const void *data)
    693 {
    694         devcon_t *devcon;
     682static int write_block(devcon_t *devcon, bn_t boff, size_t block_size)
     683{
     684        ipcarg_t retval;
    695685        int rc;
    696686
    697         devcon = devcon_search(dev_handle);
    698687        assert(devcon);
    699        
    700         fibril_mutex_lock(&devcon->comm_area_lock);
    701 
    702         memcpy(devcon->comm_area, data, devcon->pblock_size * cnt);
    703         rc = read_blocks(devcon, ba, cnt);
    704 
    705         fibril_mutex_unlock(&devcon->comm_area_lock);
    706 
    707         return rc;
    708 }
    709 
    710 /** Get device block size.
    711  *
    712  * @param dev_handle    Device handle of the block device.
    713  * @param bsize         Output block size.
    714  *
    715  * @return              EOK on success or negative error code on failure.
    716  */
    717 int block_get_bsize(dev_handle_t dev_handle, size_t *bsize)
    718 {
    719         devcon_t *devcon;
    720 
    721         devcon = devcon_search(dev_handle);
    722         assert(devcon);
    723        
    724         return get_block_size(devcon->dev_phone, bsize);
    725 }
    726 
    727 /** Read blocks from block device.
    728  *
    729  * @param devcon        Device connection.
    730  * @param ba            Address of first block.
    731  * @param cnt           Number of blocks.
    732  * @param src           Buffer for storing the data.
    733  *
    734  * @return              EOK on success or negative error code on failure.
    735  */
    736 static int read_blocks(devcon_t *devcon, bn_t ba, size_t cnt)
    737 {
    738         int rc;
    739 
    740         assert(devcon);
    741         rc = async_req_3_0(devcon->dev_phone, BD_READ_BLOCKS, LOWER32(ba),
    742             UPPER32(ba), cnt);
    743         return rc;
    744 }
    745 
    746 /** Write block to block device.
    747  *
    748  * @param devcon        Device connection.
    749  * @param ba            Address of first block.
    750  * @param cnt           Number of blocks.
    751  * @param src           Buffer containing the data to write.
    752  *
    753  * @return              EOK on success or negative error code on failure.
    754  */
    755 static int write_blocks(devcon_t *devcon, bn_t ba, size_t cnt)
    756 {
    757         int rc;
    758 
    759         assert(devcon);
    760         rc = async_req_3_0(devcon->dev_phone, BD_WRITE_BLOCKS, LOWER32(ba),
    761             UPPER32(ba), cnt);
    762         return rc;
    763 }
    764 
    765 /** Get block size used by the device. */
    766 static int get_block_size(int dev_phone, size_t *bsize)
    767 {
    768         ipcarg_t bs;
    769         int rc;
    770 
    771         rc = async_req_0_1(dev_phone, BD_GET_BLOCK_SIZE, &bs);
    772         if (rc == EOK)
    773                 *bsize = (size_t) bs;
    774 
    775         return rc;
     688        rc = async_req_2_1(devcon->dev_phone, BD_WRITE_BLOCK, boff, block_size,
     689            &retval);
     690        if ((rc != EOK) || (retval != EOK))
     691                return (rc != EOK ? rc : (int) retval);
     692
     693        return EOK;
    776694}
    777695
Note: See TracChangeset for help on using the changeset viewer.