summaryrefslogtreecommitdiffstats
path: root/sys/geom
diff options
context:
space:
mode:
authorphk <phk@FreeBSD.org>2004-11-28 20:57:25 +0000
committerphk <phk@FreeBSD.org>2004-11-28 20:57:25 +0000
commitb760ac8e3818a6c093f90f5fb964538febfa387d (patch)
tree5101bc5f3387c4e5965140bbaebd9fcd72f5270e /sys/geom
parent13275047a7979120b77e1cc111a8983602f37bfd (diff)
downloadFreeBSD-src-b760ac8e3818a6c093f90f5fb964538febfa387d.zip
FreeBSD-src-b760ac8e3818a6c093f90f5fb964538febfa387d.tar.gz
Fix a long standing bug in geom_mbr which is only now exposed by the
correct open/close behaviour of filesystems: When an ioctl to modify the MBR arrives, we cannot take for granted that we have the consumer open. The symptom is that one cannot run 'boot0cfg -s2 /dev/ad0' in single-user mode because / is the only open partition in only open r1w0e1. If it is not, we attempt to increase the write count by one and decrease it again afterwards. Presumably most if not all other slices suffer from the same problem.
Diffstat (limited to 'sys/geom')
-rw-r--r--sys/geom/geom_mbr.c18
1 files changed, 14 insertions, 4 deletions
diff --git a/sys/geom/geom_mbr.c b/sys/geom/geom_mbr.c
index 3f8daef..2e19757 100644
--- a/sys/geom/geom_mbr.c
+++ b/sys/geom/geom_mbr.c
@@ -159,20 +159,30 @@ g_mbr_ioctl(struct g_provider *pp, u_long cmd, void *data, struct thread *td)
struct g_mbr_softc *ms;
struct g_slicer *gsp;
struct g_consumer *cp;
- int error;
+ int error, opened;
gp = pp->geom;
gsp = gp->softc;
ms = gsp->softc;
+ opened = 0;
+ error = 0;
switch(cmd) {
case DIOCSMBR: {
DROP_GIANT();
g_topology_lock();
- /* Validate and modify our slicer instance to match. */
- error = g_mbr_modify(gp, ms, data);
cp = LIST_FIRST(&gp->consumer);
- error = g_write_data(cp, 0, data, 512);
+ if (cp->acw == 0) {
+ error = g_access(cp, 0, 1, 0);
+ if (error == 0)
+ opened = 1;
+ }
+ if (!error)
+ error = g_mbr_modify(gp, ms, data);
+ if (!error)
+ error = g_write_data(cp, 0, data, 512);
+ if (opened)
+ g_access(cp, 0, -1 , 0);
g_topology_unlock();
PICKUP_GIANT();
return(error);
OpenPOWER on IntegriCloud