Index: uspace/lib/c/generic/vbd.c
===================================================================
--- uspace/lib/c/generic/vbd.c	(revision 1626cd4d3269f272038f96a6fa17c3536f1b084c)
+++ uspace/lib/c/generic/vbd.c	(revision 6bc542bfcd4de3d747e25cc6e0894f9581445ca1)
@@ -107,5 +107,4 @@
 }
 
-#include <io/log.h>
 /** Get disk information. */
 int vbd_disk_info(vbd_t *vbd, service_id_t sid, vbd_disk_info_t *vinfo)
@@ -115,10 +114,7 @@
 	ipc_call_t answer;
 
-	log_msg(LOG_DEFAULT, LVL_DEBUG, "vbd_disk_info() begin exchange");
 	exch = async_exchange_begin(vbd->sess);
 	aid_t req = async_send_1(exch, VBD_DISK_INFO, sid, &answer);
-	log_msg(LOG_DEFAULT, LVL_DEBUG, "vbd_disk_info() read start");
 	int rc = async_data_read_start(exch, vinfo, sizeof(vbd_disk_info_t));
-	log_msg(LOG_DEFAULT, LVL_DEBUG, "vbd_disk_info() end exch");
 	async_exchange_end(exch);
 
@@ -128,10 +124,8 @@
 	}
 
-	log_msg(LOG_DEFAULT, LVL_DEBUG, "vbd_disk_info() wait fore req reply");
 	async_wait_for(req, &retval);
 	if (retval != EOK)
 		return EIO;
 
-	log_msg(LOG_DEFAULT, LVL_DEBUG, "vbd_disk_info() done");
 	return EOK;
 }
@@ -293,24 +287,32 @@
 {
 	async_exch_t *exch;
-	sysarg_t part;
+	sysarg_t retval;
+	ipc_call_t answer;
+
+	exch = async_exchange_begin(vbd->sess);
+	aid_t req = async_send_1(exch, VBD_PART_CREATE, disk, &answer);
+	int rc = async_data_write_start(exch, pspec, sizeof(vbd_part_spec_t));
+	async_exchange_end(exch);
+
+	if (rc != EOK) {
+		async_forget(req);
+		return EIO;
+	}
+
+	async_wait_for(req, &retval);
+	if (retval != EOK)
+		return EIO;
+
+	*rpart = (vbd_part_id_t)IPC_GET_ARG1(answer);
+	return EOK;
+
+}
+
+int vbd_part_delete(vbd_t *vbd, vbd_part_id_t part)
+{
+	async_exch_t *exch;
 	int retval;
 
 	exch = async_exchange_begin(vbd->sess);
-	retval = async_req_1_1(exch, VBD_PART_CREATE, disk, &part);
-	async_exchange_end(exch);
-
-	if (retval != EOK)
-		return EIO;
-
-	*rpart = (vbd_part_id_t)part;
-	return EOK;
-}
-
-int vbd_part_delete(vbd_t *vbd, vbd_part_id_t part)
-{
-	async_exch_t *exch;
-	int retval;
-
-	exch = async_exchange_begin(vbd->sess);
 	retval = async_req_1_0(exch, VBD_PART_DELETE, part);
 	async_exchange_end(exch);
Index: uspace/lib/c/include/vbd.h
===================================================================
--- uspace/lib/c/include/vbd.h	(revision 1626cd4d3269f272038f96a6fa17c3536f1b084c)
+++ uspace/lib/c/include/vbd.h	(revision 6bc542bfcd4de3d747e25cc6e0894f9581445ca1)
@@ -59,7 +59,17 @@
 } vbd_disk_info_t;
 
+/** Specification of new partition */
 typedef struct {
+	/** Partition index */
+	int index;
+	/** First block */
+	aoff64_t block0;
+	/** Number of blocks */
+	aoff64_t nblocks;
+	/** Partition type */
+	uint64_t ptype;
 } vbd_part_spec_t;
 
