Index: uspace/app/fdisk/fdisk.c
===================================================================
--- uspace/app/fdisk/fdisk.c	(revision edebb4a154d7503a1a506cd53ce84ae086f387d6)
+++ uspace/app/fdisk/fdisk.c	(revision ea0ff6b69b253afa7b6b4e9cd38ef8e91ec0daab)
@@ -51,4 +51,6 @@
 	/** Delete label */
 	devac_delete_label,
+	/** Erase disk */
+	devac_erase_disk,
 	/** Create (primary) partition */
 	devac_create_pri_part,
@@ -262,4 +264,17 @@
 }
 
+static int fdsk_erase_disk(fdisk_dev_t *dev)
+{
+	int rc;
+
+	rc = fdisk_dev_erase(dev);
+	if (rc != EOK) {
+		printf("Error erasing disk.\n");
+		return rc;
+	}
+
+	return EOK;
+}
+
 static int fdsk_select_fstype(vol_fstype_t *fstype)
 {
@@ -473,4 +488,5 @@
 	fdisk_part_info_t pinfo;
 	fdisk_cap_t cap;
+	fdisk_dev_flags_t dflags;
 	char *sltype = NULL;
 	char *sdcap = NULL;
@@ -514,4 +530,6 @@
 		goto error;
 	}
+
+	fdisk_dev_get_flags(dev, &dflags);
 
 	printf("Device: %s, %s\n", sdcap, svcname);
@@ -667,5 +685,5 @@
 	}
 
-	if (linfo.ltype == lt_none) {
+	if ((dflags & fdf_can_create_label) != 0) {
 		rc = nchoice_add(choice, "Create label",
 		    (void *)devac_create_label);
@@ -675,7 +693,19 @@
 			goto error;
 		}
-	} else {
+	}
+
+	if ((dflags & fdf_can_delete_label) != 0) {
 		rc = nchoice_add(choice, "Delete label",
 		    (void *)devac_delete_label);
+		if (rc != EOK) {
+			assert(rc == ENOMEM);
+			printf("Out of memory.\n");
+			goto error;
+		}
+	}
+
+	if ((dflags & fdf_can_erase_dev) != 0) {
+		rc = nchoice_add(choice, "Erase disk",
+		    (void *)devac_erase_disk);
 		if (rc != EOK) {
 			assert(rc == ENOMEM);
@@ -704,4 +734,7 @@
 	case devac_delete_label:
 		(void) fdsk_delete_label(dev);
+		break;
+	case devac_erase_disk:
+		(void) fdsk_erase_disk(dev);
 		break;
 	case devac_create_pri_part:
Index: uspace/lib/c/generic/vol.c
===================================================================
--- uspace/lib/c/generic/vol.c	(revision edebb4a154d7503a1a506cd53ce84ae086f387d6)
+++ uspace/lib/c/generic/vol.c	(revision ea0ff6b69b253afa7b6b4e9cd38ef8e91ec0daab)
@@ -245,5 +245,5 @@
 
 	if (retval != EOK)
-		return EIO;
+		return retval;
 
 	return EOK;
Index: uspace/lib/fdisk/include/fdisk.h
===================================================================
--- uspace/lib/fdisk/include/fdisk.h	(revision edebb4a154d7503a1a506cd53ce84ae086f387d6)
+++ uspace/lib/fdisk/include/fdisk.h	(revision ea0ff6b69b253afa7b6b4e9cd38ef8e91ec0daab)
@@ -52,4 +52,6 @@
 extern int fdisk_dev_open(fdisk_t *, service_id_t, fdisk_dev_t **);
 extern void fdisk_dev_close(fdisk_dev_t *);
+extern int fdisk_dev_erase(fdisk_dev_t *);
+extern void fdisk_dev_get_flags(fdisk_dev_t *, fdisk_dev_flags_t *);
 extern int fdisk_dev_get_svcname(fdisk_dev_t *, char **);
 extern int fdisk_dev_capacity(fdisk_dev_t *, fdisk_cap_t *);
Index: uspace/lib/fdisk/include/types/fdisk.h
===================================================================
--- uspace/lib/fdisk/include/types/fdisk.h	(revision edebb4a154d7503a1a506cd53ce84ae086f387d6)
+++ uspace/lib/fdisk/include/types/fdisk.h	(revision ea0ff6b69b253afa7b6b4e9cd38ef8e91ec0daab)
@@ -57,4 +57,14 @@
 } fdisk_cunit_t;
 
+/** Fdisk device flags */
+typedef enum {
+	/** Currently we can create a label */
+	fdf_can_create_label = 0x1,
+	/** Currently we can delete the label */
+	fdf_can_delete_label = 0x2,
+	/** Currently we can erase unknown data from disk */
+	fdf_can_erase_dev = 0x4
+} fdisk_dev_flags_t;
+
 #define CU_LIMIT (cu_ybyte + 1)
 
@@ -76,7 +86,9 @@
 	/** Link in fdisk_dev_list_t.devinfos */
 	link_t ldevlist;
+	/** Service ID */
 	service_id_t svcid;
 	/** Service name or NULL if not determined yet */
 	char *svcname;
+	/** Device is initialized in libblock */
 	bool blk_inited;
 } fdisk_dev_info_t;
