diff options
author | phk <phk@FreeBSD.org> | 2003-09-01 20:45:32 +0000 |
---|---|---|
committer | phk <phk@FreeBSD.org> | 2003-09-01 20:45:32 +0000 |
commit | 38290a3baa454204f887614a0b0f40532eebc605 (patch) | |
tree | 0680a0b284f441a10aeec166634f34c98f8d1389 /sys/geom/geom_disk.c | |
parent | 4e64a48fd83170feaf276dab0b984c5fc41e3896 (diff) | |
download | FreeBSD-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_disk.c')
-rw-r--r-- | sys/geom/geom_disk.c | 30 |
1 files changed, 20 insertions, 10 deletions
diff --git a/sys/geom/geom_disk.c b/sys/geom/geom_disk.c index 43c8614..5746415 100644 --- a/sys/geom/geom_disk.c +++ b/sys/geom/geom_disk.c @@ -194,12 +194,29 @@ g_disk_done(struct bio *bp) mtx_unlock(&g_disk_done_mtx); } +static int +g_disk_ioctl(struct g_provider *pp, u_long cmd, void * data, struct thread *td) +{ + struct g_geom *gp; + struct disk *dp; + int error; + + gp = pp->geom; + dp = gp->softc; + + if (dp->d_ioctl == NULL) + return (ENOIOCTL); + g_disk_lock_giant(dp); + error = dp->d_ioctl(dp, cmd, data, 0, td); + g_disk_unlock_giant(dp); + return(error); +} + static void g_disk_start(struct bio *bp) { struct bio *bp2, *bp3; struct disk *dp; - struct g_ioctl *gio; int error; off_t off; @@ -264,15 +281,7 @@ g_disk_start(struct bio *bp) break; else if (!strcmp(bp->bio_attribute, "GEOM::kerneldump")) g_disk_kerneldump(bp, dp); - else if ((g_debugflags & G_F_DISKIOCTL) && - (dp->d_ioctl != NULL) && - !strcmp(bp->bio_attribute, "GEOM::ioctl") && - bp->bio_length == sizeof *gio) { - gio = (struct g_ioctl *)bp->bio_data; - gio->dev = dp; - gio->func = (d_ioctl_t *)(dp->d_ioctl); - error = EDIRIOCTL; - } else + else error = ENOIOCTL; break; default: @@ -317,6 +326,7 @@ g_disk_create(void *arg, int flag) gp = g_new_geomf(&g_disk_class, "%s%d", dp->d_name, dp->d_unit); gp->start = g_disk_start; gp->access = g_disk_access; + gp->ioctl = g_disk_ioctl; gp->softc = dp; gp->dumpconf = g_disk_dumpconf; pp = g_new_providerf(gp, "%s", gp->name); |