Index: uspace/app/fdisk/fdisk.c
===================================================================
--- uspace/app/fdisk/fdisk.c	(revision 70815a24cf429286a07e08f8ad1f2a835d6be638)
+++ uspace/app/fdisk/fdisk.c	(revision b7a4d06b6d03da11c24ad8eee4f374f7b8a7dc13)
@@ -51,6 +51,10 @@
 	/** Delete label */
 	devac_delete_label,
-	/** Create partition */
-	devac_create_part,
+	/** Create (primary) partition */
+	devac_create_pri_part,
+	/** Create extended partition */
+	devac_create_ext_part,
+	/** Create logical partition */
+	devac_create_log_part,
 	/** Delete partition */
 	devac_delete_part,
@@ -312,10 +316,10 @@
 }
 
-static int fdsk_create_part(fdisk_dev_t *dev)
+static int fdsk_create_part(fdisk_dev_t *dev, label_pkind_t pkind)
 {
 	int rc;
 	fdisk_part_spec_t pspec;
 	fdisk_cap_t cap;
-	fdisk_fstype_t fstype;
+	fdisk_fstype_t fstype = fdfs_none;
 	tinput_t *tinput = NULL;
 	char *scap;
@@ -345,10 +349,13 @@
 	tinput = NULL;
 
-	rc = fdsk_select_fstype(&fstype);
-	if (rc != EOK)
-		goto error;
+	if (pkind != lpk_extended) {
+		rc = fdsk_select_fstype(&fstype);
+		if (rc != EOK)
+			goto error;
+	}
 
 	fdisk_pspec_init(&pspec);
 	pspec.capacity = cap;
+	pspec.pkind = pkind;
 	pspec.fstype = fstype;
 
@@ -471,4 +478,5 @@
 	char *sfstype = NULL;
 	char *svcname = NULL;
+	char *spkind;
 	int rc;
 	int npart;
@@ -563,5 +571,20 @@
 		}
 
-		printf("Partition %d: %s, %s\n", npart, scap, sfstype);
+		printf("Partition %d: %s", npart, scap);
+		if ((linfo.flags & lf_ext_supp) != 0) {
+			rc = fdisk_pkind_format(pinfo.pkind, &spkind);
+			if (rc != EOK) {
+				printf("\nOut of memory.\n");
+				goto error;
+			}
+
+			printf(", %s", spkind);
+			free(spkind);
+		}
+
+		if (pinfo.pkind != lpk_extended)
+			printf(", %s", sfstype);
+		printf("\n");
+
 		free(scap);
 		scap = NULL;
