Index: uspace/lib/gpt/libgpt.c
===================================================================
--- uspace/lib/gpt/libgpt.c	(revision e91d17a84ab224f286ae17d7465f694def8c3f86)
+++ uspace/lib/gpt/libgpt.c	(revision d6170504a73b910b4963928493001f52b1c18826)
@@ -56,8 +56,9 @@
 static int reduce_part_array(gpt_partitions_t * p);
 static long long nearest_larger_int(double a);
+static int gpt_memcmp(const void * a, const void * b, size_t len);
 
 /** Read GPT from specific device
  * @param	dev_handle	device to read GPT from
- * 
+ *
  * @return				GPT record on success, NULL on error
  */
@@ -66,5 +67,5 @@
 	int rc;
 	size_t b_size;
-	
+
 	rc = block_get_bsize(dev_handle, &b_size);
 	if (rc != EOK) {
@@ -72,5 +73,5 @@
 		return NULL;
 	}
-	
+
 	gpt_t * gpt = malloc(sizeof(gpt_t));
 	if (gpt == NULL) {
@@ -78,13 +79,13 @@
 		return NULL;
 	}
-	
+
 	gpt->raw_data = malloc(b_size);// We might need only sizeof(gpt_header_t),
-	if (gpt == NULL) {				// but we should follow specs and have 
+	if (gpt == NULL) {				// but we should follow specs and have
 		free(gpt);					// zeroes through all the rest of the block
 		errno = ENOMEM;
 		return NULL;
 	}
-	
-	
+
+
 	rc = load_and_check_header(dev_handle, GPT_HDR_BA, b_size, gpt->raw_data);
 	if (rc == EBADCHECKSUM || rc == EINVAL) {
@@ -95,5 +96,5 @@
 			goto fail;
 		}
-		
+
 		rc = load_and_check_header(dev_handle, n_blocks - 1, b_size, gpt->raw_data);
 		if (rc == EBADCHECKSUM || rc == EINVAL) {
@@ -102,7 +103,7 @@
 		}
 	}
-	
+
 	gpt->device = dev_handle;
-	
+
 	return gpt;
 
@@ -115,7 +116,7 @@
  * @param header		GPT header to be written
  * @param dev_handle	device handle to write the data to
- * 
+ *
  * @return				0 on success, libblock error code otherwise
- * 
+ *
  * Note: Firstly write partitions (if changed), then gpt header.
  */
@@ -124,17 +125,17 @@
 	int rc;
 	size_t b_size;
-	
+
 	gpt->raw_data->header_crc32 = 0;
 	gpt->raw_data->header_crc32 = compute_crc32((uint8_t *) gpt->raw_data,
 					uint32_t_le2host(gpt->raw_data->header_size));
-	
+
 	rc = block_get_bsize(dev_handle, &b_size);
 	if (rc != EOK)
 		return rc;
-	
+
 	rc = block_init(EXCHANGE_ATOMIC, dev_handle, b_size);
 	if (rc != EOK)
 		return rc;
-	
+
 	/* Write to main GPT header location */
 	rc = block_write_direct(dev_handle, GPT_HDR_BA, GPT_HDR_BS, gpt->raw_data);
@@ -142,10 +143,10 @@
 		block_fini(dev_handle);
 		return rc;
-	
+
 	aoff64_t n_blocks;
 	rc = block_get_nblocks(dev_handle, &n_blocks);
 	if (rc != EOK)
 		return rc;
-	
+
 	/* Write to backup GPT header location */
 	//FIXME: those idiots thought it would be cool to have these fields in reverse order...
@@ -154,5 +155,5 @@
 	if (rc != EOK)
 		return rc;
-		
+
 	return 0;
 }
