Index: uspace/app/hdisk/common.h
===================================================================
--- uspace/app/hdisk/common.h	(revision 44c488656656806dc143099d9a82d6bb2b1bf293)
+++ uspace/app/hdisk/common.h	(revision 52f2c892e44995718a1719829ff88c8843672a97)
@@ -39,4 +39,10 @@
 #include <libgpt.h>
 
+typedef enum {
+	LYT_NONE,
+	LYT_MBR,
+	LYT_GPT,
+} layouts_t;
+
 union label_data {
 	mbr_label_t	*mbr;
@@ -44,4 +50,20 @@
 };
 
+typedef struct label label_t;
+
+struct label {
+	layouts_t layout;
+	union label_data data;
+	unsigned int alignment;
+	int (* destroy_label)(label_t *);
+	int (* add_part)     (label_t *, tinput_t *);
+	int (* delete_part)  (label_t *, tinput_t *);
+	int (* new_label)    (label_t *);
+	int (* print_parts)  (label_t *);
+	int (* read_parts)   (label_t *, service_id_t);
+	int (* write_parts)  (label_t *, service_id_t);
+	int (* extra_funcs)  (label_t *, tinput_t *, service_id_t);
+};
+
 #endif
 
Index: uspace/app/hdisk/func_gpt.c
===================================================================
--- uspace/app/hdisk/func_gpt.c	(revision 44c488656656806dc143099d9a82d6bb2b1bf293)
+++ uspace/app/hdisk/func_gpt.c	(revision 52f2c892e44995718a1719829ff88c8843672a97)
@@ -34,4 +34,5 @@
 
 #include <stdio.h>
+#include <str.h>
 #include <errno.h>
 #include <str_error.h>
@@ -43,41 +44,61 @@
 static int set_gpt_partition(tinput_t *, gpt_part_t *);
 
