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:
parent
b64fa0490d
commit
3f2d6e22bf
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user