@@ -160,5 +161,5 @@
 /** Parse partitions from GPT
  * @param gpt	GPT to be parsed
- * 
+ *
  * @return 		partition linked list pointer or NULL on error
  * 				error code is stored in errno
@@ -172,5 +173,5 @@
 	uint32_t ent_size = uint32_t_le2host(gpt->raw_data->entry_size);
 	uint64_t ent_lba = uint64_t_le2host(gpt->raw_data->entry_lba);
-	
+
 	res = alloc_part_array(fill);
 	if (res == NULL) {
@@ -178,5 +179,5 @@
 		return NULL;
 	}
-	
+
 	/* We can limit comm_size like this:
 	 *  - we don't need more bytes
@@ -188,5 +189,5 @@
 		return NULL;
 	}
-	
+
 	size_t block_size;
 	rc = block_get_bsize(gpt->device, &block_size);
@@ -196,9 +197,9 @@
 		return NULL;
 	}
-	
+
 	//size_t bufpos = 0;
 	//size_t buflen = 0;
 	aoff64_t pos = ent_lba * block_size;
-	
+
 	/* Now we read just sizeof(gpt_entry_t) bytes for each entry from the device.
 	 * Hopefully, this does not bypass cache (no mention in libblock.c),
@@ -212,5 +213,5 @@
 		//rc = block_seqread(gpt->device, &bufpos, &buflen, &pos, res->part_array[i], sizeof(gpt_entry_t));
 		pos += ent_size;
-		
+
 		if (rc != EOK) {
 			gpt_free_partitions(res);
@@ -219,5 +220,5 @@
 		}
 	}
-	
+
 	/* FIXME: so far my boasting about variable partition entry size
 	 * will not work. The CRC32 checksums will be different.
@@ -226,5 +227,5 @@
 	 */
 	uint32_t crc = compute_crc32((uint8_t *) res->part_array, res->fill * sizeof(gpt_entry_t));
-	
+
 	if(uint32_t_le2host(gpt->raw_data->pe_array_crc32) != crc)
 	{
@@ -233,5 +234,5 @@
 		return NULL;
 	}
-	
+
 	return res;
 }
@@ -241,5 +242,5 @@
  * @param header		GPT header belonging to the 'parts' partitions
  * @param dev_handle	device to write the data to
- * 
+ *
  * @return				returns EOK on succes, specific error code otherwise
  */
@@ -248,28 +249,28 @@
 	int rc;
 	size_t b_size;
-	
+
 	gpt->raw_data->pe_array_crc32 = compute_crc32((uint8_t *) parts->part_array, parts->fill * gpt->raw_data->entry_size);
-	
+
 	rc = block_get_bsize(dev_handle, &b_size);
 	if (rc != EOK)
 		return rc;
-	
+
 	rc = block_init(EXCHANGE_ATOMIC, dev_handle, b_size);
 	if (rc != EOK)
 		return rc;
-	
+
 	/* Write to main GPT partition array location */
-	rc = block_write_direct(dev_handle, uint64_t_le2host(gpt->raw_data->entry_lba), 
-			nearest_larger_int((uint64_t_le2host(gpt->raw_data->entry_size) * parts->fill) / b_size), 
+	rc = block_write_direct(dev_handle, uint64_t_le2host(gpt->raw_data->entry_lba),
+			nearest_larger_int((uint64_t_le2host(gpt->raw_data->entry_size) * parts->fill) / b_size),
 			parts->part_array);
 	if (rc != EOK)
 		block_fini(dev_handle);
 		return rc;
-	
+
 	aoff64_t n_blocks;
 	rc = block_get_nblocks(dev_handle, &n_blocks);
 	if (rc != EOK)
 		return rc;
-	
+
 	/* Write to backup GPT partition array location */
 	//rc = block_write_direct(dev_handle, n_blocks - 1, GPT_HDR_BS, header->raw_data);
@@ -277,17 +278,17 @@
 	if (rc != EOK)
 		return rc;
-	
-	
+
+
 	return gpt_write_gpt_header(gpt, dev_handle);
 }
 
 /** Alloc new partition
- * 
+ *
  * @param parts		partition table to carry new partition
- * 
+ *
  * @return			returns pointer to the new partition or NULL on ENOMEM
- * 
+ *
  * Note: use either gpt_alloc_partition or gpt_add_partition. The first
- * returns a pointer to write your data to, the second copies the data 
+ * returns a pointer to write your data to, the second copies the data
  * (and does not free the memory).
  */
@@ -298,17 +299,17 @@
 			return NULL;
 	}
-	
+
 	return parts->part_array + parts->fill++;
 }
 
 /** Copy partition into partition array
- * 
+ *
  * @param parts			target partition array
  * @param partition		source partition to copy
- * 
+ *
  * @return 				-1 on error, 0 otherwise
- * 
+ *
  * Note: use either gpt_alloc_partition or gpt_add_partition. The first
- * returns a pointer to write your data to, the second copies the data 
+ * returns a pointer to write your data to, the second copies the data
  * (and does not free the memory).
  */
