Index: uspace/app/hdisk/common.h
===================================================================
--- uspace/app/hdisk/common.h	(revision 622a50b2ad6b03b1b08ffc5a507e070f239fbe58)
+++ uspace/app/hdisk/common.h	(revision a2aa81cb68fd01c0a20c10390ebc0c8ec3655508)
@@ -39,7 +39,7 @@
 #include <libgpt.h>
 
-union table_data {
-	mbr_table_t	mbr;
-	gpt_table_t	gpt;
+union label_data {
+	mbr_label_t	*mbr;
+	gpt_label_t	*gpt;
 };
 
Index: uspace/app/hdisk/func_gpt.c
===================================================================
--- uspace/app/hdisk/func_gpt.c	(revision 622a50b2ad6b03b1b08ffc5a507e070f239fbe58)
+++ uspace/app/hdisk/func_gpt.c	(revision a2aa81cb68fd01c0a20c10390ebc0c8ec3655508)
@@ -43,7 +43,7 @@
 static int set_gpt_partition(tinput_t *, gpt_part_t *);
 
-int add_gpt_part(tinput_t * in, union table_data * data)
+int add_gpt_part(tinput_t * in, union label_data * data)
 {
-	gpt_part_t * p = gpt_alloc_partition(data->gpt.parts);
+	gpt_part_t * p = gpt_alloc_partition(data->gpt->parts);
 	if (p == NULL) {
 		return ENOMEM;
@@ -53,5 +53,5 @@
 }
 
-int delete_gpt_part(tinput_t * in, union table_data * data)
+int delete_gpt_part(tinput_t * in, union label_data * data)
 {
 	size_t idx;
@@ -60,5 +60,5 @@
 	idx = get_input_size_t(in);
 
-	if (gpt_remove_partition(data->gpt.parts, idx) == -1) {
+	if (gpt_remove_partition(data->gpt->parts, idx) == -1) {
 		printf("Warning: running low on memory, not resizing...\n");
 	}
@@ -67,12 +67,17 @@
 }
 
-int new_gpt_table(tinput_t * in, union table_data * data)
+int destroy_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 table_data * data)
+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)
 {
 	//int rc;
@@ -82,5 +87,5 @@
 	size_t i = 0;
 	
-	gpt_part_foreach(data->gpt.parts, iter) {
+	gpt_part_foreach(data->gpt->parts, iter) {
 		//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));
@@ -95,9 +100,14 @@
 }
 
-int write_gpt_parts(service_id_t dev_handle, union table_data * data)
+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);
+	rc = gpt_write_partitions(data->gpt->parts, data->gpt->gpt, dev_handle);
 	if (rc != EOK) {
 		printf("Error: Writing partitions failed: %d (%s)\n", rc, str_error(rc));
@@ -105,5 +115,5 @@
 	}
 
-	rc = gpt_write_gpt_header(data->gpt.gpt, dev_handle);
+	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));
@@ -114,5 +124,5 @@
 }
 
-int extra_gpt_funcs(tinput_t * in, service_id_t dev_handle, union table_data * data)
+int extra_gpt_funcs(tinput_t * in, service_id_t dev_handle, union label_data * data)
 {
 	printf("Not implemented.\n");
Index: uspace/app/hdisk/func_gpt.h
===================================================================
--- uspace/app/hdisk/func_gpt.h	(revision 622a50b2ad6b03b1b08ffc5a507e070f239fbe58)
+++ uspace/app/hdisk/func_gpt.h	(revision a2aa81cb68fd01c0a20c10390ebc0c8ec3655508)
@@ -42,10 +42,12 @@
 #include "common.h"
 
-extern int add_gpt_part(tinput_t * in, union table_data * data);
-extern int delete_gpt_part(tinput_t * in, union table_data * data);
-extern int new_gpt_table(tinput_t *, union table_data *);
-extern int print_gpt_parts(union table_data * data);
-extern int write_gpt_parts(service_id_t dev_handle, union table_data * data);
-extern int extra_gpt_funcs(tinput_t * in, service_id_t dev_handle, union table_data * data);
+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 *);
 
 #endif
Index: uspace/app/hdisk/func_mbr.c
===================================================================
--- uspace/app/hdisk/func_mbr.c	(revision 622a50b2ad6b03b1b08ffc5a507e070f239fbe58)
+++ uspace/app/hdisk/func_mbr.c	(revision a2aa81cb68fd01c0a20c10390ebc0c8ec3655508)
@@ -41,25 +41,23 @@
 #include "input.h"
 
