Index: uspace/lib/label/src/gpt.c
===================================================================
--- uspace/lib/label/src/gpt.c	(revision 99c23405e687595401687deb42d610a45b2fa761)
+++ uspace/lib/label/src/gpt.c	(revision 603c1d1f2f250c70a6ee5b7b75494f1ed4c16e1a)
@@ -120,5 +120,5 @@
 	}
 
-	rc = block_read_direct(sid, GPT_HDR_BA, 1, gpt_hdr[0]);
+	rc = block_read_direct(sid, gpt_hdr_ba, 1, gpt_hdr[0]);
 	if (rc != EOK) {
 		rc = EIO;
@@ -200,5 +200,5 @@
 	label->ops = &gpt_label_ops;
 	label->ltype = lt_gpt;
-	label->svcid = sid;
+	label->svc_id = sid;
 	label->ablock0 = ba_min;
 	label->anblocks = ba_max - ba_min + 1;
@@ -206,4 +206,6 @@
 	label->block_size = bsize;
 
+	label->lt.gpt.hdr_ba[0] = gpt_hdr_ba;
+	label->lt.gpt.hdr_ba[1] = h1ba;
 	label->lt.gpt.ptable_ba[0] = ptba[0];
 	label->lt.gpt.ptable_ba[1] = ptba[1];
@@ -222,9 +224,143 @@
 static int gpt_create(service_id_t sid, label_t **rlabel)
 {
-	return EOK;
+	label_t *label = NULL;
+	gpt_header_t *gpt_hdr = NULL;
+	uint8_t *etable = NULL;
+	size_t bsize;
+	uint32_t num_entries;
+	uint32_t esize;
+	uint64_t ptba[2];
+	uint64_t hdr_ba[2];
+	uint64_t pt_blocks;
+	uint64_t ba_min, ba_max;
+	aoff64_t nblocks;
+	uint64_t resv_blocks;
+	int i, j;
+	int rc;
+
+	rc = block_get_bsize(sid, &bsize);
+	if (rc != EOK) {
+		rc = EIO;
+		goto error;
+	}
+
+	if (bsize < 512 || (bsize % 512) != 0) {
+		rc = EINVAL;
+		goto error;
+	}
+
+	rc = block_get_nblocks(sid, &nblocks);
+	if (rc != EOK) {
+		rc = EIO;
+		goto error;
+	}
+
+	/* Number of blocks of a partition table */
+	pt_blocks = gpt_ptable_min_size / bsize;
+	/* Minimum number of reserved (not allocatable) blocks */
+	resv_blocks = 3 + 2 * pt_blocks;
+
+	if (nblocks <= resv_blocks) {
+		rc = ENOSPC;
+		goto error;
+	}
+
+	hdr_ba[0] = gpt_hdr_ba;
+	hdr_ba[1] = nblocks - 1;
+	ptba[0] = 2;
+	ptba[1] = nblocks - 1 - pt_blocks;
+	ba_min = ptba[0] + pt_blocks;
+	ba_max = ptba[1] - 1;
+	esize = sizeof(gpt_entry_t);
+
+	num_entries = pt_blocks * bsize / sizeof(gpt_entry_t);
+
+	for (i = 0; i < 2; i++) {
+		gpt_hdr = calloc(1, bsize);
+		if (gpt_hdr == NULL) {
+			rc = ENOMEM;
+			goto error;
+		}
+
+		for (j = 0; j < 8; ++j)
+			gpt_hdr->efi_signature[j] = efi_signature[j];
+		gpt_hdr->revision = host2uint32_t_le(gpt_revision);
+		gpt_hdr->header_size = host2uint32_t_le(sizeof(gpt_header_t));
+		gpt_hdr->header_crc32 = 0; /* XXX */
+		gpt_hdr->my_lba = host2uint64_t_le(hdr_ba[i]);
+		gpt_hdr->alternate_lba = host2uint64_t_le(hdr_ba[1 - i]);
+		gpt_hdr->first_usable_lba = host2uint64_t_le(ba_min);
+		gpt_hdr->last_usable_lba = host2uint64_t_le(ba_max);
+		//gpt_hdr->disk_guid
+		gpt_hdr->entry_lba = host2uint64_t_le(ptba[i]);
+		gpt_hdr->num_entries = host2uint32_t_le(num_entries);
+		gpt_hdr->entry_size = host2uint32_t_le(esize);
+		gpt_hdr->pe_array_crc32 = 0; /* XXXX */
+
+		rc = block_write_direct(sid, hdr_ba[i], 1, gpt_hdr);
+		if (rc != EOK) {
+			rc = EIO;
+			goto error;
+		}
+
+		free(gpt_hdr);
+		gpt_hdr = NULL;
+
+		etable = calloc(num_entries, esize);
+		if (etable == NULL) {
+			rc = ENOMEM;
+			goto error;
+		}
+
+		rc = block_write_direct(sid, ptba[i], pt_blocks, etable);
+		if (rc != EOK) {
+			rc = EIO;
+			goto error;
+		}
+
+		free(etable);
+		etable = 0;
+	}
+
+	label = calloc(1, sizeof(label_t));
+	if (label == NULL)
+		return ENOMEM;
+
+	list_initialize(&label->parts);
+
+	label->ops = &gpt_label_ops;
+	label->ltype = lt_gpt;
+	label->svc_id = sid;
+	label->ablock0 = ba_min;
+	label->anblocks = ba_max - ba_min + 1;
+	label->pri_entries = num_entries;
+	label->block_size = bsize;
+
+	label->lt.gpt.hdr_ba[0] = hdr_ba[0];
+	label->lt.gpt.hdr_ba[1] = hdr_ba[1];
+	label->lt.gpt.ptable_ba[0] = ptba[0];
+	label->lt.gpt.ptable_ba[1] = ptba[1];
+	label->lt.gpt.esize = esize;
+
+	*rlabel = label;
+	return EOK;
+error:
+	free(etable);
+	free(gpt_hdr);
+	free(label);
+	return rc;
 }
 
 static void gpt_close(label_t *label)
 {
+	label_part_t *part;
+
+	part = gpt_part_first(label);
+	while (part != NULL) {
+		list_remove(&part->llabel);
+		free(part);
+		part = gpt_part_first(label);
+	}
+
 	free(label);
 }
@@ -232,5 +368,58 @@
 static int gpt_destroy(label_t *label)
 {
-	return EOK;
+	gpt_header_t *gpt_hdr = NULL;
+	uint8_t *etable = NULL;
+	label_part_t *part;
+	uint64_t pt_blocks;
+	int i;
+	int rc;
+
+	part = gpt_part_first(label);
+	if (part != NULL) {
+		rc = ENOTEMPTY;
+		goto error;
+	}
+
+	pt_blocks = label->pri_entries * label->lt.gpt.esize /
+	    label->block_size;
+
+	for (i = 0; i < 2; i++) {
+		gpt_hdr = calloc(1, label->block_size);
+		if (gpt_hdr == NULL) {
+			rc = ENOMEM;
+			goto error;
+		}
+
+		rc = block_write_direct(label->svc_id, label->lt.gpt.hdr_ba[i],
+		    1, gpt_hdr);
+		if (rc != EOK) {
+			rc = EIO;
+			goto error;
+		}
+
+		free(gpt_hdr);
+		gpt_hdr = NULL;
+
+		etable = calloc(label->pri_entries, label->lt.gpt.esize);
+		if (etable == NULL) {
+			rc = ENOMEM;
+			goto error;
+		}
+
+		rc = block_write_direct(label->svc_id,
+		    label->lt.gpt.ptable_ba[i], pt_blocks, etable);
+		if (rc != EOK) {
+			rc = EIO;
+			goto error;
+		}
+
+		free(etable);
+		etable = 0;
+	}
+
+	free(label);
+	return EOK;
+error:
+	return rc;
 }
 
@@ -426,5 +615,5 @@
 		    pos / label->block_size;
 
-		rc = block_read_direct(label->svcid, ba, 1, buf);
+		rc = block_read_direct(label->svc_id, ba, 1, buf);
 		if (rc != EOK) {
 			rc = EIO;
@@ -436,5 +625,5 @@
 		*e = *pte;
 
-		rc = block_write_direct(label->svcid, ba, 1, buf);
+		rc = block_write_direct(label->svc_id, ba, 1, buf);
 		if (rc != EOK) {
 			rc = EIO;
Index: uspace/lib/label/src/label.c
===================================================================
--- uspace/lib/label/src/label.c	(revision 99c23405e687595401687deb42d610a45b2fa761)
+++ uspace/lib/label/src/label.c	(revision 603c1d1f2f250c70a6ee5b7b75494f1ed4c16e1a)
@@ -41,7 +41,9 @@
 
 #include "gpt.h"
+#include "mbr.h"
 
 static label_ops_t *probe_list[] = {
 	&gpt_label_ops,
+	&mbr_label_ops,
 	NULL
 };
@@ -72,5 +74,5 @@
 		break;
 	case lt_mbr:
-		ops = NULL;
+		ops = &mbr_label_ops;
 		break;
 	}
Index: uspace/lib/label/src/mbr.c
===================================================================
--- uspace/lib/label/src/mbr.c	(revision 99c23405e687595401687deb42d610a45b2fa761)
+++ uspace/lib/label/src/mbr.c	(revision 603c1d1f2f250c70a6ee5b7b75494f1ed4c16e1a)
@@ -142,4 +142,6 @@
 	label->ops = &mbr_label_ops;
 	label->ltype = lt_mbr;
+	label->svc_id = sid;
+	label->block_size = bsize;
 	label->ablock0 = mbr_ablock0;
 	label->anblocks = nblocks - mbr_ablock0;
@@ -155,9 +157,78 @@
 static int mbr_create(service_id_t sid, label_t **rlabel)
 {
-	return EOK;
+	label_t *label = NULL;
+	mbr_br_block_t *mbr = NULL;
+	aoff64_t nblocks;
+	size_t bsize;
+	int i;
+	int rc;
+
+	rc = block_get_bsize(sid, &bsize);
+	if (rc != EOK) {
+		rc = EIO;
+		goto error;
+	}
+
+	rc = block_get_nblocks(sid, &nblocks);
+	if (rc != EOK) {
+		rc = EIO;
+		goto error;
+	}
+
+	mbr = calloc(1, bsize);
+	if (mbr == NULL) {
+		rc = ENOMEM;
+		goto error;
+	}
+
+	label = calloc(1, sizeof(label_t));
+	if (label == NULL)
+		return ENOMEM;
+
+	list_initialize(&label->parts);
+
+	mbr->media_id = 0;
+	mbr->pad0 = 0;
+	for (i = 0; i < mbr_nprimary; i++)
+		mbr_unused_pte(&mbr->pte[i]);
+	mbr->signature = host2uint16_t_le(mbr_br_signature);
+
+	rc = block_write_direct(sid, mbr_ba, 1, mbr);
+	if (rc != EOK) {
+		rc = EIO;
+		goto error;
+	}
+
+	free(mbr);
+	mbr = NULL;
+
+	label->ops = &mbr_label_ops;
+	label->ltype = lt_mbr;
+	label->block_size = bsize;
+	label->svc_id = sid;
+	label->ablock0 = mbr_ablock0;
+	label->anblocks = nblocks - mbr_ablock0;
+	label->pri_entries = mbr_nprimary;
+
+	*rlabel = label;
+	return EOK;
+error:
+	free(mbr);
+	free(label);
+	return rc;
 }
 
 static void mbr_close(label_t *label)
 {
+	label_part_t *part;
+
+	part = mbr_part_first(label);
+	while (part != NULL) {
+		list_remove(&part->llabel);
+		free(part);
+
+		part = mbr_part_first(label);
+	}
+
 	free(label);
 }
@@ -165,5 +236,34 @@
 static int mbr_destroy(label_t *label)
 {
-	return EOK;
+	mbr_br_block_t *mbr = NULL;
+	label_part_t *part;
+	int rc;
+
+	part = mbr_part_first(label);
+	if (part != NULL) {
+		rc = ENOTEMPTY;
+		goto error;
+	}
+
+	mbr = calloc(1, label->block_size);
+	if (mbr == NULL) {
+		rc = ENOMEM;
+		goto error;
+	}
+
+	rc = block_write_direct(label->svc_id, mbr_ba, 1, mbr);
+	if (rc != EOK) {
+		rc = EIO;
+		goto error;
+	}
+
+	free(mbr);
+	mbr = NULL;
+
+	free(label);
+	return EOK;
+error:
+	free(mbr);
+	return rc;
 }
 
@@ -340,5 +440,5 @@
 		return ENOMEM;
 
-	rc = block_read_direct(label->svcid, mbr_ba, 1, br);
+	rc = block_read_direct(label->svc_id, mbr_ba, 1, br);
 	if (rc != EOK) {
 		rc = EIO;
@@ -348,5 +448,5 @@
 	br->pte[index] = *pte;
 
-	rc = block_write_direct(label->svcid, mbr_ba, 1, br);
+	rc = block_write_direct(label->svc_id, mbr_ba, 1, br);
 	if (rc != EOK) {
 		rc = EIO;
