From owner-freebsd-current Mon Sep 3 1:29:32 2001 Delivered-To: freebsd-current@freebsd.org Received: from ipcard.iptcom.net (ipcard.iptcom.net [212.9.224.5]) by hub.freebsd.org (Postfix) with ESMTP id E910537B403 for ; Mon, 3 Sep 2001 01:28:30 -0700 (PDT) Received: from vega.vega.com (dialup13-40.iptelecom.net.ua [212.9.229.40]) by ipcard.iptcom.net (8.9.3/8.9.3) with ESMTP id LAA65980; Mon, 3 Sep 2001 11:28:15 +0300 (EEST) (envelope-from sobomax@FreeBSD.org) Received: from FreeBSD.org (big_brother.vega.com [192.168.1.1]) by vega.vega.com (8.11.4/8.11.3) with ESMTP id f838R3o83593; Mon, 3 Sep 2001 11:27:04 +0300 (EEST) (envelope-from sobomax@FreeBSD.org) Message-ID: <3B933F20.8E93FDF9@FreeBSD.org> Date: Mon, 03 Sep 2001 11:28:16 +0300 From: Maxim Sobolev Organization: Vega International Capital X-Mailer: Mozilla 4.78 [en] (Windows NT 5.0; U) X-Accept-Language: en,uk,ru MIME-Version: 1.0 To: Poul-Henning Kamp Cc: current@FreeBSD.org Subject: Re: Junior Kernel Hacker task: Get rid of NCCD constant. References: <1932.999492571@critter> Content-Type: multipart/mixed; boundary="------------4C8CE2CD7293DF8D444DE7F1" Sender: owner-freebsd-current@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.ORG This is a multi-part message in MIME format. --------------4C8CE2CD7293DF8D444DE7F1 Content-Type: text/plain; charset=koi8-r Content-Transfer-Encoding: 7bit Poul-Henning Kamp wrote: > can you send me the patch again ? I get .rej files when I try > to apply it to -current... OOPS, sorry I forgot about -bB in my .cvsrc file - they are convinient when reading others' diffs, but apparently can do bad things when you are submitting your own diffs to someone else. Mea culpa... Attached please find regenerated diffs. -Maxim > > Poul-Henning > > In message <3B8F8194.1CC1DAE3@FreeBSD.org>, Maxim Sobolev writes: > >This is a multi-part message in MIME format. > >--------------E528F773298029521D660E0A > >Content-Type: text/plain; charset=x-user-defined > >Content-Transfer-Encoding: 7bit > > > >Poul-Henning Kamp wrote: > > > >> Assignment: > >> > >> There is no reason for the NCCD constant to exist anymore. > >> > >> The CCD driver already has cloning support but CCDs "softc" > >> structure is statically allocated for NCCD devices. > >> > >> Change the CCD driver to dynamically allocate memory as needed, > >> the MD driver can be used as example as the overall morphology > >> of the two drivers are the same. > > > >See attached patch. Due to the fact that statically allocated array was > >replaced with queue(9) list, it became big PITA to use kvm in the ccdconfig(8) > >utility, so in addition I've replaced kvm with ioctl interface, which > >simplifies things and allows to lift sugid bit from it (I bet rwatson and other > >trusted folks would like that ;) Also I've converted function prototypes into > >single style (deK&Rified them), because most of them were affected by the my > >changes anyway. > > > >I would like to hear comments and suggestions. > > > >Truly yours, > > > >Maxim "Jr. Kernel Hacker" Sobolev --------------4C8CE2CD7293DF8D444DE7F1 Content-Type: text/plain; charset=koi8-r; name="ccd.diff" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="ccd.diff" Index: sys/sys/ccdvar.h =================================================================== RCS file: /home/ncvs/src/sys/sys/ccdvar.h,v retrieving revision 1.11 diff -d -u -r1.11 ccdvar.h --- sys/sys/ccdvar.h 2000/01/16 09:25:05 1.11 +++ sys/sys/ccdvar.h 2001/09/03 08:19:24 @@ -86,19 +86,6 @@ */ /* - * A concatenated disk is described at initialization time by this structure. - */ -struct ccddevice { - int ccd_unit; /* logical unit of this ccd */ - int ccd_interleave; /* interleave (DEV_BSIZE blocks) */ - int ccd_flags; /* misc. information */ - int ccd_dk; /* disk number */ - struct vnode **ccd_vpp; /* array of component vnodes */ - char **ccd_cpp; /* array of component pathnames */ - int ccd_ndev; /* number of component devices */ -}; - -/* * This structure is used to configure a ccd via ioctl(2). */ struct ccd_ioctl { @@ -110,12 +97,6 @@ size_t ccio_size; /* (returned) size of ccd */ }; -/* ccd_flags */ -#define CCDF_SWAP 0x01 /* interleave should be dmmax */ -#define CCDF_UNIFORM 0x02 /* use LCCD of sizes for uniform interleave */ -#define CCDF_MIRROR 0x04 /* use mirroring */ -#define CCDF_PARITY 0x08 /* use parity (RAID level 5) */ - /* Mask of user-settable ccd flags. */ #define CCDF_USERMASK (CCDF_SWAP|CCDF_UNIFORM|CCDF_MIRROR|CCDF_PARITY) @@ -175,10 +156,13 @@ }; /* - * A concatenated disk is described after initialization by this structure. + * A concatenated disk is described by this structure. */ -struct ccd_softc { +struct ccd_s { + LIST_ENTRY(ccd_s) list; + int sc_unit; /* logical unit number */ + struct vnode **sc_vpp; /* array of component vnodes */ int sc_flags; /* flags */ int sc_cflags; /* configuration flags */ size_t sc_size; /* size of ccd */ @@ -195,10 +179,14 @@ }; /* sc_flags */ -#define CCDF_INITED 0x01 /* unit has been initialized */ -#define CCDF_WLABEL 0x02 /* label area is writable */ -#define CCDF_LABELLING 0x04 /* unit is currently being labelled */ -#define CCDF_WANTED 0x40 /* someone is waiting to obtain a lock */ +#define CCDF_SWAP 0x01 /* interleave should be dmmax */ +#define CCDF_UNIFORM 0x02 /* use LCCD of sizes for uniform interleave */ +#define CCDF_MIRROR 0x04 /* use mirroring */ +#define CCDF_PARITY 0x08 /* use parity (RAID level 5) */ +#define CCDF_INITED 0x10 /* unit has been initialized */ +#define CCDF_WLABEL 0x20 /* label area is writable */ +#define CCDF_LABELLING 0x40 /* unit is currently being labelled */ +#define CCDF_WANTED 0x60 /* someone is waiting to obtain a lock */ #define CCDF_LOCKED 0x80 /* unit is locked */ /* @@ -210,3 +198,15 @@ */ #define CCDIOCSET _IOWR('F', 16, struct ccd_ioctl) /* enable ccd */ #define CCDIOCCLR _IOW('F', 17, struct ccd_ioctl) /* disable ccd */ + +struct ccdconf { + int size; /* sizeof of buffer below */ + struct ccd_s *buffer; /* pointer to a configuration array */ +}; +#define CCDCONFINFO _IOWR('F', 19, struct ccdconf) /* get config */ + +struct ccdcpps { + int size; + char *buffer; +}; +#define CCDCPPINFO _IOWR('F', 20, struct ccdcpps) /* get components */ Index: sys/dev/ccd/ccd.c =================================================================== RCS file: /home/ncvs/src/sys/dev/ccd/ccd.c,v retrieving revision 1.91 diff -d -u -r1.91 ccd.c --- sys/dev/ccd/ccd.c 2001/05/08 09:10:27 1.91 +++ sys/dev/ccd/ccd.c 2001/09/03 08:19:24 @@ -87,8 +87,6 @@ * Moffett Field, CA 94035 */ -#include "ccd.h" - #include #include #include @@ -108,6 +106,8 @@ #include +MALLOC_DEFINE(M_CCD, "CCD driver", "Concatenated Disk driver"); + #if defined(CCDDEBUG) && !defined(DEBUG) #define DEBUG #endif @@ -121,7 +121,6 @@ static int ccddebug = CCDB_FOLLOW | CCDB_INIT | CCDB_IO | CCDB_LABEL | CCDB_VNODE; SYSCTL_INT(_debug, OID_AUTO, ccddebug, CTLFLAG_RW, &ccddebug, 0, ""); -#undef DEBUG #endif #define ccdunit(x) dkunit(x) @@ -157,6 +156,10 @@ #define CCDLABELDEV(dev) \ (makedev(major((dev)), dkmakeminor(ccdunit((dev)), 0, RAW_PART))) +/* convinient macros for often-used statements */ +#define IS_ALLOCATED(unit) (ccdfind(unit) != NULL) +#define IS_INITED(cs) (((cs)->sc_flags & CCDF_INITED) != 0) + static d_open_t ccdopen; static d_close_t ccdclose; static d_strategy_t ccdstrategy; @@ -183,36 +186,38 @@ /* psize */ ccdsize, /* flags */ D_DISK, }; +static LIST_HEAD(, ccd_s) ccd_softc_list = LIST_HEAD_INITIALIZER(&ccd_softc_list); + +static struct ccd_s *ccdfind(int); +static struct ccd_s *ccdnew(int); +static int ccddestroy(struct ccd_s *, struct proc *); /* called during module initialization */ -static void ccdattach __P((void)); -static int ccd_modevent __P((module_t, int, void *)); +static void ccdattach(void); +static int ccd_modevent(module_t, int, void *); /* called by biodone() at interrupt time */ -static void ccdiodone __P((struct bio *bp)); +static void ccdiodone(struct bio *bp); -static void ccdstart __P((struct ccd_softc *, struct bio *)); -static void ccdinterleave __P((struct ccd_softc *, int)); -static void ccdintr __P((struct ccd_softc *, struct bio *)); -static int ccdinit __P((struct ccddevice *, char **, struct proc *)); -static int ccdlookup __P((char *, struct proc *p, struct vnode **)); -static void ccdbuffer __P((struct ccdbuf **ret, struct ccd_softc *, - struct bio *, daddr_t, caddr_t, long)); -static void ccdgetdisklabel __P((dev_t)); -static void ccdmakedisklabel __P((struct ccd_softc *)); -static int ccdlock __P((struct ccd_softc *)); -static void ccdunlock __P((struct ccd_softc *)); +static void ccdstart(struct ccd_s *, struct bio *); +static void ccdinterleave(struct ccd_s *, int); +static void ccdintr(struct ccd_s *, struct bio *); +static int ccdinit(struct ccd_s *, char **, struct proc *); +static int ccdlookup(char *, struct proc *p, struct vnode **); +static void ccdbuffer(struct ccdbuf **ret, struct ccd_s *, + struct bio *, daddr_t, caddr_t, long); +static void ccdgetdisklabel(dev_t); +static void ccdmakedisklabel(struct ccd_s *); +static int ccdlock(struct ccd_s *); +static void ccdunlock(struct ccd_s *); #ifdef DEBUG -static void printiinfo __P((struct ccdiinfo *)); +static void printiinfo(struct ccdiinfo *); #endif /* Non-private for the benefit of libkvm. */ -struct ccd_softc *ccd_softc; -struct ccddevice *ccddevs; -struct ccdbuf *ccdfreebufs; -static int numccdfreebufs; -static int numccd = 0; +struct ccdbuf *ccdfreebufs; +static int numccdfreebufs; /* * getccdbuf() - Allocate and zero a ccd buffer. @@ -281,6 +286,47 @@ #define CCD_OFFSET 16 #endif +static struct ccd_s * +ccdfind(int unit) +{ + struct ccd_s *sc = NULL; + + /* XXX: LOCK(unique unit numbers) */ + LIST_FOREACH(sc, &ccd_softc_list, list) { + if (sc->sc_unit == unit) + break; + } + /* XXX: UNLOCK(unique unit numbers) */ + return ((sc == NULL) || (sc->sc_unit != unit) ? NULL : sc); +} + +static struct ccd_s * +ccdnew(int unit) +{ + struct ccd_s *sc; + + /* XXX: LOCK(unique unit numbers) */ + if (IS_ALLOCATED(unit) || unit > DKMAXUNIT) + return (NULL); + + MALLOC(sc, struct ccd_s *, sizeof(*sc), M_CCD, M_WAITOK | M_ZERO); + sc->sc_unit = unit; + LIST_INSERT_HEAD(&ccd_softc_list, sc, list); + /* XXX: UNLOCK(unique unit numbers) */ + return (sc); +} + +static int +ccddestroy(struct ccd_s *sc, struct proc *p) +{ + + /* XXX: LOCK(unique unit numbers) */ + LIST_REMOVE(sc, list); + /* XXX: UNLOCK(unique unit numbers) */ + FREE(sc, M_CCD); + return (0); +} + static void ccd_clone(void *arg, char *name, int namelen, dev_t *dev) { @@ -292,8 +338,6 @@ i = dev_stdclone(name, &s, "ccd", &u); if (i != 2) return; - if (u >= numccd) - return; if (*s < 'a' || *s > 'h') return; if (s[1] != '\0') @@ -304,48 +348,19 @@ /* * Called by main() during pseudo-device attachment. All we need - * to do is allocate enough space for devices to be configured later, and - * add devsw entries. + * to do is to add devsw entries. */ static void ccdattach() { - int i; - int num = NCCD; - - if (num > 1) - printf("ccd0-%d: Concatenated disk drivers\n", num-1); - else - printf("ccd0: Concatenated disk driver\n"); - - ccd_softc = (struct ccd_softc *)malloc(num * sizeof(struct ccd_softc), - M_DEVBUF, M_NOWAIT); - ccddevs = (struct ccddevice *)malloc(num * sizeof(struct ccddevice), - M_DEVBUF, M_NOWAIT); - if ((ccd_softc == NULL) || (ccddevs == NULL)) { - printf("WARNING: no memory for concatenated disks\n"); - if (ccd_softc != NULL) - free(ccd_softc, M_DEVBUF); - if (ccddevs != NULL) - free(ccddevs, M_DEVBUF); - return; - } - numccd = num; - bzero(ccd_softc, num * sizeof(struct ccd_softc)); - bzero(ccddevs, num * sizeof(struct ccddevice)); + printf("ccd0: Concatenated disk driver\n"); cdevsw_add(&ccd_cdevsw); - /* XXX: is this necessary? */ - for (i = 0; i < numccd; ++i) - ccddevs[i].ccd_dk = -1; EVENTHANDLER_REGISTER(dev_clone, ccd_clone, 0, 1000); } static int -ccd_modevent(mod, type, data) - module_t mod; - int type; - void *data; +ccd_modevent(module_t mod, int type, void *data) { int error = 0; @@ -368,12 +383,8 @@ DEV_MODULE(ccd, ccd_modevent, NULL); static int -ccdinit(ccd, cpaths, p) - struct ccddevice *ccd; - char **cpaths; - struct proc *p; +ccdinit(struct ccd_s *cs, char **cpaths, struct proc *p) { - struct ccd_softc *cs = &ccd_softc[ccd->ccd_unit]; struct ccdcinfo *ci = NULL; /* XXX */ size_t size; int ix; @@ -387,12 +398,10 @@ #ifdef DEBUG if (ccddebug & (CCDB_FOLLOW|CCDB_INIT)) - printf("ccdinit: unit %d\n", ccd->ccd_unit); + printf("ccdinit: unit %d\n", cs->sc_unit); #endif cs->sc_size = 0; - cs->sc_ileave = ccd->ccd_interleave; - cs->sc_nccdisks = ccd->ccd_ndev; /* Allocate space for the component info. */ cs->sc_cinfo = malloc(cs->sc_nccdisks * sizeof(struct ccdcinfo), @@ -405,7 +414,7 @@ maxsecsize = 0; minsize = 0; for (ix = 0; ix < cs->sc_nccdisks; ix++) { - vp = ccd->ccd_vpp[ix]; + vp = cs->sc_vpp[ix]; ci = &cs->sc_cinfo[ix]; ci->ci_vp = vp; @@ -418,7 +427,7 @@ #ifdef DEBUG if (ccddebug & (CCDB_FOLLOW|CCDB_INIT)) printf("ccd%d: can't copy path, error = %d\n", - ccd->ccd_unit, error); + cs->sc_unit, error); #endif goto fail; } @@ -435,7 +444,7 @@ #ifdef DEBUG if (ccddebug & (CCDB_FOLLOW|CCDB_INIT)) printf("ccd%d: %s: ioctl failed, error = %d\n", - ccd->ccd_unit, ci->ci_path, error); + cs->sc_unit, ci->ci_path, error); #endif goto fail; } @@ -448,7 +457,7 @@ #ifdef DEBUG if (ccddebug & (CCDB_FOLLOW|CCDB_INIT)) printf("ccd%d: %s: incorrect partition type\n", - ccd->ccd_unit, ci->ci_path); + cs->sc_unit, ci->ci_path); #endif error = EFTYPE; goto fail; @@ -466,7 +475,7 @@ #ifdef DEBUG if (ccddebug & (CCDB_FOLLOW|CCDB_INIT)) printf("ccd%d: %s: size == 0\n", - ccd->ccd_unit, ci->ci_path); + cs->sc_unit, ci->ci_path); #endif error = ENODEV; goto fail; @@ -487,7 +496,7 @@ #ifdef DEBUG if (ccddebug & (CCDB_FOLLOW|CCDB_INIT)) printf("ccd%d: interleave must be at least %d\n", - ccd->ccd_unit, (maxsecsize / DEV_BSIZE)); + cs->sc_unit, (maxsecsize / DEV_BSIZE)); #endif error = EINVAL; goto fail; @@ -502,12 +511,12 @@ * overall size. Half the space is lost when CCDF_MIRROR is * specified. One disk is lost when CCDF_PARITY is specified. */ - if (ccd->ccd_flags & CCDF_UNIFORM) { + if (cs->sc_flags & CCDF_UNIFORM) { for (ci = cs->sc_cinfo; ci < &cs->sc_cinfo[cs->sc_nccdisks]; ci++) { ci->ci_size = minsize; } - if (ccd->ccd_flags & CCDF_MIRROR) { + if (cs->sc_flags & CCDF_MIRROR) { /* * Check to see if an even number of components * have been specified. The interleave must also @@ -515,21 +524,21 @@ * guarentee the topology. */ if (cs->sc_nccdisks % 2) { - printf("ccd%d: mirroring requires an even number of disks\n", ccd->ccd_unit ); + printf("ccd%d: mirroring requires an even number of disks\n", cs->sc_unit ); error = EINVAL; goto fail; } if (cs->sc_ileave == 0) { - printf("ccd%d: an interleave must be specified when mirroring\n", ccd->ccd_unit); + printf("ccd%d: an interleave must be specified when mirroring\n", cs->sc_unit); error = EINVAL; goto fail; } cs->sc_size = (cs->sc_nccdisks/2) * minsize; - } else if (ccd->ccd_flags & CCDF_PARITY) { + } else if (cs->sc_flags & CCDF_PARITY) { cs->sc_size = (cs->sc_nccdisks-1) * minsize; } else { if (cs->sc_ileave == 0) { - printf("ccd%d: an interleave must be specified when using parity\n", ccd->ccd_unit); + printf("ccd%d: an interleave must be specified when using parity\n", cs->sc_unit); error = EINVAL; goto fail; } @@ -540,7 +549,7 @@ /* * Construct the interleave table. */ - ccdinterleave(cs, ccd->ccd_unit); + ccdinterleave(cs, cs->sc_unit); /* * Create pseudo-geometry based on 1MB cylinders. It's @@ -554,14 +563,13 @@ /* * Add an devstat entry for this device. */ - devstat_add_entry(&cs->device_stats, "ccd", ccd->ccd_unit, + devstat_add_entry(&cs->device_stats, "ccd", cs->sc_unit, ccg->ccg_secsize, DEVSTAT_ALL_SUPPORTED, DEVSTAT_TYPE_STORARRAY |DEVSTAT_TYPE_IF_OTHER, DEVSTAT_PRIORITY_ARRAY); cs->sc_flags |= CCDF_INITED; - cs->sc_cflags = ccd->ccd_flags; /* So we can find out later... */ - cs->sc_unit = ccd->ccd_unit; + cs->sc_cflags = cs->sc_flags; /* So we can find out later... */ return (0); fail: while (ci > cs->sc_cinfo) { @@ -573,9 +581,7 @@ } static void -ccdinterleave(cs, unit) - struct ccd_softc *cs; - int unit; +ccdinterleave(struct ccd_s *cs, int unit) { struct ccdcinfo *ci, *smallci; struct ccdiinfo *ii; @@ -697,13 +703,10 @@ /* ARGSUSED */ static int -ccdopen(dev, flags, fmt, p) - dev_t dev; - int flags, fmt; - struct proc *p; +ccdopen(dev_t dev, int flags, int fmt, struct proc *p) { int unit = ccdunit(dev); - struct ccd_softc *cs; + struct ccd_s *cs; struct disklabel *lp; int error = 0, part, pmask; @@ -711,9 +714,8 @@ if (ccddebug & CCDB_FOLLOW) printf("ccdopen(%p, %x)\n", dev, flags); #endif - if (unit >= numccd) - return (ENXIO); - cs = &ccd_softc[unit]; + + cs = IS_ALLOCATED(unit) ? ccdfind(unit) : ccdnew(unit); if ((error = ccdlock(cs)) != 0) return (error); @@ -728,7 +730,7 @@ * open partitions. If not, then it's safe to update * the in-core disklabel. */ - if ((cs->sc_flags & CCDF_INITED) && (cs->sc_openmask == 0)) + if (IS_INITED(cs) && (cs->sc_openmask == 0)) ccdgetdisklabel(dev); /* Check that the partition exists. */ @@ -746,13 +748,10 @@ /* ARGSUSED */ static int -ccdclose(dev, flags, fmt, p) - dev_t dev; - int flags, fmt; - struct proc *p; +ccdclose(dev_t dev, int flags, int fmt, struct proc *p) { int unit = ccdunit(dev); - struct ccd_softc *cs; + struct ccd_s *cs; int error = 0, part; #ifdef DEBUG @@ -760,9 +759,9 @@ printf("ccdclose(%p, %x)\n", dev, flags); #endif - if (unit >= numccd) + if (!IS_ALLOCATED(unit)) return (ENXIO); - cs = &ccd_softc[unit]; + cs = ccdfind(unit); if ((error = ccdlock(cs)) != 0) return (error); @@ -771,16 +770,19 @@ /* ...that much closer to allowing unconfiguration... */ cs->sc_openmask &= ~(1 << part); - ccdunlock(cs); + /* collect "garbage" if possible */ + if (!IS_INITED(cs) && (cs->sc_flags & CCDF_WANTED) == 0) + ccddestroy(cs, p); + else + ccdunlock(cs); return (0); } static void -ccdstrategy(bp) - struct bio *bp; +ccdstrategy(struct bio *bp) { int unit = ccdunit(bp->bio_dev); - struct ccd_softc *cs = &ccd_softc[unit]; + struct ccd_s *cs = ccdfind(unit); int s; int wlabel; struct disklabel *lp; @@ -789,7 +791,7 @@ if (ccddebug & CCDB_FOLLOW) printf("ccdstrategy(%p): unit %d\n", bp, unit); #endif - if ((cs->sc_flags & CCDF_INITED) == 0) { + if (!IS_INITED(cs)) { biofinish(bp, NULL, ENXIO); return; } @@ -854,9 +856,7 @@ } static void -ccdstart(cs, bp) - struct ccd_softc *cs; - struct bio *bp; +ccdstart(struct ccd_s *cs, struct bio *bp) { long bcount, rcount; struct ccdbuf *cbp[4]; @@ -930,13 +930,7 @@ * Build a component buffer header. */ static void -ccdbuffer(cb, cs, bp, bn, addr, bcount) - struct ccdbuf **cb; - struct ccd_softc *cs; - struct bio *bp; - daddr_t bn; - caddr_t addr; - long bcount; +ccdbuffer(struct ccdbuf **cb, struct ccd_s *cs, struct bio *bp, daddr_t bn, caddr_t addr, long bcount) { struct ccdcinfo *ci, *ci2 = NULL; /* XXX */ struct ccdbuf *cbp; @@ -1073,7 +1067,7 @@ * context for ccdiodone */ cbp->cb_obp = bp; - cbp->cb_unit = cs - ccd_softc; + cbp->cb_unit = cs->sc_unit; cbp->cb_comp = ci - cs->sc_cinfo; #ifdef DEBUG @@ -1104,9 +1098,7 @@ } static void -ccdintr(cs, bp) - struct ccd_softc *cs; - struct bio *bp; +ccdintr(struct ccd_s *cs, struct bio *bp) { #ifdef DEBUG if (ccddebug & CCDB_FOLLOW) @@ -1126,8 +1118,7 @@ * take a ccd interrupt. */ static void -ccdiodone(ibp) - struct bio *ibp; +ccdiodone(struct bio *ibp) { struct ccdbuf *cbp = (struct ccdbuf *)ibp; struct bio *bp = cbp->cb_obp; @@ -1157,7 +1148,7 @@ if (cbp->cb_buf.bio_flags & BIO_ERROR) { const char *msg = ""; - if ((ccd_softc[unit].sc_cflags & CCDF_MIRROR) && + if ((ccdfind(unit)->sc_cflags & CCDF_MIRROR) && (cbp->cb_buf.bio_cmd == BIO_READ) && (cbp->cb_pflags & CCDPF_MIRROR_DONE) == 0) { /* @@ -1166,7 +1157,7 @@ * are doing a scan we do not keep hitting the * bad disk first. */ - struct ccd_softc *cs = &ccd_softc[unit]; + struct ccd_s *cs = ccdfind(unit); msg = ", trying other disk"; cs->sc_pick = 1 - cs->sc_pick; @@ -1190,7 +1181,7 @@ * we free the second I/O without initiating it. */ - if (ccd_softc[unit].sc_cflags & CCDF_MIRROR) { + if (ccdfind(unit)->sc_cflags & CCDF_MIRROR) { if (cbp->cb_buf.bio_cmd == BIO_WRITE) { /* * When writing, handshake with the second buffer @@ -1244,36 +1235,28 @@ if (bp->bio_resid < 0) panic("ccdiodone: count"); if (bp->bio_resid == 0) - ccdintr(&ccd_softc[unit], bp); + ccdintr(ccdfind(unit), bp); splx(s); } static int -ccdioctl(dev, cmd, data, flag, p) - dev_t dev; - u_long cmd; - caddr_t data; - int flag; - struct proc *p; +ccdioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) { int unit = ccdunit(dev); int i, j, lookedup = 0, error = 0; int part, pmask, s; - struct ccd_softc *cs; + struct ccd_s *cs; struct ccd_ioctl *ccio = (struct ccd_ioctl *)data; - struct ccddevice ccd; char **cpp; struct vnode **vpp; - if (unit >= numccd) + if (!IS_ALLOCATED(unit)) return (ENXIO); - cs = &ccd_softc[unit]; - - bzero(&ccd, sizeof(ccd)); + cs = ccdfind(unit); switch (cmd) { case CCDIOCSET: - if (cs->sc_flags & CCDF_INITED) + if (IS_INITED(cs)) return (EBUSY); if ((flag & FWRITE) == 0) @@ -1283,9 +1266,8 @@ return (error); /* Fill in some important bits. */ - ccd.ccd_unit = unit; - ccd.ccd_interleave = ccio->ccio_ileave; - if (ccd.ccd_interleave == 0 && + cs->sc_ileave = ccio->ccio_ileave; + if (cs->sc_ileave == 0 && ((ccio->ccio_flags & CCDF_MIRROR) || (ccio->ccio_flags & CCDF_PARITY))) { printf("ccd%d: disabling mirror/parity, interleave is 0\n", unit); @@ -1302,7 +1284,7 @@ unit); ccio->ccio_flags |= CCDF_UNIFORM; } - ccd.ccd_flags = ccio->ccio_flags & CCDF_USERMASK; + cs->sc_flags = ccio->ccio_flags & CCDF_USERMASK; /* * Allocate space for and copy in the array of @@ -1345,18 +1327,24 @@ } ++lookedup; } - ccd.ccd_cpp = cpp; - ccd.ccd_vpp = vpp; - ccd.ccd_ndev = ccio->ccio_ndisks; + cs->sc_vpp = vpp; + cs->sc_nccdisks = ccio->ccio_ndisks; /* * Initialize the ccd. Fills in the softc for us. */ - if ((error = ccdinit(&ccd, cpp, p)) != 0) { + if ((error = ccdinit(cs, cpp, p)) != 0) { for (j = 0; j < lookedup; ++j) (void)vn_close(vpp[j], FREAD|FWRITE, p->p_ucred, p); - bzero(&ccd_softc[unit], sizeof(struct ccd_softc)); + /* + * We can't ccddestroy() cs just yet, because nothing + * prevents user-level app to do another ioctl() + * without closing the device first, therefore + * declare unit null and void and let ccdclose() + * destroy it when it is safe to do so. + */ + cs->sc_flags &= (CCDF_WANTED | CCDF_LOCKED); free(vpp, M_DEVBUF); free(cpp, M_DEVBUF); ccdunlock(cs); @@ -1367,7 +1355,6 @@ * The ccd has been successfully initialized, so * we can place it into the array and read the disklabel. */ - bcopy(&ccd, &ccddevs[unit], sizeof(ccd)); ccio->ccio_unit = unit; ccio->ccio_size = cs->sc_size; ccdgetdisklabel(dev); @@ -1377,7 +1364,7 @@ break; case CCDIOCCLR: - if ((cs->sc_flags & CCDF_INITED) == 0) + if (!IS_INITED(cs)) return (ENXIO); if ((flag & FWRITE) == 0) @@ -1394,9 +1381,8 @@ return (EBUSY); } - /* - * Free ccd_softc information and clear entry. - */ + /* Declare unit null and void (reset all flags) */ + cs->sc_flags &= (CCDF_WANTED | CCDF_LOCKED); /* Close the components and free their pathnames. */ for (i = 0; i < cs->sc_nccdisks; ++i) { @@ -1422,38 +1408,93 @@ /* Free component info and interleave table. */ free(cs->sc_cinfo, M_DEVBUF); free(cs->sc_itable, M_DEVBUF); - cs->sc_flags &= ~CCDF_INITED; - - /* - * Free ccddevice information and clear entry. - */ - free(ccddevs[unit].ccd_cpp, M_DEVBUF); - free(ccddevs[unit].ccd_vpp, M_DEVBUF); - ccd.ccd_dk = -1; - bcopy(&ccd, &ccddevs[unit], sizeof(ccd)); + free(cs->sc_vpp, M_DEVBUF); - /* - * And remove the devstat entry. - */ + /* And remove the devstat entry. */ devstat_remove_entry(&cs->device_stats); /* This must be atomic. */ s = splhigh(); ccdunlock(cs); - bzero(cs, sizeof(struct ccd_softc)); splx(s); break; + case CCDCONFINFO: + { + int ninit = 0; + struct ccdconf *conf = (struct ccdconf *)data; + struct ccd_s *tmpcs; + struct ccd_s *ubuf = conf->buffer; + + /* XXX: LOCK(unique unit numbers) */ + LIST_FOREACH(tmpcs, &ccd_softc_list, list) + if (IS_INITED(tmpcs)) + ninit++; + + if (conf->size == 0) { + conf->size = sizeof(struct ccd_s) * ninit; + break; + } else if ((conf->size / sizeof(struct ccd_s) != ninit) || + (conf->size % sizeof(struct ccd_s) != 0)) { + /* XXX: UNLOCK(unique unit numbers) */ + return (EINVAL); + } + + ubuf += ninit; + LIST_FOREACH(tmpcs, &ccd_softc_list, list) { + if (!IS_INITED(tmpcs)) + continue; + error = copyout(tmpcs, --ubuf, + sizeof(struct ccd_s)); + if (error != 0) + /* XXX: UNLOCK(unique unit numbers) */ + return (error); + } + /* XXX: UNLOCK(unique unit numbers) */ + } + break; + + case CCDCPPINFO: + if (!IS_INITED(cs)) + return (ENXIO); + + { + int len = 0; + struct ccdcpps *cpps = (struct ccdcpps *)data; + char *ubuf = cpps->buffer; + + + for (i = 0; i < cs->sc_nccdisks; ++i) + len += cs->sc_cinfo[i].ci_pathlen; + + if (cpps->size == 0) { + cpps->size = len; + break; + } else if (cpps->size != len) { + return (EINVAL); + } + + for (i = 0; i < cs->sc_nccdisks; ++i) { + len = cs->sc_cinfo[i].ci_pathlen; + error = copyout(cs->sc_cinfo[i].ci_path, ubuf, + len); + if (error != 0) + return (error); + ubuf += len; + } + } + break; + case DIOCGDINFO: - if ((cs->sc_flags & CCDF_INITED) == 0) + if (!IS_INITED(cs)) return (ENXIO); *(struct disklabel *)data = cs->sc_label; break; case DIOCGPART: - if ((cs->sc_flags & CCDF_INITED) == 0) + if (!IS_INITED(cs)) return (ENXIO); ((struct partinfo *)data)->disklab = &cs->sc_label; @@ -1463,7 +1504,7 @@ case DIOCWDINFO: case DIOCSDINFO: - if ((cs->sc_flags & CCDF_INITED) == 0) + if (!IS_INITED(cs)) return (ENXIO); if ((flag & FWRITE) == 0) @@ -1491,7 +1532,7 @@ break; case DIOCWLABEL: - if ((cs->sc_flags & CCDF_INITED) == 0) + if (!IS_INITED(cs)) return (ENXIO); if ((flag & FWRITE) == 0) @@ -1510,19 +1551,18 @@ } static int -ccdsize(dev) - dev_t dev; +ccdsize(dev_t dev) { - struct ccd_softc *cs; + struct ccd_s *cs; int part, size; if (ccdopen(dev, 0, S_IFCHR, curproc)) return (-1); - cs = &ccd_softc[ccdunit(dev)]; + cs = ccdfind(ccdunit(dev)); part = ccdpart(dev); - if ((cs->sc_flags & CCDF_INITED) == 0) + if (!IS_INITED(cs)) return (-1); if (cs->sc_label.d_partitions[part].p_fstype != FS_SWAP) @@ -1537,8 +1577,7 @@ } static int -ccddump(dev) - dev_t dev; +ccddump(dev_t dev) { /* Not implemented. */ @@ -1551,10 +1590,7 @@ * set *vpp to the file's vnode. */ static int -ccdlookup(path, p, vpp) - char *path; - struct proc *p; - struct vnode **vpp; /* result */ +ccdlookup(char *path, struct proc *p, struct vnode **vpp) { struct nameidata nd; struct vnode *vp; @@ -1564,7 +1600,7 @@ flags = FREAD | FWRITE; if ((error = vn_open(&nd, &flags, 0)) != 0) { #ifdef DEBUG - if (ccddebug & CCDB_FOLLOW|CCDB_INIT) + if (ccddebug & (CCDB_FOLLOW|CCDB_INIT)) printf("ccdlookup: vn_open error = %d\n", error); #endif return (error); @@ -1601,11 +1637,10 @@ * up. */ static void -ccdgetdisklabel(dev) - dev_t dev; +ccdgetdisklabel(dev_t dev) { int unit = ccdunit(dev); - struct ccd_softc *cs = &ccd_softc[unit]; + struct ccd_s *cs = ccdfind(unit); char *errstring; struct disklabel *lp = &cs->sc_label; struct ccdgeom *ccg = &cs->sc_geom; @@ -1658,8 +1693,7 @@ * that a disklabel isn't present. */ static void -ccdmakedisklabel(cs) - struct ccd_softc *cs; +ccdmakedisklabel(struct ccd_s *cs) { struct disklabel *lp = &cs->sc_label; @@ -1679,8 +1713,7 @@ * Several drivers do this; it should be abstracted and made MP-safe. */ static int -ccdlock(cs) - struct ccd_softc *cs; +ccdlock(struct ccd_s *cs) { int error; @@ -1697,8 +1730,7 @@ * Unlock and wake up any waiters. */ static void -ccdunlock(cs) - struct ccd_softc *cs; +ccdunlock(struct ccd_s *cs) { cs->sc_flags &= ~CCDF_LOCKED; @@ -1710,8 +1742,7 @@ #ifdef DEBUG static void -printiinfo(ii) - struct ccdiinfo *ii; +printiinfo(struct ccdiinfo *ii) { int ix, i; Index: sbin/ccdconfig/Makefile =================================================================== RCS file: /home/ncvs/src/sbin/ccdconfig/Makefile,v retrieving revision 1.5 diff -d -u -r1.5 Makefile --- sbin/ccdconfig/Makefile 2001/05/18 13:41:24 1.5 +++ sbin/ccdconfig/Makefile 2001/09/03 08:19:24 @@ -3,9 +3,4 @@ PROG= ccdconfig MAN= ccdconfig.8 -LDADD+= -lkvm -DPADD+= ${LIBKVM} -BINGRP= kmem -BINMODE= 2555 - .include Index: sbin/ccdconfig/ccdconfig.8 =================================================================== RCS file: /home/ncvs/src/sbin/ccdconfig/ccdconfig.8,v retrieving revision 1.17 diff -d -u -r1.17 ccdconfig.8 --- sbin/ccdconfig/ccdconfig.8 2001/07/15 07:49:06 1.17 +++ sbin/ccdconfig/ccdconfig.8 2001/09/03 08:19:25 @@ -61,8 +61,6 @@ .Op Fl f Ar config_file .Nm .Fl g -.Op Fl M Ar core -.Op Fl N Ar system .Op Ar ccd Op Ar ... .Sh DESCRIPTION .Nm Ccdconfig @@ -86,16 +84,6 @@ Dump the current ccd configuration in a format suitable for use as the ccd configuration file. If no arguments are specified, every configured ccd is dumped. Otherwise, the configuration of each listed ccd is dumped. -.It Fl M Ar core -Extract values associated with the name list from -.Pa core -instead of the default -.Pa /dev/mem . -.It Fl N Ar system -Use -.Ar system -as the kernel instead of the running kernel (as determined from -.Xr getbootfile 3 ) . .It Fl u Unconfigure a ccd. .It Fl U Index: sbin/ccdconfig/ccdconfig.c =================================================================== RCS file: /home/ncvs/src/sbin/ccdconfig/ccdconfig.c,v retrieving revision 1.20 diff -d -u -r1.20 ccdconfig.c --- sbin/ccdconfig/ccdconfig.c 2001/08/31 16:26:34 1.20 +++ sbin/ccdconfig/ccdconfig.c 2001/09/03 08:19:25 @@ -46,7 +46,6 @@ #include #include #include -#include #include #include #include @@ -63,9 +62,6 @@ static int verbose = 0; static char *ccdconf = _PATH_CCDCONF; -static char *core = NULL; -static char *kernel = NULL; - struct flagval { char *fv_flag; int fv_val; @@ -77,14 +73,6 @@ { NULL, 0 }, }; -static struct nlist nl[] = { - { "_ccd_softc" }, -#define SYM_CCDSOFTC 0 - { "_numccd" }, -#define SYM_NUMCCD 1 - { NULL }, -}; - #define CCD_CONFIG 0 /* configure a device */ #define CCD_CONFIGALL 1 /* configure all devices */ #define CCD_UNCONFIG 2 /* unconfigure a device */ @@ -99,7 +87,7 @@ static int getmaxpartitions __P((void)); static int getrawpartition __P((void)); static int flags_to_val __P((char *)); -static void print_ccd_info __P((struct ccd_softc *, kvm_t *)); +static void print_ccd_info __P((struct ccd_s *)); static char *resolve_ccdname __P((char *)); static void usage __P((void)); @@ -130,14 +118,6 @@ action = CCD_DUMP; break; - case 'M': - core = optarg; - break; - - case 'N': - kernel = optarg; - break; - case 'u': action = CCD_UNCONFIG; ++options; @@ -162,15 +142,6 @@ if (options > 1) usage(); - /* - * Discard setgid privileges if not the running kernel so that bad - * guys can't print interesting stuff from kernel memory. - */ - if (core != NULL || kernel != NULL || action != CCD_DUMP) { - setegid(getgid()); - setgid(getgid()); - } - if (modfind("ccd") < 0) { /* Not present in kernel, try loading it */ if (kldload("ccd") < 0 || modfind("ccd") < 0) @@ -476,6 +447,14 @@ cp = "CCDIOCCLR"; break; + case CCDCONFINFO: + cp = "CCDCONFINFO"; + break; + + case CCDCPPINFO: + cp = "CCDCPPINFO"; + break; + default: cp = "unknown"; } @@ -486,78 +465,44 @@ return (0); } -#define KVM_ABORT(kd, str) { \ - (void)kvm_close((kd)); \ - warnx("%s", (str)); \ - warnx("%s", kvm_geterr((kd))); \ - return (1); \ -} - static int dump_ccd(argc, argv) int argc; char **argv; { - char errbuf[_POSIX2_LINE_MAX], *ccd, *cp; - struct ccd_softc *cs, *kcs; - size_t readsize; + char *ccd, *cp; int i, error, numccd, numconfiged = 0; - kvm_t *kd; - - bzero(errbuf, sizeof(errbuf)); + struct ccdconf conf; - if ((kd = kvm_openfiles(kernel, core, NULL, O_RDONLY, - errbuf)) == NULL) { - warnx("can't open kvm: %s", errbuf); + /* + * Read the ccd configuration data from the kernel and dump + * it to stdout. + */ + if ((ccd = resolve_ccdname("ccd0")) == NULL) { /* XXX */ + warnx("invalid ccd name: %s", cp); return (1); } - setegid(getgid()); - setgid(getgid()); - - if (kvm_nlist(kd, nl)) - KVM_ABORT(kd, "ccd-related symbols not available"); - - /* Check to see how many ccds are currently configured. */ - if (kvm_read(kd, nl[SYM_NUMCCD].n_value, (char *)&numccd, - sizeof(numccd)) != sizeof(numccd)) - KVM_ABORT(kd, "can't determine number of configured ccds"); - - if (numccd == 0) { - printf("ccd driver in kernel, but is uninitialized\n"); - goto done; + conf.size = 0; + if (do_io(ccd, CCDCONFINFO, (struct ccd_ioctl *) &conf)) + return (1); + if (conf.size == 0) { + printf("no concatenated disks configured\n"); + return (0); } - /* Allocate space for the configuration data. */ - readsize = numccd * sizeof(struct ccd_softc); - if ((cs = malloc(readsize)) == NULL) { + conf.buffer = alloca(conf.size); + if (conf.buffer == NULL) { warnx("no memory for configuration data"); - goto bad; + return (1); } - bzero(cs, readsize); + if (do_io(ccd, CCDCONFINFO, (struct ccd_ioctl *) &conf)) + return (1); - /* - * Read the ccd configuration data from the kernel and dump - * it to stdout. - */ - if (kvm_read(kd, nl[SYM_CCDSOFTC].n_value, (char *)&kcs, - sizeof(kcs)) != sizeof(kcs)) { - free(cs); - KVM_ABORT(kd, "can't find pointer to configuration data"); - } - if (kvm_read(kd, (u_long)kcs, (char *)cs, readsize) != readsize) { - free(cs); - KVM_ABORT(kd, "can't read configuration data"); - } + numconfiged = conf.size / sizeof(struct ccd_s); if (argc == 0) { - for (i = 0; i < numccd; ++i) - if (cs[i].sc_flags & CCDF_INITED) { - ++numconfiged; - print_ccd_info(&cs[i], kd); - } - - if (numconfiged == 0) - printf("no concatenated disks configured\n"); + for (i = 0; i < numconfiged; i++) + print_ccd_info(&(conf.buffer[i])); } else { while (argc) { cp = *argv++; --argc; @@ -565,85 +510,88 @@ warnx("invalid ccd name: %s", cp); continue; } - if ((error = pathtounit(ccd, &i)) != 0) { + if ((error = pathtounit(ccd, &numccd)) != 0) { warnx("%s: %s", ccd, strerror(error)); continue; } - if (i >= numccd) { - warnx("ccd%d not configured", i); + error = 1; + for (i = 0; i < numconfiged; i++) { + if (conf.buffer[i].sc_unit == numccd) { + print_ccd_info(&(conf.buffer[i])); + error = 0; + break; + } + } + if (error) { + warnx("ccd%d not configured", numccd); continue; } - if (cs[i].sc_flags & CCDF_INITED) - print_ccd_info(&cs[i], kd); - else - printf("ccd%d not configured\n", i); } - } - - free(cs); + } - done: - (void)kvm_close(kd); return (0); - - bad: - (void)kvm_close(kd); - return (1); } static void -print_ccd_info(cs, kd) - struct ccd_softc *cs; - kvm_t *kd; +print_ccd_info(cs) + struct ccd_s *cs; { + char *cp, *ccd; static int header_printed = 0; - struct ccdcinfo *cip; - size_t readsize; - char path[MAXPATHLEN]; - int i; + struct ccdcpps cpps; + /* Print out header if necessary*/ if (header_printed == 0 && verbose) { printf("# ccd\t\tileave\tflags\tcompnent devices\n"); header_printed = 1; } - readsize = cs->sc_nccdisks * sizeof(struct ccdcinfo); - if ((cip = malloc(readsize)) == NULL) { - warn("ccd%d: can't allocate memory for component info", - cs->sc_unit); - return; - } - bzero(cip, readsize); - /* Dump out softc information. */ printf("ccd%d\t\t%d\t%d\t", cs->sc_unit, cs->sc_ileave, cs->sc_cflags & CCDF_USERMASK); fflush(stdout); /* Read in the component info. */ - if (kvm_read(kd, (u_long)cs->sc_cinfo, (char *)cip, - readsize) != readsize) { + asprintf(&cp, "%s%d", cs->device_stats.device_name, + cs->device_stats.unit_number); + if (cp == NULL) { + printf("\n"); + warn("ccd%d: can't allocate memory", + cs->sc_unit); + return; + } + + if ((ccd = resolve_ccdname(cp)) == NULL) { printf("\n"); + warnx("can't read component info: invalid ccd name: %s", cp); + return; + } + cpps.size = 0; + if (do_io(ccd, CCDCPPINFO, (struct ccd_ioctl *) &cpps)) { + printf("\n"); warnx("can't read component info"); - warnx("%s", kvm_geterr(kd)); - goto done; + return; + } + cpps.buffer = alloca(cpps.size); + if (cpps.buffer == NULL) { + printf("\n"); + warn("ccd%d: can't allocate memory for component info", + cs->sc_unit); + return; + } + if (do_io(ccd, CCDCPPINFO, (struct ccd_ioctl *) &cpps)) { + printf("\n"); + warnx("can't read component info"); + return; } - /* Read component pathname and display component info. */ - for (i = 0; i < cs->sc_nccdisks; ++i) { - if (kvm_read(kd, (u_long)cip[i].ci_path, (char *)path, - cip[i].ci_pathlen) != cip[i].ci_pathlen) { - printf("\n"); - warnx("can't read component pathname"); - warnx("%s", kvm_geterr(kd)); - goto done; - } - printf((i + 1 < cs->sc_nccdisks) ? "%s " : "%s\n", path); + /* Display component info. */ + for (cp = cpps.buffer; cp - cpps.buffer < cpps.size; cp += strlen(cp) + 1) { + printf((cp + strlen(cp) + 1) < (cpps.buffer + cpps.size) ? + "%s " : "%s\n", cp); fflush(stdout); } - - done: - free(cip); + return; } static int @@ -725,7 +673,7 @@ " ccdconfig -C [-v] [-f config_file]", " ccdconfig -u [-v] ccd [...]", " ccdconfig -U [-v] [-f config_file]", - " ccdconfig -g [-M core] [-N system] [ccd [...]]"); + " ccdconfig -g [ccd [...]]"); exit(1); } Index: sys/modules/ccd/Makefile =================================================================== RCS file: /home/ncvs/src/sys/modules/ccd/Makefile,v retrieving revision 1.14 diff -d -u -r1.14 Makefile --- sys/modules/ccd/Makefile 2001/01/06 13:59:42 1.14 +++ sys/modules/ccd/Makefile 2001/09/03 08:19:26 @@ -3,13 +3,7 @@ .PATH: ${.CURDIR}/../../dev/ccd KMOD= ccd -SRCS= ccd.c ccd.h vnode_if.h +SRCS= ccd.c vnode_if.h NOMAN= - -NCCD?= 4 -CLEANFILES= ccd.h - -ccd.h: - echo "#define NCCD ${NCCD}" > ccd.h .include --------------4C8CE2CD7293DF8D444DE7F1-- To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-current" in the body of the message