Index: uspace/srv/part/mbr_part/mbr_part.c
===================================================================
--- uspace/srv/part/mbr_part/mbr_part.c	(revision 440b0ce271332b2196cbca972521f716c8f75a04)
+++ uspace/srv/part/mbr_part/mbr_part.c	(revision e27b89ad7a36cbdf96bb40b3057e485266d12200)
@@ -59,4 +59,5 @@
 #include <bool.h>
 #include <byteorder.h>
+#include <assert.h>
 #include <macros.h>
 #include <task.h>
@@ -70,7 +71,4 @@
 	/** Boot record signature */
 	BR_SIGNATURE	= 0xAA55,
-
-	/** Maximum number of partitions */
-	MAX_PART	= 64
 };
 
@@ -81,5 +79,5 @@
 
 /** Partition */
-typedef struct {
+typedef struct part {
 	/** Primary partition entry is in use */
 	bool present;
@@ -90,4 +88,6 @@
 	/** Device representing the partition (outbound device) */
 	dev_handle_t dev;
+	/** Points to next partition structure. */
+	struct part *next;
 } part_t;
 
@@ -130,8 +130,10 @@
 static dev_handle_t indev_handle;
 
-static part_t primary[MAX_PART];
+/** List of partitions. This structure is an empty head. */
+static part_t plist_head;
 
 static int mbr_init(const char *dev_name);
 static int mbr_part_read(void);
+static part_t *mbr_part_new(void);
 static void mbr_pte_to_part(uint32_t base, const pt_entry_t *pte, part_t *part);
 static void mbr_connection(ipc_callid_t iid, ipc_call_t *icall);
@@ -140,7 +142,4 @@
 static int mbr_bsa_translate(part_t *p, uint64_t ba, size_t cnt, uint64_t *gba);
 
-/** Total number of partitions entries in @c primary (including non-present). */
-static int total_part;
-
 int main(int argc, char **argv)
 {
@@ -170,4 +169,5 @@
 	dev_handle_t dev;
 	uint64_t size_mb;
+	part_t *part;
 
 	rc = devmap_device_get_handle(dev_name, &indev_handle, 0);
@@ -208,9 +208,17 @@
 	}
 
-	/* Create partition devices. */
-	for (i = 0; i < total_part; ++i) {
+	/*
+	 * Create partition devices.
+	 */
+	i = 0;
+	part = plist_head.next;
+
+	while (part != NULL) {
 		/* Skip absent partitions. */
-		if (!primary[i].present)
+		if (!part->present) {
+			part = part->next;
+			++i;
 			continue;
+		}
 
 		asprintf(&name, "%sp%d", dev_name, i);
@@ -225,11 +233,14 @@
 		}
 
-		size_mb = (primary[i].length * block_size + 1024 * 1024 - 1)
+		size_mb = (part->length * block_size + 1024 * 1024 - 1)
 		    / (1024 * 1024);
 		printf(NAME ": Registered device %s: %llu blocks %llu MB.\n",
-		    name, primary[i].length, size_mb);
-
-		primary[i].dev = dev;
+		    name, part->length, size_mb);
+
+		part->dev = dev;
 		free(name);
+
+		part = part->next;
+		++i;
 	}
 
@@ -246,4 +257,5 @@
 	part_t *ext_part, cp;
 	uint32_t base;
+	part_t *prev, *p;
 
 	brb = malloc(sizeof(br_block_t));
@@ -270,11 +282,19 @@
 
 	ext_part = NULL;
+	plist_head.next = NULL;
+	prev = &plist_head;
 
 	for (i = 0; i < N_PRIMARY; ++i) {
-		mbr_pte_to_part(0, &brb->pte[i], &primary[i]);
+		p = mbr_part_new();
+		if (p == NULL)
+			return ENOMEM;
+
+		mbr_pte_to_part(0, &brb->pte[i], p);
+		prev->next = p;
+		prev = p;
 
 		if (brb->pte[i].ptype == PT_EXTENDED) {
-			primary[i].present = false;
-			ext_part = &primary[i];
+			p->present = false;
+			ext_part = p;
 		}
 	}
@@ -312,15 +332,24 @@
 		}
 
+		p = mbr_part_new();
+		if (p == NULL)
+			return ENOMEM;
+
 		/* First PTE is the logical partition itself. */
-		mbr_pte_to_part(base, &brb->pte[0], &primary[i]);
-		++i;
+		mbr_pte_to_part(base, &brb->pte[0], p);
+		prev->next = p;
+		prev = p;
 
 		/* Second PTE describes next chain element. */
 		mbr_pte_to_part(base, &brb->pte[1], &cp);
-	} while (cp.present && i < MAX_PART);
-
-	total_part = i;
+	} while (cp.present);
 
 	return EOK;
+}
+
+/** Allocate a new @c part_t structure. */
+static part_t *mbr_part_new(void)
+{
+	return malloc(sizeof(part_t));
 }
 
@@ -338,4 +367,5 @@
 	part->present = (sa != 0 || len != 0) ? true : false;
 	part->dev = 0;
+	part->next = NULL;
 }
 
@@ -352,5 +382,4 @@
 	uint64_t ba;
 	size_t cnt;
-	int pidx, i;
 	part_t *part;
 
@@ -358,16 +387,19 @@
 	dh = IPC_GET_ARG1(*icall);
 
-	/* Determine which partition device is the client connecting to. */
-	pidx = -1;
-	for (i = 0; i < total_part; i++)
-		if (primary[i].dev == dh)
-			pidx = i;
-
-	if (pidx < 0/* || disk[disk_id].present == false*/) {
+	/* 
+	 * Determine which partition device is the client connecting to.
+	 * A linear search is not terribly fast, but we only do this
+	 * once for each connection.
+	 */
+	part = plist_head.next;
+	while (part != NULL && part->dev != dh)
+		part = part->next;
+
+	if (part == NULL) {
 		ipc_answer_0(iid, EINVAL);
 		return;
 	}
 
-	part = &primary[pidx];
+	assert(part->present == true);
 
 	/* Answer the IPC_M_CONNECT_ME_TO call. */
