diff options
author | phk <phk@FreeBSD.org> | 2004-11-28 20:57:25 +0000 |
---|---|---|
committer | phk <phk@FreeBSD.org> | 2004-11-28 20:57:25 +0000 |
commit | b760ac8e3818a6c093f90f5fb964538febfa387d (patch) | |
tree | 5101bc5f3387c4e5965140bbaebd9fcd72f5270e /sys/geom | |
parent | 13275047a7979120b77e1cc111a8983602f37bfd (diff) | |
download | FreeBSD-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.c | 18 |
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); |