-int add_gpt_part(tinput_t * in, union label_data * data)
-{
-	gpt_part_t * p = gpt_alloc_partition(data->gpt->parts);
+
+int construct_gpt_label(label_t *this)
+{
+	this->layout = LYT_GPT;
+	this->alignment = 1;
+	
+	this->add_part    = add_gpt_part;
+	this->delete_part = delete_gpt_part;
+	this->new_label   = new_gpt_label;
+	this->print_parts = print_gpt_parts;
+	this->read_parts  = read_gpt_parts;
+	this->write_parts = write_gpt_parts;
+	this->extra_funcs = extra_gpt_funcs;
+	
+	return this->new_label(this);
+}
+
+int add_gpt_part(label_t *this, tinput_t *in)
+{
+	gpt_part_t * p = gpt_get_partition(this->data.gpt);
 	if (p == NULL) {
 		return ENOMEM;
 	}
-
+	
 	return set_gpt_partition(in, p);
 }
 
-int delete_gpt_part(tinput_t * in, union label_data * data)
-{
+int delete_gpt_part(label_t *this, tinput_t *in)
+{
+	int rc;
 	size_t idx;
-
+	
 	printf("Number of the partition to delete (counted from 0): ");
 	idx = get_input_size_t(in);
-
-	if (gpt_remove_partition(data->gpt->parts, idx) == -1) {
+	
+	rc = gpt_remove_partition(this->data.gpt, idx);
+	if (rc != EOK) {
 		printf("Warning: running low on memory, not resizing...\n");
-	}
-
-	return EOK;
-}
-
-int destroy_gpt_label(union label_data *data)
-{
-	return EOK;
-}
-
-int new_gpt_label(union label_data *data)
-{
-	data->gpt->gpt = gpt_alloc_gpt_header();
-	data->gpt->parts = gpt_alloc_partitions();
-	return EOK;
-}
-
-int print_gpt_parts(union label_data *data)
+		return rc;
+	}
+	
+	return EOK;
+}
+
+int destroy_gpt_label(label_t *this)
+{
+	gpt_free_label(this->data.gpt);
+	return EOK;
+}
+
+int new_gpt_label(label_t *this)
+{
+	this->data.gpt = gpt_alloc_label();
+	return EOK;
+}
+
+int print_gpt_parts(label_t *this)
 {
 	//int rc;
@@ -87,42 +108,63 @@
 	size_t i = 0;
 	
-	gpt_part_foreach(data->gpt->parts, iter) {
+	gpt_part_foreach(this->data.gpt, iter) {
+		i++;
+		//FIXMEE!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+		if (gpt_get_part_type(iter) == GPT_PTE_UNUSED)
+			continue;
+		
+		if (i % 20 == 0)
+			printf("%15s %10s %10s Type: Name:\n", "Start:", "End:", "Length:");
+		
 		//printf("\t%10u %10u %10u %3d\n", iter->start_addr, iter->start_addr + iter->length,
 		//		iter->length, gpt_get_part_type(iter), gpt_get_part_name(iter));
-		printf("%3u\t%10llu %10llu %10llu %3d %s\n", i, gpt_get_start_lba(iter), gpt_get_end_lba(iter),
+		printf("%3u  %10llu %10llu %10llu    %3d %s\n", i-1, gpt_get_start_lba(iter), gpt_get_end_lba(iter),
 				gpt_get_end_lba(iter) - gpt_get_start_lba(iter), gpt_get_part_type(iter),
 				gpt_get_part_name(iter));
-		i++;
-	}
-
+	}
+	
 	//return rc;
 	return EOK;
 }
 
-int read_gpt_parts(service_id_t dev_handle, union label_data *data)
-{
-	return EOK;
-}
-
-int write_gpt_parts(service_id_t dev_handle, union label_data * data)
-{
-	int rc;
-
-	rc = gpt_write_partitions(data->gpt->parts, data->gpt->gpt, dev_handle);
+int read_gpt_parts(label_t *this, service_id_t dev_handle)
+{
+	int rc;
+	
+	rc = gpt_read_header(this->data.gpt, dev_handle);
+	if (rc != EOK) {
+		printf("Error: Reading header failed: %d (%s)\n", rc, str_error(rc));
+		return rc;
+	}
+	
+	rc = gpt_read_partitions(this->data.gpt);
+	if (rc != EOK) {
+		printf("Error: Reading partitions failed: %d (%s)\n", rc, str_error(rc));
+		return rc;
+	}
+	
+	return EOK;
+}
+
+int write_gpt_parts(label_t *this, service_id_t dev_handle)
+{
+	int rc;
+	
+	rc = gpt_write_partitions(this->data.gpt, dev_handle);
 	if (rc != EOK) {
 		printf("Error: Writing partitions failed: %d (%s)\n", rc, str_error(rc));
 		return rc;
 	}
-
-	rc = gpt_write_gpt_header(data->gpt->gpt, dev_handle);
-	if (rc != EOK) {
-		printf("Error: Writing partitions failed: %d (%s)\n", rc, str_error(rc));
-		return rc;
-	}
-
-	return EOK;
-}
-
-int extra_gpt_funcs(tinput_t * in, service_id_t dev_handle, union label_data * data)
+	
+	rc = gpt_write_header(this->data.gpt, dev_handle);
+	if (rc != EOK) {
+		printf("Error: Writing header failed: %d (%s)\n", rc, str_error(rc));
+		return rc;
+	}
+	
+	return EOK;
+}
+
+int extra_gpt_funcs(label_t *this, tinput_t *in, service_id_t dev_handle)
 {
 	printf("Not implemented.\n");
@@ -130,28 +172,35 @@
 }
 
-static int set_gpt_partition(tinput_t * in, gpt_part_t * p)
-{
-	//int rc;
-
+static int set_gpt_partition(tinput_t *in, gpt_part_t *p)
+{
+	int rc;
+	
 	uint64_t sa, ea;
-
+	
 	printf("Set starting address (number): ");
 	sa = get_input_uint64(in);
-
+	
 	printf("Set end addres (number): ");
 	ea = get_input_uint64(in);
-
+	
 	if (ea <= sa) {
 		printf("Invalid value.\n");
 		return EINVAL;
 	}
-
-
-	//p->start_addr = sa;
+	
 	gpt_set_start_lba(p, sa);
-	//p->length = ea - sa;
 	gpt_set_end_lba(p, ea);
-
-	return EOK;
-}
-
+	
+	
+	char *name;
+	rc = get_input_line(in, &name);
+	if (rc != EOK) {
+		printf("Error reading name: %d (%s)\n", rc, str_error(rc));
+		return rc;
+	}
+	
+	gpt_set_part_name(p, name, str_size(name));
+	
+	return EOK;
+}
+
Index: uspace/app/hdisk/func_gpt.h
===================================================================
--- uspace/app/hdisk/func_gpt.h	(revision 44c488656656806dc143099d9a82d6bb2b1bf293)
+++ uspace/app/hdisk/func_gpt.h	(revision 52f2c892e44995718a1719829ff88c8843672a97)
@@ -42,12 +42,13 @@
 #include "common.h"
 
-extern int add_gpt_part(tinput_t *, union label_data *);
-extern int delete_gpt_part(tinput_t *, union label_data *);
-extern int destroy_gpt_label(union label_data *);
-extern int new_gpt_label(union label_data *);
-extern int print_gpt_parts(union label_data *);
-extern int read_gpt_parts(service_id_t, union label_data *);
-extern int write_gpt_parts(service_id_t, union label_data *);
-extern int extra_gpt_funcs(tinput_t *, service_id_t, union label_data *);
+extern int construct_gpt_label(label_t *);
+extern int add_gpt_part     (label_t *, tinput_t *);
+extern int delete_gpt_part  (label_t *, tinput_t *);
+extern int destroy_gpt_label(label_t *);
+extern int new_gpt_label    (label_t *);
+extern int print_gpt_parts  (label_t *);
+extern int read_gpt_parts   (label_t *, service_id_t);
+extern int write_gpt_parts  (label_t *, service_id_t);
+extern int extra_gpt_funcs  (label_t *, tinput_t *, service_id_t);
 
 #endif
Index: uspace/app/hdisk/func_mbr.c
===================================================================
--- uspace/app/hdisk/func_mbr.c	(revision 44c488656656806dc143099d9a82d6bb2b1bf293)
+++ uspace/app/hdisk/func_mbr.c	(revision 52f2c892e44995718a1719829ff88c8843672a97)
@@ -41,27 +41,44 @@
 #include "input.h"
 
-static int set_mbr_partition(tinput_t *in, mbr_part_t *p);
-
-int add_mbr_part(tinput_t *in, union label_data *data)
+static int set_mbr_partition(tinput_t *in, mbr_part_t *p, unsigned int alignment);
+
+int construct_mbr_label(label_t *this)
+{
+	this->layout = LYT_MBR;
+	this->alignment = 1;
+	
+	this->add_part      = add_mbr_part;
+	this->delete_part   = delete_mbr_part;
+	this->destroy_label = destroy_mbr_label;
+	this->new_label     = new_mbr_label;
+	this->print_parts   = print_mbr_parts;
+	this->read_parts    = read_mbr_parts;
+	this->write_parts   = write_mbr_parts;
+	this->extra_funcs   = extra_mbr_funcs;
+	
+	return this->new_label(this);
+}
+
+int add_mbr_part(label_t *this, tinput_t *in)
 {
 	int rc;
 	
 	mbr_part_t *part = mbr_alloc_partition();
-
-	set_mbr_partition(in, part);
-
-	rc = mbr_add_partition(data->mbr, part);
-	if (rc != EOK) {
-		printf("Error adding partition.\n");
-	}
-	
-	return EOK;
-}
-
-int delete_mbr_part(tinput_t *in, union label_data *data)
+	
+	set_mbr_partition(in, part, this->alignment);
+	
+	rc = mbr_add_partition(this->data.mbr, part);
+	if (rc != ERR_OK) {
+		printf("Error adding partition: %d\n", rc);
+	}
+	
+	return EOK;
+}
+
+int delete_mbr_part(label_t *this, tinput_t *in)
 {
 	int rc;
 	size_t idx;
-
+	
 	printf("Number of the partition to delete (counted from 0): ");
 	idx = get_input_size_t(in);
@@ -70,22 +87,22 @@
 		return errno;
 	
-	rc = mbr_remove_partition(data->mbr, idx);
+	rc = mbr_remove_partition(this->data.mbr, idx);
 	if(rc != EOK) {
 		printf("Error: something.\n");
 	}
-
-	return EOK;
-}
-
-int destroy_mbr_label(union label_data *data)
-{
-	mbr_free_label(data->mbr);
-	return EOK;
-}
-
-int new_mbr_label(union label_data *data)
-{
-	data->mbr = mbr_alloc_label();
-	if (data->mbr == NULL)
+	
+	return EOK;
+}
+
+int destroy_mbr_label(label_t *this)
+{
+	mbr_free_label(this->data.mbr);
+	return EOK;
+}
+
+int new_mbr_label(label_t *this)
+{
+	this->data.mbr = mbr_alloc_label();
+	if (this->data.mbr == NULL)
 		return ENOMEM;
 	else
@@ -94,17 +111,20 @@
 
 /** Print current partition scheme */
-int print_mbr_parts(union label_data *data)
+int print_mbr_parts(label_t *this)
 {
 	int num = 0;
-
-	printf("Current partition scheme:\n");
+	
+	printf("Current partition scheme (MBR):\n");
 	//printf("\t\tBootable:\tStart:\tEnd:\tLength:\tType:\n");
 	printf("\t\t%10s  %10s %10s %10s %7s\n", "Bootable:", "Start:", "End:", "Length:", "Type:");
 	
 	mbr_part_t *it;
-	mbr_part_foreach(data->mbr->parts, it) {
+	//mbr_part_foreach(data->mbr, it) {
+	
+	for (it = mbr_get_first_partition(this->data.mbr); it != NULL;
+	     it = mbr_get_next_partition(this->data.mbr, it), ++num) {
 		if (it->type == PT_UNUSED)
 			continue;
-
+		
 		printf("\tP%d:\t", num);
 		if (mbr_get_flag(it, ST_BOOT))
@@ -112,10 +132,10 @@
 		else
 			printf(" ");
-
+		
 		printf("\t%10u %10u %10u %7u\n", it->start_addr, it->start_addr + it->length, it->length, it->type);
-
-		++num;
-	}
-
+		
+		//++num;
+	}
+	
 	printf("%d partitions found.\n", num);
 	
@@ -123,25 +143,24 @@
 }
 
-int read_mbr_parts(service_id_t dev_handle, union label_data *data)
+int read_mbr_parts(label_t *this, service_id_t dev_handle)
 {
 	int rc;
-	printf("mbr\n");
-	rc = mbr_read_mbr(data->mbr, dev_handle);
+	rc = mbr_read_mbr(this->data.mbr, dev_handle);
 	if (rc != EOK)
 		return rc;
-	printf("ismbr\n");
-	if (!mbr_is_mbr(data->mbr))
+	
+	if (!mbr_is_mbr(this->data.mbr))
 		return EINVAL;
-	printf("parts\n");
-	rc = mbr_read_partitions(data->mbr);
+	
+	rc = mbr_read_partitions(this->data.mbr);
 	if (rc != EOK)
 		return rc;
-	printf("end\n");
-	return EOK;
-}
-
-int write_mbr_parts(service_id_t dev_handle, union label_data *data)
-{
-	int rc = mbr_write_partitions(data->mbr, dev_handle);
+	
+	return EOK;
+}
+
+int write_mbr_parts(label_t *this, service_id_t dev_handle)
+{
+	int rc = mbr_write_partitions(this->data.mbr, dev_handle);
 	if (rc != EOK) {
 		printf("Error occured during writing: ERR: %d: %s\n", rc, str_error(rc));
@@ -151,5 +170,5 @@
 }
 
-int extra_mbr_funcs(tinput_t *in, service_id_t dev_handle, union label_data *data)
+int extra_mbr_funcs(label_t *this, tinput_t *in, service_id_t dev_handle)
 {
 	printf("Not implemented.\n");
@@ -157,5 +176,5 @@
 }
 
-static int set_mbr_partition(tinput_t *in, mbr_part_t *p)
+static int set_mbr_partition(tinput_t *in, mbr_part_t *p, unsigned int alignment)
 {
 	int c;
@@ -174,7 +193,9 @@
 			break;
 		default:
-			printf("Invalid type. Cancelled.");
+			printf("Invalid type. Cancelled.\n");
 			return EINVAL;
 	}
+	
+	printf("ST_LOGIC: %d, %hd\n", mbr_get_flag(p, ST_LOGIC), p->status);
 	
 	printf("Set type (0-255): ");
@@ -200,4 +221,9 @@
 	if (sa == 0 && errno != EOK)
 		return errno;
+	
+	if (alignment != 0 && alignment != 1) {
+		sa = mbr_get_next_aligned(sa, alignment);
+		printf("Starting address was aligned to %u.\n", sa);
+	}
 
 	printf("Set end addres (number): ");
@@ -206,4 +232,10 @@
 		return errno;
 	
+	/* Align ending address, not in use */
+	/*if (alignment != 0 && alignment != 1) {
+		ea = mbr_get_next_aligned(ea, alignment) - alignment;
+		printf("Starting address was aligned to %u.\n", ea);
+	}*/
+	
 	if(ea < sa) {
 		printf("Invalid value. Canceled.\n");
Index: uspace/app/hdisk/func_mbr.h
===================================================================
--- uspace/app/hdisk/func_mbr.h	(revision 44c488656656806dc143099d9a82d6bb2b1bf293)
+++ uspace/app/hdisk/func_mbr.h	(revision 52f2c892e44995718a1719829ff88c8843672a97)
@@ -42,12 +42,13 @@
 #include "common.h"
 
-extern int add_mbr_part(tinput_t *, union label_data *);
-extern int delete_mbr_part(tinput_t *, union label_data *);
-extern int destroy_mbr_label(union label_data *);
-extern int new_mbr_label(union label_data *);
-extern int print_mbr_parts(union label_data *);
-extern int read_mbr_parts(service_id_t, union label_data *);
-extern int write_mbr_parts(service_id_t, union label_data *);
-extern int extra_mbr_funcs(tinput_t *, service_id_t, union label_data *);
+extern int construct_mbr_label(label_t *);
+extern int add_mbr_part     (label_t *, tinput_t *);
+extern int delete_mbr_part  (label_t *, tinput_t *);
+extern int destroy_mbr_label(label_t *);
+extern int new_mbr_label    (label_t *);
+extern int print_mbr_parts  (label_t *);
+extern int read_mbr_parts   (label_t *, service_id_t);
+extern int write_mbr_parts  (label_t *, service_id_t);
+extern int extra_mbr_funcs  (label_t *, tinput_t *, service_id_t);
 
 #endif
Index: uspace/app/hdisk/func_none.c
===================================================================
--- uspace/app/hdisk/func_none.c	(revision 44c488656656806dc143099d9a82d6bb2b1bf293)
+++ uspace/app/hdisk/func_none.c	(revision 52f2c892e44995718a1719829ff88c8843672a97)
@@ -41,5 +41,21 @@
 
 
-int add_none_part(tinput_t *in, union label_data *data)
+int construct_none_label(label_t *this)
+{
+	this->layout = LYT_NONE;
+	
+	this->add_part      = add_none_part;
+	this->delete_part   = delete_none_part;
+	this->destroy_label = destroy_none_label;
+	this->new_label     = new_none_label;
+	this->print_parts   = print_none_parts;
+	this->read_parts    = read_none_parts;
+	this->write_parts   = write_none_parts;
+	this->extra_funcs   = extra_none_funcs;
+	
+	return EOK;
+}
+
+int add_none_part(label_t *this, tinput_t * in)
 {
 	not_implemented();
@@ -47,5 +63,5 @@
 }
 
-int delete_none_part(tinput_t *in, union label_data *data)
+int delete_none_part(label_t *this, tinput_t * in)
 {
 	not_implemented();
@@ -53,5 +69,10 @@
 }
 
-int destroy_none_label(union label_data *data)
+int destroy_none_label(label_t *this)
+{
+	return EOK;
+}
+
+int new_none_label(label_t *this)
 {
 	not_implemented();
@@ -59,5 +80,5 @@
 }
 
-int new_none_label(union label_data *data)
+int print_none_parts(label_t *this)
 {
 	not_implemented();
@@ -65,5 +86,5 @@
 }
 
-int print_none_parts(union label_data *data)
+int read_none_parts(label_t *this, service_id_t dev_handle)
 {
 	not_implemented();
@@ -71,5 +92,5 @@
 }
 
-int read_none_parts(service_id_t dev_handle, union label_data *data)
+int write_none_parts(label_t *this, service_id_t dev_handle)
 {
 	not_implemented();
@@ -77,11 +98,5 @@
 }
 
-int write_none_parts(service_id_t dev_handle, union label_data *data)
-{
-	not_implemented();
-	return EOK;
-}
-
-int extra_none_funcs(tinput_t *in, service_id_t dev_handle, union label_data *data)
+int extra_none_funcs(label_t *this, tinput_t * in, service_id_t dev_handle)
 {
 	not_implemented();
Index: uspace/app/hdisk/func_none.h
===================================================================
--- uspace/app/hdisk/func_none.h	(revision 44c488656656806dc143099d9a82d6bb2b1bf293)
+++ uspace/app/hdisk/func_none.h	(revision 52f2c892e44995718a1719829ff88c8843672a97)
@@ -41,12 +41,13 @@
 #include "common.h"
 
-extern int add_none_part(tinput_t *, union label_data *);
-extern int delete_none_part(tinput_t *, union label_data *);
-extern int destroy_none_label(union label_data *);
-extern int new_none_label(union label_data *);
-extern int print_none_parts(union label_data *);
-extern int read_none_parts(service_id_t, union label_data *);
-extern int write_none_parts(service_id_t, union label_data *);
-extern int extra_none_funcs(tinput_t *, service_id_t, union label_data *);
+extern int construct_none_label(label_t *);
+extern int add_none_part     (label_t *, tinput_t *);
+extern int delete_none_part  (label_t *, tinput_t *);
+extern int destroy_none_label(label_t *);
+extern int new_none_label    (label_t *);
+extern int print_none_parts  (label_t *);
+extern int read_none_parts   (label_t *, service_id_t);
+extern int write_none_parts  (label_t *, service_id_t);
+extern int extra_none_funcs  (label_t *, tinput_t *, service_id_t);
 
 #endif
Index: uspace/app/hdisk/hdisk.c
===================================================================
--- uspace/app/hdisk/hdisk.c	(revision 44c488656656806dc143099d9a82d6bb2b1bf293)
+++ uspace/app/hdisk/hdisk.c	(revision 52f2c892e44995718a1719829ff88c8843672a97)
@@ -56,15 +56,10 @@
 void print_help(void);
 void select_label_format(tinput_t *);
-void fill_label_funcs(void);
+void construct_label(layouts_t);
 void free_label(void);
 int try_read(service_id_t);
-
-int construct_none_label(void);
-
-int construct_mbr_label(void);
 int try_read_mbr(service_id_t);
-
-int construct_gpt_label(void);
 int try_read_gpt(service_id_t);
+void set_alignment(tinput_t *);
 
 
@@ -87,5 +82,4 @@
 	}
 	
-	printf("Init.\n");
 	init_label();
 	
@@ -115,5 +109,4 @@
 	mbr_free_mbr(mbr);*/
 	
-	printf("Try MBR.\n");
 	rc = try_read_mbr(dev_handle);
 	if (rc == EOK)
@@ -140,5 +133,4 @@
 	*/
 	
-	printf("Try GPT.\n");
 	rc = try_read_gpt(dev_handle);
 	if (rc == EOK)
@@ -149,5 +141,5 @@
 	
 interact:
-	printf("interact.\n");
+	
 	rc = interact(dev_handle);
 	
@@ -161,5 +153,5 @@
 {
 	int input;
-	tinput_t * in;
+	tinput_t *in;
 	
 	in = tinput_new();
@@ -179,14 +171,11 @@
 		switch(input) {
 			case 'a':
-				label.add_part(in, &label.data);
-				break;
-			case 'b':
-				label.add_part(in, &label.data);
+				label.add_part(&label, in);
 				break;
 			case 'd':
-				label.delete_part(in, &label.data);
+				label.delete_part(&label, in);
 				break;
 			case 'e':
-				label.extra_funcs(in, dev_handle, &label.data);
+				label.extra_funcs(&label, in, dev_handle);
 				break;
 			case 'f':
@@ -197,16 +186,22 @@
 				print_help();
 				break;
+			case 'l':
+				set_alignment(in);
+				break;
 			case 'n':
+				printf("Discarding label...\n");
 				free_label();
-				label.new_label(&label.data);
+				label.new_label(&label);
 				break;
 			case 'p':
-				label.print_parts(&label.data);
+				label.print_parts(&label);
 				break;
 			case 'q':
 				putchar('\n');
 				goto end;
+			case 'r':
+				label.read_parts(&label, dev_handle);
 			case 'w':
-				label.write_parts(dev_handle, &label.data);
+				label.write_parts(&label, dev_handle);
 				break;
 			default:
@@ -228,11 +223,12 @@
 		"\t 'd' \t\t Delete partition.\n"
 		"\t 'e' \t\t Extra functions (per label format).\n"
-		"\t 'f' \t\t Switch the format of the partition label."
+		"\t 'f' \t\t Switch the format of the partition label.\n"
 		"\t 'h' \t\t Prints help. See help for more.\n"
 		"\t 'l' \t\t Set alignment.\n"
 		"\t 'n' \t\t Create new label (discarding the old one).\n"
 		"\t 'p' \t\t Prints label contents.\n"
+		"\t 'q' \t\t Quit.\n"
+		"\t 'r' \t\t Read label from disk.\n"
 		"\t 'w' \t\t Write label to disk.\n"
-		"\t 'q' \t\t Quit.\n"
 		);
 
@@ -244,5 +240,5 @@
 			"1) MBR\n"
 			"2) GPT\n"
-		);
+	      );
 	
 	uint8_t val = get_input_uint8(in);
@@ -250,31 +246,31 @@
 		case 0:
 			free_label();
-			label.layout = LYT_NONE;
-			fill_label_funcs();
+			construct_label(LYT_NONE);
 			break;
 		case 1:
 			free_label();
-			label.layout = LYT_MBR;
-			fill_label_funcs();
+			construct_label(LYT_MBR);
 			break;
 		case 2:
 			free_label();
+			construct_label(LYT_GPT);
+			break;
+	}
+}
+
+void construct_label(layouts_t layout)
+{
+	switch(layout) {
+		case LYT_MBR:
+			label.layout = LYT_MBR;
+			construct_mbr_label(&label);
+			break;
+		case LYT_GPT:
 			label.layout = LYT_GPT;
-			fill_label_funcs();
-			break;
-	}
-}
-
-void fill_label_funcs(void)
-{
-	switch(label.layout) {
-		case LYT_MBR:
-			construct_mbr_label();
-			break;
-		case LYT_GPT:
-			construct_gpt_label();
+			construct_gpt_label(&label);
 			break;
 		default:
-			construct_none_label();
+			label.layout = LYT_NONE;
+			construct_none_label(&label);
 			break;
 	}
@@ -283,103 +279,38 @@
 void free_label(void)
 {
-	/*
-	switch(label.layout) {
-		case LYT_MBR:
-			destroy_mbr_label(&label);
-			break;
-		case LYT_GPT:
-			destroy_gpt_label(&label);
-			break;
-		default:
-			break;
-	}
-	*/
-	
-	label.destroy_label(&label.data);
+	label.destroy_label(&label);
 }
 
 int try_read(service_id_t dev_handle)
 {
-	fill_label_funcs();
-	printf("read_parts\n");
-	return label.read_parts(dev_handle, &label.data);
-}
-
-int construct_none_label()
-{
-	label.add_part      = add_none_part;
-	label.delete_part   = delete_none_part;
-	label.destroy_label = destroy_none_label;
-	label.new_label     = new_none_label;
-	label.print_parts   = print_none_parts;
-	label.read_parts    = read_none_parts;
-	label.write_parts   = write_none_parts;
-	label.extra_funcs   = extra_none_funcs;
-	
-	return EOK;
-}
-
-int construct_mbr_label()
-{
-	label.add_part      = add_mbr_part;
-	label.delete_part   = delete_mbr_part;
-	label.destroy_label = destroy_mbr_label;
-	label.new_label     = new_mbr_label;
-	label.print_parts   = print_mbr_parts;
-	label.read_parts    = read_mbr_parts;
-	label.write_parts   = write_mbr_parts;
-	label.extra_funcs   = extra_mbr_funcs;
-	
-	return label.new_label(&label.data);
+	return label.read_parts(&label, dev_handle);
 }
 
 int try_read_mbr(service_id_t dev_handle)
 {
-	label.layout = LYT_MBR;
+	construct_label(LYT_MBR);
 	return try_read(dev_handle);
 }
 
-int construct_gpt_label()
-{
-	label.add_part    = add_gpt_part;
-	label.delete_part = delete_gpt_part;
-	label.new_label   = new_gpt_label;
-	label.print_parts = print_gpt_parts;
-	label.read_parts  = read_gpt_parts;
-	label.write_parts = write_gpt_parts;
-	label.extra_funcs = extra_gpt_funcs;
-	
-	return label.new_label(&label.data);
-}
-
 int try_read_gpt(service_id_t dev_handle)
 {
-	label.layout = LYT_GPT;
+	construct_label(LYT_GPT);
 	return try_read(dev_handle);
 }
 
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+void set_alignment(tinput_t *in)
+{
+	printf("Set alignment to sectors: ");
+	label.alignment = get_input_uint32(in);
+	printf("Alignment set to %u sectors.\n", label.alignment);
+}
+
+
+
+
+
+
+
+
+
+
Index: uspace/app/hdisk/hdisk.h
===================================================================
--- uspace/app/hdisk/hdisk.h	(revision 44c488656656806dc143099d9a82d6bb2b1bf293)
+++ uspace/app/hdisk/hdisk.h	(revision 52f2c892e44995718a1719829ff88c8843672a97)
@@ -35,23 +35,4 @@
 #include "common.h"
 
-typedef enum {
-	LYT_NONE,
-	LYT_MBR,
-	LYT_GPT,
-} layouts_t;
-
-typedef struct label {
-	layouts_t layout;
-	union label_data data;
-	int (* add_part)     (tinput_t *,   union label_data *);
-	int (* delete_part)  (tinput_t *,   union label_data *);
-	int (* destroy_label)(              union label_data *);
-	int (* new_label)    (              union label_data *);
-	int (* print_parts)  (              union label_data *);
-	int (* read_parts)   (service_id_t, union label_data *);
-	int (* write_parts)  (service_id_t, union label_data *);
-	int (* extra_funcs)  (tinput_t *, service_id_t, union label_data *);
-} label_t;
-
 #define init_label() \
 	label.layout = LYT_NONE
Index: uspace/lib/gpt/global.c
===================================================================
--- uspace/lib/gpt/global.c	(revision 44c488656656806dc143099d9a82d6bb2b1bf293)
+++ uspace/lib/gpt/global.c	(revision 52f2c892e44995718a1719829ff88c8843672a97)
@@ -41,66 +41,69 @@
 
 const struct partition_type gpt_ptypes[] = {
-	{ "Unused entry",					"00000000-0000-0000-0000-000000000000" },
-	{ "MBR partition scheme",			"024DEE41-33E7-11D3-9D69-0008C781F39F" },
-	{ "EFI System",						"C12A7328-F81F-11D2-BA4B-00A0C93EC93B" },
-	{ "BIOS Boot",						"21686148-6449-6E6F-744E-656564454649" },
-	{ "Windows Reserved",				"E3C9E316-0B5C-4DB8-817D-F92DF00215AE" },
-	{ "Windows Basic data",				"EBD0A0A2-B9E5-4433-87C0-68B6B72699C7" },
-	{ "Windows LDM metadata", 			"5808C8AA-7E8F-42E0-85D2-E1E90434CFB3" },
-	{ "Windows LDM data", 				"AF9B60A0-1431-4F62-BC68-3311714A69AD" },
-	{ "Windows Recovery Environment",	"DE94BBA4-06D1-4D40-A16A-BFD50179D6AC" },
-	{ "Windows IBM GPFS",				"37AFFC90-EF7D-4E96-91C3-2D7AE055B174" },
-	{ "Windows Cluster metadata",		"DB97DBA9-0840-4BAE-97F0-FFB9A327C7E1" },
-	{ "HP-UX Data",						"75894C1E-3AEB-11D3-B7C1-7B03A0000000" },
-	{ "HP-UX Service",					"E2A1E728-32E3-11D6-A682-7B03A0000000" },
-	{ "Linux filesystem data",			"EBD0A0A2-B9E5-4433-87C0-68B6B72699C7" },
-	{ "Linux filesystem data",			"0FC63DAF-8483-4772-8E79-3D69D8477DE4" },
-	{ "Linux RAID",						"A19D880F-05FC-4D3B-A006-743F0F84911E" },
-	{ "Linux Swap",						"0657FD6D-A4AB-43C4-84E5-0933C84B4F4F" },
-	{ "Linux LVM",						"E6D6D379-F507-44C2-A23C-238F2A3DF928" },
-	{ "Linux Reserved",					"8DA63339-0007-60C0-C436-083AC8230908" },
-	{ "FreeBSD Boot",					"83BD6B9D-7F41-11DC-BE0B-001560B84F0F" },
-	{ "FreeBSD Data",					"516E7CB4-6ECF-11D6-8FF8-00022D09712B" },
-	{ "FreeBSD Swap",					"516E7CB5-6ECF-11D6-8FF8-00022D09712B" },
-	{ "FreeBSD UFS", 					"516E7CB6-6ECF-11D6-8FF8-00022D09712B" },
-	{ "FreeBSD Vinum VM",				"516E7CB8-6ECF-11D6-8FF8-00022D09712B" },
-	{ "FreeBSD ZFS",					"516E7CBA-6ECF-11D6-8FF8-00022D09712B" },
-	{ "Mac OS X HFS+",					"48465300-0000-11AA-AA11-00306543ECAC" },
-	{ "Mac OS X UFS",					"55465300-0000-11AA-AA11-00306543ECAC" },
-	{ "Mac OS X ZFS",					"6A898CC3-1DD2-11B2-99A6-080020736631" },
-	{ "Mac OS X RAID",					"52414944-0000-11AA-AA11-00306543ECAC" },
-	{ "Mac OS X RAID, offline",			"52414944-5F4F-11AA-AA11-00306543ECAC" },
-	{ "Mac OS X Boot",					"426F6F74-0000-11AA-AA11-00306543ECAC" },
-	{ "Mac OS X Label",					"4C616265-6C00-11AA-AA11-00306543ECAC" },
-	{ "Mac OS X TV Recovery",			"5265636F-7665-11AA-AA11-00306543ECAC" },
-	{ "Mac OS X Core Storage",			"53746F72-6167-11AA-AA11-00306543ECAC" },
-	{ "Solaris Boot",					"6A82CB45-1DD2-11B2-99A6-080020736631" },
-	{ "Solaris Root",					"6A85CF4D-1DD2-11B2-99A6-080020736631" },
-	{ "Solaris Swap",					"6A87C46F-1DD2-11B2-99A6-080020736631" },
-	{ "Solaris Backup",					"6A8B642B-1DD2-11B2-99A6-080020736631" },
-	{ "Solaris /usr",					"6A898CC3-1DD2-11B2-99A6-080020736631" },
-	{ "Solaris /var",					"6A8EF2E9-1DD2-11B2-99A6-080020736631" },
-	{ "Solaris /home",					"6A90BA39-1DD2-11B2-99A6-080020736631" },
-	{ "Solaris Alternate sector",		"6A9283A5-1DD2-11B2-99A6-080020736631" },
-	{ "Solaris Reserved",				"6A945A3B-1DD2-11B2-99A6-080020736631" },
-	{ "Solaris Reserved",				"6A9630D1-1DD2-11B2-99A6-080020736631" },
-	{ "Solaris Reserved",				"6A980767-1DD2-11B2-99A6-080020736631" },
-	{ "Solaris Reserved",				"6A96237F-1DD2-11B2-99A6-080020736631" },
-	{ "Solaris Reserved",				"6A8D2AC7-1DD2-11B2-99A6-080020736631" },
-	{ "NetBSD Swap",					"49F48D32-B10E-11DC-B99B-0019D1879648" },
-	{ "NetBSD FFS",						"49F48D5A-B10E-11DC-B99B-0019D1879648" },
-	{ "NetBSD LFS",						"49F48D82-B10E-11DC-B99B-0019D1879648" },
-	{ "NetBSD RAID",					"49F48DAA-B10E-11DC-B99B-0019D1879648" },
-	{ "NetBSD Concatenated",			"2DB519C4-B10F-11DC-B99B-0019D1879648" },
-	{ "NetBSD Encrypted",				"2DB519EC-B10F-11DC-B99B-0019D1879648" },
-	{ "ChromeOS ChromeOS kernel",		"FE3A2A5D-4F32-41A7-B725-ACCC3285A309" },
-	{ "ChromeOS rootfs",				"3CB8E202-3B7E-47DD-8A3C-7FF2A13CFCEC" },
-	{ "ChromeOS future use",			"2E0A753D-9E48-43B0-8337-B15192CB1B5E" },
-	{ "MidnightBSD Boot",				"85D5E45E-237C-11E1-B4B3-E89A8F7FC3A7" },
-	{ "MidnightBSD Data",				"85D5E45A-237C-11E1-B4B3-E89A8F7FC3A7" },
-	{ "MidnightBSD Swap",				"85D5E45B-237C-11E1-B4B3-E89A8F7FC3A7" },
-	{ "MidnightBSD UFS",				"0394Ef8B-237E-11E1-B4B3-E89A8F7FC3A7" },
-	{ "MidnightBSD Vinum VM",			"85D5E45C-237C-11E1-B4B3-E89A8F7FC3A7" },
-	{ "MidnightBSD ZFS",				"85D5E45D-237C-11E1-B4B3-E89A8F7FC3A7" },
-	{ "Uknown", NULL}	// keep this as the last one! gpt_get_part_type depends on it!
+	{ "Unused entry",					"00000000" "0000" "0000" "0000" "000000000000" },
+	{ "MBR partition scheme",			"024DEE41" "33E7" "11D3" "9D69" "0008C781F39F" },
+	{ "EFI System",						"C12A7328" "F81F" "11D2" "BA4B" "00A0C93EC93B" },
+	{ "BIOS Boot",						"21686148" "6449" "6E6F" "744E" "656564454649" },
+	{ "Windows Reserved",				"E3C9E316" "0B5C" "4DB8" "817D" "F92DF00215AE" },
+	{ "Windows Basic data",				"EBD0A0A2" "B9E5" "4433" "87C0" "68B6B72699C7" },
+	{ "Windows LDM metadata", 			"5808C8AA" "7E8F" "42E0" "85D2" "E1E90434CFB3" },
+	{ "Windows LDM data", 				"AF9B60A0" "1431" "4F62" "BC68" "3311714A69AD" },
+	{ "Windows Recovery Environment",	"DE94BBA4" "06D1" "4D40" "A16A" "BFD50179D6AC" },
+	{ "Windows IBM GPFS",				"37AFFC90" "EF7D" "4E96" "91C3" "2D7AE055B174" },
+	{ "Windows Cluster metadata",		"DB97DBA9" "0840" "4BAE" "97F0" "FFB9A327C7E1" },
+	{ "HP-UX Data",						"75894C1E" "3AEB" "11D3" "B7C1" "7B03A0000000" },
+	{ "HP-UX Service",					"E2A1E728" "32E3" "11D6" "A682" "7B03A0000000" },
+	{ "Linux filesystem data",			"EBD0A0A2" "B9E5" "4433" "87C0" "68B6B72699C7" },
+	{ "Linux filesystem data",			"0FC63DAF" "8483" "4772" "8E79" "3D69D8477DE4" },
+	{ "Linux RAID",						"A19D880F" "05FC" "4D3B" "A006" "743F0F84911E" },
+	{ "Linux Swap",						"0657FD6D" "A4AB" "43C4" "84E5" "0933C84B4F4F" },
+	{ "Linux LVM",						"E6D6D379" "F507" "44C2" "A23C" "238F2A3DF928" },
+	{ "Linux Reserved",					"8DA63339" "0007" "60C0" "C436" "083AC8230908" },
+	{ "FreeBSD Boot",					"83BD6B9D" "7F41" "11DC" "BE0B" "001560B84F0F" },
+	{ "FreeBSD Data",					"516E7CB4" "6ECF" "11D6" "8FF8" "00022D09712B" },
+	{ "FreeBSD Swap",					"516E7CB5" "6ECF" "11D6" "8FF8" "00022D09712B" },
+	{ "FreeBSD UFS", 					"516E7CB6" "6ECF" "11D6" "8FF8" "00022D09712B" },
+	{ "FreeBSD Vinum VM",				"516E7CB8" "6ECF" "11D6" "8FF8" "00022D09712B" },
+	{ "FreeBSD ZFS",					"516E7CBA" "6ECF" "11D6" "8FF8" "00022D09712B" },
+	{ "Mac OS X HFS+",					"48465300" "0000" "11AA" "AA11" "00306543ECAC" },
+	{ "Mac OS X UFS",					"55465300" "0000" "11AA" "AA11" "00306543ECAC" },
+	{ "Mac OS X ZFS",					"6A898CC3" "1DD2" "11B2" "99A6" "080020736631" },
+	{ "Mac OS X RAID",					"52414944" "0000" "11AA" "AA11" "00306543ECAC" },
+	{ "Mac OS X RAID, offline",			"52414944" "5F4F" "11AA" "AA11" "00306543ECAC" },
+	{ "Mac OS X Boot",					"426F6F74" "0000" "11AA" "AA11" "00306543ECAC" },
+	{ "Mac OS X Label",					"4C616265" "6C00" "11AA" "AA11" "00306543ECAC" },
+	{ "Mac OS X TV Recovery",			"5265636F" "7665" "11AA" "AA11" "00306543ECAC" },
+	{ "Mac OS X Core Storage",			"53746F72" "6167" "11AA" "AA11" "00306543ECAC" },
+	{ "Solaris Boot",					"6A82CB45" "1DD2" "11B2" "99A6" "080020736631" },
+	{ "Solaris Root",					"6A85CF4D" "1DD2" "11B2" "99A6" "080020736631" },
+	{ "Solaris Swap",					"6A87C46F" "1DD2" "11B2" "99A6" "080020736631" },
+	{ "Solaris Backup",					"6A8B642B" "1DD2" "11B2" "99A6" "080020736631" },
+	{ "Solaris /usr",					"6A898CC3" "1DD2" "11B2" "99A6" "080020736631" },
+	{ "Solaris /var",					"6A8EF2E9" "1DD2" "11B2" "99A6" "080020736631" },
+	{ "Solaris /home",					"6A90BA39" "1DD2" "11B2" "99A6" "080020736631" },
+	{ "Solaris Alternate sector",		"6A9283A5" "1DD2" "11B2" "99A6" "080020736631" },
+	{ "Solaris Reserved",				"6A945A3B" "1DD2" "11B2" "99A6" "080020736631" },
+	{ "Solaris Reserved",				"6A9630D1" "1DD2" "11B2" "99A6" "080020736631" },
+	{ "Solaris Reserved",				"6A980767" "1DD2" "11B2" "99A6" "080020736631" },
+	{ "Solaris Reserved",				"6A96237F" "1DD2" "11B2" "99A6" "080020736631" },
+	{ "Solaris Reserved",				"6A8D2AC7" "1DD2" "11B2" "99A6" "080020736631" },
+	{ "NetBSD Swap",					"49F48D32" "B10E" "11DC" "B99B" "0019D1879648" },
+	{ "NetBSD FFS",						"49F48D5A" "B10E" "11DC" "B99B" "0019D1879648" },
+	{ "NetBSD LFS",						"49F48D82" "B10E" "11DC" "B99B" "0019D1879648" },
+	{ "NetBSD RAID",					"49F48DAA" "B10E" "11DC" "B99B" "0019D1879648" },
+	{ "NetBSD Concatenated",			"2DB519C4" "B10F" "11DC" "B99B" "0019D1879648" },
+	{ "NetBSD Encrypted",				"2DB519EC" "B10F" "11DC" "B99B" "0019D1879648" },
+	{ "ChromeOS ChromeOS kernel",		"FE3A2A5D" "4F32" "41A7" "B725" "ACCC3285A309" },
+	{ "ChromeOS rootfs",				"3CB8E202" "3B7E" "47DD" "8A3C" "7FF2A13CFCEC" },
+	{ "ChromeOS future use",			"2E0A753D" "9E48" "43B0" "8337" "B15192CB1B5E" },
+	{ "MidnightBSD Boot",				"85D5E45E" "237C" "11E1" "B4B3" "E89A8F7FC3A7" },
+	{ "MidnightBSD Data",				"85D5E45A" "237C" "11E1" "B4B3" "E89A8F7FC3A7" },
+	{ "MidnightBSD Swap",				"85D5E45B" "237C" "11E1" "B4B3" "E89A8F7FC3A7" },
+	{ "MidnightBSD UFS",				"0394Ef8B" "237E" "11E1" "B4B3" "E89A8F7FC3A7" },
+	{ "MidnightBSD Vinum VM",			"85D5E45C" "237C" "11E1" "B4B3" "E89A8F7FC3A7" },
+	{ "MidnightBSD ZFS",				"85D5E45D" "237C" "11E1" "B4B3" "E89A8F7FC3A7" },
+	{ "Uknown", NULL} /* keep this as the last one! gpt_get_part_type depends on it! */
 };
+
+
+
Index: uspace/lib/gpt/libgpt.c
===================================================================
--- uspace/lib/gpt/libgpt.c	(revision 44c488656656806dc143099d9a82d6bb2b1bf293)
+++ uspace/lib/gpt/libgpt.c	(revision 52f2c892e44995718a1719829ff88c8843672a97)
@@ -51,10 +51,10 @@
 #include "libgpt.h"
 
-static int load_and_check_header(service_id_t handle, aoff64_t addr, size_t b_size, gpt_header_t * header);
+static int load_and_check_header(service_id_t handle, aoff64_t addr, size_t b_size, gpt_header_t *header);
 static gpt_partitions_t * alloc_part_array(uint32_t num);
-static int extend_part_array(gpt_partitions_t * p);
-static int reduce_part_array(gpt_partitions_t * p);
+static int extend_part_array(gpt_partitions_t *);
+static int reduce_part_array(gpt_partitions_t *);
 static long long nearest_larger_int(double a);
-
+static uint8_t get_byte(const char *);
 
 /** Allocate memory for gpt label */
@@ -179,5 +179,5 @@
 
 	rc = block_init(EXCHANGE_ATOMIC, dev_handle, b_size);
-	if (rc != EOK)
+	if (rc != EOK && rc != EEXIST)
 		return rc;
 
@@ -300,18 +300,29 @@
 	size_t b_size;
 	uint32_t e_size = uint32_t_le2host(label->gpt->header->entry_size);
-
+	size_t fill = label->parts->fill > GPT_MIN_PART_NUM ? label->parts->fill : GPT_MIN_PART_NUM;
+	
 	label->gpt->header->pe_array_crc32 = compute_crc32(
 	                               (uint8_t *) label->parts->part_array,
-	                               label->parts->fill * e_size);
+	                               fill * e_size);
 	
 	/* comm_size of 4096 is ignored */
 	rc = block_init(EXCHANGE_ATOMIC, dev_handle, 4096);
-	if (rc != EOK)
-		return rc;
-
+	if (rc != EOK && rc != EEXIST)
+		return rc;
+	
 	rc = block_get_bsize(dev_handle, &b_size);
 	if (rc != EOK)
 		goto fail;
-
+	
+	aoff64_t n_blocks;
+	rc = block_get_nblocks(dev_handle, &n_blocks);
+	if (rc != EOK)
+		goto fail;
+	
+	/* Write to backup GPT partition array location */
+	//rc = block_write_direct(dev_handle, n_blocks - 1, GPT_HDR_BS, header->raw_data);
+	if (rc != EOK)
+		goto fail;
+	
 	/* Write to main GPT partition array location */
 	rc = block_write_direct(dev_handle, uint64_t_le2host(label->gpt->header->entry_lba),
@@ -320,17 +331,5 @@
 	if (rc != EOK)
 		goto fail;
-
-	aoff64_t n_blocks;
-	rc = block_get_nblocks(dev_handle, &n_blocks);
-	if (rc != EOK)
-		goto fail;
-
-	/* Write to backup GPT partition array location */
-	//rc = block_write_direct(dev_handle, n_blocks - 1, GPT_HDR_BS, header->raw_data);
-	block_fini(dev_handle);
-	if (rc != EOK)
-		goto fail;
-
-
+	
 	return gpt_write_header(label, dev_handle);
 	
@@ -347,5 +346,5 @@
  * This returns a memory block (zero-filled) and needs gpt_add_partition()
  * to be called to insert it into a partition array.
- * Requires you to call gpt_free_partition after use.
+ * Requires you to call gpt_free_partition afterwards.
  */
 gpt_part_t * gpt_alloc_partition(void)
@@ -367,16 +366,51 @@
  *
  * Note: use either gpt_alloc_partition or gpt_get_partition.
- * This one return a pointer to a structure already inside the array, so
- * there's no need to call gpt_add_partition(). 
+ * This one returns a pointer to the first empty structure already
+ * inside the array, so don't call gpt_add_partition() afterwards.
  * This is the one you will usually want.
  */
 gpt_part_t * gpt_get_partition(gpt_label_t *label)
 {
-	if (label->parts->fill == label->parts->arr_size) {
-		if (extend_part_array(label->parts) == -1)
-			return NULL;
-	}
-
-	return label->parts->part_array + label->parts->fill++;
+	gpt_part_t *p;
+	
+	/* Find the first empty entry */
+	do {
+		if (label->parts->fill == label->parts->arr_size) {
+			if (extend_part_array(label->parts) == -1)
+				return NULL;
+		}
+		
+		p = label->parts->part_array + label->parts->fill++;
+		
+	} while (gpt_get_part_type(p) != GPT_PTE_UNUSED);
+	
+	return p;
+}
+
+/** Get partition already inside the label
+ *
+ * @param label   label to carrying the partition
+ * @param idx     index of the partition
+ *
+ * @return        returns pointer to the partition
+ *                or NULL when out of range
+ *
+ * Note: For new partitions use either gpt_alloc_partition or
+ * gpt_get_partition unless you want a partition at a specific place.
+ * This returns a pointer to a structure already inside the array,
+ * so don't call gpt_add_partition() afterwards.
+ * This function is handy when you want to change already existing
+ * partition or to simply write somewhere in the middle. This works only
+ * for indexes smaller than either 128 or the actual number of filled
+ * entries.
+ */
+gpt_part_t * gpt_get_partition_at(gpt_label_t *label, size_t idx)
+{
+	return NULL;
+	
+	if (idx >= GPT_MIN_PART_NUM && idx >= label->parts->fill)
+		return NULL;
+	
+	return label->parts->part_array + idx;
 }
 
@@ -415,13 +449,18 @@
 int gpt_remove_partition(gpt_label_t *label, size_t idx)
 {
-	if (idx != label->parts->fill - 1) {
-		memmove(label->parts->part_array + idx,
-		        label->parts->part_array + idx + 1,
-		        (label->parts->fill - 1) * sizeof(gpt_entry_t));
-		label->parts->fill -= 1;
-	}
-	
-	/* FIXME: This probably shouldn't be here, but instead
-	 * in reduce_part_array() or similar */
+	if (idx >= label->parts->fill)
+		return EINVAL;
+	
+	/* FIXME! 
+	 * If we allow blank spots, we break the array. If we have more than
+	 * 128 partitions in the array and then remove something from
+	 * the first 128 partitions, we would forget to write the last one.*/
+	memset(label->parts->part_array + idx, 0, sizeof(gpt_entry_t));
+	
+	label->parts->fill -= 1;
+	
+	/* FIXME!
+	 * We cannot reduce the array so simply. We may have some partitions
+	 * there since we allow blank spots.*/
 	if (label->parts->fill < (label->parts->arr_size / 2) - GPT_IGNORE_FILL_NUM) {
 		if (reduce_part_array(label->parts) == ENOMEM)
@@ -448,9 +487,28 @@
 {
 	size_t i;
+	
 	for (i = 0; gpt_ptypes[i].guid != NULL; i++) {
-		if (bcmp(p->part_type, gpt_ptypes[i].guid, 16) == 0) {
-			break;
-		}
-	}
+		if (p->part_type[3] == get_byte(gpt_ptypes[i].guid +0) &&
+			p->part_type[2] == get_byte(gpt_ptypes[i].guid +2) &&
+			p->part_type[1] == get_byte(gpt_ptypes[i].guid +4) &&
+			p->part_type[0] == get_byte(gpt_ptypes[i].guid +6) &&
+			
+			p->part_type[5] == get_byte(gpt_ptypes[i].guid +8) &&
+			p->part_type[4] == get_byte(gpt_ptypes[i].guid +10) &&
+			
+			p->part_type[7] == get_byte(gpt_ptypes[i].guid +12) &&
+			p->part_type[6] == get_byte(gpt_ptypes[i].guid +14) &&
+			
+			p->part_type[8] == get_byte(gpt_ptypes[i].guid +16) &&
+			p->part_type[9] == get_byte(gpt_ptypes[i].guid +18) &&
+			p->part_type[10] == get_byte(gpt_ptypes[i].guid +20) &&
+			p->part_type[11] == get_byte(gpt_ptypes[i].guid +22) &&
+			p->part_type[12] == get_byte(gpt_ptypes[i].guid +24) &&
+			p->part_type[13] == get_byte(gpt_ptypes[i].guid +26) &&
+			p->part_type[14] == get_byte(gpt_ptypes[i].guid +28) &&
+			p->part_type[15] == get_byte(gpt_ptypes[i].guid +30))
+				break;
+	}
+	
 	return i;
 }
@@ -516,5 +574,5 @@
 
 /** Copy partition name */
-void gpt_set_part_name(gpt_part_t * p, char * name[], size_t length)
+void gpt_set_part_name(gpt_part_t *p, char *name, size_t length)
 {
 	if (length >= 72)
@@ -645,7 +703,14 @@
 }
 
-
-
-
-
-
+static uint8_t get_byte(const char * c)
+{
+	uint8_t val = 0;
+	char hex[3] = {*c, *(c+1), 0};
+	
+	errno = str_uint8_t(hex, NULL, 16, false, &val);
+	return val;
+}
+
+
+
+
Index: uspace/lib/gpt/libgpt.h
===================================================================
--- uspace/lib/gpt/libgpt.h	(revision 44c488656656806dc143099d9a82d6bb2b1bf293)
+++ uspace/lib/gpt/libgpt.h	(revision 52f2c892e44995718a1719829ff88c8843672a97)
@@ -52,4 +52,7 @@
 /** How much fill we ignore before resizing partition array */
 #define GPT_IGNORE_FILL_NUM 10
+
+/** Unused partition entry */
+#define GPT_PTE_UNUSED 0
 
 /** GPT header signature ("EFI PART" in ASCII) */
@@ -149,4 +152,5 @@
 extern gpt_part_t *    gpt_alloc_partition (void);
 extern gpt_part_t *    gpt_get_partition   (gpt_label_t *);
+extern gpt_part_t *    gpt_get_partition_at(gpt_label_t *, size_t);
 extern int             gpt_add_partition   (gpt_label_t *, gpt_part_t *);
 extern int             gpt_remove_partition(gpt_label_t *, size_t);
@@ -159,5 +163,5 @@
 extern uint64_t        gpt_get_end_lba  (gpt_part_t *);
 extern unsigned char * gpt_get_part_name(gpt_part_t *);
-extern void            gpt_set_part_name(gpt_part_t *, char *[], size_t);
+extern void            gpt_set_part_name(gpt_part_t *, char *, size_t);
 extern bool            gpt_get_flag     (gpt_part_t *, GPT_ATTR);
 extern void            gpt_set_flag     (gpt_part_t *, GPT_ATTR, bool);
@@ -165,7 +169,7 @@
 
 
-#define gpt_part_foreach(parts, iterator) \
-		for(gpt_part_t * iterator = (parts)->part_array; \
-		    iterator < (parts)->part_array + (parts)->fill; ++iterator)
+#define gpt_part_foreach(label, iterator) \
+		for(gpt_part_t * iterator = (label)->parts->part_array; \
+		    iterator < (label)->parts->part_array + (label)->parts->fill; ++iterator)
 
 extern void gpt_free_gpt(gpt_t *);
Index: uspace/lib/mbr/libmbr.c
===================================================================
--- uspace/lib/mbr/libmbr.c	(revision 44c488656656806dc143099d9a82d6bb2b1bf293)
+++ uspace/lib/mbr/libmbr.c	(revision 52f2c892e44995718a1719829ff88c8843672a97)
@@ -52,4 +52,6 @@
 static int check_encaps(mbr_part_t *, mbr_part_t *);
 static int check_preceeds(mbr_part_t *, mbr_part_t *);
+static mbr_err_val mbr_add_primary(mbr_label_t *label, mbr_part_t *p);
+static mbr_err_val mbr_add_logical(mbr_label_t *label, mbr_part_t *p);
 
 /** Allocate and initialize mbr_label_t structure */
@@ -168,18 +170,18 @@
 	mbr_part_t *ext = NULL;
 	//mbr_partitions_t *parts;
-	printf("check\n");
+	
 	if (label->parts != NULL)
 		mbr_free_partitions(label->parts);
-	printf("check2\n");
+	
 	label->parts = mbr_alloc_partitions();
 	if (label->parts == NULL) {
 		return ENOMEM;
 	}
-	printf("primary\n");
+	
 	/* Generate the primary partitions */
 	for (i = 0; i < N_PRIMARY; ++i) {
 		if (label->mbr->raw_data.pte[i].ptype == PT_UNUSED)
 			continue;
-		printf("pcheck1\n");
+		
 		p = mbr_alloc_partition();
 		if (p == NULL) {
@@ -188,5 +190,5 @@
 			return ENOMEM;
 		}
-		printf("pcheck2\n");
+		
 		rc_ext = decode_part(&(label->mbr->raw_data.pte[i]), p, 0);
 		mbr_set_flag(p, ST_LOGIC, false);
@@ -198,20 +200,19 @@
 			return EINVAL;
 		}
-		printf("pcheck3\n");
+		
 		if (rc_ext) {
 			ext = p;
-			label->parts->l_extended = list_nth(&(label->parts->list), i);
-		}
-		printf("pcheck4\n");
-	}
-	printf("logical\n");
+			label->parts->l_extended = &p->link;
+		}
+	}
+	
 	/* Fill in the primary partitions and generate logical ones, if any */
 	rc = decode_logical(label, ext);
 	if (rc != EOK) {
-		printf(LIBMBR_NAME ": Error occured during decoding the MBR.\n" \
-			   LIBMBR_NAME ": Partition list may be incomplete.\n");
+		printf(LIBMBR_NAME ": Error during decoding logical partitions: %d - %s.\n" \
+			   LIBMBR_NAME ": Partition list may be incomplete.\n", rc, str_error(rc));
 		return rc;
 	}
