fix fdisk calcuations. from cinap. we may have lost the ability to detect when are partitions are too big for the fdisk table with this update, but at least the cacluations are correct in the cases fdisk will work now. Reference: /n/atom/patch/applied2013/fdiskfix Date: Mon Oct 14 19:31:07 CES 2013 Signed-off-by: quanstro@quanstro.net --- /sys/src/cmd/disk/prep/fdisk.c Mon Oct 14 19:29:12 2013 +++ /sys/src/cmd/disk/prep/fdisk.c Mon Oct 14 19:29:12 2013 @@ -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); @@ -267,9 +266,9 @@ Part; Tentry; - u32int lba; - u32int size; - int primary; + int ebrtype; + vlong ebrstart; + int primary; }; struct Recover { @@ -391,11 +390,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); @@ -411,19 +412,25 @@ p->changed = 0; p->start = lba/sec2cyl; - p->end = (lba+size)/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 @@ -487,7 +494,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; @@ -495,15 +502,12 @@ Dospart *p; if(xbase == 0) - xbase = lba; - - diskread(edit->disk, &table, Tablesize, mbroffset+lba, Toffset); - addrecover(table, mbroffset+lba); + xbase = ebrstart; - if(table.magic[0] != Magic0 || table.magic[1] != Magic1) { - assert(lba != 0); + diskread(edit->disk, &table, Tablesize, ebrstart, Toffset); + addrecover(table, ebrstart); + if(table.magic[0] != Magic0 || table.magic[1] != Magic1) return; - } for(tp=table.entry, ep=tp+NTentry; tptype) { @@ -512,10 +516,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; @@ -533,15 +537,10 @@ findmbr(Edit *edit) { Table table; - Tentry *tp; diskread(edit->disk, &table, Tablesize, 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 @@ -645,7 +644,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; @@ -668,7 +667,6 @@ int i, ok; char *name, *vname; Name *n; - vlong start, end; char *sep; vname = types[part->type].name; @@ -677,9 +675,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') @@ -709,7 +704,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 @@ -804,14 +799,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); @@ -1012,21 +1019,22 @@ Tentry *tp, *ep; Dospart *p; Disk *disk; + vlong nextebrstart; +// int nextebrtype; if(i == edit->npart){ *endlba = edit->disk->secs; Finish: if(startlba < *endlba){ disk = edit->disk; - diskread(disk, &table, Tablesize, mbroffset+startlba, Toffset); + diskread(disk, &table, Tablesize, startlba, Toffset); tp = table.entry; ep = tp+NTentry; for(; tpdisk, &table, Tablesize, mbroffset+startlba, Toffset) < 0) + if(diskwrite(edit->disk, &table, Tablesize, startlba, Toffset) < 0) recover(edit); } return i; @@ -1034,19 +1042,31 @@ p = (Dospart*)edit->part[i]; if(p->primary){ - *endlba = (vlong)p->start*sec2cyl; + *endlba = startlba; goto Finish; } disk = edit->disk; - diskread(disk, &table, Tablesize, mbroffset+startlba, Toffset); + diskread(disk, &table, Tablesize, startlba, Toffset); tp = table.entry; ep = tp+NTentry; - ni = wrextend(edit, i+1, xbase, p->end*sec2cyl, 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->end*sec2cyl); + wrtentry(disk, tp, p->type, startlba, p->ctlstart, p->ctlend); tp++; if(p->end*sec2cyl != *endlba){ @@ -1061,7 +1081,7 @@ table.magic[0] = Magic0; table.magic[1] = Magic1; - if(diskwrite(edit->disk, &table, Tablesize, mbroffset+startlba, Toffset) < 0) + if(diskwrite(edit->disk, &table, Tablesize, startlba, Toffset) < 0) recover(edit); return ni; } @@ -1069,38 +1089,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, Tablesize, mbroffset, Toffset); + diskread(disk, &table, Tablesize, 0, Toffset); tp = table.entry; ep = tp+NTentry; for(i=0; inpart && tppart[i]; - if(p->start == 0) - s = disk->s; - else - s = p->start*sec2cyl; if(p->primary) { *tp = p->Tentry; - wrtentry(disk, tp, p->type, 0, s, p->end*sec2cyl); + wrtentry(disk, tp, p->type, 0, p->ctlstart, p->ctlend); tp++; i++; } else { - ni = wrextend(edit, i, p->start*sec2cyl, p->start*sec2cyl, &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; } @@ -1111,7 +1123,7 @@ if(i != edit->npart) sysfatal("cannot happen #1"); - if(diskwrite(disk, &table, Tablesize, mbroffset, Toffset) < 0) + if(diskwrite(disk, &table, Tablesize, 0, Toffset) < 0) recover(edit); /* bring parts up to date */