summaryrefslogtreecommitdiffstats
path: root/sys/geom/geom_dev.c
diff options
context:
space:
mode:
authorphk <phk@FreeBSD.org>2003-09-01 20:45:32 +0000
committerphk <phk@FreeBSD.org>2003-09-01 20:45:32 +0000
commit38290a3baa454204f887614a0b0f40532eebc605 (patch)
tree0680a0b284f441a10aeec166634f34c98f8d1389 /sys/geom/geom_dev.c
parent4e64a48fd83170feaf276dab0b984c5fc41e3896 (diff)
downloadFreeBSD-src-38290a3baa454204f887614a0b0f40532eebc605.zip
FreeBSD-src-38290a3baa454204f887614a0b0f40532eebc605.tar.gz
Simplify the ioctl handling in GEOM.
This replaces the current ioctl processing with a direct call path from geom_dev() where the ioctl arrives (from SPECFS) to any directly connected GEOM class. The inverse of the above is no longer supported. This is the situation were you have one or more intervening GEOM classes, for instance a BSDlabel on top of a MBR or PC98. If you want to issue MBR or PC98 specific ioctls, you will need to issue them on a MBR or PC98 providers. This paves the way for inviting CD's, FD's and other special cases inside GEOM.
Diffstat (limited to 'sys/geom/geom_dev.c')
-rw-r--r--sys/geom/geom_dev.c45
1 files changed, 5 insertions, 40 deletions
diff --git a/sys/geom/geom_dev.c b/sys/geom/geom_dev.c
index 470ac8d..8da252f 100644
--- a/sys/geom/geom_dev.c
+++ b/sys/geom/geom_dev.c
@@ -279,17 +279,14 @@ g_dev_ioctl(dev_t dev, u_long cmd, caddr_t data, int fflag, struct thread *td)
struct g_kerneldump kd;
int i, error;
u_int u;
- struct g_ioctl *gio;
gp = dev->si_drv1;
cp = dev->si_drv2;
- gio = NULL;
error = 0;
KASSERT(cp->acr || cp->acw,
("Consumer with zero access count in g_dev_ioctl"));
- gio = NULL;
i = IOCPARM_LEN(cmd);
switch (cmd) {
case DIOCGSECTORSIZE:
@@ -331,46 +328,14 @@ g_dev_ioctl(dev_t dev, u_long cmd, caddr_t data, int fflag, struct thread *td)
break;
default:
- gio = g_malloc(sizeof *gio, M_WAITOK | M_ZERO);
- gio->cmd = cmd;
- gio->data = data;
- gio->fflag = fflag;
- gio->td = td;
- i = sizeof *gio;
- /*
- * We always issue ioctls as getattr since the direction of data
- * movement in ioctl is no indication of the ioctl being a "set"
- * or "get" type ioctl or if such simplistic terms even apply
- */
- error = g_io_getattr("GEOM::ioctl", cp, &i, gio);
- break;
+ if (cp->provider->geom->ioctl != NULL) {
+ error = cp->provider->geom->ioctl(cp->provider, cmd, data, td);
+ if (error != ENOIOCTL)
+ return (error);
+ }
}
- if (error == EDIRIOCTL) {
- KASSERT(gio != NULL, ("NULL gio but EDIRIOCTL"));
- KASSERT(gio->func != NULL, ("NULL function but EDIRIOCTL"));
- error = (gio->func)(gio->dev, cmd, data, fflag, td);
- }
g_waitidle();
- if (gio != NULL && (error == EOPNOTSUPP || error == ENOIOCTL)) {
- if (g_debugflags & G_T_TOPOLOGY) {
- i = IOCGROUP(cmd);
- printf("IOCTL(0x%lx) \"%s\"", cmd, gp->name);
- if (i > ' ' && i <= '~')
- printf(" '%c'", (int)IOCGROUP(cmd));
- else
- printf(" 0x%lx", IOCGROUP(cmd));
- printf("/%ld ", cmd & 0xff);
- if (cmd & IOC_IN)
- printf("I");
- if (cmd & IOC_OUT)
- printf("O");
- printf("(%ld) = ENOIOCTL\n", IOCPARM_LEN(cmd));
- }
- error = ENOTTY;
- }
- if (gio != NULL)
- g_free(gio);
return (error);
}
OpenPOWER on IntegriCloud