@@ -580,10 +603,47 @@
 
 	if (linfo.dcnt == dc_label) {
-		rc = nchoice_add(choice, "Create partition",
-		    (void *)devac_create_part);
-		if (rc != EOK) {
-			assert(rc == ENOMEM);
-			printf("Out of memory.\n");
-			goto error;
+		if ((linfo.flags & lf_ext_supp) != 0) {
+			if ((linfo.flags & lf_can_create_pri) != 0) {
+				rc = nchoice_add(choice, "Create primary "
+				    "partition",
+				    (void *)devac_create_pri_part);
+				if (rc != EOK) {
+					assert(rc == ENOMEM);
+					printf("Out of memory.\n");
+					goto error;
+				}
+			}
+
+			if ((linfo.flags & lf_can_create_ext) != 0) {
+				rc = nchoice_add(choice, "Create extended "
+				    "partition",
+				    (void *)devac_create_ext_part);
+				if (rc != EOK) {
+					assert(rc == ENOMEM);
+					printf("Out of memory.\n");
+					goto error;
+				}
+			}
+
+			if ((linfo.flags & lf_can_create_log) != 0) {
+				rc = nchoice_add(choice, "Create logical "
+				    "partition",
+				    (void *)devac_create_log_part);
+				if (rc != EOK) {
+					assert(rc == ENOMEM);
+					printf("Out of memory.\n");
+					goto error;
+				}
+			}
+		} else { /* (linfo.flags & lf_ext_supp) == 0 */
+			if ((linfo.flags & lf_can_create_pri) != 0) {
+				rc = nchoice_add(choice, "Create partition",
+				    (void *)devac_create_pri_part);
+				if (rc != EOK) {
+					assert(rc == ENOMEM);
+					printf("Out of memory.\n");
+					goto error;
+				}
+			}
 		}
 	}
@@ -637,6 +697,12 @@
 		(void) fdsk_delete_label(dev);
 		break;
-	case devac_create_part:
-		(void) fdsk_create_part(dev);
+	case devac_create_pri_part:
+		(void) fdsk_create_part(dev, lpk_primary);
+		break;
+	case devac_create_ext_part:
+		(void) fdsk_create_part(dev, lpk_extended);
+		break;
+	case devac_create_log_part:
+		(void) fdsk_create_part(dev, lpk_logical);
 		break;
 	case devac_delete_part:
Index: uspace/lib/c/generic/vbd.c
===================================================================
--- uspace/lib/c/generic/vbd.c	(revision 70815a24cf429286a07e08f8ad1f2a835d6be638)
+++ uspace/lib/c/generic/vbd.c	(revision b7a4d06b6d03da11c24ad8eee4f374f7b8a7dc13)
@@ -264,20 +264,21 @@
 {
 	async_exch_t *exch;
-	sysarg_t index;
-	sysarg_t b0_lo, b0_hi;
-	sysarg_t nb_lo, nb_hi;
-	int retval;
-
-	exch = async_exchange_begin(vbd->sess);
-	retval = async_req_1_5(exch, VBD_PART_GET_INFO, part, &index,
-	    &b0_lo, &b0_hi, &nb_lo, &nb_hi);
-	async_exchange_end(exch);
-
-	if (retval != EOK)
-		return EIO;
-
-	pinfo->index = index;
-	pinfo->block0 = MERGE_LOUP32(b0_lo, b0_hi);
-	pinfo->nblocks = MERGE_LOUP32(nb_lo, nb_hi);
+	sysarg_t retval;
+	ipc_call_t answer;
+
+	exch = async_exchange_begin(vbd->sess);
+	aid_t req = async_send_1(exch, VBD_PART_GET_INFO, part, &answer);
+	int rc = async_data_read_start(exch, pinfo, sizeof(vbd_part_info_t));
+	async_exchange_end(exch);
+
+	if (rc != EOK) {
+		async_forget(req);
+		return EIO;
+	}
+
+	async_wait_for(req, &retval);
+	if (retval != EOK)
+		return EIO;
+
 	return EOK;
 }
Index: uspace/lib/c/generic/vol.c
===================================================================
--- uspace/lib/c/generic/vol.c	(revision 70815a24cf429286a07e08f8ad1f2a835d6be638)
+++ uspace/lib/c/generic/vol.c	(revision b7a4d06b6d03da11c24ad8eee4f374f7b8a7dc13)
@@ -192,9 +192,10 @@
 {
 	async_exch_t *exch;
-	sysarg_t dcnt, ltype;
+	sysarg_t dcnt, ltype, flags;
 	int retval;
 
 	exch = async_exchange_begin(vol->sess);
-	retval = async_req_1_2(exch, VOL_DISK_INFO, sid, &dcnt, &ltype);
+	retval = async_req_1_3(exch, VOL_DISK_INFO, sid, &dcnt, &ltype,
+	    &flags);
 	async_exchange_end(exch);
 
@@ -204,4 +205,5 @@
 	vinfo->dcnt = (label_disk_cnt_t)dcnt;
 	vinfo->ltype = (label_type_t)ltype;
+	vinfo->flags = (label_flags_t)flags;
 	return EOK;
 }
Index: uspace/lib/c/include/types/label.h
===================================================================
--- uspace/lib/c/include/types/label.h	(revision 70815a24cf429286a07e08f8ad1f2a835d6be638)
+++ uspace/lib/c/include/types/label.h	(revision b7a4d06b6d03da11c24ad8eee4f374f7b8a7dc13)
@@ -58,4 +58,25 @@
 #define LT_LIMIT (lt_gpt + 1)
 
+/** Partition kind */
+typedef enum {
+	/** Primary partition */
+	lpk_primary,
+	/** Extended partition */
+	lpk_extended,
+	/** Logical partition */
+	lpk_logical
+} label_pkind_t;
+
+/** Label flags */
+typedef enum {
+	/** Label supports extended (and logical) partitions */
+	lf_ext_supp = 0x1,
+	/** Currently it is possible to create a primary partition */
+	lf_can_create_pri = 0x2,
+	/** Currently it is possible to create an extended partition */
+	lf_can_create_ext = 0x4,
+	/** Currrently it is possible to create a logical partition */
+	lf_can_create_log = 0x8
+} label_flags_t;
 
 #endif
Index: uspace/lib/c/include/vbd.h
===================================================================
--- uspace/lib/c/include/vbd.h	(revision 70815a24cf429286a07e08f8ad1f2a835d6be638)
+++ uspace/lib/c/include/vbd.h	(revision b7a4d06b6d03da11c24ad8eee4f374f7b8a7dc13)
@@ -51,4 +51,6 @@
 	/** Label type */
 	label_type_t ltype;
+	/** Label flags */
+	label_flags_t flags;
 	/** First block that can be allocated */
 	aoff64_t ablock0;
@@ -67,4 +69,6 @@
 	/** Number of blocks */
 	aoff64_t nblocks;
+	/** Partition kind */
+	label_pkind_t pkind;
 	/** Partition type */
 	uint64_t ptype;
@@ -75,4 +79,6 @@
 	/** Partition index */
 	int index;
+	/** Partition kind */
+	label_pkind_t pkind;
 	/** First block */
 	aoff64_t block0;
Index: uspace/lib/c/include/vol.h
===================================================================
--- uspace/lib/c/include/vol.h	(revision 70815a24cf429286a07e08f8ad1f2a835d6be638)
+++ uspace/lib/c/include/vol.h	(revision b7a4d06b6d03da11c24ad8eee4f374f7b8a7dc13)
@@ -53,4 +53,6 @@
 	/** Label type, if disk contents is label */
 	label_type_t ltype;
+	/** Label flags */
+	label_flags_t flags;
 } vol_disk_info_t;
 
