Index: uspace/app/hdisk/common.h
===================================================================
--- uspace/app/hdisk/common.h	(revision c9f6115020f44dba562d0790b12bf25c1529f9a4)
+++ uspace/app/hdisk/common.h	(revision 6e8e4e191b06e73e7414d8e4538ce949d1bd24f9)
@@ -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 c9f6115020f44dba562d0790b12bf25c1529f9a4)
+++ uspace/app/hdisk/func_gpt.c	(revision 6e8e4e191b06e73e7414d8e4538ce949d1bd24f9)
@@ -43,7 +43,24 @@
 static int set_gpt_partition(tinput_t *, gpt_part_t *);
 
-int add_gpt_part(tinput_t * in, union label_data * data)
+
+int construct_gpt_label(label_t *this)
 {
-	gpt_part_t * p = gpt_alloc_partition(data->gpt->parts);
+	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_alloc_partition(this->data.gpt->parts);
 	if (p == NULL) {
 		return ENOMEM;
@@ -53,5 +70,5 @@
 }
 
-int delete_gpt_part(tinput_t * in, union label_data * data)
+int delete_gpt_part(label_t *this, tinput_t * in)
 {
 	size_t idx;
@@ -60,5 +77,5 @@
 	idx = get_input_size_t(in);
 
-	if (gpt_remove_partition(data->gpt->parts, idx) == -1) {
+	if (gpt_remove_partition(this->data.gpt->parts, idx) == -1) {
 		printf("Warning: running low on memory, not resizing...\n");
 	}
@@ -67,17 +84,17 @@
 }
 
-int destroy_gpt_label(union label_data *data)
+int destroy_gpt_label(label_t *this)
 {
 	return EOK;
 }
 
-int new_gpt_label(union label_data *data)
+int new_gpt_label(label_t *this)
 {
-	data->gpt->gpt = gpt_alloc_gpt_header();
-	data->gpt->parts = gpt_alloc_partitions();
+	this->data.gpt->gpt = gpt_alloc_gpt_header();
+	this->data.gpt->parts = gpt_alloc_partitions();
 	return EOK;
 }
 
-int print_gpt_parts(union label_data *data)
+int print_gpt_parts(label_t *this)
 {
 	//int rc;
@@ -87,5 +104,9 @@
 	size_t i = 0;
 	
-	gpt_part_foreach(data->gpt->parts, iter) {
+	gpt_part_foreach(this->data.gpt->parts, iter) {
+		//FIXMEE!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+		if (gpt_get_part_type(iter) == 62)
+			continue;
+		
 		//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));
@@ -100,14 +121,14 @@
 }
 
-int read_gpt_parts(service_id_t dev_handle, union label_data *data)
+int read_gpt_parts(label_t *this, service_id_t dev_handle)
 {
 	return EOK;
 }
 
-int write_gpt_parts(service_id_t dev_handle, union label_data * data)
+int write_gpt_parts(label_t *this, service_id_t dev_handle)
 {
 	int rc;
 
-	rc = gpt_write_partitions(data->gpt->parts, data->gpt->gpt, dev_handle);
+	rc = gpt_write_partitions(this->data.gpt->parts, this->data.gpt->gpt, dev_handle);
 	if (rc != EOK) {
 		printf("Error: Writing partitions failed: %d (%s)\n", rc, str_error(rc));
@@ -115,5 +136,5 @@
 	}
 
-	rc = gpt_write_gpt_header(data->gpt->gpt, dev_handle);
+	rc = gpt_write_gpt_header(this->data.gpt->gpt, dev_handle);
 	if (rc != EOK) {
 		printf("Error: Writing partitions failed: %d (%s)\n", rc, str_error(rc));
@@ -124,5 +145,5 @@
 }
 
-int extra_gpt_funcs(tinput_t * in, service_id_t dev_handle, union label_data * data)
+int extra_gpt_funcs(label_t *this, tinput_t * in, service_id_t dev_handle)
 {
 	printf("Not implemented.\n");
Index: uspace/app/hdisk/func_gpt.h
===================================================================
--- uspace/app/hdisk/func_gpt.h	(revision c9f6115020f44dba562d0790b12bf25c1529f9a4)
+++ uspace/app/hdisk/func_gpt.h	(revision 6e8e4e191b06e73e7414d8e4538ce949d1bd24f9)
@@ -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 c9f6115020f44dba562d0790b12bf25c1529f9a4)
+++ uspace/app/hdisk/func_mbr.c	(revision 6e8e4e191b06e73e7414d8e4538ce949d1bd24f9)
@@ -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 c9f6115020f44dba562d0790b12bf25c1529f9a4)
+++ uspace/app/hdisk/func_mbr.h	(revision 6e8e4e191b06e73e7414d8e4538ce949d1bd24f9)
@@ -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 c9f6115020f44dba562d0790b12bf25c1529f9a4)
+++ uspace/app/hdisk/func_none.c	(revision 6e8e4e191b06e73e7414d8e4538ce949d1bd24f9)
@@ -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 c9f6115020f44dba562d0790b12bf25c1529f9a4)
+++ uspace/app/hdisk/func_none.h	(revision 6e8e4e191b06e73e7414d8e4538ce949d1bd24f9)
@@ -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 c9f6115020f44dba562d0790b12bf25c1529f9a4)
+++ uspace/app/hdisk/hdisk.c	(revision 6e8e4e191b06e73e7414d8e4538ce949d1bd24f9)
@@ -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 c9f6115020f44dba562d0790b12bf25c1529f9a4)
+++ uspace/app/hdisk/hdisk.h	(revision 6e8e4e191b06e73e7414d8e4538ce949d1bd24f9)
@@ -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/mbr/libmbr.c
===================================================================
--- uspace/lib/mbr/libmbr.c	(revision c9f6115020f44dba562d0790b12bf25c1529f9a4)
+++ uspace/lib/mbr/libmbr.c	(revision 6e8e4e191b06e73e7414d8e4538ce949d1bd24f9)
@@ -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 */
@@ -171,18 +173,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) {
@@ -191,6 +193,7 @@
 			return ENOMEM;
 		}
-		printf("pcheck2\n");
+		
 		rc_ext = decode_part(&(label->mbr->raw_data.pte[i]), p, 0);
+		printf("p: %d %u %u\n", rc_ext, p->start_addr, p->length);
 		mbr_set_flag(p, ST_LOGIC, false);
 		rc = mbr_add_partition(label, p);
@@ -201,20 +204,20 @@
 			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");
+			printf("ext: %u %u\n", p->start_addr, p->length);
+			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;
 }
@@ -243,6 +246,7 @@
 	
 	/* 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);	
+		printf("status: %hu\n", p->status);
 		encode_part(p, &(label->mbr->raw_data.pte[i]), 0, false);
 		l = l->next;
@@ -256,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
@@ -284,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 */
@@ -293,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);
@@ -393,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);
 }
 
@@ -572,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)
@@ -582,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;
 }
 
@@ -630,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;
@@ -694,4 +680,5 @@
 	
 	while (ebr->pte[1].ptype != PT_UNUSED) {
+		
 		ebr = alloc_br();
 		if (ebr == NULL) {
@@ -715,5 +702,4 @@
 			goto free_ebr_end;
 		}
-		
 		
 		decode_part(&(ebr->pte[0]), p, addr);
@@ -762,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));
 	}
 }
@@ -782,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;
 	}
@@ -815,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 c9f6115020f44dba562d0790b12bf25c1529f9a4)
+++ uspace/lib/mbr/libmbr.h	(revision 6e8e4e191b06e73e7414d8e4538ce949d1bd24f9)
@@ -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))
 