-	printf("finish\n");
+	
 	return EOK;
 }
@@ -225,4 +226,10 @@
 int mbr_write_partitions(mbr_label_t *label, service_id_t dev_handle)
 {
+	if (label->parts == NULL)
+		return EOK;
+	
+	if (label->mbr == NULL)
+		label->mbr = mbr_alloc_mbr();
+	
 	int i = 0;
 	int rc;
@@ -240,5 +247,5 @@
 	
 	/* Encoding primary partitions */
-	for (i = 0; i < label->parts->n_primary; i++) {
+	for (i = 0; i < N_PRIMARY; i++) {
 		p = list_get_instance(l, mbr_part_t, link);	
 		encode_part(p, &(label->mbr->raw_data.pte[i]), 0, false);
@@ -253,9 +260,11 @@
 	}
 	
-	if (ext == NULL)
+	if (ext == NULL) {
+		rc = EOK;
 		goto end;
+	}
 	
 	uint32_t base = ext->start_addr;
-	mbr_part_t * prev_p;
+	mbr_part_t *prev_p;
 	
 	/* Note for future changes: Some thought has been put into design
@@ -281,8 +290,44 @@
 		}
 		free(tmp);
+		rc = EOK;
 		goto end;
 	}
 	
 	prev_p = p;
+	
+	/* Check EBR addresses
+	 * This piece of code saves previous EBR placements from other
+	 * software. But if our user modifies the logical partition chain,
+	 * we have to fix those placements if needed.*/
+	link_t *l_ebr = l;
+	link_t *l_iter;
+	mbr_part_t *tmp = mbr_alloc_partition();
+	tmp->length = 1;
+	while (l_ebr != &(label->parts->list.head)) {
+		p = list_get_instance(l_ebr, mbr_part_t, link);
+		tmp->start_addr = p->ebr_addr;
+		
+		l_iter = l;
+		while (l_iter != &(label->parts->list.head)) {
+			/* Checking whether EBR address makes sense. If not, we take a guess.
+			 * So far this is simple, we just take the first preceeding sector.
+			 * Fdisk always reserves at least 2048 sectors (1MiB), so it can have 
+			 * the EBR aligned as well as the partition itself. Parted reserves
+			 * minimum one sector, like we do.
+			 * 
+			 * Note that we know there is at least one sector free from previous checks.
+			 * Also note that the user can set ebr_addr to their liking (if it's valid). */		 
+			if (p->ebr_addr < base || p->ebr_addr >= base + ext->length ||
+			  check_overlap(tmp, list_get_instance(l_iter, mbr_part_t, link))) {
+				p->ebr_addr = p->start_addr - 1;
+				break;
+			}
+			
+			l_iter = l_iter->next;
+		}
+		
+		l_ebr = l_ebr->next;
+	}
+	mbr_free_partition(tmp);
 	
 	/* Encoding and writing logical partitions */
@@ -290,16 +335,4 @@
 		p = list_get_instance(l, mbr_part_t, link);
 		
-		/* Checking whether EBR address makes sense. If not, we take a guess.
-		 * So far this is simple, we just take the first preceeding sector.
-		 * Fdisk always reserves at least 2048 sectors (1MiB), so it can have 
-		 * the EBR aligned as well as the partition itself. Parted reserves
-		 * minimum one sector, like we do.
-		 * 
-		 * Note that we know there is at least one sector free from previous checks.
-		 * Also note that the user can set ebr_addr to their liking (if it's valid). */		 
-		if (p->ebr_addr >= p->start_addr || p->ebr_addr <= (prev_p->start_addr + prev_p->length)) {
-			p->ebr_addr = p->start_addr - 1;
-			DEBUG_PRINT_0(LIBMBR_NAME ": Warning: invalid EBR address.\n");
-		}
 		
 		encode_part(p, &(p->ebr->pte[0]), p->ebr_addr, false);
@@ -390,107 +423,38 @@
 mbr_err_val mbr_add_partition(mbr_label_t *label, mbr_part_t *p)
 {
-	int rc;
-	mbr_partitions_t *parts = label->parts;
-	
+	int rc1, rc2;
 	aoff64_t nblocks;
-	printf("add1.\n");
-	rc = block_init(EXCHANGE_ATOMIC, label->device, 512);
-	if (rc != EOK) {
-		printf(LIBMBR_NAME ": Error while getting number of blocks: %d - %s.\n", rc, str_error(rc));
+	
+	rc1 = block_init(EXCHANGE_ATOMIC, label->device, 512);
+	if (rc1 != EOK && rc1 != EEXIST) {
+		printf(LIBMBR_NAME ": Error during libblock init: %d - %s.\n", rc1, str_error(rc1));
 		return ERR_LIBBLOCK;
 	}
-	printf("add2.\n");
-	rc = block_get_nblocks(label->device, &nblocks);
-	block_fini(label->device);
-	if (rc != EOK) {
-		printf(LIBMBR_NAME ": Error while getting number of blocks: %d - %s.\n", rc, str_error(rc));
+	
+	rc2 = block_get_nblocks(label->device, &nblocks);
+	
+	if (rc1 != EEXIST)
+		block_fini(label->device);
+	
+	if (rc2 != EOK) {
+		printf(LIBMBR_NAME ": Error while getting number of blocks: %d - %s.\n", rc2, str_error(rc2));
 		return ERR_LIBBLOCK;
 	}
-	printf("add3.\n");
-	if (mbr_get_flag(p, ST_LOGIC)) { 
+	
+	if ((aoff64_t) p->start_addr + p->length > nblocks)
+		return ERR_OUT_BOUNDS;
+	
+	if (label->parts == NULL) {
+		label->parts = mbr_alloc_partitions();
+		if (label->parts == NULL)
+			return ENOMEM; //FIXME! merge mbr_err_val into errno.h
+	}
+	
+	if (mbr_get_flag(p, ST_LOGIC))
 		/* adding logical partition */
-		
-		/* is there any extended partition? */
-		if (parts->l_extended == NULL)
-			return ERR_NO_EXTENDED;
-		
-		/* is the logical partition inside the extended one? */
-		mbr_part_t *ext = list_get_instance(parts->l_extended, mbr_part_t, link);
-		if (!check_encaps(p, ext))
-			return ERR_OUT_BOUNDS;
-		
-		/* find a place for the new partition in a sorted linked list */
-		//mbr_part_t *last = list_get_instance(list_last(&(parts->list)), mbr_part_t, link);
-		mbr_part_t *iter;
-		//uint32_t ebr_space = 1;
-		mbr_part_foreach(parts, iter) {
-			if (mbr_get_flag(iter, ST_LOGIC)) {
-				if (check_overlap(p, iter)) 
-					return ERR_OVERLAP;
-				if (check_preceeds(iter, p)) {
-					/* checking if there's at least one sector of space preceeding */
-					if ((iter->start_addr + iter->length) >= p->start_addr - 1)
-						return ERR_NO_EBR;
-				} else {
-					/* checking if there's at least one sector of space following (for following partitions's EBR) */
-					if ((p->start_addr + p->length) >= iter->start_addr - 1)
-						return ERR_NO_EBR;
-				}
-			}
-		}
-		
-		/* alloc EBR if it's not already there */
-		if (p->ebr == NULL) {
-			p->ebr = alloc_br();
-			if (p->ebr == NULL) {
-				return ERR_NOMEM;
-			}
-		}
-		
-		/* add it */
-		list_append(&(p->link), &(parts->list));
-		parts->n_logical += 1;
-	} else {
+		return mbr_add_logical(label, p);
+	else
 		/* adding primary */
-		
-		if (parts->n_primary == 4) {
-			return ERR_PRIMARY_FULL;
-		}
-		
-		/* Check if partition makes space for MBR itself. */
-		if (p->start_addr == 0 || ((aoff64_t) p->start_addr) + p->length >= nblocks) {
-			return ERR_OUT_BOUNDS;
-		}
-		printf("add4.\n");
-		/* if it's extended, is there any other one? */
-		if ((p->type == PT_EXTENDED || p->type == PT_EXTENDED_LBA) && parts->l_extended != NULL) {
-			return ERR_EXTENDED_PRESENT;
-		}
-		printf("add5.\n");
-		/* find a place and add it */
-		mbr_part_t *iter;
-		mbr_part_t *empty = NULL;
-		mbr_part_foreach(parts, iter) {
-			printf("type: %x\n", iter->type);
-			if (iter->type == PT_UNUSED) {
-				if (empty == NULL)
-					empty = iter;
-			} else if (check_overlap(p, iter))
-				return ERR_OVERLAP;
-		}
-		printf("add6. %p, %p\n", empty, p);
-		list_insert_after(&(p->link), &(empty->link));
-		printf("add6.1.\n");
-		list_remove(&(empty->link));
-		printf("add6.2.\n");
-		free(empty);
-		printf("add7.\n");
-		parts->n_primary += 1;
-		
-		if (p->type == PT_EXTENDED || p->type == PT_EXTENDED_LBA)
-			parts->l_extended = &(p->link);
-	}
-	printf("add8.\n");
-	return ERR_OK;
+		return mbr_add_primary(label, p);
 }
 
@@ -569,5 +533,5 @@
 void mbr_set_flag(mbr_part_t *p, MBR_FLAGS flag, bool value)
 {
-	uint8_t status = p->status;
+	uint16_t status = p->status;
 
 	if (value)
@@ -579,9 +543,35 @@
 }
 
-/** Get next aligned address (in sectors!) */
+/** Get next aligned address */
 uint32_t mbr_get_next_aligned(uint32_t addr, unsigned int alignment)
 {
 	uint32_t div = addr / alignment;
 	return (div + 1) * alignment;
+}
+
+list_t * mbr_get_list(mbr_label_t *label)
+{
+	if (label->parts != NULL)
+		return &(label->parts->list);
+	else
+		return NULL;
+}
+
+mbr_part_t * mbr_get_first_partition(mbr_label_t *label)
+{
+	list_t *list = mbr_get_list(label);
+	if (list != NULL && !list_empty(list))
+		return list_get_instance(list->head.next, mbr_part_t, link);
+	else
+		return NULL;
+}
+
+mbr_part_t * mbr_get_next_partition(mbr_label_t *label, mbr_part_t *p)
+{
+	list_t *list = mbr_get_list(label);
+	if (list != NULL && &(p->link) != list_last(list))
+		return list_get_instance(p->link.next, mbr_part_t, link);
+	else
+		return NULL;
 }
 
@@ -627,6 +617,5 @@
 	trgt->type = src->ptype;
 
-	/* Checking only 0x80; otherwise writing will fix to 0x00 */
-	trgt->status = (trgt->status & 0xFF00) | src->status;
+	trgt->status = (trgt->status & 0xFF00) | (uint16_t) src->status;
 
 	trgt->start_addr = uint32_t_le2host(src->first_lba) + base;
@@ -691,4 +680,5 @@
 	
 	while (ebr->pte[1].ptype != PT_UNUSED) {
+		
 		ebr = alloc_br();
 		if (ebr == NULL) {
@@ -712,5 +702,4 @@
 			goto free_ebr_end;
 		}
-		
 		
 		decode_part(&(ebr->pte[0]), p, addr);
@@ -759,15 +748,9 @@
 			trgt->length = host2uint32_t_le(src->length);
 		}
+		
+		if (trgt->ptype == PT_UNUSED)
+			memset(trgt, 0, sizeof(pt_entry_t));
 	} else {
-		trgt->status = 0;
-		trgt->first_chs[0] = 0;
-		trgt->first_chs[1] = 0;
-		trgt->first_chs[2] = 0;
-		trgt->ptype = 0;
-		trgt->last_chs[0] = 0;
-		trgt->last_chs[1] = 0;
-		trgt->last_chs[2] = 0;
-		trgt->first_lba = 0;
-		trgt->length = 0;
+		memset(trgt, 0, sizeof(pt_entry_t));
 	}
 }
@@ -779,7 +762,7 @@
 static int check_overlap(mbr_part_t * p1, mbr_part_t * p2)
 {
-	if (p1->start_addr < p2->start_addr && p1->start_addr + p1->length < p2->start_addr) {
+	if (p1->start_addr < p2->start_addr && p1->start_addr + p1->length <= p2->start_addr) {
 		return 0;
-	} else if (p1->start_addr > p2->start_addr && p2->start_addr + p2->length < p1->start_addr) {
+	} else if (p1->start_addr > p2->start_addr && p2->start_addr + p2->length <= p1->start_addr) {
 		return 0;
 	}
@@ -812,5 +795,93 @@
 }
 
-
-
-
+mbr_err_val mbr_add_primary(mbr_label_t *label, mbr_part_t *p)
+{
+	if (label->parts->n_primary == 4) {
+		return ERR_PRIMARY_FULL;
+	}
+	
+	/* Check if partition makes space for MBR itself. */
+	if (p->start_addr == 0) {
+		return ERR_OUT_BOUNDS;
+	}
+	
+	/* if it's extended, is there any other one? */
+	if ((p->type == PT_EXTENDED || p->type == PT_EXTENDED_LBA) && label->parts->l_extended != NULL) {
+		return ERR_EXTENDED_PRESENT;
+	}
+	
+	/* find a place and add it */
+	mbr_part_t *iter;
+	mbr_part_t *empty = NULL;
+	mbr_part_foreach(label, iter) {
+		if (iter->type == PT_UNUSED) {
+			if (empty == NULL)
+				empty = iter;
+		} else if (check_overlap(p, iter))
+			return ERR_OVERLAP;
+	}
+	
+	list_insert_after(&(p->link), &(empty->link));
+	list_remove(&(empty->link));
+	free(empty);
+	
+	label->parts->n_primary += 1;
+	
+	if (p->type == PT_EXTENDED || p->type == PT_EXTENDED_LBA)
+		label->parts->l_extended = &(p->link);
+	
+	return EOK;
+}
+
+mbr_err_val mbr_add_logical(mbr_label_t *label, mbr_part_t *p)
+{
+	/* is there any extended partition? */
+	if (label->parts->l_extended == NULL)
+		return ERR_NO_EXTENDED;
+	
+	/* is the logical partition inside the extended one? */
+	mbr_part_t *ext = list_get_instance(label->parts->l_extended, mbr_part_t, link);
+	if (!check_encaps(p, ext))
+		return ERR_OUT_BOUNDS;
+	
+	/* find a place for the new partition in a sorted linked list */
+	bool first_logical = true;
+	mbr_part_t *iter;
+	mbr_part_foreach(label, iter) {
+		if (mbr_get_flag(iter, ST_LOGIC)) {
+			if (check_overlap(p, iter)) 
+				return ERR_OVERLAP;
+			if (check_preceeds(iter, p)) {
+				/* checking if there's at least one sector of space preceeding */
+				if ((iter->start_addr + iter->length) >= p->start_addr - 1)
+					return ERR_NO_EBR;
+			} else if (first_logical){
+				/* First logical partition's EBR is before every other
+				 * logical partition. Thus we don't check if this partition
+				 * leaves enough space for it. */
+				first_logical = false;
+			} else {
+				/* checking if there's at least one sector of space following (for following partitions's EBR) */
+				if ((p->start_addr + p->length) >= iter->start_addr - 1)
+					return ERR_NO_EBR;
+			}
+		}
+	}
+	
+	/* alloc EBR if it's not already there */
+	if (p->ebr == NULL) {
+		p->ebr = alloc_br();
+		if (p->ebr == NULL) {
+			return ERR_NOMEM;
+		}
+	}
+	
+	/* add it */
+	list_append(&(p->link), &(label->parts->list));
+	label->parts->n_logical += 1;
+	
+	return EOK;
+}
+
+
+
Index: uspace/lib/mbr/libmbr.h
===================================================================
--- uspace/lib/mbr/libmbr.h	(revision 44c488656656806dc143099d9a82d6bb2b1bf293)
+++ uspace/lib/mbr/libmbr.h	(revision 52f2c892e44995718a1719829ff88c8843672a97)
@@ -213,8 +213,11 @@
 extern void         mbr_set_flag(mbr_part_t *, MBR_FLAGS, bool);
 extern uint32_t     mbr_get_next_aligned(uint32_t, unsigned int);
-
-#define mbr_part_foreach(parts, iterator)	\
-        for (iterator  = list_get_instance((parts)->list.head.next, mbr_part_t, link); \
-             iterator != list_get_instance(&((parts)->list.head), mbr_part_t, link); \
+extern list_t *     mbr_get_list(mbr_label_t *);
+extern mbr_part_t * mbr_get_first_partition(mbr_label_t *);
+extern mbr_part_t * mbr_get_next_partition(mbr_label_t *, mbr_part_t *);
+
+#define mbr_part_foreach(label, iterator) \
+        for (iterator  = list_get_instance((label)->parts->list.head.next, mbr_part_t, link); \
+             iterator != list_get_instance(&((label)->parts->list.head), mbr_part_t, link); \
              iterator  = list_get_instance(iterator->link.next, mbr_part_t, link))
 