Index: uspace/lib/fdisk/include/fdisk.h
===================================================================
--- uspace/lib/fdisk/include/fdisk.h	(revision 70815a24cf429286a07e08f8ad1f2a835d6be638)
+++ uspace/lib/fdisk/include/fdisk.h	(revision b7a4d06b6d03da11c24ad8eee4f374f7b8a7dc13)
@@ -72,4 +72,5 @@
 extern int fdisk_ltype_format(label_type_t, char **);
 extern int fdisk_fstype_format(fdisk_fstype_t, char **);
+extern int fdisk_pkind_format(label_pkind_t, char **);
 
 #endif
Index: uspace/lib/fdisk/include/types/fdisk.h
===================================================================
--- uspace/lib/fdisk/include/types/fdisk.h	(revision 70815a24cf429286a07e08f8ad1f2a835d6be638)
+++ uspace/lib/fdisk/include/types/fdisk.h	(revision b7a4d06b6d03da11c24ad8eee4f374f7b8a7dc13)
@@ -119,4 +119,6 @@
 	/** Label type */
 	label_type_t ltype;
+	/** Label flags */
+	label_flags_t flags;
 } fdisk_label_info_t;
 
@@ -131,4 +133,6 @@
 	/** Capacity */
 	fdisk_cap_t capacity;
+	/** Partition kind */
+	label_pkind_t pkind;
 	/** File system type */
 	fdisk_fstype_t fstype;
@@ -147,4 +151,6 @@
 	/** Desired capacity */
 	fdisk_cap_t capacity;
+	/** Partition kind */
+	label_pkind_t pkind;
 	/** File system type */
 	fdisk_fstype_t fstype;
@@ -153,5 +159,8 @@
 /** Partition info */
 typedef struct {
+	/** Capacity */
 	fdisk_cap_t capacity;
+	/** Partition kind */
+	label_pkind_t pkind;
 	/** File system type */
 	fdisk_fstype_t fstype;
Index: uspace/lib/fdisk/src/fdisk.c
===================================================================
--- uspace/lib/fdisk/src/fdisk.c	(revision 70815a24cf429286a07e08f8ad1f2a835d6be638)
+++ uspace/lib/fdisk/src/fdisk.c	(revision b7a4d06b6d03da11c24ad8eee4f374f7b8a7dc13)
@@ -271,4 +271,5 @@
 	part->block0 = pinfo.block0;
 	part->nblocks = pinfo.nblocks;
+	part->pkind = pinfo.pkind;
 
 	/* Insert to list by block address */
@@ -442,4 +443,5 @@
 	info->dcnt = vinfo.dcnt;
 	info->ltype = vinfo.ltype;
+	info->flags = vinfo.flags;
 	return EOK;
 error:
@@ -497,4 +499,5 @@
 	info->capacity = part->capacity;
 	info->fstype = part->fstype;
+	info->pkind = part->pkind;
 	return EOK;
 }
@@ -671,4 +674,30 @@
 }
 
+int fdisk_pkind_format(label_pkind_t pkind, char **rstr)
+{
+	const char *spkind;
+	char *s;
+
+	spkind = NULL;
+	switch (pkind) {
+	case lpk_primary:
+		spkind = "Primary";
+		break;
+	case lpk_extended:
+		spkind = "Extended";
+		break;
+	case lpk_logical:
+		spkind = "Logical";
+		break;
+	}
+
+	s = str_dup(spkind);
+	if (s == NULL)
+		return ENOMEM;
+
+	*rstr = s;
+	return EOK;
+}
+
 /** Get free partition index. */
 static int fdisk_part_get_free_idx(fdisk_dev_t *dev, int *rindex)
