Index: uspace/lib/label/Makefile
===================================================================
--- uspace/lib/label/Makefile	(revision 78d50bd06d1f1eb12182cb42a78d0182b9256f3d)
+++ uspace/lib/label/Makefile	(revision 3faa03dd95010d106f2bcc2ad1b10dd7ed86bcff)
@@ -33,4 +33,6 @@
 
 SOURCES = \
+	src/mbr.c \
+	src/gpt.c \
 	src/label.c
 
Index: uspace/lib/label/include/std/gpt.h
===================================================================
--- uspace/lib/label/include/std/gpt.h	(revision 3faa03dd95010d106f2bcc2ad1b10dd7ed86bcff)
+++ uspace/lib/label/include/std/gpt.h	(revision 3faa03dd95010d106f2bcc2ad1b10dd7ed86bcff)
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2015 Jiri Svoboda
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup bd
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBLABEL_STD_GPT_H_
+#define LIBLABEL_STD_GPT_H_
+
+#include <sys/types.h>
+
+/** Block address of GPT header. */
+#define GPT_HDR_BA	1
+
+/** GPT header */
+typedef struct {
+	uint8_t efi_signature[8];
+	uint32_t revision;
+	uint32_t header_size;
+	uint32_t header_crc32;
+	uint32_t reserved;
+	uint64_t my_lba;
+	uint64_t alternate_lba;
+	uint64_t first_usable_lba;
+	uint64_t last_usable_lba;
+	uint8_t disk_guid[16];
+	uint64_t entry_lba;
+	uint32_t num_entries;
+	uint32_t entry_size;
+	uint32_t pe_array_crc32;
+} __attribute__((packed)) gpt_header_t;
+
+/** GPT partition entry */
+typedef struct {
+	uint8_t part_type[16];
+	uint8_t part_id[16];
+	uint64_t start_lba;
+	uint64_t end_lba;
+	uint64_t attributes;
+	uint16_t part_name[36];
+} __attribute__((packed)) gpt_entry_t;
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/label/include/std/mbr.h
===================================================================
--- uspace/lib/label/include/std/mbr.h	(revision 3faa03dd95010d106f2bcc2ad1b10dd7ed86bcff)
+++ uspace/lib/label/include/std/mbr.h	(revision 3faa03dd95010d106f2bcc2ad1b10dd7ed86bcff)
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2015 Jiri Svoboda
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup bd
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBLABEL_STD_MBR_H_
+#define LIBLABEL_STD_MBR_H_
+
+#include <stdint.h>
+
+/** Block address of Master Boot Record. */
+#define MBR_BA	0
+
+enum {
+	/** Number of primary partition records */
+	mbr_nprimary = 4,
+
+	/** Boot record signature */
+	mbr_br_signature = 0xAA55
+};
+
+enum ptype {
+	/** Unused partition entry */
+	mbr_pt_unused	= 0x00,
+	/** Extended partition */
+	mbr_pt_extended	= 0x05
+};
+
+/** Structure of a partition table entry */
+typedef struct {
+	uint8_t status;
+	/** CHS of fist block in partition */
+	uint8_t first_chs[3];
+	/** Partition type */
+	uint8_t ptype;
+	/** CHS of last block in partition */
+	uint8_t last_chs[3];
+	/** LBA of first block in partition */
+	uint32_t first_lba;
+	/** Number of blocks in partition */
+	uint32_t length;
+} __attribute__((packed)) mbr_pte_t;
+
+/** Structure of a boot-record block */
+typedef struct {
+	/* Area for boot code */
+	uint8_t code_area[440];
+
+	/* Optional media ID */
+	uint32_t media_id;
+
+	uint16_t pad0;
+
+	/** Partition table entries */
+	mbr_pte_t pte[mbr_nprimary];
+
+	/** Boot record block signature (@c BR_SIGNATURE) */
+	uint16_t signature;
+} __attribute__((packed)) mbr_br_block_t;
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/label/include/types/liblabel.h
===================================================================
--- uspace/lib/label/include/types/liblabel.h	(revision 78d50bd06d1f1eb12182cb42a78d0182b9256f3d)
+++ uspace/lib/label/include/types/liblabel.h	(revision 3faa03dd95010d106f2bcc2ad1b10dd7ed86bcff)
@@ -42,4 +42,22 @@
 #include <vol.h>
 
