Ignore:
File:
1 edited

Legend:

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

    rb7adc22 rdd8b6a8  
    4040#include <ipc/services.h>
    4141#include <errno.h>
    42 #include <sys/mman.h>
    4342#include <async.h>
    4443#include <as.h>
     
    5655#include "block.h"
    5756
     57#define MAX_WRITE_RETRIES 10
     58
    5859/** Lock protecting the device connection list */
    5960static FIBRIL_MUTEX_INITIALIZE(dcl_lock);
     
    8081        void *bb_buf;
    8182        aoff64_t bb_addr;
     83        aoff64_t pblocks;    /**< Number of physical blocks */
    8284        size_t pblock_size;  /**< Physical block size. */
    8385        cache_t *cache;
     
    104106
    105107static int devcon_add(service_id_t service_id, async_sess_t *sess,
    106     size_t bsize, bd_t *bd)
     108    size_t bsize, aoff64_t dev_size, bd_t *bd)
    107109{
    108110        devcon_t *devcon;
     
    119121        devcon->bb_addr = 0;
    120122        devcon->pblock_size = bsize;
     123        devcon->pblocks = dev_size;
    121124        devcon->cache = NULL;
    122125       
     
    165168                return rc;
    166169        }
    167        
    168         rc = devcon_add(service_id, sess, bsize, bd);
     170
     171        aoff64_t dev_size;
     172        rc = bd_get_num_blocks(bd, &dev_size);
    169173        if (rc != EOK) {
    170174                bd_close(bd);
     
    173177        }
    174178       
     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       
    175186        return EOK;
    176187}
     
    183194        if (devcon->cache)
    184195                (void) block_cache_fini(service_id);
     196       
     197        (void)bd_sync_cache(devcon->bd, 0, 0);
    185198       
    186199        devcon_remove(devcon);
     
    350363        fibril_mutex_initialize(&b->lock);
    351364        b->refcnt = 1;
     365        b->write_failures = 0;
    352366        b->dirty = false;
    353367        b->toxic = false;
     
    374388        block_t *b;
    375389        link_t *link;
    376 
     390        aoff64_t p_ba;
    377391        int rc;
    378392       
     
    383397       
    384398        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
    385410
    386411retry:
     
    459484                                         * another block next time.
    460485                                         */
    461                                         fibril_mutex_unlock(&b->lock);
    462                                         goto retry;
    463                                 }
     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
    464499                                b->dirty = false;
    465500                                if (!fibril_mutex_trylock(&cache->lock)) {
     
    578613                rc = write_blocks(devcon, block->pba, cache->blocks_cluster,
    579614                    block->data, block->size);
     615                if (rc == EOK)
     616                        block->write_failures = 0;
    580617                block->dirty = false;
    581618        }
     
    603640                                 */
    604641                                block->refcnt++;
    605                                 fibril_mutex_unlock(&block->lock);
    606                                 fibril_mutex_unlock(&cache->lock);
    607                                 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                                }
    608654                        }
    609655                        /*
     
    771817        devcon_t *devcon = devcon_search(service_id);
    772818        assert(devcon);
    773        
     819
    774820        return bd_get_num_blocks(devcon->bd, nblocks);
    775821}
     
    833879 *
    834880 * @return Allocated TOC structure.
    835  * @return NULL on failure.
    836  *
    837  */
    838 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)
    839886{
    840887        devcon_t *devcon = devcon_search(service_id);
    841         toc_block_t *toc = NULL;
    842         int rc;
    843        
    844         assert(devcon);
    845        
    846         toc = (toc_block_t *) malloc(sizeof(toc_block_t));
    847         if (toc == NULL)
    848                 return NULL;
    849        
    850         rc = bd_read_toc(devcon->bd, session, toc, sizeof(toc_block_t));
    851         if (rc != EOK) {
    852                 free(toc);
    853                 return NULL;
    854         }
    855        
    856         return toc;
     888       
     889        assert(devcon);
     890        return bd_read_toc(devcon->bd, session, buf, bufsize);
    857891}
    858892
Note: See TracChangeset for help on using the changeset viewer.