@@ -765,8 +794,12 @@
 		return EIO;
 
+	memset(vpspec, 0, sizeof(vbd_part_spec_t));
 	vpspec->index = index;
 	vpspec->block0 = fblock0;
 	vpspec->nblocks = req_blocks;
-	vpspec->ptype = 42;
+	vpspec->pkind = pspec->pkind;
+	if (pspec->pkind != lpk_extended)
+		vpspec->ptype = 42;
+
 	return EOK;
 }
Index: uspace/lib/label/include/types/liblabel.h
===================================================================
--- uspace/lib/label/include/types/liblabel.h	(revision 70815a24cf429286a07e08f8ad1f2a835d6be638)
+++ uspace/lib/label/include/types/liblabel.h	(revision b7a4d06b6d03da11c24ad8eee4f374f7b8a7dc13)
@@ -68,4 +68,6 @@
 	/** Label type */
 	label_type_t ltype;
+	/** Label flags */
+	label_flags_t flags;
 	/** First block that can be allocated */
 	aoff64_t ablock0;
@@ -77,4 +79,6 @@
 	/** Partition index */
 	int index;
+	/** Partition kind */
+	label_pkind_t pkind;
 	/** Address of first block */
 	aoff64_t block0;
@@ -88,5 +92,9 @@
 	struct label *label;
 	/** Link to label_t.parts */
-	link_t llabel;
+	link_t lparts;
+	/** Link to label_t.pri_parts */
+	link_t lpri;
+	/** Link to label_t.log_parts */
+	link_t llog;
 	/** Index */
 	int index;
@@ -109,4 +117,6 @@
 	/** Number of blocks */
 	aoff64_t nblocks;
+	/** Partition kind */
+	label_pkind_t pkind;
 	/** Partition type */
 	uint64_t ptype;
@@ -135,4 +145,8 @@
 	/** Partitions */
 	list_t parts; /* of label_part_t */
+	/** Primary partitions */
+	list_t pri_parts; /* of label_part_t */
+	/** Logical partitions */
+	list_t log_parts; /* of label_part_t */
 	/** First block that can be allocated */
 	aoff64_t ablock0;
@@ -141,4 +155,6 @@
 	/** Number of primary partition entries */
 	int pri_entries;
+	/** Index of extended partition or -1 if there is none */
+	int ext_part_idx;
 	/** Block size */
 	size_t block_size;
Index: uspace/lib/label/src/gpt.c
===================================================================
--- uspace/lib/label/src/gpt.c	(revision 70815a24cf429286a07e08f8ad1f2a835d6be638)
+++ uspace/lib/label/src/gpt.c	(revision b7a4d06b6d03da11c24ad8eee4f374f7b8a7dc13)
@@ -150,4 +150,6 @@
 
 	list_initialize(&label->parts);
+	list_initialize(&label->pri_parts);
+	list_initialize(&label->log_parts);
 
 	for (j = 0; j < 2; j++) {
@@ -300,4 +302,5 @@
 	label->pri_entries = num_entries;
 	label->block_size = bsize;
+	label->ext_part_idx = -1;
 
 	label->lt.gpt.hdr_ba[0] = gpt_hdr_ba;
@@ -436,4 +439,6 @@
 
 	list_initialize(&label->parts);
+	list_initialize(&label->pri_parts);
+	list_initialize(&label->log_parts);
 
 	label->ops = &gpt_label_ops;
@@ -444,4 +449,5 @@
 	label->pri_entries = num_entries;
 	label->block_size = bsize;
+	label->ext_part_idx = -1;
 
 	label->lt.gpt.hdr_ba[0] = hdr_ba[0];
@@ -468,5 +474,6 @@
 	part = gpt_part_first(label);
 	while (part != NULL) {
-		list_remove(&part->llabel);
+		list_remove(&part->lparts);
+		list_remove(&part->lpri);
 		free(part);
 		part = gpt_part_first(label);
@@ -532,4 +539,9 @@
 }
 
+static bool gpt_can_create_pri(label_t *label)
+{
+	return list_count(&label->parts) < (size_t)label->pri_entries;
+}
+
 static int gpt_get_info(label_t *label, label_info_t *linfo)
 {
@@ -537,4 +549,7 @@
 	linfo->dcnt = dc_label;
 	linfo->ltype = lt_gpt;
+	linfo->flags = 0;
+	if (gpt_can_create_pri(label))
+		linfo->flags = linfo->flags | lf_can_create_pri;
 	linfo->ablock0 = label->ablock0;
 	linfo->anblocks = label->anblocks;
@@ -550,5 +565,5 @@
 		return NULL;
 
-	return list_get_instance(link, label_part_t, llabel);
+	return list_get_instance(link, label_part_t, lparts);
 }
 
@@ -557,9 +572,9 @@
 	link_t *link;
 
-	link = list_next(&part->llabel, &part->label->parts);
+	link = list_next(&part->lparts, &part->label->parts);
 	if (link == NULL)
 		return NULL;
 
-	return list_get_instance(link, label_part_t, llabel);
+	return list_get_instance(link, label_part_t, lparts);
 }
 
