shithub: riscv

Download patch

ref: 1c5d8e24e35e3d3765a90d4f6094e7343799d97b
parent: bd24f31a4e97db36bc4124ab5a270a75ffdaba3f
author: cinap_lenrek <cinap_lenrek@localhost>
date: Sun Jul 17 17:17:28 EDT 2011

fdisk: attempt fixing extended partition handling

--- a/sys/src/cmd/disk/prep/fdisk.c
+++ b/sys/src/cmd/disk/prep/fdisk.c
@@ -14,7 +14,7 @@
 	Mpart = 64,
 };
 
-static void rdpart(Edit*, uvlong, uvlong);
+static void rdpart(Edit*, uvlong, uvlong, int);
 static void findmbr(Edit*);
 static void autopart(Edit*);
 static void wrpart(Edit*);
@@ -27,7 +27,6 @@
 static int file;
 static int rdonly;
 static int doauto;
-static vlong mbroffset;
 static int printflag;
 static int printchs;
 static int sec2cyl;
@@ -151,7 +150,7 @@
 	if(blank)
 		blankpart(&edit);
 	else
-		rdpart(&edit, 0, 0);
+		rdpart(&edit, 0, 0, 0);
 
 	if(doauto)
 		autopart(&edit);
@@ -263,9 +262,9 @@
 	Part;
 	Tentry;
 
-	u32int	lba;
-	u32int	size;
-	int		primary;
+	int	ebrtype;
+	vlong	ebrstart;
+	int	primary;
 };
 
 struct Recover {
@@ -385,11 +384,13 @@
 }
 
 static Dospart*
-mkpart(char *name, int primary, vlong lba, vlong size, Tentry *t)
+mkpart(char *name, vlong lba, vlong size, Tentry *t, vlong ebrstart, int ebrtype)
 {
 	static int n;
+	int primary;
 	Dospart *p;
 
+	primary = (ebrstart == 0) && (ebrtype == 0);
 	p = emalloc(sizeof(*p));
 	if(name)
 		p->name = estrdup(name);
@@ -406,18 +407,25 @@
 	p->changed = 0;
 	p->start = lba/sec2cyl;
 	p->end = (lba+size+sec2cyl-1)/sec2cyl;
+
 	p->ctlstart = lba;
 	p->ctlend = lba+size;
-	p->lba = lba;
-	if (p->lba != lba)
-		fprint(2, "%s: start of partition (%lld) won't fit in MBR table\n", argv0, lba);
-	p->size = size;
-	if (p->size != size)
-		fprint(2, "%s: size of partition (%lld) won't fit in MBR table\n", argv0, size);
+
+	p->ebrstart = ebrstart;
+	p->ebrtype = ebrtype;
 	p->primary = primary;
+
 	return p;
 }
 
+static int
+mkebrtype(vlong end)
+{
+	if(end >= 1024*sec2cyl)
+		return TypeEXTHUGE;
+	return TypeEXTENDED;
+}
+
 /*
  * Recovery takes care of remembering what the various tables
  * looked like when we started, attempting to restore them when
@@ -481,7 +489,7 @@
  * from the disk into the part array.
  */
 static void