@@ -317,16 +318,16 @@
 	if (parts->fill == parts->arr_size) {
 		if (extend_part_array(parts) == -1)
-			return -1;
+			return ENOMEM;
 	}
 	extend_part_array(parts);
-	return parts;
+	return EOK;;
 }
 
 /** Remove partition from array
- * 
+ *
  * @param idx		index of the partition to remove
- * 
+ *
  * @return			-1 on error, 0 otherwise
- * 
+ *
  * Note: even if it fails, the partition still gets removed. Only
  * reducing the array failed.
@@ -335,13 +336,13 @@
 {
 	if (idx != parts->fill - 1) {
-		memcpy(parts->part_array + idx, parts->part_array + fill - 1, sizeof(gpt_entry_t));
+		memcpy(parts->part_array + idx, parts->part_array + parts->fill - 1, sizeof(gpt_entry_t));
 		parts->fill -= 1;
 	}
-	
+
 	if (parts->fill < (parts->arr_size / 2) - GPT_IGNORE_FILL_NUM) {
 		if (reduce_part_array(parts) == -1)
 			return -1;
 	}
-	
+
 	return 0;
 }
@@ -355,5 +356,5 @@
 
 /** Free partition list
- * 
+ *
  * @param parts		partition list to be freed
  */
@@ -371,5 +372,5 @@
 	size_t i;
 	for (i = 0; gpt_ptypes[i].guid != NULL; i++) {
-		if (memcmp(p->raw_data.part_type, gpt_ptypes[i].guid, 16) == 0) {
+		if (gpt_memcmp(p->part_type, gpt_ptypes[i].guid, 16) == 0) {
 			break;
 		}
@@ -381,42 +382,66 @@
  * @param p			partition to be set
  * @param type		partition type to set
- * 					- see gpt_ptypes to choose from
- * 
- */
-void gpt_set_part_type(gpt_part_t * p, int type)
+ * 					- see our fine selection at gpt_ptypes to choose from
+ */
+void gpt_set_part_type(gpt_part_t * p, size_t type)
 {
 	/* Beware: first 3 blocks are byteswapped! */
-	p->raw_data.part_type[3] = gpt_ptypes[type].guid[0];
-	p->raw_data.part_type[2] = gpt_ptypes[type].guid[1];
-	p->raw_data.part_type[1] = gpt_ptypes[type].guid[2];
-	p->raw_data.part_type[0] = gpt_ptypes[type].guid[3];
-	
-	p->raw_data.part_type[5] = gpt_ptypes[type].guid[4];
-	p->raw_data.part_type[4] = gpt_ptypes[type].guid[5];
-	
-	p->raw_data.part_type[7] = gpt_ptypes[type].guid[6];
-	p->raw_data.part_type[6] = gpt_ptypes[type].guid[7];
-	
-	p->raw_data.part_type[8] = gpt_ptypes[type].guid[8];
-	p->raw_data.part_type[9] = gpt_ptypes[type].guid[9];
-	p->raw_data.part_type[10] = gpt_ptypes[type].guid[10];
-	p->raw_data.part_type[11] = gpt_ptypes[type].guid[11];
-	p->raw_data.part_type[12] = gpt_ptypes[type].guid[12];
-	p->raw_data.part_type[13] = gpt_ptypes[type].guid[13];
-	p->raw_data.part_type[14] = gpt_ptypes[type].guid[14];
-	p->raw_data.part_type[15] = gpt_ptypes[type].guid[15];
-}
-
-char * gpt_get_part_name(gpt_entry_t * p)
-{
-	return p->raw_data.part_name;
+	p->part_type[3] = gpt_ptypes[type].guid[0];
+	p->part_type[2] = gpt_ptypes[type].guid[1];
+	p->part_type[1] = gpt_ptypes[type].guid[2];
+	p->part_type[0] = gpt_ptypes[type].guid[3];
+
+	p->part_type[5] = gpt_ptypes[type].guid[4];
+	p->part_type[4] = gpt_ptypes[type].guid[5];
+
+	p->part_type[7] = gpt_ptypes[type].guid[6];
+	p->part_type[6] = gpt_ptypes[type].guid[7];
+
+	p->part_type[8] = gpt_ptypes[type].guid[8];
+	p->part_type[9] = gpt_ptypes[type].guid[9];
+	p->part_type[10] = gpt_ptypes[type].guid[10];
+	p->part_type[11] = gpt_ptypes[type].guid[11];
+	p->part_type[12] = gpt_ptypes[type].guid[12];
+	p->part_type[13] = gpt_ptypes[type].guid[13];
+	p->part_type[14] = gpt_ptypes[type].guid[14];
+	p->part_type[15] = gpt_ptypes[type].guid[15];
+}
+
+/** Get partition starting LBA */
+uint64_t gpt_get_start_lba(gpt_part_t * p)
+{
+	return uint64_t_le2host(p->start_lba);
+}
+
+/** Set partition starting LBA */
+void gpt_set_start_lba(gpt_part_t * p, uint64_t start)
+{
+	p->start_lba = host2uint64_t_le(start);
+}
+
+/** Get partition ending LBA */
+uint64_t gpt_get_end_lba(gpt_part_t * p)
+{
+	return uint64_t_le2host(p->end_lba);
+}
+
+/** Set partition ending LBA */
+void gpt_set_end_lba(gpt_part_t * p, uint64_t end)
+{
+	p->end_lba = host2uint64_t_le(end);
+}
+
+
+unsigned char * gpt_get_part_name(gpt_part_t * p)
+{
+	return p->part_name;
 }
 
 /** Copy partition name */
-void gpt_set_part_name(gpt_entry_t * p, char * name[], size_t length)
+void gpt_set_part_name(gpt_part_t * p, char * name[], size_t length)
 {
 	if (length >= 72)
 		length = 71;
-	
+
 	memcpy(p->part_name, name, length);
 	p->part_name[length] = '\0';
@@ -424,13 +449,13 @@
 
 /** Get partition attribute */
-extern bool gpt_get_flag(gpt_part_t * p, GPT_ATTR flag)
-{
-	return (p->raw_data.attributes & (((uint64_t) 1) << flag)) ? 1 : 0;
+bool gpt_get_flag(gpt_part_t * p, GPT_ATTR flag)
+{
+	return (p->attributes & (((uint64_t) 1) << flag)) ? 1 : 0;
 }
 
 /** Set partition attribute */
-extern void gpt_set_flag(gpt_part_t * p, GPT_ATTR flag, bool value)
-{
-	uint64_t attr = p->raw_data.attributes;
+void gpt_set_flag(gpt_part_t * p, GPT_ATTR flag, bool value)
+{
+	uint64_t attr = p->attributes;
 
 	if (value)
@@ -439,5 +464,5 @@
 		attr = attr ^ (attr & (((uint64_t) 1) << flag));
 
-	p->raw_data.attributes = attr;
+	p->attributes = attr;
 }
 
@@ -447,15 +472,15 @@
 {
 	int rc;
-	
+
 	rc = block_init(EXCHANGE_ATOMIC, dev_handle, b_size);
 	if (rc != EOK)
 		return rc;
-	
+
 	rc = block_read_direct(dev_handle, addr, GPT_HDR_BS, header);
 	block_fini(dev_handle);
 	if (rc != EOK)
 		return rc;
-	
-	
+
+
 	unsigned int i;
 	/* Check the EFI signature */
@@ -464,5 +489,5 @@
 			return EINVAL;
 	}
-	
+
 	/* Check the CRC32 of the header */
 	uint32_t crc = header->header_crc32;
@@ -472,5 +497,5 @@
 	else
 		header->header_crc32 = crc;
-	
+
 	/* Check for zeroes in the rest of the block */
 	for (i = sizeof(gpt_header_t); i < b_size; ++i) {
@@ -478,5 +503,5 @@
 			return EINVAL;
 	}
-		
+
 	return EOK;
 }
@@ -489,5 +514,5 @@
 		return NULL;
 	}
-	
+
 	uint32_t size = num > GPT_BASE_PART_NUM ? num : GPT_BASE_PART_NUM;
 	res->part_array = malloc(size * sizeof(gpt_entry_t));
@@ -497,8 +522,8 @@
 		return NULL;
 	}
-	
+
 	res->fill = num;
 	res->arr_size = size;
-	
+
 	return res;
 }
@@ -512,10 +537,10 @@
 		return -1;
 	}