@@ -567,4 +582,5 @@
 {
 	pinfo->index = part->index;
+	pinfo->pkind = lpk_primary;
 	pinfo->block0 = part->block0;
 	pinfo->nblocks = part->nblocks;
@@ -587,4 +603,10 @@
 
 	if (pspec->index < 1 || pspec->index > label->pri_entries) {
+		rc = EINVAL;
+		goto error;
+	}
+
+	/* GPT only has primary partitions */
+	if (pspec->pkind != lpk_primary) {
 		rc = EINVAL;
 		goto error;
@@ -614,5 +636,6 @@
 	}
 
-	list_append(&part->llabel, &label->parts);
+	list_append(&part->lparts, &label->parts);
+	list_append(&part->lpri, &label->pri_parts);
 
 	*rpart = part;
@@ -636,5 +659,6 @@
 		return EIO;
 
-	list_remove(&part->llabel);
+	list_remove(&part->lparts);
+	list_remove(&part->lpri);
 	free(part);
 	return EOK;
@@ -694,5 +718,6 @@
 
 	part->label = label;
-	list_append(&part->llabel, &label->parts);
+	list_append(&part->lparts, &label->parts);
+	list_append(&part->lpri, &label->pri_parts);
 	return EOK;
 }
Index: uspace/lib/label/src/mbr.c
===================================================================
--- uspace/lib/label/src/mbr.c	(revision 70815a24cf429286a07e08f8ad1f2a835d6be638)
+++ uspace/lib/label/src/mbr.c	(revision b7a4d06b6d03da11c24ad8eee4f374f7b8a7dc13)
@@ -122,4 +122,6 @@
 
 	list_initialize(&label->parts);
+	list_initialize(&label->pri_parts);
+	list_initialize(&label->log_parts);
 
 	/* Verify boot record signature */
@@ -130,4 +132,5 @@
 	}
 
+	label->ext_part_idx = -1;
 	for (entry = 0; entry < mbr_nprimary; entry++) {
 		eptr = &mbr->pte[entry];
@@ -187,4 +190,6 @@
 
 	list_initialize(&label->parts);
+	list_initialize(&label->pri_parts);
+	list_initialize(&label->log_parts);
 
 	mbr->media_id = 0;
@@ -210,4 +215,5 @@
 	label->anblocks = nblocks - mbr_ablock0;
 	label->pri_entries = mbr_nprimary;
+	label->ext_part_idx = -1;
 
 	*rlabel = label;
@@ -225,5 +231,9 @@
 	part = mbr_part_first(label);
 	while (part != NULL) {
-		list_remove(&part->llabel);
+		list_remove(&part->lparts);
+		if (link_used(&part->lpri))
+			list_remove(&part->lpri);
+		if (link_used(&part->llog))
+			list_remove(&part->llog);
 		free(part);
 
@@ -273,6 +283,21 @@
 	linfo->dcnt = dc_label;
 	linfo->ltype = lt_mbr;
+
+	/* We support extended partitions */
+	linfo->flags = lf_ext_supp;
+
+	/** Can create primary if there is a free slot */
+	if (list_count(&label->pri_parts) < mbr_nprimary)
+		linfo->flags |= lf_can_create_pri;
+	/* Can create extended if there is a free slot and no extended */
+	if ((linfo->flags & lf_can_create_pri) != 0 && label->ext_part_idx < 0)
+		linfo->flags |= lf_can_create_ext;
+	/* Can create logical if there is an extended partition */
+	if (label->ext_part_idx >= 0)
+		linfo->flags |= lf_can_create_log;
+
 	linfo->ablock0 = label->ablock0;
 	linfo->anblocks = label->anblocks;
+
 	return EOK;
 }
@@ -286,5 +311,5 @@
 		return NULL;
 
-	return list_get_instance(link, label_part_t, llabel);
+	return list_get_instance(link, label_part_t, lparts);
 }
 
@@ -293,11 +318,12 @@
 	link_t *link;
 
-	link = list_next(&part->llabel, &part->label->parts);
+	link = list_next(&part->lparts, &part->label->parts);
 	if (link == NULL)
 		return NULL;
 
