summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorae <ae@FreeBSD.org>2011-09-08 04:14:16 +0000
committerae <ae@FreeBSD.org>2011-09-08 04:14:16 +0000
commit3f2d6e22bf0098f8f5abd77b7d5d13f5d6d9606b (patch)
tree24ce23462b5024bc481a59cca4ac09d635baac24
parentb64fa0490d80fdf799dfb862922a20fb1540bc37 (diff)
downloadFreeBSD-src-3f2d6e22bf0098f8f5abd77b7d5d13f5d6d9606b.zip
FreeBSD-src-3f2d6e22bf0098f8f5abd77b7d5d13f5d6d9606b.tar.gz
Don't use the whole free space when resizing partition to a larger size
on a disk with non zero stripesize (e.g. disks with 4k sector size)[1]. Also do not use automatic alignment when size is exactly specified, but an alignment is not. Use automatic alignment only for case when user omits both "-s" and "-a" options. Reported by: Mikael Fridh <frimik at gmail> [1] Approved by: re (kib) MFC after: 1 week
-rw-r--r--sbin/geom/class/part/geom_part.c12
1 files changed, 6 insertions, 6 deletions
diff --git a/sbin/geom/class/part/geom_part.c b/sbin/geom/class/part/geom_part.c
index a456911..8db0773 100644
--- a/sbin/geom/class/part/geom_part.c
+++ b/sbin/geom/class/part/geom_part.c
@@ -308,7 +308,7 @@ gpart_autofill_resize(struct gctl_req *req)
off_t last, size, start, new_size;
off_t lba, new_lba, alignment, offset;
const char *s;
- int error, idx;
+ int error, idx, has_alignment;
idx = (int)gctl_get_intmax(req, GPART_PARAM_INDEX);
if (idx < 1)
@@ -334,8 +334,9 @@ gpart_autofill_resize(struct gctl_req *req)
errx(EXIT_FAILURE, "Provider for geom %s not found.", s);
s = gctl_get_ascii(req, "alignment");
+ has_alignment = (*s == '*') ? 0 : 1;
alignment = 1;
- if (*s != '*') {
+ if (has_alignment) {
error = g_parse_lba(s, pp->lg_sectorsize, &alignment);
if (error)
errc(EXIT_FAILURE, error, "Invalid alignment param");
@@ -358,7 +359,7 @@ gpart_autofill_resize(struct gctl_req *req)
if (error)
errc(EXIT_FAILURE, error, "Invalid size param");
/* no autofill necessary. */
- if (alignment == 1)
+ if (has_alignment == 0)
goto done;
}
@@ -380,7 +381,8 @@ gpart_autofill_resize(struct gctl_req *req)
lba = (off_t)strtoimax(s, NULL, 0);
size = lba - start + 1;
- if (new_size > 0 && new_size <= size) {
+ pp = find_provider(gp, lba + 1);
+ if (new_size > 0 && (new_size <= size || pp == NULL)) {
/* The start offset may be not aligned, so we align the end
* offset and then calculate the size.
*/
@@ -388,8 +390,6 @@ gpart_autofill_resize(struct gctl_req *req)
alignment) - start - offset;
goto done;
}
-
- pp = find_provider(gp, lba + 1);
if (pp == NULL) {
new_size = ALIGNDOWN(last + offset + 1, alignment) -
start - offset;
OpenPOWER on IntegriCloud