Index: uspace/lib/libblock/libblock.c
===================================================================
--- uspace/lib/libblock/libblock.c	(revision cd688d9d407ba17ea6df2aeaa333efe0c6c756d1)
+++ uspace/lib/libblock/libblock.c	(revision 402a18fea4d8130d968ebe076514596f024af690)
@@ -331,4 +331,5 @@
 	link_t *l;
 	unsigned long key = boff;
+	int rc = EOK;
 	
 	devcon = devcon_search(dev_handle);
@@ -350,4 +351,6 @@
 		if (b->refcnt++ == 0)
 			list_remove(&b->free_link);
+		if (b->toxic)
+			rc = EIO;
 		fibril_mutex_unlock(&b->lock);
 		fibril_mutex_unlock(&cache->lock);
@@ -356,6 +359,4 @@
 		 * The block was not found in the cache.
 		 */
-		int rc;
-
 		if (cache_can_grow(cache)) {
 			/*
@@ -402,5 +403,14 @@
 				    cache->block_size);
 				fibril_mutex_unlock(&devcon->com_area_lock);
-				assert(rc == EOK);
+				if (rc != EOK) {
+					/*
+					 * We did not manage to write the block
+					 * to the device. Keep it around for
+					 * another try. Hopefully, we will grab
+					 * another block next time.
+					 */
+					fibril_mutex_unlock(&b->lock);
+					goto retry;
+				}
 				b->dirty = false;
 				if (!fibril_mutex_trylock(&cache->lock)) {
@@ -446,13 +456,15 @@
 			fibril_mutex_lock(&devcon->com_area_lock);
 			rc = read_block(devcon, b->boff, cache->block_size);
-			assert(rc == EOK);
 			memcpy(b->data, devcon->com_area, cache->block_size);
 			fibril_mutex_unlock(&devcon->com_area_lock);
-		}
+			if (rc != EOK) 
+				b->toxic = true;
+		} else
+			rc = EOK;
 
 		fibril_mutex_unlock(&b->lock);
 	}
 	*block = b;
-	return EOK;
+	return rc;
 }
 
@@ -471,5 +483,5 @@
 	unsigned blocks_cached;
 	enum cache_mode mode;
-	int rc;
+	int rc = EOK;
 
 	assert(devcon);
@@ -492,4 +504,6 @@
 	 */
 	fibril_mutex_lock(&block->lock);
+	if (block->toxic)
+		block->dirty = false;	/* will not write back toxic block */
 	if (block->dirty && (block->refcnt == 1) &&
 	    (blocks_cached > CACHE_HI_WATERMARK || mode != CACHE_MODE_WB)) {
@@ -497,5 +511,4 @@
 		memcpy(devcon->com_area, block->data, block->size);
 		rc = write_block(devcon, block->boff, block->size);
-		assert(rc == EOK);
 		fibril_mutex_unlock(&devcon->com_area_lock);
 		block->dirty = false;
@@ -508,9 +521,13 @@
 		/*
 		 * Last reference to the block was dropped. Either free the
-		 * block or put it on the free list.
+		 * block or put it on the free list. In case of an I/O error,
+		 * free the block.
 		 */
-		if (cache->blocks_cached > CACHE_HI_WATERMARK) {
-			/*
-			 * Currently there are too many cached blocks.
+		if ((cache->blocks_cached > CACHE_HI_WATERMARK) ||
+		    (rc != EOK)) {
+			/*
+			 * Currently there are too many cached blocks or there
+			 * was an I/O error when writing the block back to the
+			 * device.
 			 */
 			if (block->dirty) {
@@ -533,5 +550,5 @@
 			cache->blocks_cached--;
 			fibril_mutex_unlock(&cache->lock);
-			return;
+			return rc;
 		}
 		/*
@@ -553,5 +570,5 @@
 	fibril_mutex_unlock(&cache->lock);
 
-	return EOK;
+	return rc;
 }
 
