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
This commit is contained in:
Andrey V. Elsukov 2011-09-08 04:14:16 +00:00
parent fc4de9b7fc
commit 6a0a87741b
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=225445

View File

@ -308,7 +308,7 @@ gpart_autofill_resize(struct gctl_req *req)
off_t last, size, start, new_size; off_t last, size, start, new_size;
off_t lba, new_lba, alignment, offset; off_t lba, new_lba, alignment, offset;
const char *s; const char *s;
int error, idx; int error, idx, has_alignment;
idx = (int)gctl_get_intmax(req, GPART_PARAM_INDEX); idx = (int)gctl_get_intmax(req, GPART_PARAM_INDEX);
if (idx < 1) if (idx < 1)
@ -334,8 +334,9 @@ gpart_autofill_resize(struct gctl_req *req)
errx(EXIT_FAILURE, "Provider for geom %s not found.", s); errx(EXIT_FAILURE, "Provider for geom %s not found.", s);
s = gctl_get_ascii(req, "alignment"); s = gctl_get_ascii(req, "alignment");
has_alignment = (*s == '*') ? 0 : 1;
alignment = 1; alignment = 1;
if (*s != '*') { if (has_alignment) {
error = g_parse_lba(s, pp->lg_sectorsize, &alignment); error = g_parse_lba(s, pp->lg_sectorsize, &alignment);
if (error) if (error)
errc(EXIT_FAILURE, error, "Invalid alignment param"); errc(EXIT_FAILURE, error, "Invalid alignment param");
@ -358,7 +359,7 @@ gpart_autofill_resize(struct gctl_req *req)
if (error) if (error)
errc(EXIT_FAILURE, error, "Invalid size param"); errc(EXIT_FAILURE, error, "Invalid size param");
/* no autofill necessary. */ /* no autofill necessary. */
if (alignment == 1) if (has_alignment == 0)
goto done; goto done;
} }
@ -380,7 +381,8 @@ gpart_autofill_resize(struct gctl_req *req)
lba = (off_t)strtoimax(s, NULL, 0); lba = (off_t)strtoimax(s, NULL, 0);
size = lba - start + 1; 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 /* The start offset may be not aligned, so we align the end
* offset and then calculate the size. * offset and then calculate the size.
*/ */
@ -388,8 +390,6 @@ gpart_autofill_resize(struct gctl_req *req)
alignment) - start - offset; alignment) - start - offset;
goto done; goto done;
} }
pp = find_provider(gp, lba + 1);
if (pp == NULL) { if (pp == NULL) {
new_size = ALIGNDOWN(last + offset + 1, alignment) - new_size = ALIGNDOWN(last + offset + 1, alignment) -
start - offset; start - offset;