-	
+
 	memcpy(tmp, p->part_array, p->fill);
 	free(p->part_array);
 	p->part_array = tmp;
 	p->arr_size = nsize;
-	
+
 	return 0;
 }
@@ -530,5 +555,5 @@
 			return -1;
 		}
-		
+
 		memcpy(tmp, p->part_array, p->fill < nsize ? p->fill  : nsize);
 		free(p->part_array);
@@ -536,5 +561,5 @@
 		p->arr_size = nsize;
 	}
-	
+
 	return 0;
 }
@@ -546,9 +571,25 @@
 		return (long long) a;
 	}
-	
+
 	return ((long long) a) + 1;
 }
 
-
-
-
+static int gpt_memcmp(const void * a, const void * b, size_t len)
+{
+	size_t i;
+	int diff;
+	const unsigned char * x = a;
+	const unsigned char * y = b;
+
+	for (i = 0; i < len; i++) {
+		diff = (int)*(x++) - (int)*(y++);
+		if (diff != 0) {
+			return diff;
+		}
+	}
+	return 0;
+}
+
+
+
+
Index: uspace/lib/gpt/libgpt.h
===================================================================
--- uspace/lib/gpt/libgpt.h	(revision e91d17a84ab224f286ae17d7465f694def8c3f86)
+++ uspace/lib/gpt/libgpt.h	(revision d6170504a73b910b4963928493001f52b1c18826)
@@ -102,14 +102,17 @@
 } __attribute__((packed)) gpt_entry_t;
 