-rdpart(Edit *edit, uvlong lba, uvlong xbase)
+rdpart(Edit *edit, uvlong xbase, uvlong ebrstart, int ebrtype)
 {
 	char *err;
 	Table table;
@@ -489,15 +497,12 @@
 	Dospart *p;
 
 	if(xbase == 0)
-		xbase = lba;
+		xbase = ebrstart;
 
-	diskread(edit->disk, &table, sizeof table, mbroffset+lba, Toffset);
-	addrecover(table, mbroffset+lba);
-
-	if(table.magic[0] != Magic0 || table.magic[1] != Magic1) {
-		assert(lba != 0);
+	diskread(edit->disk, &table, sizeof table, ebrstart, Toffset);
+	addrecover(table, ebrstart);
+	if(table.magic[0] != Magic0 || table.magic[1] != Magic1)
 		return;
-	}
 
 	for(tp=table.entry, ep=tp+NTentry; tp<ep && npart < Mpart; tp++) {
 		switch(tp->type) {
@@ -506,10 +511,10 @@
 		case TypeEXTENDED:
 		case TypeEXTHUGE:
 		case TypeLINUXEXT:
-			rdpart(edit, xbase+getle32(tp->xlba), xbase);
+			rdpart(edit, xbase, xbase+getle32(tp->xlba), tp->type);
 			break;
 		default:
-			p = mkpart(nil, lba==0, lba+getle32(tp->xlba), getle32(tp->xsize), tp);
+			p = mkpart(nil, ebrstart+getle32(tp->xlba), getle32(tp->xsize), tp, ebrstart, ebrtype);
 			if(err = addpart(edit, p))
 				fprint(2, "adding partition: %s\n", err);
 			break;
@@ -532,10 +537,6 @@
 	diskread(edit->disk, &table, sizeof(Table), 0, Toffset);
 	if(table.magic[0] != Magic0 || table.magic[1] != Magic1)
 		sysfatal("did not find master boot record");
-
-	for(tp = table.entry; tp < &table.entry[NTentry]; tp++)
-		if(tp->type == TypeDMDDO)
-			mbroffset = edit->disk->s;
 }
 
 static int
@@ -639,7 +640,7 @@
 		bigstart += edit->disk->s;
 		bigsize -= edit->disk->s;
 	}
-	p = mkpart(nil, 1, bigstart, bigsize, nil);
+	p = mkpart(nil, bigstart, bigsize, nil, 0, 0);
 	p->active = active;
 	p->changed = 1;
 	p->type = Type9;
@@ -662,7 +663,6 @@
 	int i, ok;
 	char *name, *vname;
 	Name *n;
-	vlong start, end;
 	char *sep;
 
 	vname = types[part->type].name;
@@ -671,9 +671,6 @@
 		return;
 	}
 
-	start = mbroffset+part->lba;
-	end = start+part->size;
-
 	/* avoid names like plan90 */
 	i = strlen(vname) - 1;
 	if(vname[i] >= '0' && vname[i] <= '9')
@@ -703,7 +700,7 @@
 	part->ctlname = name;
 
 	if(fd >= 0)
-		print("part %s %lld %lld\n", name, start, end);
+		print("part %s %lld %lld\n", name, part->ctlstart, part->ctlend);
 }
 
 static void