+typedef struct label label_t;
+typedef struct label_part label_part_t;
+typedef struct label_part_info label_part_info_t;
+typedef struct label_part_spec label_part_spec_t;
+
+/** Ops for individual label type */
+typedef struct {
+	int (*open)(service_id_t, label_t **);
+	int (*create)(service_id_t, label_t **);
+	void (*close)(label_t *);
+	int (*destroy)(label_t *);
+	label_part_t *(*part_first)(label_t *);
+	label_part_t *(*part_next)(label_part_t *);
+	void (*part_get_info)(label_part_t *, label_part_info_t *);
+	int (*part_create)(label_t *, label_part_spec_t *, label_part_t **);
+	int (*part_destroy)(label_part_t *);
+} label_ops_t;
+
 typedef struct {
 	/** Disk contents */
@@ -49,28 +67,34 @@
 } label_info_t;
 
-typedef struct {
+struct label_part_info {
 	/** Address of first block */
 	aoff64_t block0;
 	/** Number of blocks */
 	aoff64_t nblocks;
-} label_part_info_t;
+};
 
 /** Partition */
-typedef struct {
+struct label_part {
 	/** Containing label */
 	struct label *label;
 	/** Link to label_t.parts */
 	link_t llabel;
-} label_part_t;
+	aoff64_t block0;
+	aoff64_t nblocks;
+};
 
 /** Specification of new partition */
-typedef struct {
-} label_part_spec_t;
+struct label_part_spec {
+};
 
 /** Label instance */
-typedef struct label {
+struct label {
+	/** Label type ops */
+	label_ops_t *ops;
+	/** Label type */
+	label_type_t ltype;
 	/** Partitions */
 	list_t parts; /* of label_part_t */
-} label_t;
+};
 
 #endif