-static int set_mbr_partition(tinput_t * in, mbr_part_t * p);
-
-
-int add_mbr_part(tinput_t * in, union table_data * data)
+static int set_mbr_partition(tinput_t *in, mbr_part_t *p);
+
+int add_mbr_part(tinput_t *in, union label_data *data)
 {
 	int rc;
 	
-	mbr_part_t * part = mbr_alloc_partition();
+	mbr_part_t *part = mbr_alloc_partition();
 
 	set_mbr_partition(in, part);
 
-	rc = mbr_add_partition(data->mbr.parts, part);
+	rc = mbr_add_partition(data->mbr, part);
 	if (rc != EOK) {
 		printf("Error adding partition.\n");
 	}
 	
-	
-	return rc;
-}
-
-int delete_mbr_part(tinput_t * in, union table_data * data)
+	return EOK;
+}
+
+int delete_mbr_part(tinput_t *in, union label_data *data)
 {
 	int rc;
@@ -72,5 +70,5 @@
 		return errno;
 	
-	rc = mbr_remove_partition(data->mbr.parts, idx);
+	rc = mbr_remove_partition(data->mbr, idx);
 	if(rc != EOK) {
 		printf("Error: something.\n");
@@ -80,13 +78,21 @@
 }
 
-int new_mbr_table(tinput_t * in, union table_data * data)
-{
-	data->mbr.mbr = mbr_alloc_mbr();
-	data->mbr.parts = mbr_alloc_partitions();
-	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 ENOMEM;
+	else
+		return EOK;
 }
 
 /** Print current partition scheme */
-int print_mbr_parts(union table_data * data)
+int print_mbr_parts(union label_data *data)
 {
 	int num = 0;
@@ -96,6 +102,6 @@
 	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_t *it;
+	mbr_part_foreach(data->mbr->parts, it) {
 		if (it->type == PT_UNUSED)
 			continue;
@@ -117,7 +123,25 @@
 }
 
-int write_mbr_parts(service_id_t dev_handle, union table_data * data)
-{
-	int rc = mbr_write_partitions(data->mbr.parts, data->mbr.mbr, dev_handle);
+int read_mbr_parts(service_id_t dev_handle, union label_data *data)
+{
+	int rc;
+	printf("mbr\n");
+	rc = mbr_read_mbr(data->mbr, dev_handle);
+	if (rc != EOK)
+		return rc;
+	printf("ismbr\n");
+	if (!mbr_is_mbr(data->mbr))
+		return EINVAL;
+	printf("parts\n");
+	rc = mbr_read_partitions(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);
 	if (rc != EOK) {
 		printf("Error occured during writing: ERR: %d: %s\n", rc, str_error(rc));
@@ -127,5 +151,5 @@
 }
 
-int extra_mbr_funcs(tinput_t * in, service_id_t dev_handle, union table_data * data)
+int extra_mbr_funcs(tinput_t *in, service_id_t dev_handle, union label_data *data)
 {
 	printf("Not implemented.\n");
@@ -133,5 +157,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)
 {
 	int c;
@@ -159,5 +183,5 @@
 		return errno;
 
-	///TODO: there can only be one bootable partition; let's do it just like fdisk
+	///TODO: there can only be one boolabel partition; let's do it just like fdisk
 	printf("Bootable? (y/n): ");
 	c = getchar();
Index: uspace/app/hdisk/func_mbr.h
===================================================================
--- uspace/app/hdisk/func_mbr.h	(revision 622a50b2ad6b03b1b08ffc5a507e070f239fbe58)
+++ uspace/app/hdisk/func_mbr.h	(revision a2aa81cb68fd01c0a20c10390ebc0c8ec3655508)
@@ -42,10 +42,12 @@
 #include "common.h"
 
-extern int add_mbr_part(tinput_t * in, union table_data * data);
-extern int delete_mbr_part(tinput_t * in, union table_data * data);
-extern int new_mbr_table(tinput_t *, union table_data *);
-extern int print_mbr_parts(union table_data * data);
-extern int write_mbr_parts(service_id_t dev_handle, union table_data * data);
-extern int extra_mbr_funcs(tinput_t * in, service_id_t dev_handle, union table_data * data);
+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 *);
 
 #endif
Index: uspace/app/hdisk/func_none.c
===================================================================
--- uspace/app/hdisk/func_none.c	(revision 622a50b2ad6b03b1b08ffc5a507e070f239fbe58)
+++ uspace/app/hdisk/func_none.c	(revision a2aa81cb68fd01c0a20c10390ebc0c8ec3655508)
@@ -40,5 +40,6 @@
 static void not_implemented(void);
 
-int add_none_part(tinput_t * in, union table_data * data)
+
+int add_none_part(tinput_t *in, union label_data *data)
 {
 	not_implemented();
@@ -46,5 +47,5 @@
 }
 
-int delete_none_part(tinput_t * in, union table_data * data)
+int delete_none_part(tinput_t *in, union label_data *data)
 {
 	not_implemented();
@@ -52,5 +53,5 @@
 }
 
-int new_none_table(tinput_t * in, union table_data * data)
+int destroy_none_label(union label_data *data)
 {
 	not_implemented();
@@ -58,5 +59,5 @@
 }
 
-int print_none_parts(union table_data * data)
+int new_none_label(union label_data *data)
 {
 	not_implemented();
@@ -64,5 +65,5 @@
 }
 
-int write_none_parts(service_id_t dev_handle, union table_data * data)
+int print_none_parts(union label_data *data)
 {
 	not_implemented();
@@ -70,5 +71,17 @@
 }
 
-int extra_none_funcs(tinput_t * in, service_id_t dev_handle, union table_data * data)
+int read_none_parts(service_id_t dev_handle, union label_data *data)
+{
+	not_implemented();
+	return EOK;
+}
+
+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)
 {
 	not_implemented();
Index: uspace/app/hdisk/func_none.h
===================================================================
--- uspace/app/hdisk/func_none.h	(revision 622a50b2ad6b03b1b08ffc5a507e070f239fbe58)
+++ uspace/app/hdisk/func_none.h	(revision a2aa81cb68fd01c0a20c10390ebc0c8ec3655508)
@@ -41,10 +41,12 @@
 #include "common.h"
 
-extern int add_none_part(tinput_t * in, union table_data * data);
-extern int delete_none_part(tinput_t * in, union table_data * data);
-extern int new_none_table(tinput_t *, union table_data *);
-extern int print_none_parts(union table_data * data);
-extern int write_none_parts(service_id_t dev_handle, union table_data * data);
-extern int extra_none_funcs(tinput_t * in, service_id_t dev_handle, union table_data * data);
+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 *);
 
 #endif
Index: uspace/app/hdisk/hdisk.c
===================================================================
--- uspace/app/hdisk/hdisk.c	(revision 622a50b2ad6b03b1b08ffc5a507e070f239fbe58)
+++ uspace/app/hdisk/hdisk.c	(revision a2aa81cb68fd01c0a20c10390ebc0c8ec3655508)
@@ -53,22 +53,32 @@
 #include "func_none.h"
 
-int interact(service_id_t dev_handle);
+int interact(service_id_t);
 void print_help(void);
-void select_table_format(tinput_t * in);
-void fill_table_funcs(void);
-void free_table(void);
-
-static table_t table;
+void select_label_format(tinput_t *);
+void fill_label_funcs(void);
+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);
+
+
+static label_t label;
 
 int main(int argc, char ** argv)
 {
 	if (argc == 1) {
-		printf("I'd like to have an argument, please.\n");
-		return 1;
-	}
-
+		printf("Missing argument. Please specify a device to operate on.\n");
+		return -1;
+	}
+	
 	int rc;
 	service_id_t dev_handle;
-
+	
 	rc = loc_service_get_id(argv[1], &dev_handle, IPC_FLAG_BLOCKING);
 	if (rc != EOK) {
@@ -76,7 +86,9 @@
 		return -1;
 	}
-
-	init_table();
-
+	
+	printf("Init.\n");
+	init_label();
+	
+	/*
 	mbr_t * mbr = mbr_read_mbr(dev_handle);
 	if(mbr == NULL) {
@@ -87,6 +99,6 @@
 
 	if(mbr_is_mbr(mbr)) {
-		table.layout = LYT_MBR;
-		set_table_mbr(mbr);
+		label.layout = LYT_MBR;
+		set_label_mbr(mbr);
 		mbr_partitions_t * parts = mbr_read_partitions(mbr);
 		if(parts == NULL) {
@@ -95,16 +107,23 @@
 			parts = mbr_alloc_partitions();
 		}
-		set_table_mbr_parts(parts);
-		fill_table_funcs();
+		set_label_mbr_parts(parts);
+		fill_label_funcs();
 		goto interact;
 	}
 	
 	
-	mbr_free_mbr(mbr);
+	mbr_free_mbr(mbr);*/
+	
+	printf("Try MBR.\n");
+	rc = try_read_mbr(dev_handle);
+	if (rc == EOK)
+		goto interact;
+	
+	/*
 	gpt_t * gpt = gpt_read_gpt_header(dev_handle);
 	
 	if(gpt != NULL) {
-		table.layout = LYT_GPT;
-		set_table_gpt(gpt);
+		label.layout = LYT_GPT;
+		set_label_gpt(gpt);
 		
 		gpt_partitions_t * parts = gpt_read_partitions(gpt);
@@ -115,15 +134,23 @@
 			parts = gpt_alloc_partitions();
 		}
-		set_table_gpt_parts(parts);
-		fill_table_funcs();
+		set_label_gpt_parts(parts);
+		fill_label_funcs();
 		goto interact;
 	}
-	printf("No partition table recognized. Create a new one.\n");
-	table.layout = LYT_NONE;
+	*/
+	
+	printf("Try GPT.\n");
+	rc = try_read_gpt(dev_handle);
+	if (rc == EOK)
+		goto interact;
+	
+	printf("No label recognized. Create a new one.\n");
+	label.layout = LYT_NONE;
 	
 interact:
+	printf("interact.\n");
 	rc = interact(dev_handle);
 	
-	free_table();
+	free_label();
 	
 	return rc;
@@ -152,15 +179,18 @@
 		switch(input) {
 			case 'a':
-				table.add_part(in, &table.data);
+				label.add_part(in, &label.data);
+				break;
+			case 'b':
+				label.add_part(in, &label.data);
 				break;
 			case 'd':
-				table.delete_part(in, &table.data);
+				label.delete_part(in, &label.data);
 				break;
 			case 'e':
-				table.extra_funcs(in, dev_handle, &table.data);
+				label.extra_funcs(in, dev_handle, &label.data);
 				break;
 			case 'f':
-				free_table();
-				select_table_format(in);
+				free_label();
+				select_label_format(in);
 				break;
 			case 'h':
@@ -168,9 +198,9 @@
 				break;
 			case 'n':
-				free_table();
-				table.new_table(in, &table.data);
+				free_label();
+				label.new_label(&label.data);
 				break;
 			case 'p':
-				table.print_parts(&table.data);
+				label.print_parts(&label.data);
 				break;
 			case 'q':
@@ -178,5 +208,5 @@
 				goto end;
 			case 'w':
-				table.write_parts(dev_handle, &table.data);
+				label.write_parts(dev_handle, &label.data);
 				break;
 			default:
@@ -197,10 +227,11 @@
 		"\t 'a' \t\t Add partition.\n"
 		"\t 'd' \t\t Delete partition.\n"
-		"\t 'e' \t\t Extra functions (per table format).\n"
-		"\t 'f' \t\t Switch the format of the partition table."
+		"\t 'e' \t\t Extra functions (per label format).\n"
+		"\t 'f' \t\t Switch the format of the partition label."
 		"\t 'h' \t\t Prints help. See help for more.\n"
-		"\t 'n' \t\t Create new table (discarding the old one).\n"
-		"\t 'p' \t\t Prints the table contents.\n"
-		"\t 'w' \t\t Write table to disk.\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 'w' \t\t Write label to disk.\n"
 		"\t 'q' \t\t Quit.\n"
 		);
@@ -208,5 +239,5 @@
 }
 
-void select_table_format(tinput_t * in)
+void select_label_format(tinput_t * in)
 {
 	printf("Available formats are: \n"
@@ -218,76 +249,137 @@
 	switch(val) {
 		case 0:
-			table.layout = LYT_NONE;
-			fill_table_funcs();
+			free_label();
+			label.layout = LYT_NONE;
+			fill_label_funcs();
 			break;
 		case 1:
-			table.layout = LYT_MBR;
-			fill_table_funcs();
+			free_label();
+			label.layout = LYT_MBR;
+			fill_label_funcs();
 			break;
 		case 2:
-			table.layout = LYT_GPT;
-			fill_table_funcs();
-			break;
-	}
-}
-
-void fill_table_funcs(void)
-{
-	switch(table.layout) {
+			free_label();
+			label.layout = LYT_GPT;
+			fill_label_funcs();
+			break;
+	}
+}
+
+void fill_label_funcs(void)
+{
+	switch(label.layout) {
 		case LYT_MBR:
-			table.add_part = add_mbr_part;
-			table.delete_part = delete_mbr_part;
-			table.new_table = new_mbr_table;
-			table.print_parts = print_mbr_parts;
-			table.write_parts = write_mbr_parts;
-			table.extra_funcs = extra_mbr_funcs;
+			construct_mbr_label();
 			break;
 		case LYT_GPT:
-			table.add_part = add_gpt_part;
-			table.delete_part = delete_gpt_part;
-			table.new_table	= new_gpt_table;
-			table.print_parts = print_gpt_parts;
-			table.write_parts = write_gpt_parts;
-			table.extra_funcs = extra_gpt_funcs;
+			construct_gpt_label();
 			break;
 		default:
-			table.add_part = add_none_part;
-			table.delete_part = delete_none_part;
-			table.new_table = new_none_table;
-			table.print_parts = print_none_parts;
-			table.write_parts = write_none_parts;
-			table.extra_funcs = extra_none_funcs;
-			break;
-	}
-}
-
-void free_table(void)
-{
-	switch(table.layout) {
+			construct_none_label();
+			break;
+	}
+}
+
+void free_label(void)
+{
+	/*
+	switch(label.layout) {
 		case LYT_MBR:
-			if (table.data.mbr.parts != NULL) {
-				mbr_free_partitions(table.data.mbr.parts);
-				table.data.mbr.parts = NULL;
-			}
-			if (table.data.mbr.mbr != NULL) {
-				mbr_free_mbr(table.data.mbr.mbr);
-				table.data.mbr.mbr = NULL;
-			}
+			destroy_mbr_label(&label);
 			break;
 		case LYT_GPT:
-			if (table.data.gpt.parts != NULL) {
-				gpt_free_partitions(table.data.gpt.parts);
-				table.data.gpt.parts = NULL;
-			}
-			if (table.data.gpt.gpt != NULL) {
-				gpt_free_gpt(table.data.gpt.gpt);
-				table.data.gpt.gpt = NULL;
-			}
+			destroy_gpt_label(&label);
 			break;
 		default:
 			break;
 	}
-}
-
-
-
+	*/
+	
+	label.destroy_label(&label.data);
+}
+
+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);
+}
+
+int try_read_mbr(service_id_t dev_handle)
+{
+	label.layout = 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;
+	return try_read(dev_handle);
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Index: uspace/app/hdisk/hdisk.h
===================================================================
--- uspace/app/hdisk/hdisk.h	(revision 622a50b2ad6b03b1b08ffc5a507e070f239fbe58)
+++ uspace/app/hdisk/hdisk.h	(revision a2aa81cb68fd01c0a20c10390ebc0c8ec3655508)
@@ -39,29 +39,20 @@
 	LYT_MBR,
 	LYT_GPT,
-} LAYOUTS;
+} layouts_t;
 
