Index: uspace/lib/block/block.c
===================================================================
--- uspace/lib/block/block.c	(revision 7eb6c96392769a3bab70af54ff262130f072c967)
+++ uspace/lib/block/block.c	(revision 3d353861de6cebab6ab932a2b33b6625786f8aa4)
@@ -55,4 +55,6 @@
 #include "block.h"
 
+#define MAX_WRITE_RETRIES 10
+
 /** Lock protecting the device connection list */
 static FIBRIL_MUTEX_INITIALIZE(dcl_lock);
@@ -79,4 +81,5 @@
 	void *bb_buf;
 	aoff64_t bb_addr;
+	aoff64_t pblocks;    /**< Number of physical blocks */
 	size_t pblock_size;  /**< Physical block size. */
 	cache_t *cache;
@@ -103,5 +106,5 @@
 
 static int devcon_add(service_id_t service_id, async_sess_t *sess,
-    size_t bsize, bd_t *bd)
+    size_t bsize, aoff64_t dev_size, bd_t *bd)
 {
 	devcon_t *devcon;
@@ -118,4 +121,5 @@
 	devcon->bb_addr = 0;
 	devcon->pblock_size = bsize;
+	devcon->pblocks = dev_size;
 	devcon->cache = NULL;
 	
@@ -164,6 +168,14 @@
 		return rc;
 	}
-	
-	rc = devcon_add(service_id, sess, bsize, bd);
+
+	aoff64_t dev_size;
+	rc = bd_get_num_blocks(bd, &dev_size);
+	if (rc != EOK) {
+		bd_close(bd);
+		async_hangup(sess);
+		return rc;
+	}
+	
+	rc = devcon_add(service_id, sess, bsize, dev_size, bd);
 	if (rc != EOK) {
 		bd_close(bd);
@@ -349,4 +361,5 @@
 	fibril_mutex_initialize(&b->lock);
 	b->refcnt = 1;
+	b->write_failures = 0;
 	b->dirty = false;
 	b->toxic = false;
@@ -373,5 +386,5 @@
 	block_t *b;
 	link_t *link;
-
+	aoff64_t p_ba;
 	int rc;
 	
@@ -382,4 +395,15 @@
 	
 	cache = devcon->cache;
+
+	/* Check whether the logical block (or part of it) is beyond
+	 * the end of the device or not.
+	 */
+	p_ba = ba_ltop(devcon, ba);
+	p_ba += cache->blocks_cluster;
+	if (p_ba >= devcon->pblocks) {
+		/* This request cannot be satisfied */
+		return EIO;
+	}
+
 
 retry:
@@ -458,7 +482,17 @@
 					 * another block next time.
 					 */
-					fibril_mutex_unlock(&b->lock);
-					goto retry;
-				}
+					if (b->write_failures < MAX_WRITE_RETRIES) {
+						b->write_failures++;
+						fibril_mutex_unlock(&b->lock);
+						goto retry;
+					} else {
+						printf("Too many errors writing block %"
+				    		    PRIuOFF64 "from device handle %" PRIun "\n"
+						    "SEVERE DATA LOSS POSSIBLE\n",
+				    		    b->lba, devcon->service_id);
+					}
+				} else
+					b->write_failures = 0;
+
 				b->dirty = false;
 				if (!fibril_mutex_trylock(&cache->lock)) {
@@ -577,4 +611,6 @@
 		rc = write_blocks(devcon, block->pba, cache->blocks_cluster,
 		    block->data, block->size);
+		if (rc == EOK)
+			block->write_failures = 0;
 		block->dirty = false;
 	}
@@ -602,7 +638,16 @@
 				 */
 				block->refcnt++;
-				fibril_mutex_unlock(&block->lock);
 				fibril_mutex_unlock(&cache->lock);
-				goto retry;
+
+				if (block->write_failures < MAX_WRITE_RETRIES) {
+					block->write_failures++;
+					fibril_mutex_unlock(&block->lock);
+					goto retry;
+				} else {
+					printf("Too many errors writing block %"
+				            PRIuOFF64 "from device handle %" PRIun "\n"
+					    "SEVERE DATA LOSS POSSIBLE\n",
+				    	    block->lba, devcon->service_id);
+				}
 			}
 			/*
@@ -770,5 +815,5 @@
 	devcon_t *devcon = devcon_search(service_id);
 	assert(devcon);
-	
+
 	return bd_get_num_blocks(devcon->bd, nblocks);
 }
Index: uspace/lib/block/block.h
===================================================================
--- uspace/lib/block/block.h	(revision 7eb6c96392769a3bab70af54ff262130f072c967)
+++ uspace/lib/block/block.h	(revision 3d353861de6cebab6ab932a2b33b6625786f8aa4)
@@ -81,4 +81,6 @@
 	/** Size of the block. */
 	size_t size;
+	/** Number of write failures. */
+	int write_failures;
 	/** Link for placing the block into the free block list. */
 	link_t free_link;