Index: uspace/lib/label/src/gpt.c
===================================================================
--- uspace/lib/label/src/gpt.c	(revision 3faa03dd95010d106f2bcc2ad1b10dd7ed86bcff)
+++ uspace/lib/label/src/gpt.c	(revision 3faa03dd95010d106f2bcc2ad1b10dd7ed86bcff)
@@ -0,0 +1,261 @@
+/*
+ * Copyright (c) 2015 Jiri Svoboda
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup liblabel
+ * @{
+ */
+/**
+ * @file GUID Partition Table label.
+ */
+
+#include <block.h>
+#include <byteorder.h>
+#include <errno.h>
+#include <stdlib.h>
+
+#include "std/gpt.h"
+#include "gpt.h"
+
+static int gpt_open(service_id_t, label_t **);
+static int gpt_create(service_id_t, label_t **);
+static void gpt_close(label_t *);
+static int gpt_destroy(label_t *);
+static label_part_t *gpt_part_first(label_t *);
+static label_part_t *gpt_part_next(label_part_t *);
+static void gpt_part_get_info(label_part_t *, label_part_info_t *);
+static int gpt_part_create(label_t *, label_part_spec_t *, label_part_t **);
+static int gpt_part_destroy(label_part_t *);
+
+static int gpt_pte_to_part(label_t *, gpt_entry_t *);
+
+const uint8_t efi_signature[8] = {
+	/* "EFI PART" in ASCII */
+	0x45, 0x46, 0x49, 0x20, 0x50, 0x41, 0x52, 0x54
+};
+
+label_ops_t gpt_label_ops = {
+	.open = gpt_open,
+	.create = gpt_create,
+	.close = gpt_close,
+	.destroy = gpt_destroy,
+	.part_first = gpt_part_first,
+	.part_next = gpt_part_next,
+	.part_get_info = gpt_part_get_info,
+	.part_create = gpt_part_create,
+	.part_destroy = gpt_part_destroy
+};
+
+static int gpt_open(service_id_t sid, label_t **rlabel)
+{
+	label_t *label = NULL;
+	gpt_header_t *gpt_hdr = NULL;
+	gpt_entry_t *eptr;
+	uint8_t *etable = NULL;
+	size_t bsize;
+	uint32_t num_entries;
+	uint32_t esize;
+	uint32_t bcnt;
+	uint64_t ba;
+	uint32_t entry;
+	int i;
+	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;
+	}
+
+	gpt_hdr = calloc(1, bsize);
+	if (gpt_hdr == NULL) {
+		rc = ENOMEM;
+		goto error;
+	}
+
+	rc = block_read_direct(sid, GPT_HDR_BA, 1, gpt_hdr);
+	if (rc != EOK) {
+		rc = EIO;
+		goto error;
+	}
+
+	label = calloc(1, sizeof(label_t));
+	if (label == NULL)
+		return ENOMEM;
+
+	list_initialize(&label->parts);
+
+	for (i = 0; i < 8; ++i) {
+		if (gpt_hdr->efi_signature[i] != efi_signature[i]) {
+			rc = EINVAL;
+			goto error;
+		}
+	}
+
+	num_entries = uint32_t_le2host(gpt_hdr->num_entries);
+	esize = uint32_t_le2host(gpt_hdr->entry_size);
+	bcnt = (num_entries + esize - 1) / esize;
+	ba = uint64_t_le2host(gpt_hdr->entry_lba);
+
+	if (num_entries < 1) {
+		rc = EINVAL;
+		goto error;
+	}
+
+	if (esize < sizeof(gpt_entry_t)) {
+		rc = EINVAL;
+		goto error;
+	}
+
+	etable = calloc(num_entries, esize);
+	if (etable == NULL) {
+		rc = ENOMEM;
+		goto error;
+	}
+
+	rc = block_read_direct(sid, ba, bcnt, etable);
+	if (rc != EOK) {
+		rc = EIO;
+		goto error;
+	}
+
+	for (entry = 0; entry < num_entries; entry++) {
+		eptr = (gpt_entry_t *)(etable + entry * esize);
+		rc = gpt_pte_to_part(label, eptr);
+		if (rc != EOK)
+			goto error;
+	}
+
+	free(etable);
+	etable = NULL;
+	free(gpt_hdr);
+	gpt_hdr = NULL;
+
+	label->ops = &gpt_label_ops;
+	label->ltype = lt_gpt;
+	*rlabel = label;
+	return EOK;
+error:
+	free(etable);
+	free(gpt_hdr);
+	free(label);
+	return rc;
+}
+
+static int gpt_create(service_id_t sid, label_t **rlabel)
+{
+	return EOK;
+}
+
+static void gpt_close(label_t *label)
+{
+	free(label);
+}
+
+static int gpt_destroy(label_t *label)
+{
+	return EOK;
+}
+
+static label_part_t *gpt_part_first(label_t *label)
+{
+	link_t *link;
+
+	link = list_first(&label->parts);
+	if (link == NULL)
+		return NULL;
+
+	return list_get_instance(link, label_part_t, llabel);
+}
+
+static label_part_t *gpt_part_next(label_part_t *part)
+{
+	link_t *link;
+
+	link = list_next(&part->llabel, &part->label->parts);
+	if (link == NULL)
+		return NULL;
+
+	return list_get_instance(link, label_part_t, llabel);
+}
+
+static void gpt_part_get_info(label_part_t *part, label_part_info_t *pinfo)
+{
+	pinfo->block0 = part->block0;
+	pinfo->nblocks = part->nblocks;
+}
+
+static int gpt_part_create(label_t *label, label_part_spec_t *pspec,
+    label_part_t **rpart)
+{
+	return EOK;
+}
+
+static int gpt_part_destroy(label_part_t *part)
+{
+	return EOK;
+}
+
+static int gpt_pte_to_part(label_t *label, gpt_entry_t *pte)
+{
+	label_part_t *part;
+	bool present;
+	uint64_t b0, b1;
+	int i;
+
+	present = false;
+	for (i = 0; i < 8; i++)
+		if (pte->part_type[i] != 0x00)
+			present = true;
+
+	if (!present)
+		return EOK;
+
+	part = calloc(1, sizeof(label_part_t));
+	if (part == NULL)
+		return ENOMEM;
+
+	b0 = uint64_t_le2host(pte->start_lba);
+	b1 = uint64_t_le2host(pte->end_lba);
+	if (b1 <= b0)
+		return EINVAL;
+
+	part->block0 = b0;
+	part->nblocks = b1 - b0 + 1;
+
+	part->label = label;
+	list_append(&part->llabel, &label->parts);
+	return EOK;
+}
+
+/** @}
+ */
Index: uspace/lib/label/src/gpt.h
===================================================================
--- uspace/lib/label/src/gpt.h	(revision 3faa03dd95010d106f2bcc2ad1b10dd7ed86bcff)
+++ uspace/lib/label/src/gpt.h	(revision 3faa03dd95010d106f2bcc2ad1b10dd7ed86bcff)
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2015 Jiri Svoboda
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup liblabel
+ * @{
+ */
+/**
+ * @file GUID Partition Table label.
+ */
+
+#ifndef LIBLABEL_GPT_H_
+#define LIBLABEL_GPT_H_
+
+#include <types/liblabel.h>
+
+extern label_ops_t gpt_label_ops;
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/label/src/label.c
===================================================================
--- uspace/lib/label/src/label.c	(revision 78d50bd06d1f1eb12182cb42a78d0182b9256f3d)
+++ uspace/lib/label/src/label.c	(revision 3faa03dd95010d106f2bcc2ad1b10dd7ed86bcff)
@@ -40,28 +40,44 @@
 #include <stdlib.h>
 
+#include "gpt.h"
+
+static label_ops_t *probe_list[] = {
+	&gpt_label_ops,
+	NULL
+};
+
 int label_open(service_id_t sid, label_t **rlabel)
 {
-	label_t *label;
+	label_ops_t **ops;
+	int rc;
 
-	label = calloc(1, sizeof(label_t));
-	if (label == NULL)
-		return ENOMEM;
+	ops = &probe_list[0];
+	while (ops[0] != NULL) {
+		rc = ops[0]->open(sid, rlabel);
+		if (rc == EOK)
+			return EOK;
+		++ops;
+	}
 
-	list_initialize(&label->parts);
-	*rlabel = label;
-	return EOK;
+	return ENOTSUP;
 }
 
 int label_create(service_id_t sid, label_type_t ltype, label_t **rlabel)
 {
-	label_t *label;
+	label_ops_t *ops = NULL;
 
-	label = calloc(1, sizeof(label_t));
-	if (label == NULL)
-		return ENOMEM;
+	switch (ltype) {
+	case lt_gpt:
+		ops = &gpt_label_ops;
+		break;
+	case lt_mbr:
+		ops = NULL;
+		break;
+	}
 
-	list_initialize(&label->parts);
-	*rlabel = label;
-	return EOK;
+	if (ops == NULL)
+		return ENOTSUP;
+
+	return ops->create(sid, rlabel);
 }
 
@@ -71,11 +87,10 @@
 		return;
 
-	free(label);
+	label->ops->close(label);
 }
 
 int label_destroy(label_t *label)
 {
-	free(label);
-	return EOK;
+	return label->ops->destroy(label);
 }
 
