Index: uspace/app/fdisk/fdisk.c
===================================================================
--- uspace/app/fdisk/fdisk.c	(revision 4b6635a753fc6cfed370d74f7f99b2d9848440e0)
+++ uspace/app/fdisk/fdisk.c	(revision edebb4a154d7503a1a506cd53ce84ae086f387d6)
@@ -565,5 +565,9 @@
 		}
 
-		printf("Partition %d: %s", npart, scap);
+		if (linfo.ltype == lt_none)
+			printf("Entire disk: %s", scap);
+		else
+			printf("Partition %d: %s", npart, scap);
+
 		if ((linfo.flags & lf_ext_supp) != 0) {
 			rc = fdisk_pkind_format(pinfo.pkind, &spkind);
@@ -653,5 +657,5 @@
 	}
 
-	if (npart > 0) {
+	if ((linfo.flags & lf_can_delete_part) != 0) {
 		rc = nchoice_add(choice, "Delete partition",
 		    (void *)devac_delete_part);
Index: uspace/lib/c/generic/vol.c
===================================================================
--- uspace/lib/c/generic/vol.c	(revision 4b6635a753fc6cfed370d74f7f99b2d9848440e0)
+++ uspace/lib/c/generic/vol.c	(revision edebb4a154d7503a1a506cd53ce84ae086f387d6)
@@ -188,4 +188,25 @@
 }
 
+/** Add partition.
+ *
+ * After a partition is created (e.g. as a result of deleting a label
+ * the dummy partition is created), it can take some (unknown) time
+ * until it is discovered.
+ */
+int vol_part_add(vol_t *vol, service_id_t sid)
+{
+	async_exch_t *exch;
+	int retval;
+
+	exch = async_exchange_begin(vol->sess);
+	retval = async_req_1_0(exch, VOL_PART_ADD, sid);
+	async_exchange_end(exch);
+
+	if (retval != EOK)
+		return retval;
+
+	return EOK;
+}
+
 /** Get partition information. */
 int vol_part_info(vol_t *vol, service_id_t sid, vol_part_info_t *vinfo)
Index: uspace/lib/c/include/ipc/vol.h
===================================================================
--- uspace/lib/c/include/ipc/vol.h	(revision 4b6635a753fc6cfed370d74f7f99b2d9848440e0)
+++ uspace/lib/c/include/ipc/vol.h	(revision edebb4a154d7503a1a506cd53ce84ae086f387d6)
@@ -38,4 +38,5 @@
 typedef enum {
 	VOL_GET_PARTS = IPC_FIRST_USER_METHOD,
+	VOL_PART_ADD,
 	VOL_PART_INFO,
 	VOL_PART_EMPTY
Index: uspace/lib/c/include/types/label.h
===================================================================
--- uspace/lib/c/include/types/label.h	(revision 4b6635a753fc6cfed370d74f7f99b2d9848440e0)
+++ uspace/lib/c/include/types/label.h	(revision edebb4a154d7503a1a506cd53ce84ae086f387d6)
@@ -81,6 +81,8 @@
 	/** Currently it is possible to create an extended partition */
 	lf_can_create_ext = 0x8,
-	/** Currrently it is possible to create a logical partition */
-	lf_can_create_log = 0x10
+	/** Currently it is possible to create a logical partition */
+	lf_can_create_log = 0x10,
+	/** Currently it is possible to delete a partition */
+	lf_can_delete_part = 0x20
 } label_flags_t;
 
Index: uspace/lib/c/include/types/vol.h
===================================================================
--- uspace/lib/c/include/types/vol.h	(revision 4b6635a753fc6cfed370d74f7f99b2d9848440e0)
+++ uspace/lib/c/include/types/vol.h	(revision edebb4a154d7503a1a506cd53ce84ae086f387d6)
@@ -55,4 +55,18 @@
 #define VOL_FSTYPE_LIMIT (fs_ext4 + 1)
 
+/** Volume service */
+typedef struct vol {
+	/** Volume service session */
+	async_sess_t *sess;
+} vol_t;
+
+/** Partition information */
+typedef struct {
+	/** Partition content type */
+	vol_part_cnt_t pcnt;
+	/** Filesystem type */
+	vol_fstype_t fstype;
+} vol_part_info_t;
+
 #endif
 
Index: uspace/lib/c/include/vol.h
===================================================================
--- uspace/lib/c/include/vol.h	(revision 4b6635a753fc6cfed370d74f7f99b2d9848440e0)
+++ uspace/lib/c/include/vol.h	(revision edebb4a154d7503a1a506cd53ce84ae086f387d6)
@@ -42,21 +42,8 @@
 #include <types/vol.h>
 
-/** Volume service */
-typedef struct vol {
-	/** Volume service session */
-	async_sess_t *sess;
-} vol_t;
-
-/** Partition information */
-typedef struct {
-	/** Partition content type */
-	vol_part_cnt_t pcnt;
-	/** Filesystem type */
-	vol_fstype_t fstype;
-} vol_part_info_t;
-
 extern int vol_create(vol_t **);
 extern void vol_destroy(vol_t *);
 extern int vol_get_parts(vol_t *, service_id_t **, size_t *);
+extern int vol_part_add(vol_t *, service_id_t);
 extern int vol_part_info(vol_t *, service_id_t, vol_part_info_t *);
 extern int vol_part_empty(vol_t *, service_id_t);
Index: uspace/lib/fdisk/src/fdisk.c
===================================================================
--- uspace/lib/fdisk/src/fdisk.c	(revision 4b6635a753fc6cfed370d74f7f99b2d9848440e0)
+++ uspace/lib/fdisk/src/fdisk.c	(revision edebb4a154d7503a1a506cd53ce84ae086f387d6)
@@ -58,4 +58,6 @@
 };
 