+/** Partition info */
 typedef struct {
 	/** Partition index */
Index: uspace/lib/fdisk/src/fdisk.c
===================================================================
--- uspace/lib/fdisk/src/fdisk.c	(revision 1626cd4d3269f272038f96a6fa17c3536f1b084c)
+++ uspace/lib/fdisk/src/fdisk.c	(revision 6bc542bfcd4de3d747e25cc6e0894f9581445ca1)
@@ -58,4 +58,7 @@
 };
 
+static int fdisk_part_spec_prepare(fdisk_dev_t *, fdisk_part_spec_t *,
+    vbd_part_spec_t *);
+
 static void fdisk_dev_info_delete(fdisk_dev_info_t *info)
 {
@@ -497,15 +500,17 @@
 	int rc;
 
-	part = calloc(1, sizeof(fdisk_part_t));
-	if (part == NULL)
-		return ENOMEM;
-
+	printf("fdisk_part_create()\n");
+
+	rc = fdisk_part_spec_prepare(dev, pspec, &vpspec);
+	if (rc != EOK)
+		return EIO;
+
+	printf("fdisk_part_create() - call vbd_part_create\n");
 	rc = vbd_part_create(dev->fdisk->vbd, dev->sid, &vpspec, &partid);
-	if (rc != EOK) {
-		free(part);
-		return EIO;
-	}
-
-	rc = fdisk_part_add(dev, partid, rpart);
+	if (rc != EOK)
+		return EIO;
+
+	printf("fdisk_part_create() - call fdisk_part_add\n");
+	rc = fdisk_part_add(dev, partid, &part);
 	if (rc != EOK) {
 		/* Try rolling back */
@@ -514,7 +519,10 @@
 	}
 
-	(*rpart)->fstype = pspec->fstype;
-	(*rpart)->capacity = pspec->capacity;
-
+	printf("fdisk_part_create() - done\n");
+	part->fstype = pspec->fstype;
+	part->capacity = pspec->capacity;
+
+	if (rpart != NULL)
+		*rpart = part;
 	return EOK;
 }
@@ -650,4 +658,105 @@
 }
 
+/** Get free partition index. */
+static int fdisk_part_get_free_idx(fdisk_dev_t *dev, int *rindex)
+{
+	link_t *link;
+	fdisk_part_t *part;
+	int nidx;
+
+	link = list_first(&dev->parts_idx);
+	nidx = 1;
+	while (link != NULL) {
+		part = list_get_instance(link, fdisk_part_t, ldev_idx);
+		if (part->index > nidx)
+			break;
+		nidx = part->index;
+		link = list_next(link, &dev->parts_idx);
+	}
+
+	if (nidx > 4 /* XXXX actual number of slots*/) {
+		return ELIMIT;
+	}
+
+	*rindex = nidx;
+	return EOK;
+}
+
+/** Get free range of blocks.
+ *
+ * Get free range of blocks of at least the specified size (first fit).
+ */
+static int fdisk_part_get_free_range(fdisk_dev_t *dev, aoff64_t nblocks,
+    aoff64_t *rblock0, aoff64_t *rnblocks)
+{
+	link_t *link;
+	fdisk_part_t *part;
+	uint64_t avail;
+	int nba;
+
+	link = list_first(&dev->parts_ba);
+	nba = dev->dinfo.ablock0;
+	while (link != NULL) {
+		part = list_get_instance(link, fdisk_part_t, ldev_ba);
+		if (part->block0 - nba >= nblocks)
+			break;
+		nba = part->block0 + part->nblocks;
+		link = list_next(link, &dev->parts_ba);
+	}
+
+	if (link != NULL) {
+		/* Free range before a partition */
+		avail = part->block0 - nba;
+	} else {
+		/* Free range at the end */
+		avail = dev->dinfo.ablock0 + dev->dinfo.anblocks - nba;
+
+		/* Verify that the range is large enough */
+		if (avail < nblocks)
+			return ELIMIT;
+	}
+
+	*rblock0 = nba;
+	*rnblocks = avail;
+	return EOK;
+}
+
+/** Prepare new partition specification for VBD. */
+static int fdisk_part_spec_prepare(fdisk_dev_t *dev, fdisk_part_spec_t *pspec,
+    vbd_part_spec_t *vpspec)
+{
+	uint64_t cbytes;
+	aoff64_t req_blocks;
+	aoff64_t fblock0;
+	aoff64_t fnblocks;
+	uint64_t block_size;
+	unsigned i;
+	int index;
+	int rc;
+
+//	pspec->fstype
+	printf("fdisk_part_spec_prepare()\n");
+	block_size = dev->dinfo.block_size;
+	cbytes = pspec->capacity.value;
+	for (i = 0; i < pspec->capacity.cunit; i++)
+		cbytes = cbytes * 1000;
+
+	req_blocks = (cbytes + block_size - 1) / block_size;
+
+	rc = fdisk_part_get_free_idx(dev, &index);
+	if (rc != EOK)
+		return EIO;
+
+	rc = fdisk_part_get_free_range(dev, req_blocks, &fblock0, &fnblocks);
+	if (rc != EOK)
+		return EIO;
+
+	vpspec->index = index;
+	vpspec->block0 = fblock0;
+	vpspec->nblocks = req_blocks;
+	vpspec->ptype = 42;
+	return EOK;
+}
+
 /** @}
  */
