more cleanups.. lots of code shuffled around too

routines renamed.. more simplifications,
some warnings squashed.
This commit is contained in:
Julian Elischer 1995-09-07 06:01:36 +00:00
parent 60c7a2cd4e
commit 65ba86052a
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=10598
4 changed files with 240 additions and 241 deletions

View File

@ -1,21 +1,20 @@
/* THIS FILE PRODUCED AUTOMATICALLY */
void devfs_sinit(caddr_t junk) /*proto*/;
dn_p dev_findname(dn_p dir,char *name) /*proto*/;
int dev_finddir(char *orig_path, dn_p dirnode, int create, dn_p *dn_pp) /*proto*/;
int dev_add_node(char *name, dn_p dirnode,devnm_p back, int entrytype, union typeinfo *by, devnm_p *devnm_pp) /*proto*/;
int dev_remove(devnm_p devnmp) /*proto*/;
int dev_add_name(char *name, dn_p dirnode,devnm_p back, int entrytype, union typeinfo *by, devnm_p *devnm_pp) /*proto*/;
int dev_touch(devnm_p key) /* update the node for this dev */ /*proto*/;
void devfs_dn_free(dn_p dnp) /*proto*/;
int get_cdev_major_num(caddr_t addr) /*proto*/;
int get_bdev_major_num(caddr_t addr) /*proto*/;
int devfs_add_fronts(devnm_p parent,devnm_p child) /*proto*/;
dn_p dev_findname(dn_p dir,char *name) /*proto*/;
int dev_mk_front(dn_p parent, devnm_p back, devnm_p *dnm_pp, struct devfsmount *dvm) /*proto*/;
int devfs_make_plane(struct devfsmount *devfs_mp_p) /*proto*/;
void dev_remove_dev(devnm_p devnmp) /*proto*/;
int dev_dup_plane(struct devfsmount *devfs_mp_p) /*proto*/;
void devfs_free_plane(struct devfsmount *devfs_mp_p) /*proto*/;
void devfs_remove_fronts(devnm_p devnmp) /*proto*/;
int dev_dup_name(dn_p parent, devnm_p back, devnm_p *dnm_pp, struct devfsmount *dvm) /*proto*/;
void dev_free_name(devnm_p devnmp) /*proto*/;
int devfs_vntodn(struct vnode *vn_p, dn_p *dn_pp) /*proto*/;
int devfs_dntovn(dn_p dnp, struct vnode **vn_pp) /*proto*/;
int get_cdev_major_num(caddr_t addr) /*proto*/;
int get_bdev_major_num(caddr_t addr) /*proto*/;
int devfs_init(void) /*proto*/;
int devfs_mount( struct mount *mp, char *path, caddr_t data, struct nameidata *ndp, struct proc *p) /*proto*/;
int mountdevfs( struct mount *mp, struct proc *p) /*proto*/;

View File