@@ -83,5 +98,6 @@
 {
 	memset(linfo, 0, sizeof(label_info_t));
-	linfo->dcnt = dc_empty;
+	linfo->dcnt = dc_label;
+	linfo->ltype = label->ltype;
 	return EOK;
 }
@@ -89,28 +105,15 @@
 label_part_t *label_part_first(label_t *label)
 {
-	link_t *link;
-
-	link = list_first(&label->parts);
-	if (link == NULL)
-		return NULL;
-
-	return list_get_instance(link, label_part_t, llabel);
+	return label->ops->part_first(label);
 }
 
 label_part_t *label_part_next(label_part_t *part)
 {
-	link_t *link;
-
-	link = list_next(&part->llabel, &part->label->parts);
-	if (link == NULL)
-		return NULL;
-
-	return list_get_instance(link, label_part_t, llabel);
+	return part->label->ops->part_next(part);
 }
 
 void label_part_get_info(label_part_t *part, label_part_info_t *pinfo)
 {
-	pinfo->block0 = 0;
-	pinfo->nblocks = 0;
+	return part->label->ops->part_get_info(part, pinfo);
 }
 
@@ -118,21 +121,10 @@
     label_part_t **rpart)
 {
-	label_part_t *part;
-
-	part = calloc(1, sizeof(label_part_t));
-	if (part == NULL)
-		return ENOMEM;
-
-	part->label = label;
-	list_append(&part->llabel, &label->parts);
-	*rpart = part;
-	return EOK;
+	return label->ops->part_create(label, pspec, rpart);
 }
 
 int label_part_destroy(label_part_t *part)
 {
-	list_remove(&part->llabel);
-	free(part);
-	return EOK;
+	return part->label->ops->part_destroy(part);
 }
 
