On Saturday 26 July 2014 17:38:06 Fung wrote: > http://www.openbsd.org/faq/faq4.html#Morefdisk > > uh-oh! What's our offset? Simple -- the offset of the previous partition > plus the size of the partition, in this case, 63+10490382 = 10490445. > > offset: [0] 10490445 > size: [0] * > fdisk:*1> > > in this situation, default offset = 0 , may this fuction change to auto > caculate the default to 10490445 ? just like > offset: [10490445]
Yes, it can. Bitrig already does it, so find the patch below. I had it in my tree for some time and already tested it on amd64. Best regards, Markus Index: cmd.c =================================================================== RCS file: /cvs/src/sbin/fdisk/cmd.c,v retrieving revision 1.71 diff -u -p -u -r1.71 cmd.c --- cmd.c 31 Mar 2014 23:04:03 -0000 1.71 +++ cmd.c 26 Jul 2014 17:49:05 -0000 @@ -141,7 +141,7 @@ Xedit(char *args, struct disk *disk, str int offset) { const char *errstr; - int pn, num, ret; + int pn, num, ret, new; struct prt *pp; pn = strtonum(args, 0, 3, &errstr); @@ -151,6 +151,8 @@ Xedit(char *args, struct disk *disk, str } pp = &mbr->part[pn]; + new = (pp->id == DOSPTYP_UNUSED); + /* Edit partition type */ ret = Xsetpid(args, disk, mbr, tt, offset); @@ -165,6 +167,10 @@ Xedit(char *args, struct disk *disk, str printf("Partition %d is disabled.\n", pn); return (ret); } + + /* Use remaining free space for new partitions */ + if (new) + MBR_fillremaining(mbr, disk, pn); /* Change table entry */ if (ask_yn("Do you wish to edit in CHS mode?")) { Index: mbr.c =================================================================== RCS file: /cvs/src/sbin/fdisk/mbr.c,v retrieving revision 1.40 diff -u -p -u -r1.40 mbr.c --- mbr.c 21 May 2014 15:55:19 -0000 1.40 +++ mbr.c 26 Jul 2014 17:49:05 -0000 @@ -57,54 +57,16 @@ MBR_init(struct disk *disk, struct mbr * mbr->part[2].flag = 0; mbr->part[3].flag = DOSACTIVE; - mbr->signature = DOSMBR_SIGNATURE; - - /* Use whole disk. Reserve first track, or first cyl, if possible. */ mbr->part[3].id = DOSPTYP_OPENBSD; - if (disk->heads > 1) - mbr->part[3].shead = 1; - else - mbr->part[3].shead = 0; - if (disk->heads < 2 && disk->cylinders > 1) - mbr->part[3].scyl = 1; - else - mbr->part[3].scyl = 0; - mbr->part[3].ssect = 1; - - /* Go right to the end */ - mbr->part[3].ecyl = disk->cylinders - 1; - mbr->part[3].ehead = disk->heads - 1; - mbr->part[3].esect = disk->sectors; - - /* Fix up start/length fields */ - PRT_fix_BN(disk, &mbr->part[3], 3); + mbr->signature = DOSMBR_SIGNATURE; #if defined(__powerpc__) || defined(__mips__) /* Now fix up for the MS-DOS boot partition on PowerPC. */ mbr->part[0].flag = DOSACTIVE; /* Boot from dos part */ mbr->part[3].flag = 0; - mbr->part[3].ns += mbr->part[3].bs; - mbr->part[3].bs = mbr->part[0].bs + mbr->part[0].ns; - mbr->part[3].ns -= mbr->part[3].bs; - PRT_fix_CHS(disk, &mbr->part[3]); - if ((mbr->part[3].shead != 1) || (mbr->part[3].ssect != 1)) { - /* align the partition on a cylinder boundary */ - mbr->part[3].shead = 0; - mbr->part[3].ssect = 1; - mbr->part[3].scyl += 1; - } - /* Fix up start/length fields */ - PRT_fix_BN(disk, &mbr->part[3], 3); #endif - /* Start OpenBSD MBR partition on a power of 2 block number. */ - i = 1; - while (i < DL_SECTOBLK(&dl, mbr->part[3].bs)) - i *= 2; - adj = DL_BLKTOSEC(&dl, i) - mbr->part[3].bs; - mbr->part[3].bs += adj; - mbr->part[3].ns -= adj; - PRT_fix_CHS(disk, &mbr->part[3]); + MBR_fillremaining(mbr, disk, 3); } void @@ -257,4 +219,68 @@ MBR_pcopy(struct disk *disk, struct mbr for (i = 0; i < NDOSPART; i++) PRT_parse(disk, &dos_parts[i], 0, 0, &mbr->part[i]); +} + +void +MBR_fillremaining(struct mbr *mbr, struct disk *disk, int pn) +{ + struct prt *part, *p; + u_int64_t adj; + daddr_t i; + + part = &mbr->part[pn]; + + /* Use whole disk. Reserve first track, or first cyl, if possible. */ + if (disk->heads > 1) + part->shead = 1; + else + part->shead = 0; + if (disk->heads < 2 && disk->cylinders > 1) + part->scyl = 1; + else + part->scyl = 0; + part->ssect = 1; + + /* Go right to the end */ + part->ecyl = disk->cylinders - 1; + part->ehead = disk->heads - 1; + part->esect = disk->sectors; + + /* Fix up start/length fields */ + PRT_fix_BN(disk, part, pn); + +#if defined(__powerpc__) || defined(__mips__) + if ((part->shead != 1) || (part->ssect != 1)) { + /* align the partition on a cylinder boundary */ + part->shead = 0; + part->ssect = 1; + part->scyl += 1; + } + /* Fix up start/length fields */ + PRT_fix_BN(disk, part, pn); +#endif + + /* Start OpenBSD MBR partition on a power of 2 block number. */ + i = 1; + while (i < DL_SECTOBLK(&dl, part->bs)) + i *= 2; + adj = DL_BLKTOSEC(&dl, i) - part->bs; + part->bs += adj; + part->ns -= adj; + PRT_fix_CHS(disk, part); + + /* Shrink to remaining free space */ + for (i = 0; i < NDOSPART; i++) { + p = &mbr->part[i]; + if (i != pn && PRT_overlap(part, p)) { + if (p->bs > part->bs) { + part->ns = p->bs - part->bs; + } else { + part->ns += part->bs; + part->bs = p->bs + p->ns; + part->ns -= part->bs; + } + } + } + PRT_fix_CHS(disk, part); } Index: mbr.h =================================================================== RCS file: /cvs/src/sbin/fdisk/mbr.h,v retrieving revision 1.17 diff -u -p -u -r1.17 mbr.h --- mbr.h 23 Mar 2014 13:56:24 -0000 1.17 +++ mbr.h 26 Jul 2014 17:49:05 -0000 @@ -44,5 +44,6 @@ void MBR_init(struct disk *, struct mbr int MBR_read(int, off_t, struct dos_mbr *); int MBR_write(int, off_t, struct dos_mbr *); void MBR_pcopy(struct disk *, struct mbr *); +void MBR_fillremaining(struct mbr *, struct disk *, int); #endif /* _MBR_H */ Index: part.c =================================================================== RCS file: /cvs/src/sbin/fdisk/part.c,v retrieving revision 1.66 diff -u -p -u -r1.66 part.c --- part.c 5 May 2014 17:18:08 -0000 1.66 +++ part.c 26 Jul 2014 17:49:05 -0000 @@ -303,6 +303,12 @@ PRT_print(int num, struct prt *partn, ch } } +int +PRT_overlap(struct prt *p1, struct prt *p2) +{ + return (p1->bs + p1->ns > p2->bs && p2->bs + p2->ns > p1->bs); +} + void PRT_fix_BN(struct disk *disk, struct prt *part, int pn) { Index: part.h =================================================================== RCS file: /cvs/src/sbin/fdisk/part.h,v retrieving revision 1.16 diff -u -p -u -r1.16 part.h --- part.h 25 Mar 2014 12:59:03 -0000 1.16 +++ part.h 26 Jul 2014 17:49:05 -0000 @@ -43,6 +43,7 @@ void PRT_parse(struct disk *, struct dos struct prt *); void PRT_make(struct prt *, off_t, off_t, struct dos_partition *); void PRT_print(int, struct prt *, char *); +int PRT_overlap(struct prt *, struct prt *); /* This does CHS -> bs/ns */ void PRT_fix_BN(struct disk *, struct prt *, int);