diff options
Diffstat (limited to 'lkm/vinum/vinum.c')
-rw-r--r-- | lkm/vinum/vinum.c | 544 |
1 files changed, 0 insertions, 544 deletions
diff --git a/lkm/vinum/vinum.c b/lkm/vinum/vinum.c deleted file mode 100644 index 2717f0c..0000000 --- a/lkm/vinum/vinum.c +++ /dev/null @@ -1,544 +0,0 @@ -/*- - * Copyright (c) 1997, 1998 - * Nan Yang Computer Services Limited. All rights reserved. - * - * This software is distributed under the so-called ``Berkeley - * License'': - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Nan Yang Computer - * Services Limited. - * 4. Neither the name of the Company nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * This software is provided ``as is'', and any express or implied - * warranties, including, but not limited to, the implied warranties of - * merchantability and fitness for a particular purpose are disclaimed. - * In no event shall the company or contributors be liable for any - * direct, indirect, incidental, special, exemplary, or consequential - * damages (including, but not limited to, procurement of substitute - * goods or services; loss of use, data, or profits; or business - * interruption) however caused and on any theory of liability, whether - * in contract, strict liability, or tort (including negligence or - * otherwise) arising in any way out of the use of this software, even if - * advised of the possibility of such damage. - * - * $Id: vinum.c,v 1.20 1998/10/29 02:15:30 grog Exp grog $ - */ - -#define STATIC /* nothing while we're testing XXX */ - -#define REALLYKERNEL -#include "vinumhdr.h" -#include "sys/sysproto.h" /* for sync(2) */ -#ifdef DEBUG -#include <sys/reboot.h> -int debug = 0; -#endif - -/* pointer to ioctl p parameter, to save passing it around */ -struct proc *myproc; - -#if __FreeBSD__ < 3 -STATIC struct cdevsw vinum_cdevsw; -STATIC struct bdevsw vinum_bdevsw = -{ - vinumopen, vinumclose, vinumstrategy, vinumioctl, - vinumdump, vinumsize, 0, - "vinum", &vinum_cdevsw, -1 -}; -#else /* goodbye, bdevsw */ -STATIC struct cdevsw vinum_cdevsw = -{ - vinumopen, vinumclose, vinumread, vinumwrite, - vinumioctl, nostop, nullreset, nodevtotty, - seltrue, nommap, vinumstrategy, "vinum", - NULL, -1, vinumdump, vinumsize, - D_DISK, 0, -1 -}; -#endif - -/* Called by main() during pseudo-device attachment. */ -STATIC void vinumattach(void *); - -STATIC void vinumgetdisklabel(dev_t); -void vinum_scandisk(void); -int vinum_inactive(void); -void free_vinum(int); - -#ifndef ACTUALLY_LKM_NOT_KERNEL -STATIC int vinum_modevent(module_t mod, modeventtype_t type, void *unused); -#endif - -#if __FreeBSD__ >= 3 -/* Why aren't these declared anywhere? XXX */ -int setjmp(jmp_buf); -void longjmp(jmp_buf, int); -#endif - -extern jmp_buf command_fail; /* return here if config fails */ - -struct _vinum_conf vinum_conf; /* configuration information */ - -STATIC int vinum_devsw_installed = 0; - -/* - * 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. - */ -void -vinumattach(void *dummy) -{ - BROKEN_GDB; - char *buf; /* pointer to temporary buffer */ - struct _ioctl_reply *ioctl_reply; /* struct to return */ - struct uio uio; - struct iovec iovec; - - /* modload should prevent multiple loads, so this is worth a panic */ - if ((vinum_conf.flags & VF_LOADED) != NULL) - panic("vinum: already loaded"); - - printf("vinum: loaded\n"); - vinum_conf.flags |= VF_LOADED; /* we're loaded now */ - - /* We don't have a p pointer here, so take it from curproc */ - myproc = curproc; -#if __FreeBSD__ < 3 - bdevsw_add_generic(BDEV_MAJOR, CDEV_MAJOR, &vinum_bdevsw); -#else - cdevsw_add_generic(BDEV_MAJOR, CDEV_MAJOR, &vinum_cdevsw); -#endif -#ifdef DEVFS -#error DEVFS not finished yet -#endif - - uio.uio_iov = &iovec; - uio.uio_iovcnt = 1; /* just one buffer */ - uio.uio_offset = 0; /* start at the beginning */ - uio.uio_resid = 512; /* one sector */ - uio.uio_segflg = UIO_SYSSPACE; /* we're in system space */ - uio.uio_rw = UIO_READ; /* do we need this? */ - uio.uio_procp = curproc; /* do it for our own process */ - - iovec.iov_len = 512; - buf = (char *) Malloc(iovec.iov_len); /* get a buffer */ - CHECKALLOC(buf, "vinum: no memory\n"); /* can't get 512 bytes? */ - iovec.iov_base = buf; /* read into buf */ - - /* allocate space: drives... */ - DRIVE = (struct drive *) Malloc(sizeof(struct drive) * INITIAL_DRIVES); - CHECKALLOC(DRIVE, "vinum: no memory\n"); - vinum_conf.drives_allocated = INITIAL_DRIVES; /* number of drive slots allocated */ - vinum_conf.drives_used = 0; /* and number in use */ - - /* volumes, ... */ - VOL = (struct volume *) Malloc(sizeof(struct volume) * INITIAL_VOLUMES); - CHECKALLOC(VOL, "vinum: no memory\n"); - vinum_conf.volumes_allocated = INITIAL_VOLUMES; /* number of volume slots allocated */ - vinum_conf.volumes_used = 0; /* and number in use */ - - /* plexes, ... */ - PLEX = (struct plex *) Malloc(sizeof(struct plex) * INITIAL_PLEXES); - CHECKALLOC(PLEX, "vinum: no memory\n"); - vinum_conf.plexes_allocated = INITIAL_PLEXES; /* number of plex slots allocated */ - vinum_conf.plexes_used = 0; /* and number in use */ - - /* and subdisks */ - SD = (struct sd *) Malloc(sizeof(struct sd) * INITIAL_SUBDISKS); - CHECKALLOC(SD, "vinum: no memory\n"); - vinum_conf.subdisks_allocated = INITIAL_SUBDISKS; /* number of sd slots allocated */ - vinum_conf.subdisks_used = 0; /* and number in use */ - - ioctl_reply = NULL; /* no reply on longjmp */ -} - -/* Check if we have anything open. If so, return 0 (not inactive), - * otherwise 1 (inactive) */ -int -vinum_inactive(void) -{ - BROKEN_GDB; - int i; - int can_do = 1; /* assume we can do it */ - - lock_config(); - for (i = 0; i < vinum_conf.volumes_used; i++) { - if (VOL[i].pid != NULL) { /* volume is open */ - can_do = 0; - break; - } - } - unlock_config(); - return can_do; -} - -/* Free all structures. - * If cleardrive is 0, save the configuration; otherwise - * remove the configuration from the drive. - * - * Before coming here, ensure that no volumes are open. - */ -void -free_vinum(int cleardrive) -{ - BROKEN_GDB; - int i; - - if (cleardrive) { - for (i = 0; i < vinum_conf.drives_used; i++) - remove_drive(i); /* remove the drive */ - } else { /* keep the config */ - save_config(); - if (DRIVE != NULL) { - for (i = 0; i < vinum_conf.drives_used; i++) - free_drive(&DRIVE[i]); /* close files and things */ - Free(DRIVE); - } - } - if (SD != NULL) - Free(SD); - if (PLEX != NULL) { - for (i = 0; i < vinum_conf.plexes_used; i++) { - struct plex *plex = &vinum_conf.plex[i]; - - if (plex->state != plex_unallocated) { /* we have real data there */ - if (plex->sdnos) - Free(plex->sdnos); - if (plex->unmapped_regions) - Free(plex->unmapped_region); - if (plex->defective_regions) - Free(plex->defective_region); - } - } - Free(PLEX); - } - if (VOL != NULL) - Free(VOL); - bzero(&vinum_conf, sizeof(vinum_conf)); -} - -#ifdef ACTUALLY_LKM_NOT_KERNEL /* stuff for LKMs */ - -MOD_MISC(vinum); - -/* - * Function called when loading the driver. - */ - -STATIC int -vinum_load(struct lkm_table *lkmtp, int cmd) -{ - BROKEN_GDB; - vinumattach(NULL); - return 0; /* OK */ -} - -/* - * Function called when unloading the driver. - */ -STATIC int -vinum_unload(struct lkm_table *lkmtp, int cmd) -{ - BROKEN_GDB; - if (vinum_inactive()) { /* is anything open? */ - struct sync_args dummyarg = - {0}; -#if __FreeBSD__ < 3 - int retval; -#endif - - printf("vinum: unloaded\n"); -#if __FreeBSD__ < 3 - sync(curproc, &dummyarg, &retval); /* write out buffers */ -#else - sync(curproc, &dummyarg); /* write out buffers */ -#endif - free_vinum(0); /* no: clean up */ -#if __FreeBSD__ < 3 - bdevsw[BDEV_MAJOR] = NULL; /* clear bdevsw */ -#endif - cdevsw[CDEV_MAJOR] = NULL; /* and cdevsw */ - return 0; - } else - return EBUSY; -} - -/* - * Dispatcher function for the module (load/unload/stat). - */ -int -vinum_mod(struct lkm_table *lkmtp, int cmd, int ver) -{ - BROKEN_GDB; - MOD_DISPATCH(vinum, /* module name */ - lkmtp, /* LKM table */ - cmd, /* command */ - ver, - vinum_load, /* load with this function */ - vinum_unload, /* and unload with this */ - lkm_nullcmd); -} - -#else /* not LKM */ - -STATIC int -vinum_modevent(module_t mod, modeventtype_t type, void *unused) -{ - struct sync_args dummyarg = - {0}; - - BROKEN_GDB; - switch (type) { - case MOD_LOAD: - vinumattach(NULL); - return 0; /* OK */ - case MOD_UNLOAD: - if (!vinum_inactive()) /* is anything open? */ - return EBUSY; - sync(curproc, &dummyarg); /* write out buffers */ - free_vinum(0); /* no: clean up */ - cdevsw[CDEV_MAJOR] = NULL; /* and cdevsw */ - return 0; - default: - break; - } - return 0; -} - -moduledata_t vinum_mod = -{ - "vinum", - vinum_modevent, - 0 -}; -DECLARE_MODULE(vinum, vinum_mod, SI_SUB_DRIVERS, SI_ORDER_MIDDLE); - -#endif /* LKM */ - -/* ARGSUSED */ -/* Open a vinum object - * At the moment, we only open volumes and the - * super device. It's a nice concept to be - * able to open drives, subdisks and plexes, but - * I can't think what good it could be */ -int -vinumopen(dev_t dev, - int flags, - int fmt, - struct proc *p) -{ - BROKEN_GDB; - int s; /* spl */ - int error; - unsigned int index; - struct volume *vol; - struct plex *plex; - struct sd *sd; - struct devcode *device; - - device = (struct devcode *) &dev; - - error = 0; - /* First, decide what we're looking at */ - switch (device->type) { - case VINUM_VOLUME_TYPE: - index = VOLNO(dev); - if (index >= vinum_conf.volumes_used) - return ENXIO; /* no such device */ - vol = &VOL[index]; - - switch (vol->state) { - case volume_unallocated: - case volume_uninit: - return ENXIO; - - case volume_up: - s = splhigh(); /* quick lock */ - if (error) - return error; - if (vol->opencount == 0) - vol->openflags = flags; /* set our flags */ - vol->opencount++; - vol->pid = p->p_pid; /* and say who we are (do we need this? XXX) */ - splx(s); - return 0; - - case volume_down: - return EIO; - - default: - return EINVAL; - } - - case VINUM_PLEX_TYPE: - if (VOLNO(dev) >= vinum_conf.volumes_used) - return ENXIO; - index = PLEXNO(dev); /* get plex index in vinum_conf */ - if (index >= vinum_conf.plexes_used) - return ENXIO; /* no such device */ - plex = &PLEX[index]; - - switch (plex->state) { - case plex_unallocated: - return EINVAL; - - default: - s = splhigh(); - if (plex->pid /* it's open already */ - && (plex->pid != p->p_pid)) { /* and not by us, */ - splx(s); - return EBUSY; /* one at a time, please */ - } - plex->pid = p->p_pid; /* and say who we are (do we need this? XXX) */ - splx(s); - return 0; - } - - case VINUM_SD_TYPE: - if ((VOLNO(dev) >= vinum_conf.volumes_used) || /* no such volume */ - (PLEXNO(dev) >= vinum_conf.plexes_used)) /* or no such plex */ - return ENXIO; /* no such device */ - index = SDNO(dev); /* get the subdisk number */ - if (index >= vinum_conf.subdisks_used) - return ENXIO; /* no such device */ - sd = &SD[index]; - - /* Opening a subdisk is always a special operation, so we - * ignore the state as long as it represents a real subdisk */ - switch (sd->state) { - case sd_unallocated: - case sd_uninit: - return EINVAL; - - default: - s = splhigh(); - if (sd->pid /* it's open already */ - && (sd->pid != p->p_pid)) { /* and not by us, */ - splx(s); - return EBUSY; /* one at a time, please */ - } - sd->pid = p->p_pid; /* and say who we are (do we need this? XXX) */ - splx(s); - return 0; - } - - case VINUM_DRIVE_TYPE: - default: - return ENODEV; /* don't know what to do with these */ - - case VINUM_SUPERDEV_TYPE: - if (p->p_ucred->cr_uid == 0) { /* root calling, */ - vinum_conf.opencount++; /* one more opener */ - return 0; /* no worries opening super dev */ - } else - return EPERM; /* you can't do that! */ - } -} - -/* ARGSUSED */ -int -vinumclose(dev_t dev, - int flags, - int fmt, - struct proc *p) -{ - BROKEN_GDB; - unsigned int index; - struct volume *vol; - struct plex *plex; - struct sd *sd; - struct devcode *device = (struct devcode *) &dev; - - index = VOLNO(dev); - /* First, decide what we're looking at */ - switch (device->type) { - case VINUM_VOLUME_TYPE: - if (index >= vinum_conf.volumes_used) - return ENXIO; /* no such device */ - vol = &VOL[index]; - - switch (vol->state) { - case volume_unallocated: - case volume_uninit: - return ENXIO; - - case volume_up: - vol->opencount = 0; /* reset our flags */ - vol->pid = NULL; /* and forget who owned us */ - return 0; - - case volume_down: - return EIO; - - default: - return EINVAL; - } - - case VINUM_PLEX_TYPE: - if (VOLNO(dev) >= vinum_conf.volumes_used) - return ENXIO; - index = PLEXNO(dev); /* get plex index in vinum_conf */ - if (index >= vinum_conf.plexes_used) - return ENXIO; /* no such device */ - plex = &PLEX[index]; - plex->pid = 0; - return 0; - - case VINUM_SD_TYPE: - if ((VOLNO(dev) >= vinum_conf.volumes_used) || /* no such volume */ - (PLEXNO(dev) >= vinum_conf.plexes_used)) /* or no such plex */ - return ENXIO; /* no such device */ - index = SDNO(dev); /* get the subdisk number */ - if (index >= vinum_conf.subdisks_used) - return ENXIO; /* no such device */ - sd = &SD[index]; - sd->pid = 0; - return 0; - - case VINUM_SUPERDEV_TYPE: - if (p->p_ucred->cr_uid == 0) /* root calling, */ - vinum_conf.opencount--; /* one less opener */ - return 0; /* no worries closing super dev */ - - case VINUM_DRIVE_TYPE: - default: - return ENODEV; /* don't know what to do with these */ - } -} - -/* size routine */ -int -vinumsize(dev_t dev) -{ - BROKEN_GDB; - struct volume *vol; - int size; - - vol = &VOL[VOLNO(dev)]; - - if (vol->state == volume_up) - size = vol->size; - else - return 0; /* err on the size of conservatism */ - - return size; -} - -int -vinumdump(dev_t dev) -{ - /* Not implemented. */ - return ENXIO; -} |