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);