-typedef struct g_part {
-	/** Partition entry is in use */
-	bool present;
-	/** Address of first block */
-	aoff64_t start_addr;
-	/** Number of blocks */
-	aoff64_t length;
-	/** Raw data access */
-	gpt_entry_t raw_data;	//TODO: a pointer or just a member?
-}gpt_part_t;
+
+//typedef struct g_part {
+	///** Partition entry is in use **/
+	//bool present;
+	///** Address of first block */
+	//aoff64_t start_addr;
+	///** Number of blocks */
+	//aoff64_t length;
+	///** Raw data access */
+	//gpt_entry_t raw_data;	//TODO: a pointer or just a member?
+//}gpt_part_t;
+typedef gpt_entry_t gpt_part_t;
+
 
 typedef struct gpt_parts {
@@ -140,18 +143,25 @@
 extern int gpt_write_gpt_header(gpt_t * header, service_id_t dev_handle);
 
-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 char * 			  gpt_get_part_name(gpt_entry_t * p);
-extern void 			  gpt_set_part_name(gpt_entry_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 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 start);
+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);
+
+
 
 #define gpt_foreach(parts, i, iterator) \
-		for(size_t i = 0, gpt_part_t * iterator = parts->part_array;
+		for(size_t i = 0, gpt_part_t * iterator = parts->part_array; \
 		    i < parts->fill; i++, iterator++)
 
Index: uspace/lib/mbr/libmbr.c
===================================================================
--- uspace/lib/mbr/libmbr.c	(revision e91d17a84ab224f286ae17d7465f694def8c3f86)
+++ uspace/lib/mbr/libmbr.c	(revision d6170504a73b910b4963928493001f52b1c18826)
@@ -48,4 +48,7 @@
 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);
+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);
 
 /** Read MBR from specific device
@@ -142,5 +145,5 @@
 		if (mbr->raw_data.pte[i].ptype == PT_UNUSED)
 			continue;
-		
+
 		p = malloc(sizeof(mbr_part_t));
 		if (p == NULL) {
@@ -179,5 +182,5 @@
 int mbr_write_partitions(mbr_partitions_t * parts, mbr_t * mbr, service_id_t dev_handle)
 {
-	bool logical = false;
+	//bool logical = false;
 	int i = 0;
 	int rc;
@@ -185,10 +188,10 @@
 	mbr_part_t * ext = (parts->l_extended == NULL) ? NULL
 					: list_get_instance(parts->l_extended, mbr_part_t, link);
-	
-	br_block_t * last_ebr = NULL;
-	link_t * it;
-	
+
+	//br_block_t * last_ebr = NULL;
+	//link_t * it;
+
 	DEBUG_PRINT_3(LIBMBR_NAME "Writing partitions: n_primary: %u, n_logical:%u, l_extended:%p", parts->n_primary, parts->n_logical, parts->l_extended);
-	
+
 	rc = block_init(EXCHANGE_ATOMIC, dev_handle, 512);
 	if (rc != EOK) {
@@ -196,10 +199,123 @@
 		return rc;
 	}
+	/*
+	// Encoding primary partitions
+	for (i = 0; i < parts->n_primary; i++) {
+		encode_part(p, &(mbr->raw_data.pte[i]), 0);
+	}
+
+	// Writing MBR
+	rc = block_write_direct(dev_handle, 0, 1, &(mbr->raw_data));
+	if (rc != EOK) {
+		DEBUG_PRINT_2(LIBMBR_NAME ": Error (%d): %s.\n", rc, str_error(rc));
+		goto end;
+	}
+
+	uint32_t base = ext->start_addr;
+	uint32_t addr = base;
+
+	// Encoding and writing logical partitions
+	mbr_part_foreach(parts, p) {
+		if (p->ebr == NULL) {
+			p->ebr = alloc_br();
+			if (p->ebr == NULL)
+			{
+				rc = ENOMEM;
+				goto end;
+			}
+		}
+
+
+	}*/
+
+	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);
+		l = l->next;
+	}
+
+	// Writing MBR
+	rc = block_write_direct(dev_handle, 0, 1, &(mbr->raw_data));
+	if (rc != EOK) {
+		DEBUG_PRINT_2(LIBMBR_NAME ": Error (%d): %s.\n", rc, str_error(rc));
+		goto end;
+	}
 
 	if (ext == NULL)
 		goto no_extended;
 