Index: uspace/lib/label/include/types/liblabel.h
===================================================================
--- uspace/lib/label/include/types/liblabel.h	(revision 1626cd4d3269f272038f96a6fa17c3536f1b084c)
+++ uspace/lib/label/include/types/liblabel.h	(revision 6bc542bfcd4de3d747e25cc6e0894f9581445ca1)
@@ -98,4 +98,12 @@
 /** Specification of new partition */
 struct label_part_spec {
+	/** Partition index */
+	int index;
+	/** First block */
+	aoff64_t block0;
+	/** Number of blocks */
+	aoff64_t nblocks;
+	/** Partition type */
+	uint64_t ptype;
 };
 
Index: uspace/lib/label/src/gpt.c
===================================================================
--- uspace/lib/label/src/gpt.c	(revision 1626cd4d3269f272038f96a6fa17c3536f1b084c)
+++ uspace/lib/label/src/gpt.c	(revision 6bc542bfcd4de3d747e25cc6e0894f9581445ca1)
@@ -242,5 +242,23 @@
     label_part_t **rpart)
 {
-	return ENOTSUP;
+	label_part_t *part;
+
+	part = calloc(1, sizeof(label_part_t));
+	if (part == NULL)
+		return ENOMEM;
+
+	/* XXX Verify index, block0, nblocks */
+
+	part->index = pspec->index;
+	part->block0 = pspec->block0;
+	part->nblocks = pspec->nblocks;
+
+	/* XXX Modify partition table */
+
+	part->label = label;
+	list_append(&part->llabel, &label->parts);
+
+	*rpart = part;
+	return EOK;
 }
 
Index: uspace/lib/label/src/mbr.c
===================================================================
--- uspace/lib/label/src/mbr.c	(revision 1626cd4d3269f272038f96a6fa17c3536f1b084c)
+++ uspace/lib/label/src/mbr.c	(revision 6bc542bfcd4de3d747e25cc6e0894f9581445ca1)
@@ -206,5 +206,18 @@
     label_part_t **rpart)
 {
-	return ENOTSUP;
+	label_part_t *part;
+
+	part = calloc(1, sizeof(label_part_t));
+	if (part == NULL)
+		return ENOMEM;
+
+	part->index = pspec->index;
+	part->block0 = pspec->block0;
+	part->nblocks = pspec->nblocks;
+
+	part->label = label;
+
+	*rpart = part;
+	return EOK;
 }
 
