diff options
Diffstat (limited to 'sys/miscfs/devfs/devfs_back.c')
| -rw-r--r-- | sys/miscfs/devfs/devfs_back.c | 467 |
1 files changed, 0 insertions, 467 deletions
diff --git a/sys/miscfs/devfs/devfs_back.c b/sys/miscfs/devfs/devfs_back.c deleted file mode 100644 index 20a69e5a97d2..000000000000 --- a/sys/miscfs/devfs/devfs_back.c +++ /dev/null @@ -1,467 +0,0 @@ - -/* - * Written by Julian Elischer (julian@DIALix.oz.au) - * - * $Header: /home/ncvs/src/sys/miscfs/devfs/devfs_back.c,v 1.4 1995/09/03 05:43:38 julian Exp $ - */ - -#include "param.h" -#include "systm.h" -#include "types.h" -#include "kernel.h" -#include "file.h" /* define FWRITE ... */ -#include "conf.h" -#include "stat.h" -#include "mount.h" -#include "vnode.h" -#include "malloc.h" -#include "dir.h" /* defines dirent structure */ -#include "devfsdefs.h" -#include "sys/devfsext.h" - - -SYSINIT(devfs, SI_SUB_DEVFS, SI_ORDER_FIRST, devfs_sinit, NULL) - -devnm_p dev_root; /* root of the backing tree */ - -/* - * Set up the root directory node in the backing plane - * This is happenning before the vfs system has been - * set up yet, so be careful about what we reference.. - * Notice that the ops are by indirection.. as they haven't - * been set up yet! - */ -void devfs_sinit() /*proto*/ -{ - int retval; /* we will discard this */ - /* - * call the right routine at the right time with the right args.... - */ - retval = dev_add_node("root",NULL,DEV_DIR,NULL,&dev_root); - printf("DEVFS: ready for devices\n"); -} - -/***********************************************************************\ -* Given a starting node (0 for root) and a pathname, return the node * -* for the end item on the path. It MUST BE A DIRECTORY. If the 'CREATE' * -* option is true, then create any missing nodes in the path and create * -* and return the final node as well. * -* Generally, this MUST be the first function called by any module * -* as it also calls the initial setup code, in case it has never been * -* done yet. * -* This is used to set up a directory, before making nodes in it.. * -* * -* Warning: This function is RECURSIVE. * -* char *path, find this dir (err if not dir) * -* dn_p dirnode, starting point (0 = root) * -* int create, create path if not found * -* dn_p *dn_pp) where to return the node of the dir * -\***********************************************************************/ -int dev_finddir(char *orig_path, dn_p dirnode, int create, dn_p *dn_pp) /*proto*/ -{ - devnm_p devnmp; - char pathbuf[DEVMAXPATHSIZE]; - char *path; - char *name; - register char *cp; - int retval; - - - DBPRINT(("dev_finddir\n")); - if(!dirnode) dirnode = dev_root->dnp; - if(dirnode->type != DEV_DIR) return ENOTDIR; - if(strlen(orig_path) > (DEVMAXPATHSIZE - 1)) return ENAMETOOLONG; - path = pathbuf; - strcpy(path,orig_path); - while(*path == '/') path++; /* always absolute, skip leading / */ - /***************************************\ - * find the next segment of the name * - \***************************************/ - cp = name = path; - while((*cp != '/') && (*cp != 0)) - { - cp++; - } - /***********************************************\ - * Check to see if it's the last component * - \***********************************************/ - if(*cp) - { - path = cp + 1; /* path refers to the rest */ - *cp = 0; /* name is now a separate string */ - if(!(*path)) - { - path = (char *)0; /* was trailing slash */ - } - } - else - { - path = (char *)0; /* no more to do */ - } - - /***************************************\ - * Start scanning along the linked list * - \***************************************/ - devnmp = dirnode->by.Dir.dirlist; - while(devnmp && strcmp(devnmp->name,name)) - { - devnmp = devnmp->next; - } - if(devnmp) - { /* check it's a directory */ - if(devnmp->dnp->type != DEV_DIR) return ENOTDIR; - } - else - { - /***************************************\ - * The required element does not exist * - * So we will add it if asked to. * - \***************************************/ - if(!create) return ENOENT; - - if(retval = dev_add_node(name, dirnode ,DEV_DIR, - NULL, &devnmp)) - { - return retval; - } - } - if(path) /* decide whether to recurse more or return */ - { - return (dev_finddir(path,devnmp->dnp,create,dn_pp)); - } - else - { - *dn_pp = devnmp->dnp; - return 0; - } -} - -/***********************************************************************\ -* Add a new element to the devfs backing structure. * -* If we're creating a root node, then dirname is NULL * -\***********************************************************************/ -int dev_add_node(char *name, dn_p dirnode, int entrytype, union typeinfo *by, devnm_p *devnm_pp) /*proto*/ -{ - devnm_p devnmp; - devnm_p realthing; /* needed to create an alias */ - dn_p dnp; - int retval; - - DBPRINT(("dev_add_node\n")); - if(dirnode ) { - if(dirnode->type != DEV_DIR) return(ENOTDIR); - - retval = dev_finddir(name,dirnode,0,&dnp); /*don't create!*/ - dnp = NULL; /*just want the return code..*/ - if(retval != ENOENT) /* only acceptable answer */ - return(EEXIST); - } - /* - * make sure the name is legal - */ - if(strlen(name) > (DEVMAXNAMESIZE - 1)) return (ENAMETOOLONG); - /* - * Allocate and fill out a new backing node - */ - if(!(devnmp = (devnm_p)malloc(sizeof(devnm_t), - M_DEVFSBACK, M_NOWAIT))) - { - return ENOMEM; - } - bzero(devnmp,sizeof(devnm_t)); - if(!(dnp = (dn_p)malloc(sizeof(devnode_t), - M_DEVFSNODE, M_NOWAIT))) - { - free(devnmp,M_DEVFSBACK); - return ENOMEM; - } - bzero(dnp,sizeof(devnode_t)); - /* - * Link hte two together - * include the implicit link in the count of links to the devnode.. - * this stops it from being accidentally freed later. - */ - devnmp->dnp = dnp; - dnp->links = 1; /* implicit from our own name-node */ - - /* - * note the node type we are adding - * and set the creation times to NOW - * put in it's name - */ - strcpy(devnmp->name,name); - dnp->type = entrytype; - TIMEVAL_TO_TIMESPEC(&time,&(dnp->ctime)) - dnp->mtime = dnp->ctime; - dnp->atime = dnp->ctime; - - /* - * And set up a new 'clones' list (empty) - */ - devnmp->prev_frontp = &(devnmp->next_front); - - /* - * Check if we are making a root node.. - * (with no parent) - */ - if(dirnode) { - /* - * Put it on the END of the linked list of directory entries - */ - devnmp->parent = dirnode; - devnmp->prevp = dirnode->by.Dir.dirlast; - devnmp->next = *(devnmp->prevp); /* should be NULL */ /*right?*/ - *(devnmp->prevp) = devnmp; - dirnode->by.Dir.dirlast = &(devnmp->next); - dirnode->by.Dir.entrycount++; - } - /* - * return the answer - */ - switch(entrytype) { - case DEV_DIR: - /* - * As it's a directory, make sure it has a null entries list - */ - dnp->by.Dir.dirlast = - &(dnp->by.Dir.dirlist); - dnp->by.Dir.dirlist = (devnm_p)0; - if ( dirnode ) { - dnp->by.Dir.parent = (dn_p)dirnode; - } else { - /* root loops to self */ - dnp->by.Dir.parent = dnp; - } - dnp->by.Dir.parent->links++; /* account for .. */ - dnp->links++; /* for .*/ - dnp->by.Dir.myname = devnmp; - /* - * make sure that the ops associated with it are the ops - * that we use (by default) for directories - */ - dnp->ops = &devfs_vnodeop_p; - dnp->mode |= 0555; /* default perms */ - break; - case DEV_BDEV: - /* - * Make sure it has DEVICE type ops - * and device specific fields are correct - */ - dnp->ops = &dev_spec_vnodeop_p; - dnp->by.Bdev.bdevsw = by->Bdev.bdevsw; - dnp->by.Bdev.dev = by->Bdev.dev; - break; - case DEV_CDEV: - /* - * Make sure it has DEVICE type ops - * and device specific fields are correct - */ - dnp->ops = &dev_spec_vnodeop_p; - dnp->by.Cdev.cdevsw = by->Cdev.cdevsw; - dnp->by.Cdev.dev = by->Cdev.dev; - break; - case DEV_DDEV: - /* - * store the address of (the address of) the ops - * and the magic cookie to use with them - */ - dnp->by.Ddev.arg = by->Ddev.arg; - dnp->ops = by->Ddev.ops; - break; - - - case DEV_ALIAS: - /* - * point to the node we want to shadow - * Also store the fact we exist so that aliases - * can be deleted accuratly when the original node - * is deleted.. (i.e. when device is removed) - */ - realthing = by->Alias.realthing; - dnp->by.Alias.realthing = realthing; - dnp->by.Alias.next = realthing->as.back.aliases; - realthing->as.back.aliases = devnmp; - realthing->as.back.alias_count++; - break; - } - /* - * If we have a parent, then maybe we should duplicate - * ourselves onto any plane that the parent is on... - * Though this may be better handled elsewhere as - * it stops this routine from being used for front nodes - */ - if(dirnode) { - if(retval = devfs_add_fronts(dirnode->by.Dir.myname,devnmp)) - { - /*XXX*//* no idea what to do if it fails... */ - return retval; - } - } - - *devnm_pp = devnmp; - return 0 ; -} - -/*********************************************************************** - * remove all fronts to this dev and also it's aliases, - * Then remove this node. - * For now only allow DEVICE nodes to go.. XXX - * directory nodes are more complicated and may need more work.. - */ -int dev_remove(devnm_p devnmp) /*proto*/ -{ - devnm_p alias; - - DBPRINT(("dev_remove\n")); - /* - * Check the type of the node.. for now don't allow dirs - */ - switch(devnmp->dnp->type) - { - case DEV_BDEV: - case DEV_CDEV: - case DEV_DDEV: - case DEV_ALIAS: - case DEV_SLNK: - break; - case DEV_DIR: - default: - return(EINVAL); - } - /* - * Free each alias - */ - while ( devnmp->as.back.alias_count) - { - alias = devnmp->as.back.aliases; - devnmp->as.back.aliases = alias->dnp->by.Alias.next; - devnmp->as.back.alias_count--; - devfs_dn_free(alias->dnp); - free (alias, M_DEVFSBACK); - } - /* - * Now remove front items of the Main node itself - */ - devfs_remove_fronts(devnmp); - - /* - * now we should free the main node - */ - devfs_dn_free(devnmp->dnp); - free (devnmp, M_DEVFSBACK); - return 0; -} - -int dev_touch(devnm_p key) /* update the node for this dev */ /*proto*/ -{ - DBPRINT(("dev_touch\n")); - TIMEVAL_TO_TIMESPEC(&time,&(key->dnp->mtime)) - return 0; /*XXX*/ -} - -void devfs_dn_free(dn_p dnp) /*proto*/ -{ - if(dnp->links <= 0) - { - printf("devfs node reference count bogus\n"); - Debugger("devfs_dn_free"); - return; - } - if(--dnp->links == 0 ) - { - devfs_dropvnode(dnp); - free (dnp, M_DEVFSNODE); - } -} -/***********************************************************************\ -* UTILITY routine: * -* Return the major number for the cdevsw entry containing the given * -* address. * -\***********************************************************************/ -int get_cdev_major_num(caddr_t addr) /*proto*/ -{ - int index = 0; - - DBPRINT(("get_cdev_major_num\n")); - while (index < nchrdev) - { - if(((caddr_t)(cdevsw[index].d_open) == addr) - ||((caddr_t)(cdevsw[index].d_read) == addr) - ||((caddr_t)(cdevsw[index].d_ioctl) == addr)) - { - return index; - } - index++; - } - return -1; -} - -int get_bdev_major_num(caddr_t addr) /*proto*/ -{ - int index = 0; - - DBPRINT(("get_bdev_major_num\n")); - while (index < nblkdev) - { - if(((caddr_t)(bdevsw[index].d_open) == addr) - ||((caddr_t)(bdevsw[index].d_strategy) == addr) - ||((caddr_t)(bdevsw[index].d_ioctl) == addr)) - { - return index; - } - index++; - } - return -1; -} - -/***********************************************************************\ -* Add the named device entry into the given directory, and make it * -* The appropriate type... (called (sometimes indirectly) by drivers..) * -\***********************************************************************/ -void *dev_add(char *path, - char *name, - void *funct, - int minor, - int chrblk, - uid_t uid, - gid_t gid, - int perms) -{ - devnm_p new_dev; - dn_p dnp; /* devnode for parent directory */ - int retval; - int major ; - union typeinfo by; - - DBPRINT(("dev_add\n")); - retval = dev_finddir(path,NULL,1,&dnp); - if (retval) return 0; - switch(chrblk) - { - case DV_CHR: - major = get_cdev_major_num(funct); - by.Cdev.cdevsw = cdevsw + major; - by.Cdev.dev = makedev(major, minor); - if( dev_add_node(name, dnp, DEV_CDEV, - &by,&new_dev)) - return 0; - break; - case DV_BLK: - major = get_bdev_major_num(funct); - by.Bdev.bdevsw = bdevsw + major; - by.Bdev.dev = makedev(major, minor); - if( dev_add_node(name, dnp, DEV_BDEV, - &by, &new_dev)) - return 0; - break; - default: - return(0); - } - new_dev->dnp->gid = gid; - new_dev->dnp->uid = uid; - new_dev->dnp->mode |= perms; - return new_dev; -} - - - |
