Changeset 402a18f in mainline for uspace/lib/libblock/libblock.c


Ignore:
Timestamp:
2009-08-27T19:57:03Z (15 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
ff62c6d
Parents:
cd688d9
Message:

Let block_get() and block_put() deal with I/O errors.

File:
1 edited

Legend:

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

    rcd688d9 r402a18f  
    331331        link_t *l;
    332332        unsigned long key = boff;
     333        int rc = EOK;
    333334       
    334335        devcon = devcon_search(dev_handle);
     
    350351                if (b->refcnt++ == 0)
    351352                        list_remove(&b->free_link);
     353                if (b->toxic)
     354                        rc = EIO;
    352355                fibril_mutex_unlock(&b->lock);
    353356                fibril_mutex_unlock(&cache->lock);
     
    356359                 * The block was not found in the cache.
    357360                 */
    358                 int rc;
    359 
    360361                if (cache_can_grow(cache)) {
    361362                        /*
     
    402403                                    cache->block_size);
    403404                                fibril_mutex_unlock(&devcon->com_area_lock);
    404                                 assert(rc == EOK);
     405                                if (rc != EOK) {
     406                                        /*
     407                                         * We did not manage to write the block
     408                                         * to the device. Keep it around for
     409                                         * another try. Hopefully, we will grab
     410                                         * another block next time.
     411                                         */
     412                                        fibril_mutex_unlock(&b->lock);
     413                                        goto retry;
     414                                }
    405415                                b->dirty = false;
    406416                                if (!fibril_mutex_trylock(&cache->lock)) {
     
    446456                        fibril_mutex_lock(&devcon->com_area_lock);
    447457                        rc = read_block(devcon, b->boff, cache->block_size);
    448                         assert(rc == EOK);
    449458                        memcpy(b->data, devcon->com_area, cache->block_size);
    450459                        fibril_mutex_unlock(&devcon->com_area_lock);
    451                 }
     460                        if (rc != EOK)
     461                                b->toxic = true;
     462                } else
     463                        rc = EOK;
    452464
    453465                fibril_mutex_unlock(&b->lock);
    454466        }
    455467        *block = b;
    456         return EOK;
     468        return rc;
    457469}
    458470
     
    471483        unsigned blocks_cached;
    472484        enum cache_mode mode;
    473         int rc;
     485        int rc = EOK;
    474486
    475487        assert(devcon);
     
    492504         */
    493505        fibril_mutex_lock(&block->lock);
     506        if (block->toxic)
     507                block->dirty = false;   /* will not write back toxic block */
    494508        if (block->dirty && (block->refcnt == 1) &&
    495509            (blocks_cached > CACHE_HI_WATERMARK || mode != CACHE_MODE_WB)) {
     
    497511                memcpy(devcon->com_area, block->data, block->size);
    498512                rc = write_block(devcon, block->boff, block->size);
    499                 assert(rc == EOK);
    500513                fibril_mutex_unlock(&devcon->com_area_lock);
    501514                block->dirty = false;
     
    508521                /*
    509522                 * Last reference to the block was dropped. Either free the
    510                  * block or put it on the free list.
     523                 * block or put it on the free list. In case of an I/O error,
     524                 * free the block.
    511525                 */
    512                 if (cache->blocks_cached > CACHE_HI_WATERMARK) {
    513                         /*
    514                          * Currently there are too many cached blocks.
     526                if ((cache->blocks_cached > CACHE_HI_WATERMARK) ||
     527                    (rc != EOK)) {
     528                        /*
     529                         * Currently there are too many cached blocks or there
     530                         * was an I/O error when writing the block back to the
     531                         * device.
    515532                         */
    516533                        if (block->dirty) {
     
    533550                        cache->blocks_cached--;
    534551                        fibril_mutex_unlock(&cache->lock);
    535                         return;
     552                        return rc;
    536553                }
    537554                /*
     
    553570        fibril_mutex_unlock(&cache->lock);
    554571
    555         return EOK;
     572        return rc;
    556573}
    557574
Note: See TracChangeset for help on using the changeset viewer.