diff options
author | ae <ae@FreeBSD.org> | 2014-05-04 16:43:57 +0000 |
---|---|---|
committer | ae <ae@FreeBSD.org> | 2014-05-04 16:43:57 +0000 |
commit | 8488e4961e9264865a12c05eb56783746541c717 (patch) | |
tree | 12c941c0050abaa059ccdc882a417404fadbf077 | |
parent | 34465d9bbec46eb9a8e3bbea36d40d9afdd3beec (diff) | |
download | FreeBSD-src-8488e4961e9264865a12c05eb56783746541c717.zip FreeBSD-src-8488e4961e9264865a12c05eb56783746541c717.tar.gz |
Prevent an unexpected shrinking on resizing due to alignment for MBR,
PC98 and VTOC8 schemes.
Reported by: jmg
MFC after: 1 week
-rw-r--r-- | sys/geom/part/g_part_mbr.c | 7 | ||||
-rw-r--r-- | sys/geom/part/g_part_pc98.c | 7 | ||||
-rw-r--r-- | sys/geom/part/g_part_vtoc8.c | 7 |
3 files changed, 18 insertions, 3 deletions
diff --git a/sys/geom/part/g_part_mbr.c b/sys/geom/part/g_part_mbr.c index 55fc789..f9f06be 100644 --- a/sys/geom/part/g_part_mbr.c +++ b/sys/geom/part/g_part_mbr.c @@ -42,6 +42,7 @@ __FBSDID("$FreeBSD$"); #include <sys/systm.h> #include <sys/sysctl.h> #include <geom/geom.h> +#include <geom/geom_int.h> #include <geom/part/g_part.h> #include "g_part_if.h" @@ -353,7 +354,11 @@ g_part_mbr_resize(struct g_part_table *basetable, size = gpp->gpp_size; if (mbr_align(basetable, NULL, &size) != 0) return (EINVAL); - + /* XXX: prevent unexpected shrinking. */ + pp = baseentry->gpe_pp; + if ((g_debugflags & 16) == 0 && size < gpp->gpp_size && + (pp->acr > 0 || pp->acw > 0 || pp->ace > 0)) + return (EBUSY); entry = (struct g_part_mbr_entry *)baseentry; baseentry->gpe_end = baseentry->gpe_start + size - 1; entry->ent.dp_size = size; diff --git a/sys/geom/part/g_part_pc98.c b/sys/geom/part/g_part_pc98.c index 9fc6b2a..b2b6e68 100644 --- a/sys/geom/part/g_part_pc98.c +++ b/sys/geom/part/g_part_pc98.c @@ -42,6 +42,7 @@ __FBSDID("$FreeBSD$"); #include <sys/systm.h> #include <sys/sysctl.h> #include <geom/geom.h> +#include <geom/geom_int.h> #include <geom/part/g_part.h> #include "g_part_if.h" @@ -360,7 +361,11 @@ g_part_pc98_resize(struct g_part_table *basetable, size = gpp->gpp_size; if (pc98_align(basetable, NULL, &size) != 0) return (EINVAL); - + /* XXX: prevent unexpected shrinking. */ + pp = baseentry->gpe_pp; + if ((g_debugflags & 0x10) == 0 && size < gpp->gpp_size && + (pp->acr > 0 || pp->acw > 0 || pp->ace > 0)) + return (EBUSY); entry = (struct g_part_pc98_entry *)baseentry; baseentry->gpe_end = baseentry->gpe_start + size - 1; pc98_set_chs(basetable, baseentry->gpe_end, &entry->ent.dp_ecyl, diff --git a/sys/geom/part/g_part_vtoc8.c b/sys/geom/part/g_part_vtoc8.c index f40052b..04d90cb 100644 --- a/sys/geom/part/g_part_vtoc8.c +++ b/sys/geom/part/g_part_vtoc8.c @@ -42,6 +42,7 @@ __FBSDID("$FreeBSD$"); #include <sys/sysctl.h> #include <sys/vtoc.h> #include <geom/geom.h> +#include <geom/geom_int.h> #include <geom/part/g_part.h> #include "g_part_if.h" @@ -367,7 +368,11 @@ g_part_vtoc8_resize(struct g_part_table *basetable, size = gpp->gpp_size; if (vtoc8_align(table, NULL, &size) != 0) return (EINVAL); - + /* XXX: prevent unexpected shrinking. */ + pp = entry->gpe_pp; + if ((g_debugflags & 0x10) == 0 && size < gpp->gpp_size && + (pp->acr > 0 || pp->acw > 0 || pp->ace > 0)) + return (EBUSY); entry->gpe_end = entry->gpe_start + size - 1; be32enc(&table->vtoc.map[entry->gpe_index - 1].nblks, size); |