+static int fdisk_dev_add_parts(fdisk_dev_t *);
+static void fdisk_dev_remove_parts(fdisk_dev_t *);
 static int fdisk_part_spec_prepare(fdisk_dev_t *, fdisk_part_spec_t *,
     vbd_part_spec_t *);
@@ -256,4 +258,5 @@
 }
 
+/** Add partition to our inventory. */
 static int fdisk_part_add(fdisk_dev_t *dev, vbd_part_id_t partid,
     fdisk_part_t **rpart)
@@ -268,4 +271,5 @@
 		return ENOMEM;
 
+	printf("vbd_part_get_info(%zu)\n", partid);
 	rc = vbd_part_get_info(dev->fdisk->vbd, partid, &pinfo);
 	if (rc != EOK) {
@@ -274,5 +278,19 @@
 	}
 
+	printf("vol_part_add(%zu)...\n", pinfo.svc_id);
+	/*
+	 * Normally vol service discovers the partition asynchronously.
+	 * Here we need to make sure the partition is already known to it.
+	 */
+	rc = vol_part_add(dev->fdisk->vol, pinfo.svc_id);
+	printf("vol_part_add->rc = %d\n", rc);
+	if (rc != EOK && rc != EEXIST) {
+		rc = EIO;
+		goto error;
+	}
+
+	printf("vol_part_info(%zu)\n", pinfo.svc_id);
 	rc = vol_part_info(dev->fdisk->vol, pinfo.svc_id, &vpinfo);
+	printf("vol_part_info->rc = %d\n", rc);
 	if (rc != EOK) {
 		rc = EIO;
@@ -316,4 +334,17 @@
 }
 
+/** Remove partition from our inventory. */
+static void fdisk_part_remove(fdisk_part_t *part)
+{
+	list_remove(&part->lparts);
+	if (link_used(&part->lpri_ba))
+		list_remove(&part->lpri_ba);
+	if (link_used(&part->lpri_idx))
+		list_remove(&part->lpri_idx);
+	if (link_used(&part->llog_ba))
+		list_remove(&part->llog_ba);
+	free(part);
+}
+
 static void fdisk_pri_part_insert_lists(fdisk_dev_t *dev, fdisk_part_t *part)
 {
@@ -373,28 +404,9 @@
 }
 