-	return list_get_instance(link, label_part_t, llabel);
-}
-
+	return list_get_instance(link, label_part_t, lparts);
+}
+
+#include <io/log.h>
 static void mbr_part_get_info(label_part_t *part, label_part_info_t *pinfo)
 {
@@ -305,4 +331,13 @@
 	pinfo->block0 = part->block0;
 	pinfo->nblocks = part->nblocks;
+
+	log_msg(LOG_DEFAULT, LVL_NOTE, "mbr_part_get_info: index=%d ptype=%d",
+	    (int)part->index, (int)part->ptype);
+	if (link_used(&part->llog))
+		pinfo->pkind = lpk_logical;
+	else if (part->ptype == mbr_pt_extended)
+		pinfo->pkind = lpk_extended;
+	else
+		pinfo->pkind = lpk_primary;
 }
 
@@ -318,10 +353,4 @@
 		return ENOMEM;
 
-	/* XXX Verify index, block0, nblocks */
-
-	if (pspec->index < 1 || pspec->index > label->pri_entries) {
-		rc = EINVAL;
-		goto error;
-	}
 
 	/* XXX Check if index is used */
@@ -331,19 +360,60 @@
 	part->block0 = pspec->block0;
 	part->nblocks = pspec->nblocks;
-	part->ptype = pspec->ptype;
-
-	rc = mbr_part_to_pte(part, &pte);
-	if (rc != EOK) {
-		rc = EINVAL;
-		goto error;
-	}
-
-	rc = mbr_pte_update(label, &pte, pspec->index - 1);
-	if (rc != EOK) {
-		rc = EIO;
-		goto error;
-	}
-
-	list_append(&part->llabel, &label->parts);
+
+	switch (pspec->pkind) {
+	case lpk_primary:
+		part->ptype = pspec->ptype;
+		break;
+	case lpk_extended:
+		part->ptype = mbr_pt_extended;
+		if (pspec->ptype != 0) {
+			rc = EINVAL;
+			goto error;
+		}
+		if (label->ext_part_idx >= 0) {
+			rc = EEXISTS;
+			goto error;
+		}
+		break;
+	case lpk_logical:
+		part->ptype = pspec->ptype;
+		if (pspec->index != 0) {
+			rc = EINVAL;
+			goto error;
+		}
+		break;
+	}
+
+	if (pspec->pkind != lpk_logical) {
+		/* Primary or extended partition */
+		/* XXX Verify index, block0, nblocks */
+
+		if (pspec->index < 1 || pspec->index > label->pri_entries) {
+			rc = EINVAL;
+			goto error;
+		}
+
+		rc = mbr_part_to_pte(part, &pte);
+		if (rc != EOK) {
+			rc = EINVAL;
+			goto error;
+		}
+
+		rc = mbr_pte_update(label, &pte, pspec->index - 1);
+		if (rc != EOK) {
+			rc = EIO;
+			goto error;
+		}
+
+		list_append(&part->lparts, &label->parts);
+		list_append(&part->lpri, &label->pri_parts);
+
+		if (pspec->pkind == lpk_extended)
+			label->ext_part_idx = pspec->index - 1;
+	} else {
+		/* Logical partition */
+		rc = ENOTSUP;
+		goto error;
+	}
 
 	*rpart = part;
@@ -367,5 +437,13 @@
 		return EIO;
 
-	list_remove(&part->llabel);
+	/* If it was the extended partition, clear ext. part. index */
+	if (part->index - 1 == part->label->ext_part_idx)
+		part->label->ext_part_idx = -1;
+
+	list_remove(&part->lparts);
+	if (link_used(&part->lpri))
+		list_remove(&part->lpri);
+	if (link_used(&part->llog))
+		list_remove(&part->llog);
 	free(part);
 	return EOK;
@@ -386,4 +464,7 @@
 		return EINVAL;
 
+	log_msg(LOG_DEFAULT, LVL_NOTE, "mbr_part_to_pte: a0=%" PRIu64
+	    " len=%" PRIu64 " ptype=%d", part->block0, part->nblocks,
+	    (int)part->ptype);
 	memset(pte, 0, sizeof(mbr_pte_t));
 	pte->ptype = part->ptype;
@@ -403,6 +484,5 @@
 
 	/* See UEFI specification 2.0 section 5.2.1 Legacy Master Boot Record */
-	if (pte->ptype == mbr_pt_unused || pte->ptype == mbr_pt_extended ||
-	    nblocks == 0)
+	if (pte->ptype == mbr_pt_unused || nblocks == 0)
 		return EOK;
 
@@ -411,4 +491,5 @@
 		return ENOMEM;
 