-typedef struct table {
-	LAYOUTS layout;
-	union table_data data;
-	int (* add_part)(tinput_t *, union table_data *);
-	int (* delete_part)(tinput_t *, union table_data *);
-	int (* new_table)(tinput_t *, union table_data *);
-	int (* print_parts)();
-	int (* write_parts)(service_id_t, union table_data *);
-	int (* extra_funcs)(tinput_t *, service_id_t, union table_data *);
-} table_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_table() \
-	table.layout = LYT_NONE
+#define init_label() \
+	label.layout = LYT_NONE
 
-#define set_table_mbr(m) \
-	table.data.mbr.mbr = (m)
-
-#define set_table_mbr_parts(p) \
-	table.data.mbr.parts = (p)
-
-#define set_table_gpt(g) \
-	table.data.gpt.gpt = (g)
-
-#define set_table_gpt_parts(p) \
-	table.data.gpt.parts = (p)
Index: uspace/lib/gpt/libgpt.h
===================================================================
--- uspace/lib/gpt/libgpt.h	(revision 622a50b2ad6b03b1b08ffc5a507e070f239fbe58)
+++ uspace/lib/gpt/libgpt.h	(revision a2aa81cb68fd01c0a20c10390ebc0c8ec3655508)
@@ -1,5 +1,5 @@
 /*
+ * Copyright (c) 2009 Jiri Svoboda
  * Copyright (c) 2011, 2012, 2013 Dominik Taborsky
- * Copyright (c) 2009 Jiri Svoboda (for some definitions from uspace/srv/bd/part/guid_part)
  * All rights reserved.
  *
@@ -130,5 +130,5 @@
 	gpt_t * gpt;
 	gpt_partitions_t * parts;
-} gpt_table_t;
+} gpt_label_t;
 
 struct partition_type {
@@ -142,23 +142,23 @@
 extern gpt_t * gpt_alloc_gpt_header(void);
 extern gpt_t * gpt_read_gpt_header(service_id_t dev_handle);
-extern int gpt_write_gpt_header(gpt_t * header, service_id_t dev_handle);
+extern int     gpt_write_gpt_header(gpt_t * header, service_id_t dev_handle);
 
-extern gpt_partitions_t *	gpt_alloc_partitions(void);
-extern gpt_partitions_t *	gpt_read_partitions	(gpt_t * gpt);
-extern int 					gpt_write_partitions	(gpt_partitions_t * parts, gpt_t * header, service_id_t dev_handle);
-extern gpt_part_t *			gpt_alloc_partition		(gpt_partitions_t * parts);
-extern int					gpt_add_partition	(gpt_partitions_t * parts, gpt_part_t * partition);
-extern int					gpt_remove_partition(gpt_partitions_t * parts, size_t idx);
+extern gpt_partitions_t * gpt_alloc_partitions(void);
+extern gpt_partitions_t * gpt_read_partitions(gpt_t * gpt);
+extern int             gpt_write_partitions(gpt_partitions_t * parts, gpt_t * header, service_id_t dev_handle);
+extern gpt_part_t *    gpt_alloc_partition (gpt_partitions_t * parts);
+extern int             gpt_add_partition   (gpt_partitions_t * parts, gpt_part_t * partition);
+extern int             gpt_remove_partition(gpt_partitions_t * parts, size_t idx);
 
-extern size_t				gpt_get_part_type	(gpt_part_t * p);
-extern void 				gpt_set_part_type	(gpt_part_t * p, size_t type);
-extern void					gpt_set_start_lba	(gpt_part_t * p, uint64_t start);
-extern uint64_t				gpt_get_start_lba	(gpt_part_t * p);
-extern void					gpt_set_end_lba		(gpt_part_t * p, uint64_t end);
-extern uint64_t				gpt_get_end_lba		(gpt_part_t * p);
-extern unsigned char * 		gpt_get_part_name	(gpt_part_t * p);
-extern void 				gpt_set_part_name	(gpt_part_t * p, char * name[], size_t length);
-extern bool					gpt_get_flag		(gpt_part_t * p, GPT_ATTR flag);
-extern void					gpt_set_flag		(gpt_part_t * p, GPT_ATTR flag, bool value);
+extern size_t          gpt_get_part_type(gpt_part_t * p);
+extern void            gpt_set_part_type(gpt_part_t * p, size_t type);
+extern void            gpt_set_start_lba(gpt_part_t * p, uint64_t start);
+extern uint64_t        gpt_get_start_lba(gpt_part_t * p);
+extern void            gpt_set_end_lba  (gpt_part_t * p, uint64_t end);
+extern uint64_t        gpt_get_end_lba  (gpt_part_t * p);
+extern unsigned char * gpt_get_part_name(gpt_part_t * p);
+extern void            gpt_set_part_name(gpt_part_t * p, char * name[], size_t length);
+extern bool            gpt_get_flag     (gpt_part_t * p, GPT_ATTR flag);
+extern void            gpt_set_flag     (gpt_part_t * p, GPT_ATTR flag, bool value);
 
 
Index: uspace/lib/mbr/libmbr.c
===================================================================
--- uspace/lib/mbr/libmbr.c	(revision 622a50b2ad6b03b1b08ffc5a507e070f239fbe58)
+++ uspace/lib/mbr/libmbr.c	(revision a2aa81cb68fd01c0a20c10390ebc0c8ec3655508)
@@ -46,10 +46,36 @@
 
 static br_block_t * alloc_br(void);
-static int decode_part(pt_entry_t * src, mbr_part_t * trgt, uint32_t base);
-static int decode_logical(mbr_t * mbr, mbr_partitions_t * p, mbr_part_t * ext);
-static void encode_part(mbr_part_t * src, pt_entry_t * trgt, uint32_t base, bool ebr);
-static int check_overlap(mbr_part_t * p1, mbr_part_t * p2);
-static int check_encaps(mbr_part_t * inner, mbr_part_t * outer);
-static int check_preceeds(mbr_part_t * preceeder, mbr_part_t * precedee);
+static int decode_part(pt_entry_t *, mbr_part_t *, uint32_t);
+static int decode_logical(mbr_label_t *, mbr_part_t *);
+static void encode_part(mbr_part_t *, pt_entry_t *, uint32_t, bool);
+static int check_overlap(mbr_part_t *, mbr_part_t *);
+static int check_encaps(mbr_part_t *, mbr_part_t *);
+static int check_preceeds(mbr_part_t *, mbr_part_t *);
+
+/** Allocate and initialize mbr_label_t structure */
+mbr_label_t * mbr_alloc_label(void)
+{
+	mbr_label_t *label = malloc(sizeof(mbr_label_t));
+	if (label == NULL)
+		return NULL;
+	
+	label->mbr = NULL;
+	label->parts = NULL;
+	label->device = 0;
+	
+	return label;
+}
+
+/** Free mbr_label_t structure */
+void mbr_free_label(mbr_label_t *label)
+{
+	if (label->mbr != NULL)
+		mbr_free_mbr(label->mbr);
+	
+	if (label->parts != NULL)
+		mbr_free_partitions(label->parts);
+	
+	free(label);
+}
 
 /** Allocate memory for mbr_t */