@@ -798,14 +795,26 @@
 cmdadd(Edit *edit, char *name, vlong start, vlong end)
 {
 	Dospart *p;
+	vlong ebrstart;
+	int ebrtype;
 
 	if(!haveroom(edit, name[0]=='p', start))
 		return "no room for partition";
 	start *= sec2cyl;
 	end *= sec2cyl;
-	if(start == 0 || name[0] != 'p')
+	if(name[0] == 'p'){
+		ebrtype = 0;
+		ebrstart = 0;
+		if(start == 0)
+			start += edit->disk->s;
+	}else{
+		if(start == 0)
+			start += edit->disk->s;
+		ebrtype =  mkebrtype(end);
+		ebrstart = start;
 		start += edit->disk->s;
-	p = mkpart(name, name[0]=='p', start, end-start, nil);
+	}
+	p = mkpart(name, start, end-start, nil, ebrstart, ebrtype);
 	p->changed = 1;
 	p->type = Type9;
 	return addpart(edit, p);
@@ -1006,6 +1015,8 @@
 	Tentry *tp, *ep;
 	Dospart *p;
 	Disk *disk;
+	vlong nextebrstart;
+	int nextebrtype;
 
 	if(i == edit->npart){
 		*endlba = edit->disk->secs;
@@ -1012,7 +1023,7 @@
 	Finish:
 		if(startlba < *endlba){
 			disk = edit->disk;
-			diskread(disk, &table, sizeof table, mbroffset+startlba, Toffset);
+			diskread(disk, &table, sizeof table, startlba, Toffset);
 			tp = table.entry;
 			ep = tp+NTentry;
 			for(; tp<ep; tp++)
@@ -1019,33 +1030,45 @@
 				memset(tp, 0, sizeof *tp);
 			table.magic[0] = Magic0;
 			table.magic[1] = Magic1;
-
-			if(diskwrite(edit->disk, &table, sizeof table, mbroffset+startlba, Toffset) < 0)
+			if(diskwrite(edit->disk, &table, sizeof table, startlba, Toffset) < 0)
 				recover(edit);
 		}
 		return i;
 	}
-
 	p = (Dospart*)edit->part[i];
 	if(p->primary){
-		*endlba = (vlong)p->ctlstart;
+		*endlba = startlba;
 		goto Finish;
 	}
 
 	disk = edit->disk;
-	diskread(disk, &table, sizeof table, mbroffset+startlba, Toffset);
+	diskread(disk, &table, sizeof table, startlba, Toffset);
 	tp = table.entry;
 	ep = tp+NTentry;
 
-	ni = wrextend(edit, i+1, xbase, p->ctlend, endlba);
+	nextebrtype = TypeEMPTY;
+	if(i+1 >= edit->npart)
+		nextebrstart = p->ctlend;
+	else{
+		Dospart *x = (Dospart*)edit->part[i+1];
+		if(x->primary)
+			nextebrstart = x->ctlstart;
+		else{
+			nextebrstart = x->ebrstart;
+			nextebrtype = x->ebrtype;
+		}
+	}
+	ni = wrextend(edit, i+1, xbase, nextebrstart, endlba);
 
 	*tp = p->Tentry;
-	wrtentry(disk, tp, p->type, startlba, startlba+disk->s, p->ctlend);
+	wrtentry(disk, tp, p->type, startlba, p->ctlstart, p->ctlend);
 	tp++;
 
-	if(p->ctlend != *endlba){
+	if(nextebrstart != *endlba){
 		memset(tp, 0, sizeof *tp);
-		wrtentry(disk, tp, TypeEXTENDED, xbase, p->ctlend, *endlba);
+		if(nextebrtype == TypeEMPTY)
+			nextebrtype = mkebrtype(*endlba);
+		wrtentry(disk, tp, nextebrtype, xbase, nextebrstart, *endlba);
 		tp++;
 	}
 
@@ -1055,7 +1078,7 @@
 	table.magic[0] = Magic0;
 	table.magic[1] = Magic1;
 
-	if(diskwrite(edit->disk, &table, sizeof table, mbroffset+startlba, Toffset) < 0)
+	if(diskwrite(edit->disk, &table, sizeof table, startlba, Toffset) < 0)
 		recover(edit);
 	return ni;
 }	
@@ -1063,38 +1086,30 @@
 static void
 wrpart(Edit *edit)
 {	
-	int i, ni, t;
+	int i, ni;
 	Table table;
 	Tentry *tp, *ep;
 	Disk *disk;
-	vlong s, endlba;
+	vlong endlba;
 	Dospart *p;
 
 	disk = edit->disk;
 
-	diskread(disk, &table, sizeof table, mbroffset, Toffset);
+	diskread(disk, &table, sizeof table, 0, Toffset);
 
 	tp = table.entry;
 	ep = tp+NTentry;
 	for(i=0; i<edit->npart && tp<ep; ) {
 		p = (Dospart*)edit->part[i];
-		if(p->start == 0)
-			s = disk->s;
-		else
-			s = p->ctlstart;
 		if(p->primary) {
 			*tp = p->Tentry;
-			wrtentry(disk, tp, p->type, 0, s, p->ctlend);
+			wrtentry(disk, tp, p->type, 0, p->ctlstart, p->ctlend);
 			tp++;
 			i++;
 		} else {
-			ni = wrextend(edit, i, p->ctlstart, p->ctlstart, &endlba);
+			ni = wrextend(edit, i, p->ebrstart, p->ebrstart, &endlba);
 			memset(tp, 0, sizeof *tp);
-			if(endlba >= 1024*sec2cyl)
-				t = TypeEXTHUGE;
-			else
-				t = TypeEXTENDED;
-			wrtentry(disk, tp, t, 0, s, endlba);
+			wrtentry(disk, tp, p->ebrtype, 0, p->ebrstart, endlba);
 			tp++;
 			i = ni;
 		}
@@ -1105,7 +1120,7 @@
 	if(i != edit->npart)
 		sysfatal("cannot happen #1");
 
-	if(diskwrite(disk, &table, sizeof table, mbroffset, Toffset) < 0)
+	if(diskwrite(disk, &table, sizeof table, 0, Toffset) < 0)
 		recover(edit);
 
 	/* bring parts up to date */