Ignore:
File:
1 edited

Legend:

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

    r4e00f87 rf9b2cb4c  
    3737 */
    3838
    39 #include "../../srv/vfs/vfs.h"
    4039#include <ipc/loc.h>
    4140#include <ipc/services.h>
    4241#include <errno.h>
    43 #include <sys/mman.h>
    4442#include <async.h>
    4543#include <as.h>
     
    5755#include "block.h"
    5856
     57#define MAX_WRITE_RETRIES 10
     58
    5959/** Lock protecting the device connection list */
    6060static FIBRIL_MUTEX_INITIALIZE(dcl_lock);
     
    8181        void *bb_buf;
    8282        aoff64_t bb_addr;
     83        aoff64_t pblocks;    /**< Number of physical blocks */
    8384        size_t pblock_size;  /**< Physical block size. */
    8485        cache_t *cache;
     
    9394        fibril_mutex_lock(&dcl_lock);
    9495       
    95         list_foreach(dcl, cur) {
    96                 devcon_t *devcon = list_get_instance(cur, devcon_t, link);
     96        list_foreach(dcl, link, devcon_t, devcon) {
    9797                if (devcon->service_id == service_id) {
    9898                        fibril_mutex_unlock(&dcl_lock);
     
    106106
    107107static int devcon_add(service_id_t service_id, async_sess_t *sess,
    108     size_t bsize, bd_t *bd)
     108    size_t bsize, aoff64_t dev_size, bd_t *bd)
    109109{
    110110        devcon_t *devcon;
     
    121121        devcon->bb_addr = 0;
    122122        devcon->pblock_size = bsize;
     123        devcon->pblocks = dev_size;
    123124        devcon->cache = NULL;
    124125       
    125126        fibril_mutex_lock(&dcl_lock);
    126         list_foreach(dcl, cur) {
    127                 devcon_t *d = list_get_instance(cur, devcon_t, link);
     127        list_foreach(dcl, link, devcon_t, d) {
    128128                if (d->service_id == service_id) {
    129129                        fibril_mutex_unlock(&dcl_lock);
     
    144144}
    145145
    146 int block_init(exch_mgmt_t mgmt, service_id_t service_id,
    147     size_t comm_size)
     146int block_init(service_id_t service_id, size_t comm_size)
    148147{
    149148        bd_t *bd;
    150149
    151         async_sess_t *sess = loc_service_connect(mgmt, service_id,
     150        async_sess_t *sess = loc_service_connect(service_id, INTERFACE_BLOCK,
    152151            IPC_FLAG_BLOCKING);
    153152        if (!sess) {
     
    168167                return rc;
    169168        }
    170        
    171         rc = devcon_add(service_id, sess, bsize, bd);
     169
     170        aoff64_t dev_size;
     171        rc = bd_get_num_blocks(bd, &dev_size);
    172172        if (rc != EOK) {
    173173                bd_close(bd);
     
    176176        }
    177177       
     178        rc = devcon_add(service_id, sess, bsize, dev_size, bd);
     179        if (rc != EOK) {
     180                bd_close(bd);
     181                async_hangup(sess);
     182                return rc;
     183        }
     184       
    178185        return EOK;
    179186}
     
    186193        if (devcon->cache)
    187194                (void) block_cache_fini(service_id);
     195       
     196        (void)bd_sync_cache(devcon->bd, 0, 0);
    188197       
    189198        devcon_remove(devcon);
     
    353362        fibril_mutex_initialize(&b->lock);
    354363        b->refcnt = 1;
     364        b->write_failures = 0;
    355365        b->dirty = false;
    356366        b->toxic = false;
     
    377387        block_t *b;
    378388        link_t *link;
    379 
     389        aoff64_t p_ba;
    380390        int rc;
    381391       
     
    386396       
    387397        cache = devcon->cache;
     398
     399        /* Check whether the logical block (or part of it) is beyond
     400         * the end of the device or not.
     401         */
     402        p_ba = ba_ltop(devcon, ba);
     403        p_ba += cache->blocks_cluster;
     404        if (p_ba >= devcon->pblocks) {
     405                /* This request cannot be satisfied */
     406                return EIO;
     407        }
     408
    388409
    389410retry:
     
    462483                                         * another block next time.
    463484                                         */
    464                                         fibril_mutex_unlock(&b->lock);
    465                                         goto retry;
    466                                 }
     485                                        if (b->write_failures < MAX_WRITE_RETRIES) {
     486                                                b->write_failures++;
     487                                                fibril_mutex_unlock(&b->lock);
     488                                                goto retry;
     489                                        } else {
     490                                                printf("Too many errors writing block %"
     491                                                    PRIuOFF64 "from device handle %" PRIun "\n"
     492                                                    "SEVERE DATA LOSS POSSIBLE\n",
     493                                                    b->lba, devcon->service_id);
     494                                        }
     495                                } else
     496                                        b->write_failures = 0;
     497
    467498                                b->dirty = false;
    468499                                if (!fibril_mutex_trylock(&cache->lock)) {
     
    581612                rc = write_blocks(devcon, block->pba, cache->blocks_cluster,
    582613                    block->data, block->size);
     614                if (rc == EOK)
     615                        block->write_failures = 0;
    583616                block->dirty = false;
    584617        }
     
    606639                                 */
    607640                                block->refcnt++;
    608                                 fibril_mutex_unlock(&block->lock);
    609                                 fibril_mutex_unlock(&cache->lock);
    610                                 goto retry;
     641
     642                                if (block->write_failures < MAX_WRITE_RETRIES) {
     643                                        block->write_failures++;
     644                                        fibril_mutex_unlock(&block->lock);
     645                                        fibril_mutex_unlock(&cache->lock);
     646                                        goto retry;
     647                                } else {
     648                                        printf("Too many errors writing block %"
     649                                            PRIuOFF64 "from device handle %" PRIun "\n"
     650                                            "SEVERE DATA LOSS POSSIBLE\n",
     651                                            block->lba, devcon->service_id);
     652                                }
    611653                        }
    612654                        /*
     
    774816        devcon_t *devcon = devcon_search(service_id);
    775817        assert(devcon);
    776        
     818
    777819        return bd_get_num_blocks(devcon->bd, nblocks);
    778820}
     
    836878 *
    837879 * @return Allocated TOC structure.
    838  * @return NULL on failure.
    839  *
    840  */
    841 toc_block_t *block_get_toc(service_id_t service_id, uint8_t session)
     880 * @return EOK on success or negative error code.
     881 *
     882 */
     883int block_read_toc(service_id_t service_id, uint8_t session, void *buf,
     884    size_t bufsize)
    842885{
    843886        devcon_t *devcon = devcon_search(service_id);
    844         toc_block_t *toc = NULL;
    845         int rc;
    846        
    847         assert(devcon);
    848        
    849         toc = (toc_block_t *) malloc(sizeof(toc_block_t));
    850         if (toc == NULL)
    851                 return NULL;
    852        
    853         rc = bd_read_toc(devcon->bd, session, toc, sizeof(toc_block_t));
    854         if (rc != EOK) {
    855                 free(toc);
    856                 return NULL;
    857         }
    858        
    859         return toc;
     887       
     888        assert(devcon);
     889        return bd_read_toc(devcon->bd, session, buf, bufsize);
    860890}
    861891
Note: See TracChangeset for help on using the changeset viewer.