@@ -60,39 +86,39 @@
 
 /** Read MBR from specific device
- * @param	dev_handle	device to read MBR from
- *
- * @return				mbr record on success, NULL on error
- */
-mbr_t * mbr_read_mbr(service_id_t dev_handle)
-{
+ * @param   label       label to write data to
+ * @param   dev_handle  device to read MBR from
+ *
+ * @return				EOK on success, error code on error
+ */
+int mbr_read_mbr(mbr_label_t *label, service_id_t dev_handle)
+{
+	if (label == NULL)
+		return EINVAL;
+	
 	int rc;
-
-	mbr_t * mbr = malloc(sizeof(mbr_t));
-	if (mbr == NULL) {
-		return NULL;
+	
+	if (label->mbr == NULL) {
+		label->mbr = mbr_alloc_mbr();
+		if (label->mbr == NULL) {
+			return ENOMEM;
+		}
 	}
 
 	rc = block_init(EXCHANGE_ATOMIC, dev_handle, 512);
-	if (rc != EOK) {
-		free(mbr);
-		return NULL;
-	}
-
-	rc = block_read_direct(dev_handle, 0, 1, &(mbr->raw_data));
-	if (rc != EOK) {
-		free(mbr);
-		block_fini(dev_handle);
-		return NULL;
-	}
-
+	if (rc != EOK)
+		return rc;
+
+	rc = block_read_direct(dev_handle, 0, 1, &(label->mbr->raw_data));
 	block_fini(dev_handle);
-
-	mbr->device = dev_handle;
-
-	return mbr;
+	if (rc != EOK)
+		return rc;
+
+	label->device = dev_handle;
+
+	return EOK;
 }
 
 /** Write mbr to disk
- * @param mbr			MBR to be written
+ * @param label			MBR to be written
  * @param dev_handle	device handle to write MBR to (may be different
  * 							from the device in 'mbr')
@@ -100,5 +126,5 @@
  * @return				0 on success, otherwise libblock error code
  */
-int mbr_write_mbr(mbr_t * mbr, service_id_t dev_handle)
+int mbr_write_mbr(mbr_label_t *label, service_id_t dev_handle)
 {
 	int rc;
@@ -109,5 +135,5 @@
 	}
 
-	rc = block_write_direct(dev_handle, 0, 1, &(mbr->raw_data));
+	rc = block_write_direct(dev_handle, 0, 1, &(label->mbr->raw_data));
 	block_fini(dev_handle);
 	if (rc != EOK) {
@@ -115,5 +141,5 @@
 	}
 
-	return 0;
+	return EOK;
 }
 
@@ -124,80 +150,87 @@
  * @return			1 if MBR, 0 if GPT
  */
-int mbr_is_mbr(mbr_t * mbr)
-{
-	return (mbr->raw_data.pte[0].ptype != PT_GPT) ? 1 : 0;
-}
-
-/** Parse partitions from MBR
- * @param mbr	MBR to be parsed
- *
- * @return 		linked list of partitions or NULL on error
- */
-mbr_partitions_t * mbr_read_partitions(mbr_t * mbr)
-{
-	int rc, i, rc_ext;
-	mbr_part_t * p;
-	mbr_part_t * ext = NULL;
-	mbr_partitions_t * parts;
-	
-	if (mbr == NULL)
-		return NULL;
-	
-	parts = mbr_alloc_partitions();
-	if (parts == NULL) {
-		return NULL;
-	}
-
-	// Generate the primary partitions
+int mbr_is_mbr(mbr_label_t *label)
+{
+	return (label->mbr->raw_data.pte[0].ptype != PT_GPT) ? 1 : 0;
+}
+
+/** Parse partitions from MBR, freeing previous partitions if any
+ * NOTE: it is assumed mbr_read_mbr(label) was called before.
+ * @param label  MBR to be parsed
+ *
+ * @return       linked list of partitions or NULL on error
+ */
+int mbr_read_partitions(mbr_label_t *label)
+{
+	if (label == NULL || label->mbr == NULL)
+		return EINVAL;
+	
+	int rc, rc_ext;
+	unsigned int i;
+	mbr_part_t *p;
+	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 (mbr->raw_data.pte[i].ptype == PT_UNUSED)
+		if (label->mbr->raw_data.pte[i].ptype == PT_UNUSED)
 			continue;
-		
+		printf("pcheck1\n");
 		p = mbr_alloc_partition();
 		if (p == NULL) {
 			printf(LIBMBR_NAME ": Error on memory allocation.\n");
-			mbr_free_partitions(parts);
-			return NULL;
-		}
-		
-		rc_ext = decode_part(&(mbr->raw_data.pte[i]), p, 0);
+			mbr_free_partitions(label->parts);
+			return ENOMEM;
+		}
+		printf("pcheck2\n");
+		rc_ext = decode_part(&(label->mbr->raw_data.pte[i]), p, 0);
 		mbr_set_flag(p, ST_LOGIC, false);
-		rc = mbr_add_partition(parts, p);
+		rc = mbr_add_partition(label, p);
 		if (rc != ERR_OK) {
 			printf(LIBMBR_NAME ": Error occured during decoding the MBR. (%d)\n" \
-				   LIBMBR_NAME ": Partition list may be incomplete.\n", rc);
-			return NULL;
-		}
-		
+			       LIBMBR_NAME ": MBR is invalid.\n", rc);
+			mbr_free_partitions(label->parts);
+			return EINVAL;
+		}
+		printf("pcheck3\n");
 		if (rc_ext) {
 			ext = p;
-			parts->l_extended = list_last(&(parts->list));
-		}
-	}
-	
-	// Fill in the primary partitions and generate logical ones, if any
-	rc = decode_logical(mbr, parts, ext);
+			label->parts->l_extended = list_nth(&(label->parts->list), i);
+		}
+		printf("pcheck4\n");
+	}
+	printf("logical\n");
+	/* 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");
-	}
-	
-	return parts;
+		return rc;
+	}
+	printf("finish\n");
+	return EOK;
 }
 
 /** Write MBR and partitions to device
- * @param parts			partition list to be written
- * @param mbr			MBR to be written with 'parts' partitions
- * @param dev_handle	device to write the data to
- *
- * @return				returns EOK on succes, specific error code otherwise
- */
-int mbr_write_partitions(mbr_partitions_t * parts, mbr_t * mbr, service_id_t dev_handle)
+ * @param label        label to write
+ * @param dev_handle   device to write the data to
+ *
+ * @return             returns EOK on succes, specific error code otherwise
+ */
+int mbr_write_partitions(mbr_label_t *label, service_id_t dev_handle)
 {
 	int i = 0;
 	int rc;
-	mbr_part_t * p;
-	mbr_part_t * ext = (parts->l_extended == NULL) ? NULL
-					: list_get_instance(parts->l_extended, mbr_part_t, link);
+	mbr_part_t *p;
+	mbr_part_t *ext = (label->parts->l_extended == NULL) ? NULL
+					: list_get_instance(label->parts->l_extended, mbr_part_t, link);
 	
 	rc = block_init(EXCHANGE_ATOMIC, dev_handle, 512);
@@ -207,15 +240,15 @@
 	}
 	