Index: uspace/lib/fdisk/src/fdisk.c
===================================================================
--- uspace/lib/fdisk/src/fdisk.c	(revision edebb4a154d7503a1a506cd53ce84ae086f387d6)
+++ uspace/lib/fdisk/src/fdisk.c	(revision ea0ff6b69b253afa7b6b4e9cd38ef8e91ec0daab)
@@ -528,4 +528,54 @@
 }
 
+/** Erase contents of unlabeled disk. */
+int fdisk_dev_erase(fdisk_dev_t *dev)
+{
+	fdisk_part_t *part;
+	int rc;
+
+	printf("fdisk_dev_erase.. check ltype\n");
+	if (dev->dinfo.ltype != lt_none)
+		return EINVAL;
+
+	printf("fdisk_dev_erase.. get first part\n");
+	part = fdisk_part_first(dev);
+	assert(part != NULL);
+	printf("fdisk_dev_erase.. check part\n");
+	if (part->pcnt == vpc_empty)
+		return EINVAL;
+
+	printf("fdisk_dev_erase.. check part\n");
+	rc = vol_part_empty(dev->fdisk->vol, part->svc_id);
+	if (rc != EOK) {
+		printf("vol_part_empty -> %d\n", rc);
+		return rc;
+	}
+
+	part->pcnt = vpc_empty;
+	return EOK;
+}
+
+void fdisk_dev_get_flags(fdisk_dev_t *dev, fdisk_dev_flags_t *rflags)
+{
+	fdisk_dev_flags_t flags;
+	fdisk_part_t *part;
+
+	flags = 0;
+
+	/* fdf_can_create_label */
+	if (dev->dinfo.ltype == lt_none) {
+		part = fdisk_part_first(dev);
+		assert(part != NULL);
+		if (part->pcnt == vpc_empty)
+			flags |= fdf_can_create_label;
+		else
+			flags |= fdf_can_erase_dev;
+	} else {
+		flags |= fdf_can_delete_label;
+	}
+
+	*rflags = flags;
+}
+
 int fdisk_dev_get_svcname(fdisk_dev_t *dev, char **rname)
 {
@@ -587,5 +637,16 @@
 int fdisk_label_create(fdisk_dev_t *dev, label_type_t ltype)
 {
-	int rc;
+	fdisk_part_t *part;
+	int rc;
+
+	/* Disk must not contain a label. */
+	if (dev->dinfo.ltype != lt_none)
+		return EEXIST;
+
+	/* Dummy partition spanning entire disk must be considered empty */
+	part = fdisk_part_first(dev);
+	assert(part != NULL);
+	if (part->pcnt != vpc_empty)
+		return EEXIST;
 
 	/* Remove dummy partition */
@@ -606,5 +667,8 @@
 {
 	fdisk_part_t *part;
-	int rc;
+	fdisk_dev_flags_t dflags;
+	int rc;
+
+	printf("fdisk_label_destroy: begin\n");
 
 	part = fdisk_part_first(dev);
@@ -616,12 +680,25 @@
 	}
 
+	printf("fdisk_label_destroy: vbd_label_delete\n");
+
 	rc = vbd_label_delete(dev->fdisk->vbd, dev->sid);
 	if (rc != EOK)
 		return EIO;
 
+	printf("fdisk_label_destroy: add parts\n");
 	rc = fdisk_dev_add_parts(dev);
 	if (rc != EOK)
 		return rc;
 
+	printf("fdisk_label_destroy: erase dev\n");
+	/* Make sure device is considered empty */
+	fdisk_dev_get_flags(dev, &dflags);
+	if ((dflags & fdf_can_erase_dev) != 0) {
+		rc = fdisk_dev_erase(dev);
+		if (rc != EOK)
+			return rc;
+	}
+
+	printf("fdisk_label_destroy: done\n");
 	return EOK;
 }
Index: uspace/srv/volsrv/empty.c
===================================================================
--- uspace/srv/volsrv/empty.c	(revision edebb4a154d7503a1a506cd53ce84ae086f387d6)
+++ uspace/srv/volsrv/empty.c	(revision ea0ff6b69b253afa7b6b4e9cd38ef8e91ec0daab)
@@ -57,40 +57,17 @@
 }
 
