Ignore:
File:
1 edited

Legend:

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

    r2463df9 rc1f26834  
    5555#include "block.h"
    5656
     57#define MAX_WRITE_RETRIES 10
     58
    5759/** Lock protecting the device connection list */
    5860static FIBRIL_MUTEX_INITIALIZE(dcl_lock);
     
    7981        void *bb_buf;
    8082        aoff64_t bb_addr;
     83        aoff64_t pblocks;    /**< Number of physical blocks */
    8184        size_t pblock_size;  /**< Physical block size. */
    8285        cache_t *cache;
     
    103106
    104107static int devcon_add(service_id_t service_id, async_sess_t *sess,
    105     size_t bsize, bd_t *bd)
     108    size_t bsize, aoff64_t dev_size, bd_t *bd)
    106109{
    107110        devcon_t *devcon;
     
    118121        devcon->bb_addr = 0;
    119122        devcon->pblock_size = bsize;
     123        devcon->pblocks = dev_size;
    120124        devcon->cache = NULL;
    121125       
     
    164168                return rc;
    165169        }
    166        
    167         rc = devcon_add(service_id, sess, bsize, bd);
     170
     171        aoff64_t dev_size;
     172        rc = bd_get_num_blocks(bd, &dev_size);
     173        if (rc != EOK) {
     174                bd_close(bd);
     175                async_hangup(sess);
     176                return rc;
     177        }
     178       
     179        rc = devcon_add(service_id, sess, bsize, dev_size, bd);
    168180        if (rc != EOK) {
    169181                bd_close(bd);
     
    349361        fibril_mutex_initialize(&b->lock);
    350362        b->refcnt = 1;
     363        b->write_failures = 0;
    351364        b->dirty = false;
    352365        b->toxic = false;
     
    373386        block_t *b;
    374387        link_t *link;
    375 
     388        aoff64_t p_ba;
    376389        int rc;
    377390       
     
    382395       
    383396        cache = devcon->cache;
     397
     398        /* Check whether the logical block (or part of it) is beyond
     399         * the end of the device or not.
     400         */
     401        p_ba = ba_ltop(devcon, ba);
     402        p_ba += cache->blocks_cluster;
     403        if (p_ba >= devcon->pblocks) {
     404                /* This request cannot be satisfied */
     405                return EIO;
     406        }
     407
    384408
    385409retry:
     
    458482                                         * another block next time.
    459483                                         */
    460                                         fibril_mutex_unlock(&b->lock);
    461                                         goto retry;
    462                                 }
     484                                        if (b->write_failures < MAX_WRITE_RETRIES) {
     485                                                b->write_failures++;
     486                                                fibril_mutex_unlock(&b->lock);
     487                                                goto retry;
     488                                        } else {
     489                                                printf("Too many errors writing block %"
     490                                                    PRIuOFF64 "from device handle %" PRIun "\n"
     491                                                    "SEVERE DATA LOSS POSSIBLE\n",
     492                                                    b->lba, devcon->service_id);
     493                                        }
     494                                } else
     495                                        b->write_failures = 0;
     496
    463497                                b->dirty = false;
    464498                                if (!fibril_mutex_trylock(&cache->lock)) {
     
    577611                rc = write_blocks(devcon, block->pba, cache->blocks_cluster,
    578612                    block->data, block->size);
     613                if (rc == EOK)
     614                        block->write_failures = 0;
    579615                block->dirty = false;
    580616        }
     
    602638                                 */
    603639                                block->refcnt++;
    604                                 fibril_mutex_unlock(&block->lock);
    605                                 fibril_mutex_unlock(&cache->lock);
    606                                 goto retry;
     640
     641                                if (block->write_failures < MAX_WRITE_RETRIES) {
     642                                        block->write_failures++;
     643                                        fibril_mutex_unlock(&block->lock);
     644                                        fibril_mutex_unlock(&cache->lock);
     645                                        goto retry;
     646                                } else {
     647                                        printf("Too many errors writing block %"
     648                                            PRIuOFF64 "from device handle %" PRIun "\n"
     649                                            "SEVERE DATA LOSS POSSIBLE\n",
     650                                            block->lba, devcon->service_id);
     651                                }
    607652                        }
    608653                        /*
     
    770815        devcon_t *devcon = devcon_search(service_id);
    771816        assert(devcon);
    772        
     817
    773818        return bd_get_num_blocks(devcon->bd, nblocks);
    774819}
Note: See TracChangeset for help on using the changeset viewer.