-int fdisk_dev_open(fdisk_t *fdisk, service_id_t sid, fdisk_dev_t **rdev)
-{
-	vbd_disk_info_t vinfo;
-	fdisk_dev_t *dev = NULL;
+static int fdisk_dev_add_parts(fdisk_dev_t *dev)
+{
 	service_id_t *psids = NULL;
 	size_t nparts, i;
 	int rc;
-
-	dev = calloc(1, sizeof(fdisk_dev_t));
-	if (dev == NULL)
-		return ENOMEM;
-
-	dev->fdisk = fdisk;
-	dev->sid = sid;
-	list_initialize(&dev->parts);
-	list_initialize(&dev->pri_idx);
-	list_initialize(&dev->pri_ba);
-	list_initialize(&dev->log_ba);
-
-	rc = vbd_disk_info(fdisk->vbd, sid, &vinfo);
-	if (rc != EOK) {
-		rc = EIO;
-		goto error;
-	}
 
 	printf("get label info\n");
@@ -408,5 +420,5 @@
 	printf("block size: %zu\n", dev->dinfo.block_size);
 	printf("get partitions\n");
-	rc = vbd_label_get_parts(fdisk->vbd, sid, &psids, &nparts);
+	rc = vbd_label_get_parts(dev->fdisk->vbd, dev->sid, &psids, &nparts);
 	if (rc != EOK) {
 		printf("failed\n");
@@ -428,4 +440,76 @@
 
 	free(psids);
+	return EOK;
+error:
+	fdisk_dev_remove_parts(dev);
+	return rc;
+}
+
+static void fdisk_dev_remove_parts(fdisk_dev_t *dev)
+{
+	fdisk_part_t *part;
+
+	part = fdisk_part_first(dev);
+	while (part != NULL) {
+		fdisk_part_remove(part);
+		part = fdisk_part_first(dev);
+	}
+}
+
+int fdisk_dev_open(fdisk_t *fdisk, service_id_t sid, fdisk_dev_t **rdev)
+{
+	vbd_disk_info_t vinfo;
+	fdisk_dev_t *dev = NULL;
+	service_id_t *psids = NULL;
+	size_t nparts, i;
+	int rc;
+
+	dev = calloc(1, sizeof(fdisk_dev_t));
+	if (dev == NULL)
+		return ENOMEM;
+
+	dev->fdisk = fdisk;
+	dev->sid = sid;
+	list_initialize(&dev->parts);
+	list_initialize(&dev->pri_idx);
+	list_initialize(&dev->pri_ba);
+	list_initialize(&dev->log_ba);
+
+	rc = vbd_disk_info(fdisk->vbd, sid, &vinfo);
+	if (rc != EOK) {
+		rc = EIO;
+		goto error;
+	}
+
+	printf("get label info\n");
+	rc = fdisk_update_dev_info(dev);
+	if (rc != EOK) {
+		printf("failed\n");
+		rc = EIO;
+		goto error;
+	}
+
+	printf("block size: %zu\n", dev->dinfo.block_size);
+	printf("get partitions\n");
+	rc = vbd_label_get_parts(fdisk->vbd, sid, &psids, &nparts);
+	if (rc != EOK) {
+		printf("failed\n");
+		rc = EIO;
+		goto error;
+	}
+	printf("OK\n");
+
+	printf("found %zu partitions.\n", nparts);
+	for (i = 0; i < nparts; i++) {
+		printf("add partition sid=%zu\n", psids[i]);
+		rc = fdisk_part_add(dev, psids[i], NULL);
+		if (rc != EOK) {
+			printf("failed\n");
+			goto error;
+		}
+		printf("OK\n");
+	}
+
+	free(psids);
 	*rdev = dev;
 	return EOK;
@@ -440,5 +524,5 @@
 		return;
 
-	/* XXX Clean up partitions */
+	fdisk_dev_remove_parts(dev);
 	free(dev);
 }
@@ -504,4 +588,7 @@
 {
 	int rc;
+
+	/* Remove dummy partition */
+	fdisk_dev_remove_parts(dev);
 
 	rc = vbd_label_create(dev->fdisk->vbd, dev->sid, ltype);
@@ -533,4 +620,8 @@
 		return EIO;
 
+	rc = fdisk_dev_add_parts(dev);
+	if (rc != EOK)
+		return rc;
+
 	return EOK;
 }
@@ -617,12 +708,5 @@
 		return EIO;
 
-	list_remove(&part->lparts);
-	if (link_used(&part->lpri_ba))
-		list_remove(&part->lpri_ba);
-	if (link_used(&part->lpri_idx))
-		list_remove(&part->lpri_idx);
-	if (link_used(&part->llog_ba))
-		list_remove(&part->llog_ba);
-	free(part);
+	fdisk_part_remove(part);
 	return EOK;
 }
Index: uspace/lib/label/src/gpt.c
===================================================================
--- uspace/lib/label/src/gpt.c	(revision 4b6635a753fc6cfed370d74f7f99b2d9848440e0)
+++ uspace/lib/label/src/gpt.c	(revision edebb4a154d7503a1a506cd53ce84ae086f387d6)
@@ -544,4 +544,9 @@
 }
 
