shithub: lwext4

Download patch

ref: 06382010385758c11ab9e643751c88c7e969ca34
parent: a59596c45bfaa80d532ed7f9ef2c6c87f8ef5340
author: gkostka <kostka.grzegorz@gmail.com>
date: Mon May 16 05:36:07 EDT 2016

ext4_mbr: introduce ext4_mbr_write procedure

--- a/include/ext4_mbr.h
+++ b/include/ext4_mbr.h
@@ -53,7 +53,11 @@
 
 /**@brief Master boot record partitions*/
 struct ext4_mbr_parts {
-	uint64_t size[4];
+
+	/**@brief Percentage division tab:
+	 *  - {50, 20, 10, 20}
+	 * Sum of all 4 elements must be <= 100*/
+	uint8_t division[4];
 };
 
 int ext4_mbr_write(struct ext4_blockdev *parent, struct ext4_mbr_parts *parts);
--- a/src/ext4_mbr.c
+++ b/src/ext4_mbr.c
@@ -126,6 +126,78 @@
 	return r;
 }
 
+int ext4_mbr_write(struct ext4_blockdev *parent, struct ext4_mbr_parts *parts)
+{
+	int r;
+	uint64_t disk_size = parent->part_size;
+	uint32_t division_sum = parts->division[0] + parts->division[1] +
+				parts->division[2] + parts->division[3];
+
+	if (division_sum > 100)
+		return EINVAL;
+
+	ext4_dbg(DEBUG_MBR, DBG_INFO "ext4_mbr_write\n");
+	r = ext4_block_init(parent);
+	if (r != EOK)
+		return r;
+
+	/*Calculate CHS*/
+	uint32_t k = 16;
+	while ((k < 256) && ((disk_size / k / 63) > 1024))
+		k *= 2;
+
+	if (k == 256)
+		--k;
+
+	const uint32_t cyl_size = 63 * k;
+	const uint32_t cyl_count = disk_size / cyl_size;
+
+	struct ext4_mbr *mbr = (void *)parent->bdif->ph_bbuf;
+	memset(mbr, 0, sizeof(struct ext4_mbr));
+
+
+	uint32_t cyl_it = 0;
+	for (int i = 0; i < 4; ++i) {
+		uint32_t cyl_part = cyl_count * parts->division[i] / 100;
+		if (!cyl_part)
+			continue;
+
+		uint32_t part_start = cyl_it * cyl_size;
+		uint32_t part_size = cyl_part * cyl_size;
+
+		if (i == 0) {
+			part_start += 63;
+			part_size -= 63;
+		}
+
+		uint32_t cyl_end = cyl_part + cyl_it - 1;
+
+		mbr->part_entry[i].status = 0;
+		mbr->part_entry[i].chs1[0] = i ? 0 : 1;;
+		mbr->part_entry[i].chs1[1] = (cyl_it >> 2) + 1;
+		mbr->part_entry[i].chs1[2] = cyl_it;
+		mbr->part_entry[i].type = 0x83;
+		mbr->part_entry[i].chs2[0] = k - 1;
+		mbr->part_entry[i].chs2[1] = (cyl_end >> 2) + 63;
+		mbr->part_entry[i].chs2[2] = cyl_end;
+
+		mbr->part_entry[i].first_lba = part_start;
+		mbr->part_entry[i].sectors = part_size;
+
+		cyl_it += cyl_part;
+	}
+
+	mbr->signature = MBR_SIGNATURE;
+	r = ext4_block_writebytes(parent, 0, parent->bdif->ph_bbuf, 512);
+	if (r != EOK)
+		goto blockdev_fini;
+
+
+	blockdev_fini:
+	ext4_block_fini(parent);
+	return r;
+}
+
 /**
  * @}
  */