Index: uspace/lib/label/src/mbr.c
===================================================================
--- uspace/lib/label/src/mbr.c	(revision 3faa03dd95010d106f2bcc2ad1b10dd7ed86bcff)
+++ uspace/lib/label/src/mbr.c	(revision 3faa03dd95010d106f2bcc2ad1b10dd7ed86bcff)
@@ -0,0 +1,221 @@
+/*
+ * Copyright (c) 2015 Jiri Svoboda
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup liblabel
+ * @{
+ */
+/**
+ * @file Master Boot Record label
+ */
+
+#include <block.h>
+#include <byteorder.h>
+#include <errno.h>
+#include <stdlib.h>
+
+#include "std/mbr.h"
+#include "mbr.h"
+
+static int mbr_open(service_id_t, label_t **);
+static int mbr_create(service_id_t, label_t **);
+static void mbr_close(label_t *);
+static int mbr_destroy(label_t *);
+static label_part_t *mbr_part_first(label_t *);
+static label_part_t *mbr_part_next(label_part_t *);
+static void mbr_part_get_info(label_part_t *, label_part_info_t *);
+static int mbr_part_create(label_t *, label_part_spec_t *, label_part_t **);
+static int mbr_part_destroy(label_part_t *);
+
+static int mbr_pte_to_part(label_t *, mbr_pte_t *);
+
+label_ops_t mbr_label_ops = {
+	.open = mbr_open,
+	.create = mbr_create,
+	.close = mbr_close,
+	.destroy = mbr_destroy,
+	.part_first = mbr_part_first,
+	.part_next = mbr_part_next,
+	.part_get_info = mbr_part_get_info,
+	.part_create = mbr_part_create,
+	.part_destroy = mbr_part_destroy
+};
+
+static int mbr_open(service_id_t sid, label_t **rlabel)
+{
+	label_t *label = NULL;
+	mbr_br_block_t *mbr = NULL;
+	mbr_pte_t *eptr;
+	uint16_t sgn;
+	size_t bsize;
+	uint32_t entry;
+	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;
+	}
+
+	mbr = calloc(1, bsize);
+	if (mbr == NULL) {
+		rc = ENOMEM;
+		goto error;
+	}
+
+	rc = block_read_direct(sid, MBR_BA, 1, mbr);
+	if (rc != EOK) {
+		rc = EIO;
+		goto error;
+	}
+
+	label = calloc(1, sizeof(label_t));
+	if (label == NULL)
+		return ENOMEM;
+
+	list_initialize(&label->parts);
+
+	/* Verify boot record signature */
+	sgn = uint16_t_le2host(mbr->signature);
+	if (sgn != mbr_br_signature) {
+		rc = EIO;
+		goto error;
+	}
+
+	for (entry = 0; entry < mbr_nprimary; entry++) {
+		eptr = &mbr->pte[entry];
+		rc = mbr_pte_to_part(label, eptr);
+		if (rc != EOK)
+			goto error;
+	}
+
+	free(mbr);
+	mbr = NULL;
+
+	label->ops = &mbr_label_ops;
+	label->ltype = lt_mbr;
+	*rlabel = label;
+	return EOK;
+error:
+	free(mbr);
+	free(label);
+	return rc;
+}
+
+static int mbr_create(service_id_t sid, label_t **rlabel)
+{
+	return EOK;
+}
+
+static void mbr_close(label_t *label)
+{
+	free(label);
+}
+
+static int mbr_destroy(label_t *label)
+{
+	return EOK;
+}
+
+static label_part_t *mbr_part_first(label_t *label)
+{
+	link_t *link;
+
+	link = list_first(&label->parts);
+	if (link == NULL)
+		return NULL;
+
+	return list_get_instance(link, label_part_t, llabel);
+}
+
+static label_part_t *mbr_part_next(label_part_t *part)
+{
+	link_t *link;
+
+	link = list_next(&part->llabel, &part->label->parts);
+	if (link == NULL)
+		return NULL;
+
+	return list_get_instance(link, label_part_t, llabel);
+}
+
+static void mbr_part_get_info(label_part_t *part, label_part_info_t *pinfo)
+{
+	pinfo->block0 = part->block0;
+	pinfo->nblocks = part->nblocks;
+}
+
+static int mbr_part_create(label_t *label, label_part_spec_t *pspec,
+    label_part_t **rpart)
+{
+	return EOK;
+}
+
+static int mbr_part_destroy(label_part_t *part)
+{
+	return EOK;
+}
+
+static int mbr_pte_to_part(label_t *label, mbr_pte_t *pte)
+{
+	label_part_t *part;
+	uint32_t block0;
+	uint32_t nblocks;
+
+	block0 = uint32_t_le2host(pte->first_lba);
+	nblocks = uint32_t_le2host(pte->length);
+
+	/* 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)
+		return EOK;
+
+	part = calloc(1, sizeof(label_part_t));
+	if (part == NULL)
+		return ENOMEM;
+
+	part->block0 = block0;
+	part->nblocks = nblocks;
+
+	/*
+	 * TODO: Verify
+	 *   - partition must reside on disk
+	 *   - partition must not overlap any other partition
+	 */
+
+	part->label = label;
+	list_append(&part->llabel, &label->parts);
+	return EOK;
+}
+
+/** @}
+ */
Index: uspace/lib/label/src/mbr.h
===================================================================
--- uspace/lib/label/src/mbr.h	(revision 3faa03dd95010d106f2bcc2ad1b10dd7ed86bcff)
+++ uspace/lib/label/src/mbr.h	(revision 3faa03dd95010d106f2bcc2ad1b10dd7ed86bcff)
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2015 Jiri Svoboda
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup liblabel
+ * @{
+ */
+/**
+ * @file Master Boot Record label
+ */
+
+#ifndef LIBLABEL_MBR_H_
+#define LIBLABEL_MBR_H_
+
+#include <types/liblabel.h>
+
+extern label_ops_t mbr_label_ops;
+
+#endif
+
+/** @}
+ */