-	link_t * l = parts->list.head.next;
-	
-	// Encoding primary partitions
-	for (i = 0; i < parts->n_primary; i++) {
-		p = list_get_instance(l, mbr_part_t, link);
-		encode_part(p, &(mbr->raw_data.pte[i]), 0, false);
+	link_t *l = label->parts->list.head.next;
+	
+	/* Encoding primary partitions */
+	for (i = 0; i < label->parts->n_primary; i++) {
+		p = list_get_instance(l, mbr_part_t, link);	
+		encode_part(p, &(label->mbr->raw_data.pte[i]), 0, false);
 		l = l->next;
 	}
 	
-	// Writing MBR
-	rc = block_write_direct(dev_handle, 0, 1, &(mbr->raw_data));
+	/* Writing MBR */
+	rc = block_write_direct(dev_handle, 0, 1, &(label->mbr->raw_data));
 	if (rc != EOK) {
 		printf(LIBMBR_NAME ": Error while writing MBR : %d - %s.\n", rc, str_error(rc));
@@ -234,6 +267,6 @@
 	 * as much power over it as you can get. Thanks. */
 	
-	// Encoding and writing first logical partition
-	if (l != &(parts->list.head)) {
+	/* Encoding and writing first logical partition */
+	if (l != &(label->parts->list.head)) {
 		p = list_get_instance(l, mbr_part_t, link);
 		p->ebr_addr = base;
@@ -256,6 +289,6 @@
 	prev_p = p;
 	
-	// Encoding and writing logical partitions
-	while (l != &(parts->list.head)) {
+	/* Encoding and writing logical partitions */
+	while (l != &(label->parts->list.head)) {
 		p = list_get_instance(l, mbr_part_t, link);
 		
@@ -286,5 +319,5 @@
 	}
 	
-	// write the last EBR
+	/* write the last EBR */
 	encode_part(NULL, &(prev_p->ebr->pte[1]), 0, false);
 	rc = block_write_direct(dev_handle, prev_p->ebr_addr, 1, prev_p->ebr);
@@ -305,5 +338,5 @@
 mbr_part_t * mbr_alloc_partition(void)
 {
-	mbr_part_t * p = malloc(sizeof(mbr_part_t));
+	mbr_part_t *p = malloc(sizeof(mbr_part_t));
 	if (p == NULL) {
 		return NULL;
@@ -312,10 +345,10 @@
 	link_initialize(&(p->link));
 	p->ebr = NULL;
-	p->type = 0;
+	p->type = PT_UNUSED;
 	p->status = 0;
 	p->start_addr = 0;
 	p->length = 0;
 	p->ebr_addr = 0;
-
+	
 	return p;
 }
@@ -324,13 +357,26 @@
 mbr_partitions_t * mbr_alloc_partitions(void)
 {
-	mbr_partitions_t * parts = malloc(sizeof(mbr_partitions_t));
+	mbr_partitions_t *parts = malloc(sizeof(mbr_partitions_t));
 	if (parts == NULL) {
 		return NULL;
 	}
-
+	
 	list_initialize(&(parts->list));
 	parts->n_primary = 0;
 	parts->n_logical = 0;
 	parts->l_extended = NULL;
+	
+	/* add blank primary partitions */
+	int i;
+	mbr_part_t *p;
+	for (i = 0; i < N_PRIMARY; ++i) {
+		p = mbr_alloc_partition();
+		if (p == NULL) {
+			mbr_free_partitions(parts);
+			return NULL;
+		}
+		list_append(&(p->link), &(parts->list));
+	}
+	
 
 	return parts;
@@ -340,25 +386,45 @@
  * 	Performs checks, sorts the list.
  * 
- * @param parts			partition list to add to
+ * @param label			label to add to
  * @param p				partition to add
  * 
  * @return				ERR_OK (0) on success, other MBR_ERR_VAL otherwise
  */
-MBR_ERR_VAL mbr_add_partition(mbr_partitions_t * parts, mbr_part_t * p)
-{
-	if (mbr_get_flag(p, ST_LOGIC)) { // adding logical part
-		// is there any extended partition?
+mbr_err_val mbr_add_partition(mbr_label_t *label, mbr_part_t *p)
+{
+	int rc;
+	mbr_partitions_t *parts = label->parts;
+	
+	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));
+		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));
+		return ERR_LIBBLOCK;
+	}
+	printf("add3.\n");
+	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);
+		/* 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;
+		/* 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)) {
@@ -366,22 +432,16 @@
 					return ERR_OVERLAP;
 				if (check_preceeds(iter, p)) {
-					last = iter;
-					ebr_space = p->start_addr - (last->start_addr + last->length);
-				} else
-					break;
+					/* 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;
+				}
 			}
 		}
 		
-		// checking if there's at least one sector of space preceeding
-		if (ebr_space < 1)
-			return ERR_NO_EBR;
-		
-		// checking if there's at least one sector of space following (for following partitions's EBR)
-		if (last->link.next != &(parts->list.head)) {
-			if (list_get_instance(&(last->link.next), mbr_part_t, link)->start_addr <= p->start_addr + p->length + 1)
-				return ERR_NO_EBR;
-		}
-		
-		// alloc EBR if it's not already there
+		/* alloc EBR if it's not already there */
 		if (p->ebr == NULL) {
 			p->ebr = alloc_br();
@@ -391,37 +451,42 @@
 		}
 		
-		// add it
-		list_insert_after(&(p->link), &(last->link));
+		/* add it */
+		list_append(&(p->link), &(parts->list));
 		parts->n_logical += 1;
-	} else { // adding primary
+	} else {
+		/* adding primary */
+		
 		if (parts->n_primary == 4) {
 			return ERR_PRIMARY_FULL;
 		}
 		
-		// TODO: should we check if it's inside the drive's upper boundary?
-		if (p->start_addr == 0) {
+		/* 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;
 		}
-		
-		// if it's extended, is there any other one?
+		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;
 		}
-		
-		// find a place and add it
-		if (list_empty(&(parts->list))) {
-			list_append(&(p->link), &(parts->list));
-		} else {
-			mbr_part_t * iter;
-			mbr_part_foreach(parts, iter) {
-				if (mbr_get_flag(iter, ST_LOGIC)) {
-					list_insert_before(&(p->link), &(iter->link));
-					break;
-				} else if (check_overlap(p, iter))
-					return ERR_OVERLAP;
-			}
-			if (iter == list_get_instance(&(parts->list.head.prev), mbr_part_t, link))
-				list_append(&(p->link), &(parts->list));
-		}
+		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;
 		
@@ -429,5 +494,5 @@
 			parts->l_extended = &(p->link);
 	}
-
+	printf("add8.\n");
 	return ERR_OK;
 }
@@ -435,28 +500,26 @@
 /** Remove partition
  * 	Removes partition by index, indexed from zero. When removing extended
- * partition, all logical partitions get removed as well.
+ *  partition, all logical partitions get removed as well.
  * 
- * @param parts			partition list to remove from
+ * @param label			label to remove from
  * @param idx			index of the partition to remove
  * 
  * @return				EOK on success, EINVAL if idx invalid
  */
-int mbr_remove_partition(mbr_partitions_t * parts, size_t idx)
-{
-	link_t * l = list_nth(&(parts->list), idx);
+int mbr_remove_partition(mbr_label_t *label, size_t idx)
+{
+	link_t *l = list_nth(&(label->parts->list), idx);
 	if (l == NULL)
 		return EINVAL;
 	
-	mbr_part_t * p;
-	
-	/* TODO: if it is extended partition, should we also remove all logical?
-	 * If we don't, we break the consistency of the list. If we do,
-	 * the user will have to input them all over again. So yes. */
-	if (l == parts->l_extended) {
-		parts->l_extended = NULL;
-		
-		link_t * it = l->next;
-		link_t * next_it;
-		while (it != &(parts->list.head)) {
+	mbr_part_t *p;
+	
+	/* If we're removing an extended partition, remove all logical as well */
+	if (l == label->parts->l_extended) {
+		label->parts->l_extended = NULL;
+		
+		link_t *it = l->next;
+		link_t *next_it;
+		while (it != &(label->parts->list.head)) {
 			next_it = it->next;
 			
@@ -464,5 +527,5 @@
 			if (mbr_get_flag(p, ST_LOGIC)) {
 				list_remove(it);
-				parts->n_logical -= 1;
+				label->parts->n_logical -= 1;
 				mbr_free_partition(p);
 			}
@@ -473,14 +536,19 @@
 	}
 	
-	list_remove(l);
-	
+	/* Remove the partition itself */
 	p = list_get_instance(l, mbr_part_t, link);
-	if (mbr_get_flag(p, ST_LOGIC))
-		parts->n_logical -= 1;
-	else
-		parts->n_primary -= 1;
-	
-	
-	mbr_free_partition(p);
+	if (mbr_get_flag(p, ST_LOGIC)) {
+		label->parts->n_logical -= 1;
+		list_remove(l);
+		mbr_free_partition(p);
+	} else {
+		/* Cannot remove primary - it would break ordering, just zero it */
+		label->parts->n_primary -= 1;
+		p->type = 0;
+		p->status = 0;
+		p->start_addr = 0;
+		p->length = 0;
+		p->ebr_addr = 0;
+	}
 	
 	return EOK;
@@ -488,5 +556,5 @@
 
 /** mbr_part_t destructor */
-void mbr_free_partition(mbr_part_t * p)
+void mbr_free_partition(mbr_part_t *p)
 {
 	if (p->ebr != NULL)
@@ -496,5 +564,5 @@
 
 /** Get flag bool value */
-int mbr_get_flag(mbr_part_t * p, MBR_FLAGS flag)
+int mbr_get_flag(mbr_part_t *p, MBR_FLAGS flag)
 {
 	return (p->status & (1 << flag)) ? 1 : 0;
@@ -502,5 +570,5 @@
 
 /** Set a specifig status flag to a value */
-void mbr_set_flag(mbr_part_t * p, MBR_FLAGS flag, bool value)
+void mbr_set_flag(mbr_part_t *p, MBR_FLAGS flag, bool value)
 {
 	uint8_t status = p->status;
@@ -522,5 +590,5 @@
 
 /** Just a wrapper for free() */
-void mbr_free_mbr(mbr_t * mbr)
+void mbr_free_mbr(mbr_t *mbr)
 {
 	free(mbr);
@@ -531,9 +599,8 @@
  * @param parts		partition list to be freed
  */
-void mbr_free_partitions(mbr_partitions_t * parts)
+void mbr_free_partitions(mbr_partitions_t *parts)
 {
 	list_foreach_safe(parts->list, cur_link, next) {
-		mbr_part_t * p = list_get_instance(cur_link, mbr_part_t, link);
-		list_remove(cur_link);
+		mbr_part_t *p = list_get_instance(cur_link, mbr_part_t, link);
 		mbr_free_partition(p);
 	}
@@ -544,7 +611,7 @@
 // Internal functions follow //
 
-static br_block_t * alloc_br()
-{
-	br_block_t * br = malloc(sizeof(br_block_t));
+static br_block_t *alloc_br()
+{
+	br_block_t *br = malloc(sizeof(br_block_t));
 	if (br == NULL)
 		return NULL;
@@ -559,11 +626,10 @@
  * @return		returns 1, if extended partition, 0 otherwise
  * */
-static int decode_part(pt_entry_t * src, mbr_part_t * trgt, uint32_t base)
+static int decode_part(pt_entry_t *src, mbr_part_t *trgt, uint32_t base)
 {
 	trgt->type = src->ptype;
 
 	/* Checking only 0x80; otherwise writing will fix to 0x00 */
-	//trgt->bootable = (src->status == B_ACTIVE) ? true : false;
-	mbr_set_flag(trgt, ST_BOOT, (src->status == B_ACTIVE) ? true : false);
+	trgt->status = (trgt->status & 0xFF00) | src->status;
 
 	trgt->start_addr = uint32_t_le2host(src->first_lba) + base;
@@ -574,22 +640,17 @@
 
 /** Parse MBR contents to mbr_part_t list */
-static int decode_logical(mbr_t * mbr, mbr_partitions_t * parts, mbr_part_t * ext)
+static int decode_logical(mbr_label_t *label, mbr_part_t * ext)
 {
 	int rc;
-	mbr_part_t * p;
-
-	if (mbr == NULL || parts == NULL)
-		return EINVAL;
-
+	mbr_part_t *p;
 
 	if (ext == NULL)
 		return EOK;
 
-
 	uint32_t base = ext->start_addr;
 	uint32_t addr = base;
-	br_block_t * ebr;
-	
-	rc = block_init(EXCHANGE_ATOMIC, mbr->device, 512);
+	br_block_t *ebr;
+	
+	rc = block_init(EXCHANGE_ATOMIC, label->device, 512);
 	if (rc != EOK)
 		return rc;
@@ -601,5 +662,5 @@
 	}
 	
-	rc = block_read_direct(mbr->device, addr, 1, ebr);
+	rc = block_read_direct(label->device, addr, 1, ebr);
 	if (rc != EOK) {
 		goto free_ebr_end;
@@ -626,5 +687,5 @@
 	p->ebr = ebr;
 	p->ebr_addr = addr;
-	rc = mbr_add_partition(parts, p);
+	rc = mbr_add_partition(label, p);
 	if (rc != ERR_OK) 
 		return EINVAL;
@@ -639,5 +700,5 @@
 		}
 		
-		rc = block_read_direct(mbr->device, addr, 1, ebr);
+		rc = block_read_direct(label->device, addr, 1, ebr);
 		if (rc != EOK) {
 			goto free_ebr_end;
@@ -660,5 +721,5 @@
 		p->ebr = ebr;
 		p->ebr_addr = addr;
-		rc = mbr_add_partition(parts, p);
+		rc = mbr_add_partition(label, p);
 		if (rc != ERR_OK)
 			return EINVAL;
@@ -674,5 +735,5 @@
 	
 end:
-	block_fini(mbr->device);
+	block_fini(label->device);
 	
 	return rc;
@@ -683,5 +744,13 @@
 {
 	if (src != NULL) {
-		trgt->status = mbr_get_flag(src, ST_BOOT) ? B_ACTIVE : B_INACTIVE;
+		//trgt->status = mbr_get_flag(src, ST_BOOT) ? B_ACTIVE : B_INACTIVE;
+		trgt->status = (uint8_t) (src->status & 0xFF);
+		/* ingoring CHS */
+		trgt->first_chs[0] = 0xFE;
+		trgt->first_chs[1] = 0xFF;
+		trgt->first_chs[2] = 0xFF;
+		trgt->last_chs[0] = 0xFE;
+		trgt->last_chs[1] = 0xFF;
+		trgt->last_chs[2] = 0xFF;
 		if (ebr) {	// encoding reference to EBR
 			trgt->ptype = PT_EXTENDED_LBA;
Index: uspace/lib/mbr/libmbr.h
===================================================================
--- uspace/lib/mbr/libmbr.h	(revision 622a50b2ad6b03b1b08ffc5a507e070f239fbe58)
+++ uspace/lib/mbr/libmbr.h	(revision a2aa81cb68fd01c0a20c10390ebc0c8ec3655508)
@@ -1,5 +1,5 @@
 /*
+ * Copyright (c) 2009 Jiri Svoboda
  * Copyright (c) 2011, 2012, 2013 Dominik Taborsky
- * Copyright (c) 2009 Jiri Svoboda (for some definitions from uspace/srv/bd/part/mbr_part)
  * All rights reserved.
  *
@@ -74,8 +74,9 @@
 
 typedef enum {
+	/** Other flags unknown - saving previous state */
 	/** Bootability */
-	ST_BOOT = 0,
+	ST_BOOT = 7,
 	/** Logical partition, 0 = primary, 1 = logical*/
-	ST_LOGIC = 1
+	ST_LOGIC = 8
 } MBR_FLAGS;
 
@@ -102,5 +103,5 @@
 	/** Partition overlapping */
 	ERR_OVERLAP,
-	/** Logical partition out of bounds */
+	/** Partition out of bounds */
 	ERR_OUT_BOUNDS,
 	/** No space left for EBR */
@@ -108,5 +109,7 @@
 	/** Out of memory */
 	ERR_NOMEM,
-} MBR_ERR_VAL;
+	/** Libblock error */
+	ERR_LIBBLOCK,
+} mbr_err_val;
 
 
@@ -144,6 +147,4 @@
 	/** Raw access to data */
 	br_block_t raw_data;
-	/** Device where the data are from */
-	service_id_t device;
 } mbr_t;
 
@@ -156,5 +157,5 @@
 	uint8_t type;
 	/** Flags */
-	uint8_t status;
+	uint16_t status;
 	/** Address of first block */
 	uint32_t start_addr;
@@ -180,40 +181,48 @@
 
 /** Both header and partition list */
-typedef struct mbr_table {
+typedef struct mbr_label {
+	/** MBR header */
 	mbr_t * mbr;
+	/** Partition list */
 	mbr_partitions_t * parts;
-} mbr_table_t;
-
-/** Read/Write MBR header.
+	/** Device where the data are from (or for) */
+	service_id_t device;
+} mbr_label_t;
+
+/* Alloc complete label structure */
+extern mbr_label_t * mbr_alloc_label(void);
+
+/* Read/Write MBR header.
  * WARNING: when changing both header and partitions, write first header,
  * then partitions. The MBR headers' raw_data is NOT updated to follow
  * partition changes. */
 extern mbr_t * mbr_alloc_mbr(void);
-extern mbr_t * mbr_read_mbr(service_id_t dev_handle);
-extern int mbr_write_mbr(mbr_t * mbr, service_id_t dev_handle);
-extern int mbr_is_mbr(mbr_t * mbr);
-
-/** Read/Write/Set MBR partitions.
+extern int mbr_read_mbr(mbr_label_t *, service_id_t);
+extern int mbr_write_mbr(mbr_label_t *, service_id_t);
+extern int mbr_is_mbr(mbr_label_t *);
+
+/* Read/Write/Set MBR partitions.
  * NOTE: Writing partitions writes the complete header as well. */
-extern mbr_partitions_t * mbr_read_partitions(mbr_t * mbr);
-extern int 			mbr_write_partitions(mbr_partitions_t * parts, mbr_t * mbr, service_id_t dev_handle);
-extern mbr_part_t *	mbr_alloc_partition(void);
+extern int mbr_read_partitions(mbr_label_t *);
+extern int          mbr_write_partitions(mbr_label_t *, service_id_t);
+extern mbr_part_t * mbr_alloc_partition(void);
 extern mbr_partitions_t * mbr_alloc_partitions(void);
-extern MBR_ERR_VAL	mbr_add_partition(mbr_partitions_t * parts, mbr_part_t * partition);
-extern int			mbr_remove_partition(mbr_partitions_t * parts, size_t idx);
-extern int			mbr_get_flag(mbr_part_t * p, MBR_FLAGS flag);
-extern void			mbr_set_flag(mbr_part_t * p, MBR_FLAGS flag, bool value);
-extern uint32_t		mbr_get_next_aligned(uint32_t addr, unsigned int alignment);
+extern mbr_err_val  mbr_add_partition(mbr_label_t *, mbr_part_t *);
+extern int          mbr_remove_partition(mbr_label_t *, size_t);
+extern int          mbr_get_flag(mbr_part_t *, MBR_FLAGS);
+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); \
-				 iterator  = list_get_instance(iterator->link.next, mbr_part_t, link))
-
-
-/** free() wrapper functions. */
-extern void mbr_free_mbr(mbr_t * mbr);
-extern void mbr_free_partition(mbr_part_t * p);
-extern void mbr_free_partitions(mbr_partitions_t * parts);
+        for (iterator  = list_get_instance((parts)->list.head.next, mbr_part_t, link); \
+             iterator != list_get_instance(&((parts)->list.head), mbr_part_t, link); \
+             iterator  = list_get_instance(iterator->link.next, mbr_part_t, link))
+
+
+/* free() wrapper functions. */
+extern void mbr_free_label(mbr_label_t *);
+extern void mbr_free_mbr(mbr_t *);
+extern void mbr_free_partition(mbr_part_t *);
+extern void mbr_free_partitions(mbr_partitions_t *);
 
 #endif