-int vol_part_is_empty(service_id_t sid, bool *rempty)
-{
-	int rc;
-	bool block_inited = false;
-	void *buf = NULL;
-	aoff64_t nblocks;
+/** Calculate number of blocks to check.
+ *
+ * Will store to @a *ncb the number of blocks that should be checked
+ * at the beginning and end of device each.
+ *
+ * @param nblocks Total number of blocks on block device
+ * @param block_size Block size
+ * @param ncb Place to store number of blocks to check.
+ */
+static void calc_num_check_blocks(aoff64_t nblocks, size_t block_size,
+    aoff64_t *ncb)
+{
 	aoff64_t n;
-	aoff64_t i;
-	size_t block_size;
-	bool empty;
-
-	rc = block_init(EXCHANGE_SERIALIZE, sid, 2048);
-	if (rc != EOK) {
-		log_msg(LOG_DEFAULT, LVL_ERROR, "Error opening "
-		    "block device service %zu", sid);
-		rc = EIO;
-		goto error;
-	}
-
-	block_inited = true;
-
-	rc = block_get_bsize(sid, &block_size);
-	if (rc != EOK) {
-		log_msg(LOG_DEFAULT, LVL_ERROR, "Error getting "
-		    "block size.");
-		rc = EIO;
-		goto error;
-	}
-
-	rc = block_get_nblocks(sid, &nblocks);
-	if (rc != EOK) {
-		log_msg(LOG_DEFAULT, LVL_ERROR, "Error getting "
-		    "number of blocks.");
-		rc = EIO;
-		goto error;
-	}
 
 	/* Check first 16 kiB / 16 blocks, whichever is more */
@@ -104,4 +81,46 @@
 	if (n > (nblocks + 1) / 2)
 		n = (nblocks + 1) / 2;
+
+	*ncb = n;
+}
+
+int vol_part_is_empty(service_id_t sid, bool *rempty)
+{
+	int rc;
+	bool block_inited = false;
+	void *buf = NULL;
+	aoff64_t nblocks;
+	aoff64_t n;
+	aoff64_t i;
+	size_t block_size;
+	bool empty;
+
+	rc = block_init(EXCHANGE_SERIALIZE, sid, 2048);
+	if (rc != EOK) {
+		log_msg(LOG_DEFAULT, LVL_ERROR, "Error opening "
+		    "block device service %zu", sid);
+		rc = EIO;
+		goto error;
+	}
+
+	block_inited = true;
+
+	rc = block_get_bsize(sid, &block_size);
+	if (rc != EOK) {
+		log_msg(LOG_DEFAULT, LVL_ERROR, "Error getting "
+		    "block size.");
+		rc = EIO;
+		goto error;
+	}
+
+	rc = block_get_nblocks(sid, &nblocks);
+	if (rc != EOK) {
+		log_msg(LOG_DEFAULT, LVL_ERROR, "Error getting "
+		    "number of blocks.");
+		rc = EIO;
+		goto error;
+	}
+
+	calc_num_check_blocks(nblocks, block_size, &n);
 
 	buf = calloc(block_size, 1);
@@ -157,4 +176,80 @@
 }
 
+int vol_part_empty(service_id_t sid)
+{
+	int rc;
+	bool block_inited = false;
+	void *buf = NULL;
+	aoff64_t nblocks;
+	aoff64_t n;
+	aoff64_t i;
+	size_t block_size;
+
+	rc = block_init(EXCHANGE_SERIALIZE, sid, 2048);
+	if (rc != EOK) {
+		log_msg(LOG_DEFAULT, LVL_ERROR, "Error opening "
+		    "block device service %zu", sid);
+		rc = EIO;
+		goto error;
+	}
+
+	block_inited = true;
+
+	rc = block_get_bsize(sid, &block_size);
+	if (rc != EOK) {
+		log_msg(LOG_DEFAULT, LVL_ERROR, "Error getting "
+		    "block size.");
+		rc = EIO;
+		goto error;
+	}
+
+	rc = block_get_nblocks(sid, &nblocks);
+	if (rc != EOK) {
+		log_msg(LOG_DEFAULT, LVL_ERROR, "Error getting "
+		    "number of blocks.");
+		rc = EIO;
+		goto error;
+	}
+
+	calc_num_check_blocks(nblocks, block_size, &n);
+
+	buf = calloc(block_size, 1);
+	if (buf == NULL) {
+		log_msg(LOG_DEFAULT, LVL_ERROR, "Error allocating buffer.");
+		rc = ENOMEM;
+		goto error;
+	}
+
+	for (i = 0; i < n; i++) {
+		rc = block_write_direct(sid, i, 1, buf);
+		if (rc != EOK) {
+			log_msg(LOG_DEFAULT, LVL_ERROR, "Error "
+			    "reading blocks.");
+			rc = EIO;
+			goto error;
+		}
+	}
+
+	for (i = 0; i < n; i++) {
+		rc = block_write_direct(sid, nblocks - n + i, 1, buf);
+		if (rc != EOK) {
+			log_msg(LOG_DEFAULT, LVL_ERROR, "Error "
+			    "reading blocks.");
+			rc = EIO;
+			goto error;
+		}
+	}
+
+	block_fini(sid);
+	free(buf);
+	return EOK;
+error:
+	if (block_inited)
+		block_fini(sid);
+	if (buf != NULL)
+		free(buf);
+	return rc;
+}
+
 /** @}
  */
Index: uspace/srv/volsrv/empty.h
===================================================================
--- uspace/srv/volsrv/empty.h	(revision edebb4a154d7503a1a506cd53ce84ae086f387d6)
+++ uspace/srv/volsrv/empty.h	(revision ea0ff6b69b253afa7b6b4e9cd38ef8e91ec0daab)
@@ -41,4 +41,5 @@
 
 extern int vol_part_is_empty(service_id_t, bool *);
+extern int vol_part_empty(service_id_t);
 
 #endif
Index: uspace/srv/volsrv/part.c
===================================================================
--- uspace/srv/volsrv/part.c	(revision edebb4a154d7503a1a506cd53ce84ae086f387d6)
+++ uspace/srv/volsrv/part.c	(revision ea0ff6b69b253afa7b6b4e9cd38ef8e91ec0daab)
@@ -252,6 +252,17 @@
 int vol_part_empty_part(vol_part_t *part)
 {
+	int rc;
+
+	log_msg(LOG_DEFAULT, LVL_NOTE, "vol_part_empty_part()");
+
+	rc = vol_part_empty(part->svc_id);
+	if (rc != EOK) {
+		log_msg(LOG_DEFAULT, LVL_NOTE, "vol_part_empty_part() - failed %d",
+		    rc);
+		return rc;
+	}
+
+	log_msg(LOG_DEFAULT, LVL_NOTE, "vol_part_empty_part() - success");
 	part->pcnt = vpc_empty;
-
 	return EOK;
 }
Index: uspace/srv/volsrv/volsrv.c
===================================================================
--- uspace/srv/volsrv/volsrv.c	(revision edebb4a154d7503a1a506cd53ce84ae086f387d6)
+++ uspace/srv/volsrv/volsrv.c	(revision ea0ff6b69b253afa7b6b4e9cd38ef8e91ec0daab)
@@ -199,11 +199,16 @@
 
 	sid = IPC_GET_ARG1(*icall);
+	log_msg(LOG_DEFAULT, LVL_NOTE, "vol_part_empty_srv(%zu)", sid);
 
 	rc = vol_part_find_by_id(sid, &part);
 	if (rc != EOK) {
+		log_msg(LOG_DEFAULT, LVL_NOTE, "vol_part_empty_srv(%zu) - "
+		    "partition not found", sid);
 		async_answer_0(iid, ENOENT);
 		return;
 	}
 
+	log_msg(LOG_DEFAULT, LVL_NOTE, "vol_part_empty_srv(%zu) - "
+	    "call vol_part_empty_part()", sid);
 	rc = vol_part_empty_part(part);
 	if (rc != EOK) {