+
 	uint32_t base = ext->start_addr;
 	uint32_t addr = base;
+
+	// Encoding and writing first logical partition
+	if (l != &(parts->list.head)) {
+		p = list_get_instance(l, mbr_part_t, link);
+		if (p->ebr == NULL) {
+			p->ebr = alloc_br();
+			if (p->ebr == NULL) {
+				rc = ENOMEM;
+				goto end;
+			}
+		}
+
+		encode_part(p, &(p->ebr->pte[0]), base);
+
+		if (l->next == &(parts->list.head))
+			encode_part(NULL, &(p->ebr->pte[1]), base);
+		else
+			encode_part(list_get_instance(l->next, mbr_part_t, link), &(p->ebr->pte[1]), base);
+
+
+		rc = block_write_direct(dev_handle, base, 1, p->ebr);
+		if (rc != EOK) {
+			DEBUG_PRINT_2(LIBMBR_NAME ": Error (%d): %s.\n", rc, str_error(rc));
+			goto end;
+		}
+
+		l = l->next;
+	}
+
+
+
+	// Encoding and writing logical partitions
+	while (l != &(parts->list.head)) {
+		p = list_get_instance(l, mbr_part_t, link);
+		if (p->ebr == NULL) {
+			p->ebr = alloc_br();
+			if (p->ebr == NULL) {
+				rc = ENOMEM;
+				goto end;
+			}
+		}
+
+		addr = p->start_addr - base;
+		encode_part(p, &(p->ebr->pte[0]), addr);
+
+		if (l->next == &(parts->list.head))
+			encode_part(NULL, &(p->ebr->pte[1]), base);
+		else
+			encode_part(list_get_instance(l->next, mbr_part_t, link), &(p->ebr->pte[1]), base);
+
+
+		rc = block_write_direct(dev_handle, addr, 1, p->ebr);
+		if (rc != EOK) {
+			DEBUG_PRINT_2(LIBMBR_NAME ": Error (%d): %s.\n", rc, str_error(rc));
+			goto end;
+		}
+
+		l = l->next;
+	}
+
+no_extended:
+
+	/*if (ext == NULL)
+		goto no_extended;
+
+	uint32_t base = ext->start_addr;
+	uint32_t addr;// = base;
 	uint32_t prev_addr;
 	mbr_part_t * prev_part = NULL;
@@ -209,11 +325,6 @@
 		if (mbr_get_flag(p, ST_LOGIC)) {
 			// writing logical partition
-			
-			if (p->start_addr < base || p->start_addr + p->length > base + ext->length) {
-				// out of bounds
-				return EINVAL;
-			}
-			
-			
+			logical = true;
+
 			if (p->ebr == NULL) {
 				p->ebr = alloc_br();
@@ -225,7 +336,4 @@
 			}
 
-			
-			
-			
 			if (prev_part != NULL) {
 				// addr is the address of EBR
@@ -243,7 +351,8 @@
 				addr = base;
 				// base-1 means start_lba+1
-				encode_part(p, &(p->ebr->pte[0]), base - 1);
+				// Fixed: mbr_add_partition now performs checks!nevim
+				encode_part(p, &(p->ebr->pte[0]), base);
 			}
-			
+
 			//addr = p->start_addr;
 			prev_addr = addr;
@@ -260,5 +369,5 @@
 			++i;
 		}
-	}
+	} //*/
 
 	/* If there was an extended but no logical, we should overwrite
@@ -266,7 +375,7 @@
 	 * might be some garbage from the past.
 	 */
