From 5cb036f6e3167f3e8367e1c2256b3821dc226c51 Mon Sep 17 00:00:00 2001 From: yamt Date: Sat, 20 Aug 2005 12:03:52 +0000 Subject: [PATCH] add wedge support to xbd and cgd. --- sys/arch/xen/xen/xbd.c | 21 ++++++++--- sys/dev/cgd.c | 22 ++++++++--- sys/dev/dksubr.c | 86 +++++++++++++++++++++++++++++++++--------- sys/dev/dkvar.h | 3 +- 4 files changed, 101 insertions(+), 31 deletions(-) diff --git a/sys/arch/xen/xen/xbd.c b/sys/arch/xen/xen/xbd.c index 16cecbd737aa..3e2ae5a15ff2 100644 --- a/sys/arch/xen/xen/xbd.c +++ b/sys/arch/xen/xen/xbd.c @@ -1,4 +1,4 @@ -/* $NetBSD: xbd.c,v 1.20 2005/04/17 22:59:37 bouyer Exp $ */ +/* $NetBSD: xbd.c,v 1.21 2005/08/20 12:03:52 yamt Exp $ */ /* * @@ -33,7 +33,7 @@ #include -__KERNEL_RCSID(0, "$NetBSD: xbd.c,v 1.20 2005/04/17 22:59:37 bouyer Exp $"); +__KERNEL_RCSID(0, "$NetBSD: xbd.c,v 1.21 2005/08/20 12:03:52 yamt Exp $"); #include "xbd.h" #include "rnd.h" @@ -182,6 +182,10 @@ static dev_t xbd_cd_major; static dev_t xbd_cd_cdev_major; #endif +static struct dkdriver xbddkdriver = { + .d_strategy = xbdstrategy, + .d_minphys = minphys, +}; static int xbdstart(struct dk_softc *, struct buf *); static int xbd_response_handler(void *); @@ -1020,6 +1024,7 @@ xbd_attach(struct device *parent, struct device *self, void *aux) simple_lock_init(&xs->sc_slock); dk_sc_init(&xs->sc_dksc, xs, xs->sc_dev.dv_xname); + xs->sc_dksc.sc_dkdev.dk_driver = &xbddkdriver; xbdinit(xs, xbda->xa_xd, xbda->xa_dkintf); #if NRND > 0 @@ -1054,6 +1059,9 @@ xbd_detach(struct device *dv, int flags) vdevgone(cmaj, mn, mn, VCHR); } + /* Delete all of our wedges. */ + dkwedge_delall(&xs->sc_dksc.sc_dkdev); + #if 0 s = splbio(); /* Kill off any queued buffers. */ @@ -1527,14 +1535,13 @@ xbdioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) struct xbd_softc *xs; struct dk_softc *dksc; int ret; + struct disk *dk; DPRINTF_FOLLOW(("xbdioctl(%d, %08lx, %p, %d, %p)\n", dev, cmd, data, flag, p)); GETXBD_SOFTC(xs, dev); dksc = &xs->sc_dksc; - - if ((ret = lockmgr(&dksc->sc_lock, LK_EXCLUSIVE, NULL)) != 0) - return ret; + dk = &dksc->sc_dkdev; switch (cmd) { default: @@ -1542,7 +1549,6 @@ xbdioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) break; } - lockmgr(&dksc->sc_lock, LK_RELEASE, NULL); return ret; } @@ -1623,6 +1629,9 @@ xbdinit(struct xbd_softc *xs, vdisk_t *xd, struct dk_intf *dkintf) pdg->pdg_secsize); printf(" %s\n", buf); + /* Discover wedges on this disk. */ + dkwedge_discover(&xs->sc_dksc.sc_dkdev); + /* out: */ return ret; } diff --git a/sys/dev/cgd.c b/sys/dev/cgd.c index 52734d05fb68..f9fc25461d16 100644 --- a/sys/dev/cgd.c +++ b/sys/dev/cgd.c @@ -1,4 +1,4 @@ -/* $NetBSD: cgd.c,v 1.28 2005/08/20 12:01:04 yamt Exp $ */ +/* $NetBSD: cgd.c,v 1.29 2005/08/20 12:03:52 yamt Exp $ */ /*- * Copyright (c) 2002 The NetBSD Foundation, Inc. @@ -37,7 +37,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: cgd.c,v 1.28 2005/08/20 12:01:04 yamt Exp $"); +__KERNEL_RCSID(0, "$NetBSD: cgd.c,v 1.29 2005/08/20 12:03:52 yamt Exp $"); #include #include @@ -107,6 +107,11 @@ static struct dk_intf the_dkintf = { }; static struct dk_intf *di = &the_dkintf; +static struct dkdriver cgddkdriver = { + .d_strategy = cgdstrategy, + .d_minphys = minphys, +}; + /* DIAGNOSTIC and DEBUG definitions */ #if defined(CGDDEBUG) && !defined(DEBUG) @@ -172,6 +177,7 @@ cgdsoftc_init(struct cgd_softc *cs, int num) snprintf(sbuf, DK_XNAME_SIZE, "cgd%d", num); simple_lock_init(&cs->sc_slock); dk_sc_init(&cs->sc_dksc, cs, sbuf); + cs->sc_dksc.sc_dkdev.dk_driver = &cgddkdriver; pseudo_disk_init(&cs->sc_dksc.sc_dkdev); } @@ -443,6 +449,7 @@ cgdioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) { struct cgd_softc *cs; struct dk_softc *dksc; + struct disk *dk; int ret; int part = DISKPART(dev); int pmask = 1 << part; @@ -451,6 +458,7 @@ cgdioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) dev, cmd, data, flag, p)); GETCGD_SOFTC(cs, dev); dksc = &cs->sc_dksc; + dk = &dksc->sc_dkdev; switch (cmd) { case CGDIOCSET: case CGDIOCCLR: @@ -458,9 +466,6 @@ cgdioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) return EBADF; } - if ((ret = lockmgr(&dksc->sc_lock, LK_EXCLUSIVE, NULL)) != 0) - return ret; - switch (cmd) { case CGDIOCSET: if (dksc->sc_flags & DKF_INITED) @@ -484,7 +489,6 @@ cgdioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) break; } - lockmgr(&dksc->sc_lock, LK_RELEASE, NULL); return ret; } @@ -577,6 +581,9 @@ cgd_ioctl_set(struct cgd_softc *cs, void *data, struct proc *p) /* Try and read the disklabel. */ dk_getdisklabel(di, &cs->sc_dksc, 0 /* XXX ? */); + /* Discover wedges on this disk. */ + dkwedge_discover(&cs->sc_dksc.sc_dkdev); + return 0; bail: @@ -590,6 +597,9 @@ cgd_ioctl_clr(struct cgd_softc *cs, void *data, struct proc *p) { int s; + /* Delete all of our wedges. */ + dkwedge_delall(&cs->sc_dksc.sc_dkdev); + /* Kill off any queued buffers. */ s = splbio(); bufq_drain(&cs->sc_dksc.sc_bufq); diff --git a/sys/dev/dksubr.c b/sys/dev/dksubr.c index cc7905b01cb1..732169124039 100644 --- a/sys/dev/dksubr.c +++ b/sys/dev/dksubr.c @@ -1,4 +1,4 @@ -/* $NetBSD: dksubr.c,v 1.15 2005/06/28 20:23:02 drochner Exp $ */ +/* $NetBSD: dksubr.c,v 1.16 2005/08/20 12:03:52 yamt Exp $ */ /*- * Copyright (c) 1996, 1997, 1998, 1999, 2002 The NetBSD Foundation, Inc. @@ -37,7 +37,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: dksubr.c,v 1.15 2005/06/28 20:23:02 drochner Exp $"); +__KERNEL_RCSID(0, "$NetBSD: dksubr.c,v 1.16 2005/08/20 12:03:52 yamt Exp $"); #include #include @@ -84,7 +84,6 @@ dk_sc_init(struct dk_softc *dksc, void *osc, char *xname) dksc->sc_osc = osc; strncpy(dksc->sc_xname, xname, DK_XNAME_SIZE); dksc->sc_dkdev.dk_name = dksc->sc_xname; - lockinit(&dksc->sc_lock, PRIBIO, "dklk", 0, 0); } /* ARGSUSED */ @@ -96,22 +95,37 @@ dk_open(struct dk_intf *di, struct dk_softc *dksc, dev_t dev, int part = DISKPART(dev); int pmask = 1 << part; int ret = 0; + struct disk *dk = &dksc->sc_dkdev; DPRINTF_FOLLOW(("dk_open(%s, %p, 0x%x, 0x%x)\n", di->di_dkname, dksc, dev, flags)); - if ((ret = lockmgr(&dksc->sc_lock, LK_EXCLUSIVE, NULL)) != 0) + if ((ret = lockmgr(&dk->dk_openlock, LK_EXCLUSIVE, NULL)) != 0) return ret; part = DISKPART(dev); + + /* + * If there are wedges, and this is not RAW_PART, then we + * need to fail. + */ + if (dk->dk_nwedges != 0 && part != RAW_PART) { + ret = EBUSY; + goto done; + } + pmask = 1 << part; /* * If we're init'ed and there are no other open partitions then * update the in-core disklabel. */ - if ((dksc->sc_flags & DKF_INITED) && dksc->sc_dkdev.dk_openmask == 0) - dk_getdisklabel(di, dksc, dev); + if ((dksc->sc_flags & DKF_INITED)) { + if (dk->dk_openmask == 0) { + dk_getdisklabel(di, dksc, dev); + } + /* XXX re-discover wedges? */ + } /* Fail if we can't find the partition. */ if ((part != RAW_PART) && @@ -125,18 +139,17 @@ dk_open(struct dk_intf *di, struct dk_softc *dksc, dev_t dev, /* Mark our unit as open. */ switch (fmt) { case S_IFCHR: - dksc->sc_dkdev.dk_copenmask |= pmask; + dk->dk_copenmask |= pmask; break; case S_IFBLK: - dksc->sc_dkdev.dk_bopenmask |= pmask; + dk->dk_bopenmask |= pmask; break; } - dksc->sc_dkdev.dk_openmask = - dksc->sc_dkdev.dk_copenmask | dksc->sc_dkdev.dk_bopenmask; + dk->dk_openmask = dk->dk_copenmask | dk->dk_bopenmask; done: - lockmgr(&dksc->sc_lock, LK_RELEASE, NULL); + lockmgr(&dk->dk_openlock, LK_RELEASE, NULL); return ret; } @@ -148,25 +161,25 @@ dk_close(struct dk_intf *di, struct dk_softc *dksc, dev_t dev, int part = DISKPART(dev); int pmask = 1 << part; int ret; + struct disk *dk = &dksc->sc_dkdev; DPRINTF_FOLLOW(("dk_close(%s, %p, 0x%x, 0x%x)\n", di->di_dkname, dksc, dev, flags)); - if ((ret = lockmgr(&dksc->sc_lock, LK_EXCLUSIVE, NULL)) != 0) + if ((ret = lockmgr(&dk->dk_openlock, LK_EXCLUSIVE, NULL)) != 0) return ret; switch (fmt) { case S_IFCHR: - dksc->sc_dkdev.dk_copenmask &= ~pmask; + dk->dk_copenmask &= ~pmask; break; case S_IFBLK: - dksc->sc_dkdev.dk_bopenmask &= ~pmask; + dk->dk_bopenmask &= ~pmask; break; } - dksc->sc_dkdev.dk_openmask = - dksc->sc_dkdev.dk_copenmask | dksc->sc_dkdev.dk_bopenmask; + dk->dk_openmask = dk->dk_copenmask | dk->dk_bopenmask; - lockmgr(&dksc->sc_lock, LK_RELEASE, NULL); + lockmgr(&dk->dk_openlock, LK_RELEASE, NULL); return 0; } @@ -276,6 +289,7 @@ dk_ioctl(struct dk_intf *di, struct dk_softc *dksc, dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) { struct disklabel *lp; + struct disk *dk; #ifdef __HAVE_OLD_DISKLABEL struct disklabel newlabel; #endif @@ -350,6 +364,12 @@ dk_ioctl(struct dk_intf *di, struct dk_softc *dksc, dev_t dev, #endif lp = (struct disklabel *)data; + dk = &dksc->sc_dkdev; + error = lockmgr(&dk->dk_openlock, LK_EXCLUSIVE, NULL); + if (error) { + break; + } + dksc->sc_flags |= DKF_LABELLING; error = setdisklabel(dksc->sc_dkdev.dk_label, @@ -366,6 +386,7 @@ dk_ioctl(struct dk_intf *di, struct dk_softc *dksc, dev_t dev, } dksc->sc_flags &= ~DKF_LABELLING; + error = lockmgr(&dk->dk_openlock, LK_RELEASE, NULL); break; case DIOCWLABEL: @@ -388,6 +409,37 @@ dk_ioctl(struct dk_intf *di, struct dk_softc *dksc, dev_t dev, break; #endif + case DIOCAWEDGE: + { + struct dkwedge_info *dkw = (void *)data; + + if ((flag & FWRITE) == 0) + return (EBADF); + + /* If the ioctl happens here, the parent is us. */ + strcpy(dkw->dkw_parent, dksc->sc_dkdev.dk_name); + return (dkwedge_add(dkw)); + } + + case DIOCDWEDGE: + { + struct dkwedge_info *dkw = (void *)data; + + if ((flag & FWRITE) == 0) + return (EBADF); + + /* If the ioctl happens here, the parent is us. */ + strcpy(dkw->dkw_parent, dksc->sc_dkdev.dk_name); + return (dkwedge_del(dkw)); + } + + case DIOCLWEDGES: + { + struct dkwedge_list *dkwl = (void *)data; + + return (dkwedge_list(&dksc->sc_dkdev, dkwl, p)); + } + default: error = ENOTTY; } diff --git a/sys/dev/dkvar.h b/sys/dev/dkvar.h index d678a8542875..bc24764bcec4 100644 --- a/sys/dev/dkvar.h +++ b/sys/dev/dkvar.h @@ -1,4 +1,4 @@ -/* $NetBSD: dkvar.h,v 1.6 2005/06/28 20:23:02 drochner Exp $ */ +/* $NetBSD: dkvar.h,v 1.7 2005/08/20 12:03:52 yamt Exp $ */ /*- * Copyright (c) 2002 The NetBSD Foundation, Inc. @@ -59,7 +59,6 @@ struct dk_softc { #define DK_XNAME_SIZE 8 char sc_xname[DK_XNAME_SIZE]; /* external name */ struct disk sc_dkdev; /* generic disk info */ - struct lock sc_lock; /* the lock */ struct bufq_state sc_bufq; /* buffer queue */ };