summaryrefslogtreecommitdiffstats
path: root/sys/miscfs/devfs
diff options
context:
space:
mode:
Diffstat (limited to 'sys/miscfs/devfs')
-rw-r--r--sys/miscfs/devfs/devfs_back.c467
-rw-r--r--sys/miscfs/devfs/devfs_front.c476
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;
-}
OpenPOWER on IntegriCloud