+static bool gpt_can_delete_part(label_t *label)
+{
+	return list_count(&label->parts) > 0;
+}
+
 static int gpt_get_info(label_t *label, label_info_t *linfo)
 {
@@ -551,4 +556,6 @@
 	if (gpt_can_create_pri(label))
 		linfo->flags = linfo->flags | lf_can_create_pri;
+	if (gpt_can_delete_part(label))
+		linfo->flags = linfo->flags | lf_can_delete_part;
 	linfo->ablock0 = label->ablock0;
 	linfo->anblocks = label->anblocks;
Index: uspace/lib/label/src/mbr.c
===================================================================
--- uspace/lib/label/src/mbr.c	(revision 4b6635a753fc6cfed370d74f7f99b2d9848440e0)
+++ uspace/lib/label/src/mbr.c	(revision edebb4a154d7503a1a506cd53ce84ae086f387d6)
@@ -399,4 +399,9 @@
 }
 
+static bool mbr_can_delete_part(label_t *label)
+{
+	return list_count(&label->parts) > 0;
+}
+
 static int mbr_get_info(label_t *label, label_info_t *linfo)
 {
@@ -416,4 +421,7 @@
 	if (label->ext_part != NULL)
 		linfo->flags |= lf_can_create_log;
+	/* Can delete partition */
+	if (mbr_can_delete_part(label))
+		linfo->flags |= lf_can_delete_part;
 
 	linfo->ablock0 = label->ablock0;
Index: uspace/srv/bd/vbd/disk.c
===================================================================
--- uspace/srv/bd/vbd/disk.c	(revision 4b6635a753fc6cfed370d74f7f99b2d9848440e0)
+++ uspace/srv/bd/vbd/disk.c	(revision edebb4a154d7503a1a506cd53ce84ae086f387d6)
@@ -907,4 +907,6 @@
 	}
 
