summaryrefslogtreecommitdiff
path: root/sbin/disklabel/editor.c
diff options
context:
space:
mode:
authorOtto Moerbeek <otto@cvs.openbsd.org>2010-03-29 13:25:00 +0000
committerOtto Moerbeek <otto@cvs.openbsd.org>2010-03-29 13:25:00 +0000
commit64c206d4c047eaadf10c2211a82a345232185096 (patch)
tree673c26fa531b9fdc6bbe4140557864f9706b419d /sbin/disklabel/editor.c
parent511d04eae45805beb360a5505105684452db798f (diff)
Improve the way we handle spoofed paritions for Resize. Now any auto
allocated can be treated. We still check if no non-native partition overlaps the openbsd area, to avoid surprised. ok krw@ lum@
Diffstat (limited to 'sbin/disklabel/editor.c')
-rw-r--r--sbin/disklabel/editor.c62
1 files changed, 38 insertions, 24 deletions
diff --git a/sbin/disklabel/editor.c b/sbin/disklabel/editor.c
index 7f644aaacd5..8796563e9f3 100644
--- a/sbin/disklabel/editor.c
+++ b/sbin/disklabel/editor.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: editor.c,v 1.229 2010/03/25 14:35:58 sthen Exp $ */
+/* $OpenBSD: editor.c,v 1.230 2010/03/29 13:24:59 otto Exp $ */
/*
* Copyright (c) 1997-2000 Todd C. Miller <Todd.Miller@courtesan.com>
@@ -149,7 +149,7 @@ void display_edit(struct disklabel *, char, u_int64_t);
static u_int64_t starting_sector;
static u_int64_t ending_sector;
static int expert;
-static int spoofed;
+static int overlap;
/*
* Simple partition editor.
@@ -372,12 +372,11 @@ editor(struct disklabel *lp, int f)
break;
case 'R':
- if (aflag && !spoofed)
+ if (aflag && !overlap)
editor_resize(&label, arg);
else
fputs("Resize only implemented for auto "
- "allocated labels without spoofed "
- "partitions\n", stderr);
+ "allocated labels\n", stderr);
break;
case 'r': {
@@ -523,16 +522,27 @@ editor_allocspace(struct disklabel *lp_org)
int i, j, lastalloc, index = 0, fragsize;
int64_t physmem;
- spoofed = 0;
- for (i = 0; i < MAXPARTITIONS; i++)
- if (i != RAW_PART && DL_GETPSIZE(&lp_org->d_partitions[i]) != 0)
- spoofed = 1;
-
- physmem = getphysmem() / lp_org->d_secsize;
-
/* How big is the OpenBSD portion of the disk? */
find_bounds(lp_org);
+ overlap = 0;
+ for (i = 0; i < MAXPARTITIONS; i++) {
+ daddr64_t psz, pstart, pend;
+
+ pp = &lp_org->d_partitions[i];
+ psz = DL_GETPSIZE(pp);
+ pstart = DL_GETPOFFSET(pp);
+ pend = pstart + psz;
+ if (i != RAW_PART && psz != 0 &&
+ ((pstart >= starting_sector && pstart <= ending_sector) ||
+ (pend > starting_sector && pend < ending_sector))) {
+ overlap = 1;
+ break;
+ }
+ }
+
+ physmem = getphysmem() / lp_org->d_secsize;
+
cylsecs = lp_org->d_secpercyl;
again:
lp = &label;
@@ -701,11 +711,19 @@ editor_resize(struct disklabel *lp, char *p)
}
pp = &label.d_partitions[partno];
- sz = editor_countfree(lp);
+ sz = DL_GETPSIZE(pp);
+ if (sz == 0) {
+ fputs("No such partition\n", stderr);
+ return;
+ }
+ if (pp->p_fstype != FS_BSDFFS && pp->p_fstype != FS_SWAP) {
+ fputs("Cannot resize spoofed partition\n", stderr);
+ return;
+ }
secs = getuint(lp, "resize", "amount to grow (+) or shrink (-)",
- 0, sz, 0, DO_CONVERSIONS);
+ 0, editor_countfree(lp), 0, DO_CONVERSIONS);
- if (secs == 0) {
+ if (secs == 0 || secs == -1) {
fputs("Command aborted\n", stderr);
return;
}
@@ -717,12 +735,6 @@ editor_resize(struct disklabel *lp, char *p)
else
secs = ((secs - cylsecs + 1) / cylsecs) * cylsecs;
#endif
-
- sz = DL_GETPSIZE(pp);
- if (sz == 0) {
- fputs("No such partition\n", stderr);
- return;
- }
if (DL_GETPOFFSET(pp) + sz + secs > ending_sector) {
fputs("Amount too big\n", stderr);
return;
@@ -742,11 +754,13 @@ editor_resize(struct disklabel *lp, char *p)
for (i = partno + 1; i < MAXPARTITIONS; i++) {
if (i == RAW_PART)
continue;
- sz = DL_GETPSIZE(&label.d_partitions[i]);
+ pp = &label.d_partitions[i];
+ if (pp->p_fstype != FS_BSDFFS && pp->p_fstype != FS_SWAP)
+ continue;
+ sz = DL_GETPSIZE(pp);
if (sz == 0)
continue;
- pp = &label.d_partitions[i];
off = DL_GETPOFFSET(prev) + DL_GETPSIZE(prev);
if (off < ending_sector) {
@@ -1820,7 +1834,7 @@ editor_help(char *arg)
puts(
"Resize a a partition, compacting unused space between partitions\n"
"with a higher offset. The last partition will be shrunk if needed.\n"
-"Works only for auto allocated labels with no spoofed partitions\n");
+"Works only for auto allocated labels.\n");
break;
case 'r':
puts(