diff options
Diffstat (limited to 'sys/miscfs/devfs')
-rw-r--r-- | sys/miscfs/devfs/devfs_back.c | 467 | ||||
-rw-r--r-- | sys/miscfs/devfs/devfs_front.c | 476 |
2 files changed, 0 insertions, 943 deletions
diff --git a/sys/miscfs/devfs/devfs_back.c b/sys/miscfs/devfs/devfs_back.c deleted file mode 100644 index 20a69e5..0000000 --- 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; -} - - - diff --git a/sys/miscfs/devfs/devfs_front.c b/sys/miscfs/devfs/devfs_front.c deleted file mode 100644 index a3d0255..0000000 --- a/sys/miscfs/devfs/devfs_front.c +++ /dev/null @@ -1,476 +0,0 @@ -/* - * Written by Julian Elischer (julian@DIALix.oz.au) - * - * $Header: /home/ncvs/src/sys/miscfs/devfs/devfs_front.c,v 1.3 1995/04/20 07:42:41 julian Exp $ - * - */ - -#include "param.h" -#include "systm.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" - - - -/***********************************************************************\ -* Given a directory backing node, and a child backing node, add the * -* appropriate front nodes to the front nodes of the directory to * -* represent the child node to the user * -* * -* on failure, front nodes will either be correct or not exist for each * -* front dir, however dirs completed will not be stripped of completed * -* frontnodes on failure of a later parent frontnode * -* * -\***********************************************************************/ -int devfs_add_fronts(devnm_p parent,devnm_p child) /*proto*/ -{ - devnm_p newfp; - devnm_p falias; - - DBPRINT((" devfs_add_fronts\n")); - /***********************************************\ - * Find the frontnodes of the parent node * - \***********************************************/ - for (falias = parent->next_front; falias; falias = falias->next_front) - { - if(dev_findfront(falias->dnp,child->name)) - { - printf("Device %s not created, already exists\n", - child->name); - continue; - } - if( dev_mk_front(falias->dnp,child,&newfp,NULL)) - { - printf("Device %s: allocation failed\n", - child->name); - continue; - } - - } - return(0); /* for now always succeed */ -} - -/***************************************************************\ -* Search down the linked list off a front dir to find "name" * -* return the dn_p for that node. -\***************************************************************/ -dn_p dev_findfront(dn_p dir,char *name) /*proto*/ -{ - devnm_p newfp; - DBPRINT((" dev_findfront(%s)\n",name)); - if(dir->type != DEV_DIR) return 0;/*XXX*/ /* printf?*/ - - if(name[0] == '.') - { - if(name[1] == 0) - { - return dir; - } - if((name[1] == '.') && (name[2] == 0)) - { - if(dir->by.Dir.parent == dir) /* root? */ - return dir; - else - return dir->by.Dir.parent; - } - } - newfp = dir->by.Dir.dirlist; - while(newfp) - { - if(!(strcmp(name,newfp->name))) - break; - newfp = newfp->next; - } - if(newfp) - return newfp->dnp; - else - return (dn_p)0; -} - -/***************************************************************\ -* Create and link in a new front element.. * -* Parent can be 0 for a root node * -* Not presently usable to make a symlink XXX * -* Must teach this to handle where there is no back node * -* maybe split into two bits? * -\***************************************************************/ -int dev_mk_front(dn_p parent,devnm_p back,devnm_p *devnm_pp , struct devfsmount *dvm) /*proto*/ -{ - devnm_p newfp; - struct devfsmount *dmt; - devnm_p newback; - devnm_p newfront; - int error; - dn_p dnp; - - DBPRINT((" dev_mk_front\n")); - if(parent && (parent->type != DEV_DIR)) return EINVAL; - /*XXX*/ /* printf?*/ - if(!(newfp = malloc(sizeof(devnm_t),M_DEVFSFRONT,M_NOWAIT))) - { - return(ENOMEM); - } - bzero(newfp,sizeof(*newfp)); - strcpy(newfp->name,back->name); - - /*******************************************************\ - * If we are creating an alias, Then we need to find the * - * real object's file_node. (It must pre-exist) * - * this means that aliases have no front nodes... * - * In effect ALIAS back nodes are just place markers * - \*******************************************************/ - if(back->dnp->type == DEV_ALIAS) - { - back = back->dnp->by.Alias.realthing; - } - - /* - * either use the existing devnode or make our own, - * depending on if we are a dev or a dir. - */ - switch(back->dnp->type) { - case DEV_BDEV: - case DEV_CDEV: - case DEV_DDEV: - dnp = newfp->dnp = back->dnp; - newfp->dnp->links++; /* wherever it is.....*/ - break; - case DEV_DIR: - dnp = newfp->dnp = malloc(sizeof(devnode_t), - M_DEVFSNODE,M_NOWAIT); - if(!(dnp)) - { - free(newfp,M_DEVFSFRONT); - return ENOMEM; - } - /* - * we have two options.. bcopy and reset some items, - * or bzero and reset or copy some items... - */ - bcopy(back->dnp,newfp->dnp,sizeof(devnode_t)); - dnp->links = 1; /* EXTRA from '.' */ - dnp->links++; /* wherever it is.....*/ - dnp->by.Dir.dirlast = - &dnp->by.Dir.dirlist; - dnp->by.Dir.dirlist = NULL; - dnp->by.Dir.entrycount = 0; - dnp->vn = NULL; - dnp->vn_id = 0; - break; - case DEV_SLNK: /* should never happen XXX (hmm might)*/ - default: - printf("unknown DEV type\n"); - return EINVAL; - } - /*******************************************************\ - * Put it in the parent's directory list (at the end). * - \*******************************************************/ - if(parent) - { - newfp->next = *parent->by.Dir.dirlast; - newfp->prevp = parent->by.Dir.dirlast; - *parent->by.Dir.dirlast = newfp; - parent->by.Dir.dirlast = &newfp->next; - parent->by.Dir.entrycount++; - newfp->dnp->dvm = parent->dvm; /* XXX bad for devs */ - if(back->dnp->type == DEV_DIR) - { - newfp->dnp->by.Dir.parent - = parent; - parent->links++; /* only dirs have '..'*/ - } - parent->len += strlen(newfp->name) + 8;/*ok, ok?*/ - } else { - /* - * it's the root node, put in the dvm - * and link it to itself... - * we know it's a DIR - */ - dnp->by.Dir.parent = newfp->dnp; - dnp->links++; /* extra for '..'*/ - dnp->dvm = dvm; - } - - /* - * not accounted for in the link counts.. - * only used to get from the front name entries - * to the total length of the names - * which is stored in the parent's devnode - */ - newfp->parent = parent; /* is NULL for root */ - /*******************************************************\ - * Put it in the appropriate back/front list too. * - \*******************************************************/ - newfp->next_front = *back->prev_frontp; - newfp->prev_frontp = back->prev_frontp; - *back->prev_frontp = newfp; - back->prev_frontp = &(newfp->next_front); - back->frontcount++; - newfp->as.front.realthing = back; - - /* - * If it is a directory, then recurse down all the other - * subnodes in it.... - */ - if ( newfp->dnp->type == DEV_DIR) - { - for(newback = back->dnp->by.Dir.dirlist; - newback; newback = newback->next) - { - if(error = dev_mk_front(newfp->dnp, - newback, &newfront, NULL)) - { - return error; - } - } - } - *devnm_pp = newfp; - return(0); -} - -/* - * duplicate the backing tree into a tree of nodes hung off the - * mount point given as the argument. Do this by - * calling dev_mk_front() which recurses all the way - * up the tree.. - */ -int devfs_make_plane(struct devfsmount *devfs_mp_p) /*proto*/ -{ - devnm_p parent; - devnm_p new; - devnm_p realthing; - int error; - - DBPRINT((" devfs_make_plane\n")); - realthing = dev_root; - if(error = dev_mk_front(0, realthing,&new, devfs_mp_p)) - { - return error; - } - devfs_mp_p->plane_root = new; - - return error; -} - -void devfs_free_plane(struct devfsmount *devfs_mp_p) /*proto*/ -{ - devnm_p devfp; - - DBPRINT((" devfs_free_plane\n")); - devfp = devfs_mp_p->plane_root; - if(devfp) dev_free_front(devfp); -} - -/* - * Remove all the front nodes associated with a backing node - */ -void devfs_remove_fronts(devnm_p devbp) /*proto*/ -{ - while(devbp->next_front) - { - dev_free_front(devbp->next_front); - } -} -/***************************************************************\ -* Free a front node (and any below it of it's a directory node) * -\***************************************************************/ -void dev_free_front(devnm_p devfp) /*proto*/ -{ - dn_p parent = devfp->parent; - devnm_p back; - - DBPRINT((" dev_free_front\n")); - if(devfp->dnp->type == DEV_DIR) - { - while(devfp->dnp->by.Dir.dirlist) - { - dev_free_front(devfp->dnp->by.Dir.dirlist); - } - /* - * drop the reference counts on our and our parent's - * nodes for "." and ".." (root has ".." -> "." ) - */ - devfs_dn_free(devfp->dnp); /* account for '.' */ - devfs_dn_free(devfp->dnp->by.Dir.parent); /* and '..' */ - } - /* - * unlink ourselves from the directory on this plane - */ - if(parent) /* if not fs root */ - { - if( *devfp->prevp = devfp->next)/* yes, assign */ - { - devfp->next->prevp = devfp->prevp; - } - else - { - parent->by.Dir.dirlast - = devfp->prevp; - } - parent->by.Dir.entrycount--; - parent->len -= strlen(devfp->name); - } - /* - * If the node has a backing pointer we need to free ourselves - * from that.. - * Remember that we may not HAVE a backing node. - */ - if (back = devfp->as.front.realthing) /* yes an assign */ - { - if( *devfp->prev_frontp = devfp->next_front)/* yes, assign */ - { - devfp->next_front->prev_frontp = devfp->prev_frontp; - } - else - { - back->prev_frontp = devfp->prev_frontp; - } - back->frontcount--; - } - /***************************************************************\ - * If the front node has it's own devnode structure, * - * then free it. * - \***************************************************************/ - devfs_dn_free(devfp->dnp); - free(devfp,M_DEVFSFRONT); - return; -} - -/*******************************************************\ -* Theoretically this could be called for any kind of * -* vnode, however in practice it must be a DEVFS vnode * -\*******************************************************/ -int devfs_vntodn(struct vnode *vn_p, dn_p *dn_pp) /*proto*/ -{ - -DBPRINT((" vntodn ")); - if(vn_p->v_tag != VT_DEVFS) - { - printf("bad-tag "); - Debugger("bad-tag "); - return(EINVAL); - } - if(vn_p->v_usecount == 0) - { - printf("not locked! "); - } - if((vn_p->v_type == VBAD) || (vn_p->v_type == VNON)) - { - printf("bad-type "); - return(EINVAL); - } - *dn_pp = (dn_p)vn_p->v_data; - - return(0); -} - -/***************************************************************\ -* given a dev_node, find the appropriate vnode if one is already* -* associated, or get a new one an associate it with the dev_node* -* need to check about vnode references.. should we increment it?* -\***************************************************************/ -int devfs_dntovn(dn_p dnp, struct vnode **vn_pp) /*proto*/ -{ - struct vnode *vn_p, *nvp; - int error = 0; - - vn_p = dnp->vn; -DBPRINT(("dntovn ")); - if( vn_p) - { - if(vn_p->v_id != dnp->vn_id) - { - printf("bad-id "); - goto skip; - } - if(vn_p->v_tag != VT_DEVFS) - { - printf("bad-tag "); - goto skip; - } - if(vn_p->v_op != *(dnp->ops)) - { - printf("bad-ops "); - goto skip; - } - if((dn_p)(vn_p->v_data) != dnp) - { - printf("bad-rev_link "); - goto skip; - } - if(vn_p->v_type != VNON) - { - vget(vn_p,0/*lockflag ?*/); /*XXX*/ - *vn_pp = vn_p; - return(0); - } - else - { - printf("bad-type"); - } -skip: - vn_p = (struct vnode *) 0; - } - if(!(error = getnewvnode(VT_DEVFS, - dnp->dvm->mount, - *(dnp->ops), - &vn_p))) - { - dnp->vn = vn_p; - dnp->vn_id = vn_p->v_id; - *vn_pp = vn_p; -DBPRINT(("(New vnode)")); - switch(dnp->type) - { - case DEV_SLNK: - break; - case DEV_DIR: - if(dnp->by.Dir.parent == dnp) - { - vn_p->v_flag |= VROOT; - } - vn_p->v_type = VDIR; - break; - case DEV_BDEV: - vn_p->v_type = VBLK; - if (nvp = checkalias(vn_p, - dnp->by.Bdev.dev, - (struct mount *)0)) - { - vput(vn_p); - vn_p = nvp; - } - break; - case DEV_CDEV: - vn_p->v_type = VCHR; - if (nvp = checkalias(vn_p, - dnp->by.Cdev.dev, - (struct mount *)0)) - { - vput(vn_p); - vn_p = nvp; - } - break; - case DEV_DDEV: - break; - } - if ( vn_p) - { - vn_p->v_mount = dnp->dvm->mount;/* XXX Duplicated */ - *vn_pp = vn_p; - vn_p->v_data = (void *)dnp; - } - else - { - error = EINVAL; - } - } - return error; -} |