diff options
author | phk <phk@FreeBSD.org> | 2003-01-12 21:16:49 +0000 |
---|---|---|
committer | phk <phk@FreeBSD.org> | 2003-01-12 21:16:49 +0000 |
commit | b9c52945f7c6b57e5ffe6d9e3ad9eb1433a78bde (patch) | |
tree | 8a30d5399ff4847a57d6f73db94cf421c4cc1e29 /sys | |
parent | 1525f1b08ab0c9fe7371c50ae10a10fb3209f378 (diff) | |
download | FreeBSD-src-b9c52945f7c6b57e5ffe6d9e3ad9eb1433a78bde.zip FreeBSD-src-b9c52945f7c6b57e5ffe6d9e3ad9eb1433a78bde.tar.gz |
Add code to make md(4) a GEOM device driver instead of relying in
the disk mini-layer.
This is currently not enabled.
Diffstat (limited to 'sys')
-rw-r--r-- | sys/dev/md/md.c | 138 |
1 files changed, 134 insertions, 4 deletions
diff --git a/sys/dev/md/md.c b/sys/dev/md/md.c index 6f8aa78..0dc0357 100644 --- a/sys/dev/md/md.c +++ b/sys/dev/md/md.c @@ -57,6 +57,10 @@ * From: src/sys/dev/vn/vn.c,v 1.122 2000/12/16 16:06:03 */ +#ifdef notquiteyet +#include "opt_geom.h" +#endif + #include "opt_md.h" #include <sys/param.h> @@ -80,6 +84,10 @@ #include <sys/sysctl.h> #include <sys/vnode.h> +#ifndef NO_GEOM +#include <geom/geom.h> +#endif + #include <vm/vm.h> #include <vm/vm_object.h> #include <vm/vm_page.h> @@ -156,6 +164,10 @@ struct md_s { unsigned flags; char name[20]; struct proc *procp; +#ifndef NO_GEOM + struct g_geom *gp; + struct g_provider *pp; +#endif /* MD_MALLOC related fields */ struct indir *indir; @@ -336,6 +348,60 @@ s_write(struct indir *ip, off_t offset, uintptr_t ptr) return (0); } +#ifndef NO_GEOM + +struct g_class g_md_class = { + "MD", + NULL, + NULL, + G_CLASS_INITIALIZER + +}; + +static int +g_md_access(struct g_provider *pp, int r, int w, int e) +{ + struct md_s *sc; + + sc = pp->geom->softc; + r += pp->acr; + w += pp->acw; + e += pp->ace; + if ((pp->acr + pp->acw + pp->ace) == 0 && (r + w + e) > 0) { + sc->opencount = 1; + } else if ((pp->acr + pp->acw + pp->ace) > 0 && (r + w + e) == 0) { + sc->opencount = 0; + } + return (0); +} + +static void +g_md_start(struct bio *bp) +{ + struct md_s *sc; + + sc = bp->bio_to->geom->softc; + + switch(bp->bio_cmd) { + case BIO_GETATTR: + case BIO_SETATTR: + g_io_deliver(bp, EOPNOTSUPP); + return; + } + bp->bio_blkno = bp->bio_offset >> DEV_BSHIFT; + bp->bio_pblkno = bp->bio_offset / sc->secsize; + bp->bio_bcount = bp->bio_length; + /* XXX: LOCK(sc->lock) */ + bioqdisksort(&sc->bio_queue, bp); + /* XXX: UNLOCK(sc->lock) */ + + wakeup(sc); +} + +DECLARE_GEOM_CLASS(g_md_class, g_md); +#endif + +#ifdef NO_GEOM static d_strategy_t mdstrategy; static d_open_t mdopen; @@ -421,6 +487,7 @@ mdstrategy(struct bio *bp) wakeup(sc); } +#endif /* NO_GEOM */ static int mdstart_malloc(struct md_s *sc, struct bio *bp) @@ -553,10 +620,35 @@ mdstart_vnode(struct md_s *sc, struct bio *bp) return (error); } +#ifndef NO_GEOM +static void +mddone_swap(struct bio *bp) +{ + + mtx_unlock(&Giant); + bp->bio_completed = bp->bio_length - bp->bio_resid; + g_std_done(bp); + mtx_lock(&Giant); +} +#endif + static int mdstart_swap(struct md_s *sc, struct bio *bp) { +#ifndef NO_GEOM + { + struct bio *bp2; + + bp2 = g_clone_bio(bp); + bp2->bio_done = mddone_swap; + bp2->bio_blkno = bp2->bio_offset >> DEV_BSHIFT; + bp2->bio_pblkno = bp2->bio_offset / sc->secsize; + bp2->bio_bcount = bp2->bio_length; + bp = bp2; + } +#endif + bp->bio_resid = 0; if ((bp->bio_cmd == BIO_DELETE) && (sc->flags & MD_RESERVE)) biodone(bp); else @@ -612,8 +704,14 @@ md_kthread(void *arg) break; } - if (error != -1) + if (error != -1) { +#ifdef NO_GEOM biofinish(bp, &sc->stats, error); +#else /* !NO_GEOM */ + bp->bio_completed = bp->bio_length; + g_io_deliver(bp, error); + } +#endif } } @@ -672,8 +770,30 @@ mdinit(struct md_s *sc) DEVSTAT_NO_ORDERED_TAGS, DEVSTAT_TYPE_DIRECT | DEVSTAT_TYPE_IF_OTHER, DEVSTAT_PRIORITY_OTHER); +#ifdef NO_GEOM sc->dev = disk_create(sc->unit, &sc->disk, 0, &md_cdevsw, &mddisk_cdevsw); sc->dev->si_drv1 = sc; +#else /* !NO_GEOM */ + { + struct g_geom *gp; + struct g_provider *pp; + + DROP_GIANT(); + g_topology_lock(); + gp = g_new_geomf(&g_md_class, "md%d", sc->unit); + gp->start = g_md_start; + gp->access = g_md_access; + gp->softc = sc; + pp = g_new_providerf(gp, "md%d", sc->unit); + pp->mediasize = (off_t)sc->nsect * sc->secsize; + pp->sectorsize = sc->secsize; + sc->gp = gp; + sc->pp = pp; + g_error_provider(pp, 0); + g_topology_unlock(); + PICKUP_GIANT(); + } +#endif /* NO_GEOM */ } /* @@ -879,10 +999,20 @@ mddestroy(struct md_s *sc, struct thread *td) GIANT_REQUIRED; - if (sc->dev != NULL) { - devstat_remove_entry(&sc->stats); + devstat_remove_entry(&sc->stats); +#ifdef NO_GEOM + if (sc->dev != NULL) disk_destroy(sc->dev); +#else /* !NO_GEOM */ + { + if (sc->gp) { + sc->gp->flags |= G_GEOM_WITHER; + sc->gp->softc = NULL; } + if (sc->pp) + g_orphan_provider(sc->pp, ENXIO); + } +#endif sc->flags |= MD_SHUTDOWN; wakeup(sc); while (sc->procp != NULL) @@ -1155,4 +1285,4 @@ md_takeroot(void *junk) } SYSINIT(md_root, SI_SUB_MOUNT_ROOT, SI_ORDER_FIRST, md_takeroot, NULL); -#endif +#endif /* MD_ROOT */ |