summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorbde <bde@FreeBSD.org>1995-04-30 15:16:02 +0000
committerbde <bde@FreeBSD.org>1995-04-30 15:16:02 +0000
commit04e7b380b79da3e37f2328a1924b9cfc59396967 (patch)
tree6ea1b01264ec97490abf740b23ad42d03723198d /sys
parent8467ec16eaeb1a6204277b7382fdcc1a3d1992e3 (diff)
downloadFreeBSD-src-04e7b380b79da3e37f2328a1924b9cfc59396967.zip
FreeBSD-src-04e7b380b79da3e37f2328a1924b9cfc59396967.tar.gz
Change dsioctl() interface to allow DIOCSYNCSLICEINFO to update the caller's
slice pointer and to print the device name in error messages. Finishing implementing DIOCSYNCSLICEINFO (except for locking).
Diffstat (limited to 'sys')
-rw-r--r--sys/kern/subr_diskslice.c87
1 files changed, 70 insertions, 17 deletions
diff --git a/sys/kern/subr_diskslice.c b/sys/kern/subr_diskslice.c
index ba5ae99..0362851 100644
--- a/sys/kern/subr_diskslice.c
+++ b/sys/kern/subr_diskslice.c
@@ -43,7 +43,7 @@
* from: wd.c,v 1.55 1994/10/22 01:57:12 phk Exp $
* from: @(#)ufs_disksubr.c 7.16 (Berkeley) 5/4/91
* from: ufs_disksubr.c,v 1.8 1994/06/07 01:21:39 phk Exp $
- * $Id: subr_diskslice.c,v 1.9 1995/04/24 06:04:36 bde Exp $
+ * $Id: subr_diskslice.c,v 1.10 1995/04/24 17:06:59 bde Exp $
*/
#include <sys/param.h>
@@ -272,24 +272,25 @@ dsgone(sspp)
* is subject to the same restriction as dsopen().
*/
int
-dsioctl(dev, cmd, data, flags, ssp, strat, setgeom)
+dsioctl(dname, dev, cmd, data, flags, sspp, strat, setgeom)
+ char *dname;
dev_t dev;
int cmd;
caddr_t data;
int flags;
- struct diskslices *ssp;
+ struct diskslices **sspp;
d_strategy_t *strat;
ds_setgeom_t *setgeom;
{
- u_char bopenmask;
- u_char copenmask;
int error;
struct disklabel *lp;
int old_wlabel;
int slice;
struct diskslice *sp;
+ struct diskslices *ssp;
slice = dkslice(dev);
+ ssp = *sspp;
sp = &ssp->dss_slices[slice];
lp = sp->ds_label;
switch (cmd) {
@@ -364,23 +365,75 @@ dsioctl(dev, cmd, data, flags, ssp, strat, setgeom)
case DIOCSYNCSLICEINFO:
if (slice != WHOLE_DISK_SLICE || dkpart(dev) != RAW_PART)
return (EINVAL);
- bopenmask = sp->ds_bopenmask;
- copenmask = sp->ds_copenmask;
- sp->ds_bopenmask &= ~(1 << RAW_PART);
- sp->ds_copenmask &= ~(1 << RAW_PART);
- sp->ds_openmask &= ~(1 << RAW_PART);
+ if (!*(int *)data)
+ for (slice = 0; slice < ssp->dss_nslices; slice++) {
+ u_char openmask;
+
+ openmask = ssp->dss_slices[slice].ds_openmask;
+ if (openmask
+ && (slice != WHOLE_DISK_SLICE
+ || openmask & ~(1 << RAW_PART)))
+ return (EBUSY);
+ }
+
+ /*
+ * Temporarily forget the current slices struct and read
+ * the current one.
+ * XXX should wait for current accesses on this disk to
+ * complete, then lock out future accesses and opens.
+ */
+ *sspp = NULL;
lp = malloc(sizeof *lp, M_DEVBUF, M_WAITOK);
*lp = *ssp->dss_slices[WHOLE_DISK_SLICE].ds_label;
- error = dsopen("SYNCSLICES", dev, 0, &ssp, lp, strat, setgeom);
- sp->ds_bopenmask = bopenmask;
- sp->ds_copenmask = copenmask;
- sp->ds_openmask = bopenmask | copenmask;
+ error = dsopen(dname, dev, S_IFCHR, sspp, lp, strat, setgeom);
+ if (error != 0) {
+ free(lp, M_DEVBUF);
+ *sspp = ssp;
+ return (error);
+ }
+
+ for (slice = 0; slice < ssp->dss_nslices; slice++) {
+ u_char openmask;
+ int part;
+
+ openmask = ssp->dss_slices[slice].ds_bopenmask;
+ for (part = 0; part < ssp->dss_nslices; part++) {
+ if (!(openmask & (1 << part)))
+ continue;
+ error = dsopen(dname,
+ dkmodslice(dkmodpart(dev, part),
+ slice),
+ S_IFBLK, sspp, lp, strat,
+ setgeom);
+ if (error != 0) {
+ free(lp, M_DEVBUF);
+ *sspp = ssp;
+ return (EBUSY);
+ }
+ }
+ openmask = ssp->dss_slices[slice].ds_copenmask;
+ for (part = 0; part < ssp->dss_nslices; part++) {
+ if (!(openmask & (1 << part)))
+ continue;
+ error = dsopen(dname,
+ dkmodslice(dkmodpart(dev, part),
+ slice),
+ S_IFCHR, sspp, lp, strat,
+ setgeom);
+ if (error != 0) {
+ free(lp, M_DEVBUF);
+ *sspp = ssp;
+ return (EBUSY);
+ }
+ }
+ }
free(lp, M_DEVBUF);
- return (error);
+ dsgone(&ssp);
+ return (0);
case DIOCWDINFO:
- error = dsioctl(dev, DIOCSDINFO, data, flags, ssp, strat,
- setgeom);
+ error = dsioctl(dname, dev, DIOCSDINFO, data, flags, &ssp,
+ strat, setgeom);
if (error != 0)
return (error);
/*
OpenPOWER on IntegriCloud