mirror of
https://github.com/freebsd/freebsd-src.git
synced 2024-11-29 19:43:41 +00:00
more cleanups.. lots of code shuffled around too
routines renamed.. more simplifications, some warnings squashed.
This commit is contained in:
parent
60c7a2cd4e
commit
65ba86052a
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=10598
@ -1,21 +1,20 @@
|
|||||||
/* THIS FILE PRODUCED AUTOMATICALLY */
|
/* THIS FILE PRODUCED AUTOMATICALLY */
|
||||||
void devfs_sinit(caddr_t junk) /*proto*/;
|
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_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_add_name(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_touch(devnm_p key) /* update the node for this dev */ /*proto*/;
|
int dev_touch(devnm_p key) /* update the node for this dev */ /*proto*/;
|
||||||
void devfs_dn_free(dn_p dnp) /*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*/;
|
int devfs_add_fronts(devnm_p parent,devnm_p child) /*proto*/;
|
||||||
dn_p dev_findname(dn_p dir,char *name) /*proto*/;
|
void dev_remove_dev(devnm_p devnmp) /*proto*/;
|
||||||
int dev_mk_front(dn_p parent, devnm_p back, devnm_p *dnm_pp, struct devfsmount *dvm) /*proto*/;
|
int dev_dup_plane(struct devfsmount *devfs_mp_p) /*proto*/;
|
||||||
int devfs_make_plane(struct devfsmount *devfs_mp_p) /*proto*/;
|
|
||||||
void devfs_free_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*/;
|
void dev_free_name(devnm_p devnmp) /*proto*/;
|
||||||
int devfs_vntodn(struct vnode *vn_p, dn_p *dn_pp) /*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 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_init(void) /*proto*/;
|
||||||
int devfs_mount( struct mount *mp, char *path, caddr_t data, struct nameidata *ndp, struct proc *p) /*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*/;
|
int mountdevfs( struct mount *mp, struct proc *p) /*proto*/;
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
/*
|
/*
|
||||||
* Written by Julian Elischer (julian@DIALix.oz.au)
|
* 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"
|
#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....
|
* 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
|
#ifdef PARANOID
|
||||||
if(retval) panic("devfs_sinit: dev_add_node failed ");
|
if(retval) panic("devfs_sinit: dev_add_name failed ");
|
||||||
#endif
|
#endif
|
||||||
devfs_hidden_mount = (struct mount *)malloc(sizeof(struct mount),
|
devfs_hidden_mount = (struct mount *)malloc(sizeof(struct mount),
|
||||||
M_MOUNT,M_NOWAIT);
|
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 *
|
* 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' *
|
* 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(!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))
|
NULL, &devnmp))
|
||||||
{
|
{
|
||||||
return retval;
|
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 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 *
|
* 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 *
|
* 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 devnmp;
|
||||||
devnm_p realthing; /* needed to create an alias */
|
devnm_p realthing; /* needed to create an alias */
|
||||||
dn_p dnp;
|
dn_p dnp;
|
||||||
int retval;
|
int retval;
|
||||||
|
|
||||||
DBPRINT(("dev_add_node\n"));
|
DBPRINT(("dev_add_name\n"));
|
||||||
if(dirnode ) {
|
if(dirnode ) {
|
||||||
if(dirnode->type != DEV_DIR) return(ENOTDIR);
|
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;
|
*devnm_pp = devnmp;
|
||||||
return 0 ;
|
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*/
|
int dev_touch(devnm_p key) /* update the node for this dev */ /*proto*/
|
||||||
{
|
{
|
||||||
DBPRINT(("dev_touch\n"));
|
DBPRINT(("dev_touch\n"));
|
||||||
@ -435,104 +427,15 @@ void devfs_dn_free(dn_p dnp) /*proto*/
|
|||||||
}
|
}
|
||||||
if(--dnp->links == 0 )
|
if(--dnp->links == 0 )
|
||||||
{
|
{
|
||||||
|
/*probably need to do other cleanups XXX */
|
||||||
devfs_dropvnode(dnp);
|
devfs_dropvnode(dnp);
|
||||||
free (dnp, M_DEVFSNODE);
|
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 *
|
* 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 *
|
* front dir, however dirs completed will not be stripped of completed *
|
||||||
* frontnodes on failure of a later frontnode *
|
* 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*/
|
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);
|
child->name);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (dev_add_node(child->name,parent->dnp,child,
|
if (dev_add_name(child->name,parent->dnp,child,
|
||||||
type,NULL,&newnmp))
|
type,NULL,&newnmp))
|
||||||
{
|
{
|
||||||
printf("Device %s: allocation failed\n",
|
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 */
|
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)
|
dev_free_name(devnmp->next_front);
|
||||||
{
|
|
||||||
return dir;
|
|
||||||
}
|
|
||||||
if((name[1] == '.') && (name[2] == 0))
|
|
||||||
{
|
|
||||||
return dir->by.Dir.parent; /* for root, .. == . */
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
newfp = dir->by.Dir.dirlist;
|
/*
|
||||||
while(newfp)
|
* then free the main node
|
||||||
{
|
*/
|
||||||
if(!(strcmp(name,newfp->name)))
|
dev_free_name(devnmp);
|
||||||
return newfp->dnp;
|
return ;
|
||||||
newfp = newfp->next;
|
}
|
||||||
|
|
||||||
|
/***************************************************************
|
||||||
|
* 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;
|
||||||
}
|
}
|
||||||
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.. *
|
* Create and link in a new front element.. *
|
||||||
* Parent can be 0 for a root node *
|
* Parent can be 0 for a root node *
|
||||||
* Not presently usable to make a symlink XXX *
|
* Not presently usable to make a symlink XXX *
|
||||||
* Must teach this to handle where there is no back node *
|
* recursively will create subnodes corresponding to equivalent *
|
||||||
* maybe split into two bits? *
|
* 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;
|
devnm_p newnmp;
|
||||||
struct devfsmount *dmt;
|
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;
|
int error;
|
||||||
dn_p dnp = back->dnp;
|
dn_p dnp = back->dnp;
|
||||||
|
|
||||||
DBPRINT((" dev_mk_front\n"));
|
DBPRINT((" dev_dup_name\n"));
|
||||||
/*
|
/*
|
||||||
* go get the node made
|
* 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;
|
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;
|
for(newback = back->dnp->by.Dir.dirlist;
|
||||||
newback; newback = newback->next)
|
newback; newback = newback->next)
|
||||||
{
|
{
|
||||||
if(error = dev_mk_front(newnmp->dnp,
|
if(error = dev_dup_name(newnmp->dnp,
|
||||||
newback, &newfront, NULL))
|
newback, &newfront, NULL))
|
||||||
{
|
{
|
||||||
break; /* back out with an error */
|
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;
|
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*/
|
void dev_free_name(devnm_p devnmp) /*proto*/
|
||||||
{
|
{
|
||||||
@ -768,6 +668,13 @@ void dev_free_name(devnm_p devnmp) /*proto*/
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*******************************************************\
|
||||||
|
*********************************************************
|
||||||
|
* ROUTINES to control the connection between devfs *
|
||||||
|
* nodes and the system's vnodes *
|
||||||
|
*********************************************************
|
||||||
|
\*******************************************************/
|
||||||
|
|
||||||
/*******************************************************\
|
/*******************************************************\
|
||||||
* Theoretically this could be called for any kind of *
|
* Theoretically this could be called for any kind of *
|
||||||
* vnode, however in practice it must be a DEVFS vnode *
|
* vnode, however in practice it must be a DEVFS vnode *
|
||||||
@ -899,3 +806,94 @@ DBPRINT(("(New vnode)"));
|
|||||||
}
|
}
|
||||||
return error;
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Written by Julian Elischer (julian@DIALix.oz.au)
|
* 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_stat.f_fsid.val[1] = MOUNT_DEVFS;
|
||||||
mp->mnt_flag |= MNT_LOCAL;
|
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;
|
mp->mnt_data = (qaddr_t)0;
|
||||||
free((caddr_t)devfs_mp_p, M_DEVFSMNT);
|
free((caddr_t)devfs_mp_p, M_DEVFSMNT);
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Written by Julian Elischer (julian@DIALix.oz.au)
|
* 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.
|
* symlinks can wait 'til later.
|
||||||
*/
|
*/
|
||||||
@ -683,7 +683,8 @@ DBPRINT(("read\n"));
|
|||||||
case VREG:
|
case VREG:
|
||||||
return(EINVAL);
|
return(EINVAL);
|
||||||
case VDIR:
|
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 VCHR:
|
||||||
case VBLK:
|
case VBLK:
|
||||||
error = spec_read(ap);
|
error = spec_read(ap);
|
||||||
@ -887,6 +888,9 @@ int devfs_readdir(struct vop_readdir_args *ap) /*proto*/
|
|||||||
struct vnode *a_vp;
|
struct vnode *a_vp;
|
||||||
struct uio *a_uio;
|
struct uio *a_uio;
|
||||||
struct ucred *a_cred;
|
struct ucred *a_cred;
|
||||||
|
int *eofflag;
|
||||||
|
int *ncookies;
|
||||||
|
u_int **cookies;
|
||||||
} */
|
} */
|
||||||
{
|
{
|
||||||
struct vnode *vp = ap->a_vp;
|
struct vnode *vp = ap->a_vp;
|
||||||
@ -1196,15 +1200,13 @@ void devfs_dropvnode(dn_p dnp) /*proto*/
|
|||||||
{
|
{
|
||||||
struct vnode *vn_p;
|
struct vnode *vn_p;
|
||||||
|
|
||||||
|
#ifdef PARANOID
|
||||||
if(!dnp)
|
if(!dnp)
|
||||||
{
|
{
|
||||||
printf("devfs: dn count dropped too early\n");
|
printf("devfs: dn count dropped too early\n");
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
vn_p = dnp->vn;
|
vn_p = dnp->vn;
|
||||||
if(!vn_p)
|
|
||||||
{
|
|
||||||
printf("devfs: vn count dropped too early\n");
|
|
||||||
}
|
|
||||||
/*
|
/*
|
||||||
* check if we have a vnode.......
|
* check if we have a vnode.......
|
||||||
*/
|
*/
|
||||||
|
Loading…
Reference in New Issue
Block a user