-	
+	/*
 	last_ebr = prev_part->ebr;
-	
+
 	if (!logical)
 	{
@@ -276,17 +385,18 @@
 			goto end;
 		}
-		
+
 		last_ebr->pte[0].ptype = PT_UNUSED;
 	}
-	
-	
+
+
 	encode_part(NULL, &(last_ebr->pte[1]), 0);
 	rc = block_write_direct(dev_handle, addr, 1, last_ebr);
-	
+
 	if (!logical)
 	{
 		free(last_ebr);
 	}
-	
+	*/
+	/*
 	if (rc != EOK) {
 		DEBUG_PRINT_2(LIBMBR_NAME ": Error (%d): %s.\n", rc, str_error(rc));
@@ -297,5 +407,5 @@
 
 no_extended:
-
+	*/
 	/*list_foreach(parts->list, it) {
 		p = list_get_instance(it, mbr_part_t, link);
@@ -313,5 +423,5 @@
 		}
 	}*/
-	
+	/*
 	it = parts->list.head.next;
 	for (i = 0; i < N_PRIMARY; i++) {
@@ -329,5 +439,5 @@
 
 			}
-			
+
 			it = it->next;
 		} else {
@@ -335,5 +445,5 @@
 		}
 	}
-	
+
 
 skip:
@@ -343,4 +453,5 @@
 		goto end;
 	}
+	*/
 
 	/*
@@ -405,5 +516,5 @@
 
 	rc = EOK;
-	
+
 end:
 	block_fini(dev_handle);
@@ -437,5 +548,5 @@
 
 	list_initialize(&(parts->list));
-	
+
 	parts->n_primary = 0;
 	parts->n_logical = 0;
@@ -445,23 +556,59 @@
 }
 
-/** Add partition */
+/** Add partition
+ * 	Performs checks, sorts the list.
+ */
 int mbr_add_partition(mbr_partitions_t * parts, mbr_part_t * p)
 {
-	list_append(&(p->link), &(parts->list));
 	if (mbr_get_flag(p, ST_LOGIC)) {
+		// adding logical part
+		if (parts->l_extended == NULL) {
+			return ERR_NO_EXTENDED;
+		}
+		if (!check_encaps(p, list_get_instance(parts->l_extended, mbr_part_t, link))) {
+			return ERR_OUT_BOUNDS;
+		}
+
+		mbr_part_t * last = list_get_instance(list_last(&(parts->list)), mbr_part_t, link);
+		mbr_part_foreach(parts, iter) {
+			if (mbr_get_flag(iter, ST_LOGIC)) {
+				if (check_overlap(p, iter)) {
+					return ERR_OVERLAP;
+				}
+				if (check_preceeds(p, iter)) {
+					last = iter;
+					break;
+				}
+			}
+		}
+
+		//list_prepend(&(p->link), &(parts->list));
+		list_insert_before(&(p->link), &(last->link));
 		parts->n_logical += 1;
 	} else {
-		parts->n_primary += 1;
-	}
-	/* if we're adding new logical partition, we need 1 sector for the EBR 
-	 * for that partition (including the next one); we'd better make sure here
-	 * before writing */
-	if (mbr_get_flag(p, ST_LOGIC) && p->ebr == NULL) {
-		p->start_addr += 1;
-		p->length -= 1;
-	}
-	//FIXME: we can have multiple extended partitions! :-(
-	
-	return EOK;
+		// adding primary
+		if (parts->n_primary == 4) {
+			return ERR_PRIMARY_FULL;
+		}
+		if (p->type == PT_EXTENDED && parts->l_extended != NULL) {
+			return ERR_EXTENDED_PRESENT;
+		}
+
+		if (list_empty(&(parts->list))) {
+			list_append(&(p->link), &(parts->list));
+		} else {
+			mbr_part_foreach(parts, iter) {
+				if (mbr_get_flag(iter, ST_LOGIC)) {
+					list_insert_before(&(p->link), &(iter->link));
+					parts->n_primary += 1;
+					break;
+				} else if (check_overlap(p, iter)) {
+					return ERR_OVERLAP;
+				}
+			}
+		}
+	}
+
+	return ERR_OK;
 }
 