+	part->ptype = pte->ptype;
 	part->index = index;
 	part->block0 = block0;
@@ -422,5 +503,9 @@
 
 	part->label = label;
-	list_append(&part->llabel, &label->parts);
+	list_append(&part->lparts, &label->parts);
+	list_append(&part->lpri, &label->pri_parts);
+
+	if (pte->ptype == mbr_pt_extended)
+		label->ext_part_idx = index - 1;
 	return EOK;
 }
Index: uspace/srv/bd/vbd/disk.c
===================================================================
--- uspace/srv/bd/vbd/disk.c	(revision 70815a24cf429286a07e08f8ad1f2a835d6be638)
+++ uspace/srv/bd/vbd/disk.c	(revision b7a4d06b6d03da11c24ad8eee4f374f7b8a7dc13)
@@ -125,4 +125,6 @@
 	    disk->svc_name, lpart);
 
+	label_part_get_info(lpart, &lpinfo);
+
 	part = calloc(1, sizeof(vbds_part_t));
 	if (part == NULL) {
@@ -148,5 +150,4 @@
 
 	free(name);
-	label_part_get_info(lpart, &lpinfo);
 
 	part->lpart = lpart;
@@ -302,5 +303,5 @@
 }
 
-int vbds_disk_info(service_id_t sid, vbds_disk_info_t *info)
+int vbds_disk_info(service_id_t sid, vbd_disk_info_t *info)
 {
 	vbds_disk_t *disk;
@@ -317,4 +318,5 @@
 
 	info->ltype = linfo.ltype;
+	info->flags = linfo.flags;
 	info->ablock0 = linfo.ablock0;
 	info->anblocks = linfo.anblocks;
@@ -467,4 +469,5 @@
 
 	pinfo->index = lpinfo.index;
+	pinfo->pkind = lpinfo.pkind;
 	pinfo->block0 = lpinfo.block0;
 	pinfo->nblocks = lpinfo.nblocks;
@@ -492,4 +495,5 @@
 	lpspec.block0 = pspec->block0;
 	lpspec.nblocks = pspec->nblocks;
+	lpspec.pkind = pspec->pkind;
 	lpspec.ptype = pspec->ptype;
 
Index: uspace/srv/bd/vbd/disk.h
===================================================================
--- uspace/srv/bd/vbd/disk.h	(revision 70815a24cf429286a07e08f8ad1f2a835d6be638)
+++ uspace/srv/bd/vbd/disk.h	(revision b7a4d06b6d03da11c24ad8eee4f374f7b8a7dc13)
@@ -45,5 +45,5 @@
 extern int vbds_disk_add(service_id_t);
 extern int vbds_disk_remove(service_id_t);
-extern int vbds_disk_info(service_id_t, vbds_disk_info_t *);
+extern int vbds_disk_info(service_id_t, vbd_disk_info_t *);
 extern int vbds_get_parts(service_id_t, service_id_t *, size_t, size_t *);
 extern int vbds_label_create(service_id_t, label_type_t);
Index: uspace/srv/bd/vbd/types/vbd.h
===================================================================
--- uspace/srv/bd/vbd/types/vbd.h	(revision 70815a24cf429286a07e08f8ad1f2a835d6be638)
+++ uspace/srv/bd/vbd/types/vbd.h	(revision b7a4d06b6d03da11c24ad8eee4f374f7b8a7dc13)
@@ -47,16 +47,4 @@
 typedef sysarg_t vbds_part_id_t;
 
-/** Disk info */
-typedef struct {
-	/** Label type */
-	label_type_t ltype;
-	/** First block that can be allocated */
-	aoff64_t ablock0;
-	/** Number of blocks that can be allocated */
-	aoff64_t anblocks;
-	/** Block size */
-	size_t block_size;
-} vbds_disk_info_t;
-
 /** Partition */
 typedef struct {
Index: uspace/srv/bd/vbd/vbd.c
===================================================================
--- uspace/srv/bd/vbd/vbd.c	(revision 70815a24cf429286a07e08f8ad1f2a835d6be638)
+++ uspace/srv/bd/vbd/vbd.c	(revision b7a4d06b6d03da11c24ad8eee4f374f7b8a7dc13)
@@ -107,5 +107,5 @@
 {
 	service_id_t disk_sid;
-	vbds_disk_info_t dinfo;
+	vbd_disk_info_t dinfo;
 	int rc;
 
@@ -127,5 +127,5 @@
 	}
 
-	if (size != sizeof(vbds_disk_info_t)) {
+	if (size != sizeof(vbd_disk_info_t)) {
 		async_answer_0(callid, EINVAL);
 		async_answer_0(iid, EINVAL);
@@ -219,7 +219,32 @@
 	part = IPC_GET_ARG1(*icall);
 	rc = vbds_part_get_info(part, &pinfo);
-	async_answer_5(iid, (sysarg_t)rc, pinfo.index,
-	    LOWER32(pinfo.block0), UPPER32(pinfo.block0),
-	    LOWER32(pinfo.nblocks), UPPER32(pinfo.nblocks));
+	if (rc != EOK) {
+		async_answer_0(iid, rc);
+		return;
+	}
+
+	ipc_callid_t callid;
+	size_t size;
+	if (!async_data_read_receive(&callid, &size)) {
+		async_answer_0(callid, EREFUSED);
+		async_answer_0(iid, EREFUSED);
+		return;
+	}
+
+	if (size != sizeof(vbd_part_info_t)) {
+		async_answer_0(callid, EINVAL);
+		async_answer_0(iid, EINVAL);
+		return;
+	}
+
+	rc = async_data_read_finalize(callid, &pinfo,
+	    min(size, sizeof(pinfo)));
+	if (rc != EOK) {
+		async_answer_0(callid, rc);
+		async_answer_0(iid, rc);
+		return;
+	}
+
+	async_answer_0(iid, EOK);
 }
 
Index: uspace/srv/volsrv/disk.c
===================================================================
--- uspace/srv/volsrv/disk.c	(revision 70815a24cf429286a07e08f8ad1f2a835d6be638)
+++ uspace/srv/volsrv/disk.c	(revision b7a4d06b6d03da11c24ad8eee4f374f7b8a7dc13)
@@ -271,5 +271,5 @@
 }
 
-int vol_disk_empty(vol_disk_t *disk)
+int vol_disk_empty_disk(vol_disk_t *disk)
 {
 	int rc;
@@ -286,4 +286,23 @@
 }
 
+int vol_disk_get_info(vol_disk_t *disk, vol_disk_info_t *dinfo)
+{
+	vbd_disk_info_t vdinfo;
+	int rc;
+
+	dinfo->dcnt = disk->dcnt;
+
+	if (disk->dcnt == dc_label) {
+		rc = vbd_disk_info(vbd, disk->svc_id, &vdinfo);
+		if (rc != EOK)
+			return rc;
+
+		dinfo->ltype = vdinfo.ltype;
+		dinfo->flags = vdinfo.flags;
+	}
+
+	return EOK;
+}
+
 
 /** @}
Index: uspace/srv/volsrv/disk.h
===================================================================
--- uspace/srv/volsrv/disk.h	(revision 70815a24cf429286a07e08f8ad1f2a835d6be638)
+++ uspace/srv/volsrv/disk.h	(revision b7a4d06b6d03da11c24ad8eee4f374f7b8a7dc13)
@@ -39,4 +39,5 @@
 
 #include <sys/types.h>
+#include <vol.h>
 #include "types/disk.h"
 
@@ -46,5 +47,6 @@
 extern int vol_disk_find_by_id(service_id_t, vol_disk_t **);
 extern int vol_disk_label_create(vol_disk_t *, label_type_t);
-extern int vol_disk_empty(vol_disk_t *);
+extern int vol_disk_empty_disk(vol_disk_t *);
+extern int vol_disk_get_info(vol_disk_t *, vol_disk_info_t *);
 
 #endif
Index: uspace/srv/volsrv/volsrv.c
===================================================================
--- uspace/srv/volsrv/volsrv.c	(revision 70815a24cf429286a07e08f8ad1f2a835d6be638)
+++ uspace/srv/volsrv/volsrv.c	(revision b7a4d06b6d03da11c24ad8eee4f374f7b8a7dc13)
@@ -43,4 +43,5 @@
 #include <stdlib.h>
 #include <task.h>
+#include <vol.h>
 
 #include "disk.h"
@@ -118,4 +119,5 @@
 	service_id_t sid;
 	vol_disk_t *disk;
+	vol_disk_info_t dinfo;
 	int rc;
 
@@ -127,5 +129,11 @@
 	}
 
-	async_answer_2(iid, rc, disk->dcnt, disk->ltype);
+	rc = vol_disk_get_info(disk, &dinfo);
+	if (rc != EOK) {
+		async_answer_0(iid, EIO);
+		return;
+	}
+
+	async_answer_3(iid, rc, dinfo.dcnt, dinfo.ltype, dinfo.flags);
 }
 
@@ -169,5 +177,5 @@
 	}
 
-	rc = vol_disk_empty(disk);
+	rc = vol_disk_empty_disk(disk);
 	if (rc != EOK) {
 		async_answer_0(iid, EIO);
