Ignore:
File:
1 edited

Legend:

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

    r4e00f87 rdd8b6a8  
    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);
     
    168168                return rc;
    169169        }
    170        
    171         rc = devcon_add(service_id, sess, bsize, bd);
     170
     171        aoff64_t dev_size;
     172        rc = bd_get_num_blocks(bd, &dev_size);
    172173        if (rc != EOK) {
    173174                bd_close(bd);
     
    176177        }
    177178       
     179        rc = devcon_add(service_id, sess, bsize, dev_size, bd);
     180        if (rc != EOK) {
     181                bd_close(bd);
     182                async_hangup(sess);
     183                return rc;
     184        }
     185       
    178186        return EOK;
    179187}
     
    186194        if (devcon->cache)
    187195                (void) block_cache_fini(service_id);
     196       
     197        (void)bd_sync_cache(devcon->bd, 0, 0);
    188198       
    189199        devcon_remove(devcon);
     
    353363        fibril_mutex_initialize(&b->lock);
    354364        b->refcnt = 1;
     365        b->write_failures = 0;
    355366        b->dirty = false;
    356367        b->toxic = false;
     
    377388        block_t *b;
    378389        link_t *link;
    379 
     390        aoff64_t p_ba;
    380391        int rc;
    381392       
     
    386397       
    387398        cache = devcon->cache;
     399
     400        /* Check whether the logical block (or part of it) is beyond
     401         * the end of the device or not.
     402         */
     403        p_ba = ba_ltop(devcon, ba);
     404        p_ba += cache->blocks_cluster;
     405        if (p_ba >= devcon->pblocks) {
     406                /* This request cannot be satisfied */
     407                return EIO;
     408        }
     409
    388410
    389411retry:
     
    462484                                         * another block next time.
    463485                                         */
    464                                         fibril_mutex_unlock(&b->lock);
    465                                         goto retry;
    466                                 }
     486                                        if (b->write_failures < MAX_WRITE_RETRIES) {
     487                                                b->write_failures++;
     488                                                fibril_mutex_unlock(&b->lock);
     489                                                goto retry;
     490                                        } else {
     491                                                printf("Too many errors writing block %"
     492                                                    PRIuOFF64 "from device handle %" PRIun "\n"
     493                                                    "SEVERE DATA LOSS POSSIBLE\n",
     494                                                    b->lba, devcon->service_id);
     495                                        }
     496                                } else
     497                                        b->write_failures = 0;
     498
    467499                                b->dirty = false;
    468500                                if (!fibril_mutex_trylock(&cache->lock)) {
     
    581613                rc = write_blocks(devcon, block->pba, cache->blocks_cluster,
    582614                    block->data, block->size);
     615                if (rc == EOK)
     616                        block->write_failures = 0;
    583617                block->dirty = false;
    584618        }
     
    606640                                 */
    607641                                block->refcnt++;
    608                                 fibril_mutex_unlock(&block->lock);
    609                                 fibril_mutex_unlock(&cache->lock);
    610                                 goto retry;
     642
     643                                if (block->write_failures < MAX_WRITE_RETRIES) {
     644                                        block->write_failures++;
     645                                        fibril_mutex_unlock(&block->lock);
     646                                        fibril_mutex_unlock(&cache->lock);
     647                                        goto retry;
     648                                } else {
     649                                        printf("Too many errors writing block %"
     650                                            PRIuOFF64 "from device handle %" PRIun "\n"
     651                                            "SEVERE DATA LOSS POSSIBLE\n",
     652                                            block->lba, devcon->service_id);
     653                                }
    611654                        }
    612655                        /*
     
    774817        devcon_t *devcon = devcon_search(service_id);
    775818        assert(devcon);
    776        
     819
    777820        return bd_get_num_blocks(devcon->bd, nblocks);
    778821}
     
    836879 *
    837880 * @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)
     881 * @return EOK on success or negative error code.
     882 *
     883 */
     884int block_read_toc(service_id_t service_id, uint8_t session, void *buf,
     885    size_t bufsize)
    842886{
    843887        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;
     888       
     889        assert(devcon);
     890        return bd_read_toc(devcon->bd, session, buf, bufsize);
    860891}
    861892
Note: See TracChangeset for help on using the changeset viewer.