@ -2,7 +2,7 @@
/*
* Written by Julian Elischer (julian@DIALix.oz.au)
*
* $Header: /home/ncvs/src/sys/miscfs/devfs/devfs_tree.c,v 1.2 1995/09/06 09:29:16 julian Exp $
* $Header: /home/ncvs/src/sys/miscfs/devfs/devfs_tree.c,v 1.3 1995/09/06 23:15:53 julian Exp $
*/
#include "param.h"
@ -39,9 +39,9 @@ void devfs_sinit(caddr_t junk) /*proto*/
/*
* call the right routine at the right time with the right args....
*/
retval = dev_add_node("root",NULL,NULL,DEV_DIR,NULL,&dev_root);
retval = dev_add_name("root",NULL,NULL,DEV_DIR,NULL,&dev_root);
#ifdef PARANOID
if(retval) panic("devfs_sinit: dev_add_node failed ");
if(retval) panic("devfs_sinit: dev_add_name failed ");
#endif
devfs_hidden_mount = (struct mount *)malloc(sizeof(struct mount),
M_MOUNT,M_NOWAIT);
@ -56,8 +56,43 @@ void devfs_sinit(caddr_t junk) /*proto*/
}
/***********************************************************************\
* Routines used to add and remove nodes from the base tree *
*************************************************************************
* Routines used to find our way to a point in the tree *
*************************************************************************
\***********************************************************************/
/***************************************************************\
* Search down the linked list off a dir to find "name" *
* return the dn_p for that node.
\***************************************************************/
dn_p dev_findname(dn_p dir,char *name) /*proto*/
{
devnm_p newfp;
DBPRINT((" dev_findname(%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))
{
return dir->by.Dir.parent; /* for root, .. == . */
}
}
newfp = dir->by.Dir.dirlist;
while(newfp)
{
if(!(strcmp(name,newfp->name)))
return newfp->dnp;
newfp = newfp->next;
}
return (dn_p)0;
}
/***********************************************************************\
* 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' *
@ -140,7 +175,7 @@ int dev_finddir(char *orig_path, dn_p dirnode, int create, dn_p *dn_pp) /*proto*
\***************************************/
if(!create) return ENOENT;
if(retval = dev_add_node(name, dirnode, NULL ,DEV_DIR,
if(retval = dev_add_name(name, dirnode, NULL ,DEV_DIR,
NULL, &devnmp))
{
return retval;
@ -164,15 +199,17 @@ int dev_finddir(char *orig_path, dn_p dirnode, int create, dn_p *dn_pp) /*proto*
* If we're creating a root node, then dirname is NULL *
* If devnode is non zero, then we just want to create a link to it *
* This implies that we are not at base level and it's a not a DIR *
* *
* Creates a name node, and (optionally) a new dev_node to go with it *
\***********************************************************************/
int dev_add_node(char *name, dn_p dirnode,devnm_p back, int entrytype, union typeinfo *by, devnm_p *devnm_pp) /*proto*/
int dev_add_name(char *name, dn_p dirnode,devnm_p back, 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"));
DBPRINT(("dev_add_name\n"));
if(dirnode ) {
if(dirnode->type != DEV_DIR) return(ENOTDIR);
@ -367,57 +404,12 @@ int dev_add_node(char *name, dn_p dirnode,devnm_p back, int entrytype, union typ
*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
* Remember, aliases can't have front nodes
*/
while ( alias = devnmp->as.back.aliases)
{
devnmp->as.back.aliases = alias->dnp->by.Alias.next;
devfs_dn_free(alias->dnp);
free (alias, M_DEVFSNAME);
}
/*
* 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_DEVFSNAME);
return 0;
}
/***************************************************************\
* DEV_NODE reference count manipulations.. when a ref count *
* reaches 0, the node is to be deleted *
\***************************************************************/
int dev_touch(devnm_p key) /* update the node for this dev */ /*proto*/
{
DBPRINT(("dev_touch\n"));
@ -435,104 +427,15 @@ void devfs_dn_free(dn_p dnp) /*proto*/
}
if(--dnp->links == 0 )
{
/*probably need to do other cleanups XXX */
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, NULL, 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, NULL, 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;
}
/***********************************************************************\
* Front Node Operations *
* Add or delete a chain of front nodes *
\***********************************************************************/
/***********************************************************************\
@ -544,6 +447,8 @@ void *dev_add(char *path,
* front dir, however dirs completed will not be stripped of completed *
* frontnodes on failure of a later frontnode *
* *
* This allows a new node to be propogated through all mounted planes *
* *
\***********************************************************************/
int devfs_add_fronts(devnm_p parent,devnm_p child) /*proto*/
{
@ -563,7 +468,7 @@ int devfs_add_fronts(devnm_p parent,devnm_p child) /*proto*/
child->name);
continue;
}
if (dev_add_node(child->name,parent->dnp,child,
if (dev_add_name(child->name,parent->dnp,child,
type,NULL,&newnmp))
{
printf("Device %s: allocation failed\n",
@ -574,46 +479,83 @@ int devfs_add_fronts(devnm_p parent,devnm_p child) /*proto*/
}
return(0); /* for now always succeed */
}
/***************************************************************\
* Search down the linked list off a dir to find "name" *
* return the dn_p for that node.
\***************************************************************/
dn_p dev_findname(dn_p dir,char *name) /*proto*/
{
devnm_p newfp;
DBPRINT((" dev_findname(%s)\n",name));
if(dir->type != DEV_DIR) return 0;/*XXX*/ /* printf?*/
if(name[0] == '.')
/***********************************************************************
* remove all instances of this devicename [for backing nodes..]
* note.. if there is another link to the node (non dir nodes only)
* then the devfs_node will still exist as the ref count will be non-0
* removing a directory node will remove all sup-nodes on all planes (ZAP)
*
* Used be device drivers to remove nodes that are no longer relevant
***********************************************************************/
void dev_remove_dev(devnm_p devnmp) /*proto*/
{
DBPRINT(("dev_remove_dev\n"));
/*
* Keep removing the next front node till no more exist
*/
while(devnmp->next_front)
{
if(name[1] == 0)
{
return dir;
dev_free_name(devnmp->next_front);
}
if((name[1] == '.') && (name[2] == 0))
{
return dir->by.Dir.parent; /* for root, .. == . */
/*
* then free the main node
*/
dev_free_name(devnmp);
return ;
}
/***************************************************************
* duplicate the backing tree into a tree of nodes hung off the
* mount point given as the argument. Do this by
* calling dev_dup_name which recurses all the way
* up the tree..
* If we are the first plane, just return the base root
**************************************************************/
int dev_dup_plane(struct devfsmount *devfs_mp_p) /*proto*/
{
devnm_p new;
int error = 0;
DBPRINT((" dev_dup_plane\n"));
if(devfs_up_and_going) {
if(error = dev_dup_name(NULL, dev_root, &new, devfs_mp_p)) {
return error;
}
} else { /* we are doing the dummy mount during initialisation.. */
new = dev_root;
}
newfp = dir->by.Dir.dirlist;
while(newfp)
{
if(!(strcmp(name,newfp->name)))
return newfp->dnp;
newfp = newfp->next;
}
return (dn_p)0;
devfs_mp_p->plane_root = new;
return error;
}
/***************************************************************\
* Free a whole plane
\***************************************************************/
void devfs_free_plane(struct devfsmount *devfs_mp_p) /*proto*/
{
devnm_p devnmp;
DBPRINT((" devfs_free_plane\n"));
devnmp = devfs_mp_p->plane_root;
if(devnmp) dev_free_name(devnmp);
devfs_mp_p->plane_root = NULL;
}
/***************************************************************\
* 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? *
* recursively will create subnodes corresponding to equivalent *
* child nodes in the base level *
\***************************************************************/
int dev_mk_front(dn_p parent, devnm_p back, devnm_p *dnm_pp, struct devfsmount *dvm) /*proto*/
int dev_dup_name(dn_p parent, devnm_p back, devnm_p *dnm_pp, struct devfsmount *dvm) /*proto*/
{
devnm_p newnmp;
struct devfsmount *dmt;
@ -622,11 +564,11 @@ int dev_mk_front(dn_p parent, devnm_p back, devnm_p *dnm_pp, struct devfsmount *
int error;
dn_p dnp = back->dnp;
DBPRINT((" dev_mk_front\n"));
DBPRINT((" dev_dup_name\n"));
/*
* go get the node made
*/
error = dev_add_node(back->name,parent,back,dnp->type,NULL,&newnmp);
error = dev_add_name(back->name,parent,back,dnp->type,NULL,&newnmp);
if ( error ) return error;
/*
@ -647,7 +589,7 @@ int dev_mk_front(dn_p parent, devnm_p back, devnm_p *dnm_pp, struct devfsmount *
for(newback = back->dnp->by.Dir.dirlist;
newback; newback = newback->next)
{
if(error = dev_mk_front(newnmp->dnp,
if(error = dev_dup_name(newnmp->dnp,
newback, &newfront, NULL))
{
break; /* back out with an error */
@ -658,52 +600,10 @@ int dev_mk_front(dn_p parent, devnm_p back, devnm_p *dnm_pp, struct devfsmount *
return error;
}
/*
* 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 new;
int error = 0;
DBPRINT((" devfs_make_plane\n"));
if(devfs_up_and_going) {
if(error = dev_mk_front(NULL, dev_root, &new, devfs_mp_p)) {
return error;
}
} else { /* we are doing the dummy mount during initialisation.. */
new = dev_root;
}
devfs_mp_p->plane_root = new;
return error;
}
void devfs_free_plane(struct devfsmount *devfs_mp_p) /*proto*/
{
devnm_p devnmp;
DBPRINT((" devfs_free_plane\n"));
devnmp = devfs_mp_p->plane_root;
if(devnmp) dev_free_name(devnmp);
devfs_mp_p->plane_root = NULL;
}
/*
* Remove all the front nodes associated with a backing node
*/
void devfs_remove_fronts(devnm_p devnmp) /*proto*/
{
while(devnmp->next_front)
{
dev_free_name(devnmp->next_front);
}
}
/***************************************************************\
* Free a front node (and any below it of it's a directory node) *
* Free a name node (and any below it of it's a directory node) *
* remember that if there are other names pointing to the *
* dev_node then it may not get freed yet *
\***************************************************************/
void dev_free_name(devnm_p devnmp) /*proto*/
{
@ -768,6 +668,13 @@ void dev_free_name(devnm_p devnmp) /*proto*/
return;
}
/*******************************************************\
*********************************************************
* ROUTINES to control the connection between devfs *
* nodes and the system's vnodes *
*********************************************************
\*******************************************************/
/*******************************************************\
* Theoretically this could be called for any kind of *
* vnode, however in practice it must be a DEVFS vnode *
@ -899,3 +806,94 @@ DBPRINT(("(New vnode)"));
}
return error;
}
/***********************************************************************\
* 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_name(name, dnp, NULL, 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_name(name, dnp, NULL, 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;
}

View File

@ -1,7 +1,7 @@
/*
* Written by Julian Elischer (julian@DIALix.oz.au)
*
* $Header: /home/ncvs/src/sys/miscfs/devfs/devfs_vfsops.c,v 1.4 1995/09/03 05:43:42 julian Exp $
* $Header: /home/ncvs/src/sys/miscfs/devfs/devfs_vfsops.c,v 1.5 1995/09/06 09:29:17 julian Exp $
*
*
*/
@ -105,7 +105,7 @@ int mountdevfs( struct mount *mp, struct proc *p) /*proto*/
mp->mnt_stat.f_fsid.val[1] = MOUNT_DEVFS;
mp->mnt_flag |= MNT_LOCAL;
if(error = devfs_make_plane(devfs_mp_p))
if(error = dev_dup_plane(devfs_mp_p))
{
mp->mnt_data = (qaddr_t)0;
free((caddr_t)devfs_mp_p, M_DEVFSMNT);

View File

@ -1,7 +1,7 @@
/*
* Written by Julian Elischer (julian@DIALix.oz.au)
*
* $Header: /home/ncvs/src/sys/miscfs/devfs/devfs_vnops.c,v 1.9 1995/09/06 09:29:18 julian Exp $
* $Header: /home/ncvs/src/sys/miscfs/devfs/devfs_vnops.c,v 1.10 1995/09/06 23:15:54 julian Exp $
*
* symlinks can wait 'til later.
*/
@ -683,7 +683,8 @@ DBPRINT(("read\n"));
case VREG:
return(EINVAL);
case VDIR:
return VOP_READDIR(ap->a_vp,ap->a_uio,ap->a_cred);
return VOP_READDIR(ap->a_vp,ap->a_uio,ap->a_cred,
NULL,NULL,NULL);
case VCHR:
case VBLK:
error = spec_read(ap);
@ -887,6 +888,9 @@ int devfs_readdir(struct vop_readdir_args *ap) /*proto*/
struct vnode *a_vp;
struct uio *a_uio;
struct ucred *a_cred;
int *eofflag;
int *ncookies;
u_int **cookies;
} */
{
struct vnode *vp = ap->a_vp;
@ -1196,15 +1200,13 @@ void devfs_dropvnode(dn_p dnp) /*proto*/
{
struct vnode *vn_p;
#ifdef PARANOID
if(!dnp)
{
printf("devfs: dn count dropped too early\n");
}
#endif
vn_p = dnp->vn;
if(!vn_p)
{
printf("devfs: vn count dropped too early\n");
}
/*
* check if we have a vnode.......
*/