@@ -469,5 +616,5 @@
 int mbr_remove_partition(mbr_partitions_t * parts, size_t idx)
 {
-	DEBUG_PRINT_1(LIBMBR_NAME "Removing partition: %d\n", idx);
+	DEBUG_PRINT_1(LIBMBR_NAME "Removing partition: %zu\n", idx);
 	link_t * l = list_nth(&(parts->list), idx);
 	if (l == parts->l_extended) {
@@ -482,8 +629,8 @@
 		parts->n_primary -= 1;
 	}
-	
-	
+
+
 	mbr_free_partition(p);
-	
+
 	return EOK;
 }
@@ -533,5 +680,5 @@
 		mbr_free_partition(p);
 	}
-	
+
 	free(parts);
 }
@@ -590,5 +737,5 @@
 	if (rc != EOK)
 		return rc;
-	
+
 	ebr = alloc_br();
 	if (ebr == NULL) {
@@ -606,10 +753,10 @@
 		goto free_ebr_end;
 	}
-	
+
 	if (ebr->pte[0].ptype == PT_UNUSED) {
 		rc = EOK;
 		goto free_ebr_end;
 	}
-	
+
 	p = mbr_alloc_partition();
 	if (p == NULL) {
@@ -617,5 +764,5 @@
 		goto free_ebr_end;
 	}
-	
+
 
 	decode_part(&(ebr->pte[0]), p, base);
@@ -625,5 +772,5 @@
 
 	addr = uint32_t_le2host(ebr->pte[1].first_lba) + base;
-	
+
 	while (ebr->pte[1].ptype != PT_UNUSED) {
 		ebr = alloc_br();
@@ -656,10 +803,10 @@
 		addr = uint32_t_le2host(ebr->pte[1].first_lba) + base;
 	}
-	
+
 	rc = EOK;
-	
+
 free_ebr_end:
 	free(ebr);
-	
+
 end:
 	block_fini(mbr->device);
@@ -690,2 +837,31 @@
 }
 
+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) {
+		return 0;
+	} else if (p1->start_addr > p2->start_addr && p2->start_addr + p2->length <= p1->start_addr) {
+		return 0;
+	}
+
+	return 1;
+}
+
+static int check_encaps(mbr_part_t * inner, mbr_part_t * outer)
+{
+	if (inner->start_addr <= outer->start_addr || outer->start_addr + outer->length <= inner->start_addr) {
+		return 0;
+	} else if (outer->start_addr + outer->length < inner->start_addr + inner->length) {
+		return 0;
+	}
+
+	return 1;
+}
+
+static int check_preceeds(mbr_part_t * preceeder, mbr_part_t * precedee)
+{
+	return preceeder->start_addr < precedee->start_addr;
+}
+
+
+
Index: uspace/lib/mbr/libmbr.h
===================================================================
--- uspace/lib/mbr/libmbr.h	(revision e91d17a84ab224f286ae17d7465f694def8c3f86)
+++ uspace/lib/mbr/libmbr.h	(revision d6170504a73b910b4963928493001f52b1c18826)
@@ -52,5 +52,5 @@
 	printf("%s:%d: " str, __FILE__, __LINE__, arg1, arg2, arg3)
 #else
-#define DEBUG_PRINT_0(str) 
+#define DEBUG_PRINT_0(str)
 #define DEBUG_PRINT_1(str, arg1)
 #define DEBUG_PRINT_2(str, arg1, arg2)
@@ -87,4 +87,20 @@
 	PT_GPT	= 0xEE,
 };
+
+typedef enum {
+	/** No error */
+	ERR_OK = 0,
+	/** All primary partitions already present */
+	ERR_PRIMARY_FULL,
+	/** Extended partition already present */
+	ERR_EXTENDED_PRESENT,
+	/** No extended partition present */
+	ERR_NO_EXTENDED,
+	/** Partition overlapping */
+	ERR_OVERLAP,
+	/** Logical partition out of bounds */
+	ERR_OUT_BOUNDS,
+} MBR_ERR_VAL;
+
 
 /** Structure of a partition table entry */
@@ -146,9 +162,9 @@
 	/** Number of primary partitions */
 	unsigned char n_primary;
-	/** Link to the extended partition in the list */
+	/** Index to the extended partition in the array */
 	link_t * l_extended;
 	/** Number of logical partitions */
 	unsigned int n_logical;
-	/** Partition linked list */
+	/** Logical partition linked list */
 	list_t list;
 } mbr_partitions_t;