+	log_msg(LOG_DEFAULT, LVL_NOTE, "loc_service_register('%s')",
+	    name);
 	rc = loc_service_register(name, &psid);
 	if (rc != EOK) {
Index: uspace/srv/volsrv/part.c
===================================================================
--- uspace/srv/volsrv/part.c	(revision 4b6635a753fc6cfed370d74f7f99b2d9848440e0)
+++ uspace/srv/volsrv/part.c	(revision edebb4a154d7503a1a506cd53ce84ae086f387d6)
@@ -47,6 +47,5 @@
 #include "types/part.h"
 
-static int vol_part_add(service_id_t);
-
+static int vol_part_add_locked(service_id_t);
 static LIST_INITIALIZE(vol_parts); /* of vol_part_t */
 static FIBRIL_MUTEX_INITIALIZE(vol_parts_lock);
@@ -91,5 +90,5 @@
 			log_msg(LOG_DEFAULT, LVL_NOTE, "Found partition '%lu'",
 			    (unsigned long) svcs[i]);
-			rc = vol_part_add(svcs[i]);
+			rc = vol_part_add_locked(svcs[i]);
 			if (rc != EOK) {
 				log_msg(LOG_DEFAULT, LVL_ERROR, "Could not add "
@@ -128,5 +127,5 @@
 }
 
-static int vol_part_add(service_id_t sid)
+static int vol_part_add_locked(service_id_t sid)
 {
 	vol_part_t *part;
@@ -135,4 +134,9 @@
 
 	assert(fibril_mutex_is_locked(&vol_parts_lock));
+
+	/* Check for duplicates */
+	rc = vol_part_find_by_id(sid, &part);
+	if (rc == EOK)
+		return EEXIST;
 
 	log_msg(LOG_DEFAULT, LVL_NOTE, "vol_part_add()");
@@ -160,8 +164,21 @@
 	list_append(&part->lparts, &vol_parts);
 
+	log_msg(LOG_DEFAULT, LVL_NOTE, "Added partition %zu", part->svc_id);
+
 	return EOK;
 
 error:
 	vol_part_delete(part);
+	return rc;
+}
+
+int vol_part_add(service_id_t sid)
+{
+	int rc;
+
+	fibril_mutex_lock(&vol_parts_lock);
+	rc = vol_part_add_locked(sid);
+	fibril_mutex_unlock(&vol_parts_lock);
+
 	return rc;
 }
Index: uspace/srv/volsrv/part.h
===================================================================
--- uspace/srv/volsrv/part.h	(revision 4b6635a753fc6cfed370d74f7f99b2d9848440e0)
+++ uspace/srv/volsrv/part.h	(revision edebb4a154d7503a1a506cd53ce84ae086f387d6)
@@ -40,9 +40,10 @@
 #include <loc.h>
 #include <sys/types.h>
-#include <vol.h>
+#include <types/vol.h>
 #include "types/part.h"
 
 extern int vol_part_init(void);
 extern int vol_part_discovery_start(void);
+extern int vol_part_add(service_id_t);
 extern int vol_part_get_ids(service_id_t *, size_t, size_t *);
 extern int vol_part_find_by_id(service_id_t, vol_part_t **);
Index: uspace/srv/volsrv/volsrv.c
===================================================================
--- uspace/srv/volsrv/volsrv.c	(revision 4b6635a753fc6cfed370d74f7f99b2d9848440e0)
+++ uspace/srv/volsrv/volsrv.c	(revision edebb4a154d7503a1a506cd53ce84ae086f387d6)
@@ -44,5 +44,5 @@
 #include <stdlib.h>
 #include <task.h>
-#include <vol.h>
+#include <types/vol.h>
 
 #include "part.h"
@@ -116,4 +116,21 @@
 }
 
+static void vol_part_add_srv(ipc_callid_t iid, ipc_call_t *icall)
+{
+	service_id_t sid;
+	int rc;
+
+	sid = IPC_GET_ARG1(*icall);
+
+	rc = vol_part_add(sid);
+	if (rc != EOK) {
+		async_answer_0(iid, rc);
+		return;
+	}
+
+	async_answer_0(iid, EOK);
+}
+
+
 static void vol_part_info_srv(ipc_callid_t iid, ipc_call_t *icall)
 {
@@ -124,7 +141,11 @@
 
 	sid = IPC_GET_ARG1(*icall);
+	log_msg(LOG_DEFAULT, LVL_NOTE, "vol_part_info_srv(%zu)",
+	    sid);
 	rc = vol_part_find_by_id(sid, &part);
 	if (rc != EOK) {
 		async_answer_0(iid, ENOENT);
+		log_msg(LOG_DEFAULT, LVL_NOTE, "vol_part_info_srv(%zu) - "
+		    "not found", sid);
 		return;
 	}
@@ -133,4 +154,6 @@
 	if (rc != EOK) {
 		async_answer_0(iid, EIO);
+		log_msg(LOG_DEFAULT, LVL_NOTE, "vol_part_info_srv(%zu) - "
+		    "get info failed (%d)", sid, rc);
 		return;
 	}
@@ -141,4 +164,6 @@
 		async_answer_0(callid, EREFUSED);
 		async_answer_0(iid, EREFUSED);
+		log_msg(LOG_DEFAULT, LVL_NOTE, "vol_part_info_srv(%zu) - "
+		    "read receive failed", sid);
 		return;
 	}
@@ -147,4 +172,6 @@
 		async_answer_0(callid, EINVAL);
 		async_answer_0(iid, EINVAL);
+		log_msg(LOG_DEFAULT, LVL_NOTE, "vol_part_info_srv(%zu) - "
+		    "incorrect size", sid);
 		return;
 	}
@@ -155,7 +182,11 @@
 		async_answer_0(callid, rc);
 		async_answer_0(iid, rc);
-		return;
-	}
-
+		log_msg(LOG_DEFAULT, LVL_NOTE, "vol_part_info_srv(%zu) - "
+		    "data read failed", sid);
+		return;
+	}
+
+	log_msg(LOG_DEFAULT, LVL_NOTE, "vol_part_info_srv(%zu) - "
+	    "success", sid);
 	async_answer_0(iid, EOK);
 }
@@ -206,4 +237,7 @@
 			vol_get_parts_srv(callid, &call);
 			break;
+		case VOL_PART_ADD:
+			vol_part_add_srv(callid, &call);
+			break;
 		case VOL_PART_INFO:
 			vol_part_info_srv(callid, &call);
