mirror of
https://github.com/freebsd/freebsd-src
synced 2024-11-05 18:22:52 +00:00
Submitted by: julian
I did a cleanup on the code.. (why didn't I do that before I checked it in? I hear you ask..)
This commit is contained in:
parent
d7e591aeab
commit
b79223f61b
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=7957
6 changed files with 161 additions and 176 deletions
|
@ -1,7 +1,7 @@
|
|||
this file is: /sys/miscfs/devfs/README (or soon will be)
|
||||
this file is: /sys/miscfs/devfs/README
|
||||
|
||||
to enable: add
|
||||
options devfs
|
||||
options DEVFS
|
||||
|
||||
to your config file..
|
||||
expect it to be highly useless for a while,
|
||||
|
@ -17,7 +17,8 @@ a "devnode" struct, that holds information about the device
|
|||
(or directory) and a pointer to the vnode if one has been associated
|
||||
with that node. The back node itself can be considered to be
|
||||
a directory entry, and contains the default name of the device,
|
||||
and a link to the directory that holds it.
|
||||
and a link to the directory that holds it. The devnode can be
|
||||
considered the inode.
|
||||
|
||||
When you mount the devfs somewhere (you can mount it multiple times in
|
||||
multiple places), a front layer is created that contains a tree of 'front'
|
||||
|
@ -26,6 +27,9 @@ nodes.
|
|||
Think of this as a Transparency, layed over the top of the blueprint.
|
||||
(or possibly a photocopy).
|
||||
|
||||
The front and back nodes are identical in type, but the back nodes
|
||||
are reserved for kernel use only, and are protected from the user.
|
||||
|
||||
To start with there is a 1:1 relationship between the front nodes
|
||||
and the backing nodes, however once the front plane has been created
|
||||
the nodes can be moved around within that plane (or deleted).
|
||||
|
@ -46,11 +50,6 @@ e.g. remove or rename nodes
|
|||
Multiple mountings are like multiple transparencies,
|
||||
each showing through to the original blueprint.
|
||||
|
||||
The nodes on the 'front' plane representing the particular mounting of the
|
||||
DEVFS that you are interested in, each have a link back to the 'backing'
|
||||
node to which they refer to get information about the node (e.g.
|
||||
major/minor) etc.
|
||||
|
||||
Information that is to be shared between these mounts is stored
|
||||
in the 'backing' node for that object. Once you have erased 'front'
|
||||
object, there is no memory of where the backing object was, and
|
||||
|
@ -97,10 +96,11 @@ effect of 're-propogating' through any backing nodes that find they
|
|||
have no front nodes in that plane.
|
||||
|
||||
|
||||
NOTES FOR RELEASE 1
|
||||
NOTES FOR RELEASE 1.1
|
||||
1/ this is very preliminary
|
||||
2/ Attempts to unmount a devfs structure while you are 'IN' in will
|
||||
result in a message "hanging vnode" and the system will panic.
|
||||
(in fact I see this even not being in it :( )
|
||||
3/ 'find /devfs -print' will only find the directories, and the devices
|
||||
don't show up.. (?)... find /dev/fs -ls DOES show all the devices.
|
||||
4/ the dates of all nodes is '0' i.e. 00:00 1st Jan 1970 UTC.
|
||||
|
@ -115,9 +115,11 @@ ability to unlink and mv nodes.
|
|||
them, or alternatively, corrupting things.. I need a vnode specialist
|
||||
to look at this.
|
||||
7/ The back and front node structures have become very similar with time
|
||||
and I have decided to merge them to a single structure,
|
||||
which will be called a "devname" struct, as they can be thought of
|
||||
and I decided to merge them to a single structure,
|
||||
which is called a "dev_name" struct, as they can be thought of
|
||||
as the analogue of a directory entry, except that they are linked
|
||||
together rather than in an array. The "devnode" struct can be considered
|
||||
analogous to the inodes of a UFS.
|
||||
There may still be artifacts in the code that reflect that the front and
|
||||
back nodes were once different structs.
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
|
||||
|
||||
|
||||
devb_p dev_root; /* root of the backing tree */
|
||||
devnm_p dev_root; /* root of the backing tree */
|
||||
int devfs_set_up = 0; /* note tha we HAVE set up the backing tree */
|
||||
|
||||
/*
|
||||
|
@ -33,7 +33,7 @@ int devfs_set_up = 0; /* note tha we HAVE set up the backing tree */
|
|||
void devfs_back_init() /*proto*/
|
||||
{
|
||||
|
||||
devb_p devbp;
|
||||
devnm_p devbp;
|
||||
dn_p dnp;
|
||||
/*
|
||||
* This may be called several times.. only do it if it needs
|
||||
|
@ -44,12 +44,12 @@ void devfs_back_init() /*proto*/
|
|||
/*
|
||||
* Allocate and fill out a new backing node
|
||||
*/
|
||||
if(!(devbp = (devb_p)malloc(sizeof(devb_t),
|
||||
if(!(devbp = (devnm_p)malloc(sizeof(devnm_t),
|
||||
M_DEVFSBACK, M_NOWAIT)))
|
||||
{
|
||||
return ;
|
||||
}
|
||||
bzero(devbp,sizeof(devb_t));
|
||||
bzero(devbp,sizeof(devnm_t));
|
||||
/*
|
||||
* And the devnode associated with it
|
||||
*/
|
||||
|
@ -72,15 +72,15 @@ void devfs_back_init() /*proto*/
|
|||
dnp->type = DEV_DIR;
|
||||
dnp->links++; /* for .*/
|
||||
/* root loops to self */
|
||||
dnp->by.BackDir.parent = dnp;
|
||||
dnp->by.Dir.parent = dnp;
|
||||
dnp->links++; /* for ..*/
|
||||
/*
|
||||
* set up the list of children (none so far)
|
||||
*/
|
||||
dnp->by.BackDir.dirlist = (devb_p)0;
|
||||
dnp->by.BackDir.dirlast =
|
||||
&dnp->by.BackDir.dirlist;
|
||||
dnp->by.BackDir.myname = devbp;
|
||||
dnp->by.Dir.dirlist = (devnm_p)0;
|
||||
dnp->by.Dir.dirlast =
|
||||
&dnp->by.Dir.dirlist;
|
||||
dnp->by.Dir.myname = devbp;
|
||||
/*
|
||||
* set up a pointer to directory type ops
|
||||
*/
|
||||
|
@ -96,8 +96,8 @@ void devfs_back_init() /*proto*/
|
|||
/*
|
||||
* and the list of layers
|
||||
*/
|
||||
devbp->fronts = NULL;
|
||||
devbp->lastfront = &(devbp->fronts);
|
||||
devbp->next_front = NULL;
|
||||
devbp->prev_frontp = &(devbp->next_front);
|
||||
|
||||
|
||||
/*
|
||||
|
@ -126,7 +126,7 @@ void devfs_back_init() /*proto*/
|
|||
\***********************************************************************/
|
||||
int dev_finddir(char *orig_path, dn_p dirnode, int create, dn_p *dn_pp) /*proto*/
|
||||
{
|
||||
devb_p devbp;
|
||||
devnm_p devbp;
|
||||
char pathbuf[DEVMAXPATHSIZE];
|
||||
char *path;
|
||||
char *name;
|
||||
|
@ -170,7 +170,7 @@ int dev_finddir(char *orig_path, dn_p dirnode, int create, dn_p *dn_pp) /*proto*
|
|||
/***************************************\
|
||||
* Start scanning along the linked list *
|
||||
\***************************************/
|
||||
devbp = dirnode->by.BackDir.dirlist;
|
||||
devbp = dirnode->by.Dir.dirlist;
|
||||
while(devbp && strcmp(devbp->name,name))
|
||||
{
|
||||
devbp = devbp->next;
|
||||
|
@ -207,10 +207,10 @@ int dev_finddir(char *orig_path, dn_p dirnode, int create, dn_p *dn_pp) /*proto*
|
|||
/***********************************************************************\
|
||||
* Add a new element to the devfs backing structure. *
|
||||
\***********************************************************************/
|
||||
int dev_add_node(char *name, dn_p dirnode, int entrytype, union typeinfo *by, devb_p *devb_pp) /*proto*/
|
||||
int dev_add_node(char *name, dn_p dirnode, int entrytype, union typeinfo *by, devnm_p *devnm_pp) /*proto*/
|
||||
{
|
||||
devb_p devbp;
|
||||
devb_p realthing; /* needed to create an alias */
|
||||
devnm_p devbp;
|
||||
devnm_p realthing; /* needed to create an alias */
|
||||
dn_p dnp;
|
||||
int retval;
|
||||
|
||||
|
@ -225,12 +225,12 @@ int dev_add_node(char *name, dn_p dirnode, int entrytype, union typeinfo *by, de
|
|||
/*
|
||||
* Allocate and fill out a new backing node
|
||||
*/
|
||||
if(!(devbp = (devb_p)malloc(sizeof(devb_t),
|
||||
if(!(devbp = (devnm_p)malloc(sizeof(devnm_t),
|
||||
M_DEVFSBACK, M_NOWAIT)))
|
||||
{
|
||||
return ENOMEM;
|
||||
}
|
||||
bzero(devbp,sizeof(devb_t));
|
||||
bzero(devbp,sizeof(devnm_t));
|
||||
if(!(dnp = (dn_p)malloc(sizeof(devnode_t),
|
||||
M_DEVFSNODE, M_NOWAIT)))
|
||||
{
|
||||
|
@ -257,17 +257,17 @@ int dev_add_node(char *name, dn_p dirnode, int entrytype, union typeinfo *by, de
|
|||
/*
|
||||
* And set up a new 'clones' list (empty)
|
||||
*/
|
||||
devbp->lastfront = &(devbp->fronts);
|
||||
devbp->prev_frontp = &(devbp->next_front);
|
||||
|
||||
/*
|
||||
* Put it on the END of the linked list of directory entries
|
||||
*/
|
||||
devbp->parent = dirnode;
|
||||
devbp->prevp = dirnode->by.BackDir.dirlast;
|
||||
devbp->prevp = dirnode->by.Dir.dirlast;
|
||||
devbp->next = *(devbp->prevp); /* should be NULL */ /*right?*/
|
||||
*(devbp->prevp) = devbp;
|
||||
dirnode->by.BackDir.dirlast = &(devbp->next);
|
||||
dirnode->by.BackDir.entrycount++;
|
||||
dirnode->by.Dir.dirlast = &(devbp->next);
|
||||
dirnode->by.Dir.entrycount++;
|
||||
|
||||
/*
|
||||
* return the answer
|
||||
|
@ -277,11 +277,11 @@ int dev_add_node(char *name, dn_p dirnode, int entrytype, union typeinfo *by, de
|
|||
/*
|
||||
* As it's a directory, make sure it has a null entries list
|
||||
*/
|
||||
dnp->by.BackDir.dirlast =
|
||||
&(dnp->by.BackDir.dirlist);
|
||||
dnp->by.BackDir.dirlist = (devb_p)0;
|
||||
dnp->by.BackDir.parent = (dn_p)dirnode;
|
||||
dnp->by.BackDir.myname = devbp;
|
||||
dnp->by.Dir.dirlast =
|
||||
&(dnp->by.Dir.dirlist);
|
||||
dnp->by.Dir.dirlist = (devnm_p)0;
|
||||
dnp->by.Dir.parent = (dn_p)dirnode;
|
||||
dnp->by.Dir.myname = devbp;
|
||||
/*
|
||||
* make sure that the ops associated with it are the ops
|
||||
* that we use (by default) for directories
|
||||
|
@ -326,19 +326,19 @@ int dev_add_node(char *name, dn_p dirnode, int entrytype, union typeinfo *by, de
|
|||
*/
|
||||
realthing = by->Alias.realthing;
|
||||
dnp->by.Alias.realthing = realthing;
|
||||
dnp->by.Alias.next = realthing->aliases;
|
||||
realthing->aliases = devbp;
|
||||
realthing->alias_count++;
|
||||
dnp->by.Alias.next = realthing->as.back.aliases;
|
||||
realthing->as.back.aliases = devbp;
|
||||
realthing->as.back.alias_count++;
|
||||
break;
|
||||
}
|
||||
|
||||
if(retval = devfs_add_fronts(dirnode->by.BackDir.myname/*XXX*/,devbp))
|
||||
if(retval = devfs_add_fronts(dirnode->by.Dir.myname/*XXX*/,devbp))
|
||||
{
|
||||
/*XXX*//* no idea what to do if it fails... */
|
||||
return retval;
|
||||
}
|
||||
|
||||
*devb_pp = devbp;
|
||||
*devnm_pp = devbp;
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
|
@ -348,9 +348,9 @@ int dev_add_node(char *name, dn_p dirnode, int entrytype, union typeinfo *by, de
|
|||
* For now only allow DEVICE nodes to go.. XXX
|
||||
* directory nodes are more complicated and may need more work..
|
||||
*/
|
||||
int dev_remove(devb_p devbp) /*proto*/
|
||||
int dev_remove(devnm_p devbp) /*proto*/
|
||||
{
|
||||
devb_p alias;
|
||||
devnm_p alias;
|
||||
|
||||
DBPRINT(("dev_remove\n"));
|
||||
/*
|
||||
|
@ -371,11 +371,11 @@ int dev_remove(devb_p devbp) /*proto*/
|
|||
/*
|
||||
* Free each alias
|
||||
*/
|
||||
while ( devbp->alias_count)
|
||||
while ( devbp->as.back.alias_count)
|
||||
{
|
||||
alias = devbp->aliases;
|
||||
devbp->aliases = alias->dnp->by.Alias.next;
|
||||
devbp->alias_count--;
|
||||
alias = devbp->as.back.aliases;
|
||||
devbp->as.back.aliases = alias->dnp->by.Alias.next;
|
||||
devbp->as.back.alias_count--;
|
||||
devfs_dn_free(alias->dnp);
|
||||
free (alias, M_DEVFSBACK);
|
||||
}
|
||||
|
@ -392,7 +392,7 @@ int dev_remove(devb_p devbp) /*proto*/
|
|||
return 0;
|
||||
}
|
||||
|
||||
int dev_touch(devb_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"));
|
||||
TIMEVAL_TO_TIMESPEC(&time,&(key->dnp->mtime))
|
||||
|
@ -458,9 +458,9 @@ int get_bdev_major_num(caddr_t addr) /*proto*/
|
|||
* Add the named device entry into the given directory, and make it *
|
||||
* The appropriate type... (called (sometimes indirectly) by drivers..) *
|
||||
\***********************************************************************/
|
||||
devb_p dev_add(char *path,char *name,caddr_t funct,int minor,int chrblk,uid_t uid,gid_t gid, int perms) /*proto*/
|
||||
devnm_p dev_add(char *path,char *name,caddr_t funct,int minor,int chrblk,uid_t uid,gid_t gid, int perms) /*proto*/
|
||||
{
|
||||
devb_p new_dev;
|
||||
devnm_p new_dev;
|
||||
dn_p dnp; /* devnode for parent directory */
|
||||
int retval;
|
||||
int major ;
|
||||
|
|
|
@ -29,16 +29,16 @@
|
|||
* frontnodes on failure of a later parent frontnode *
|
||||
* *
|
||||
\***********************************************************************/
|
||||
int devfs_add_fronts(devb_p parent,devb_p child) /*proto*/
|
||||
int devfs_add_fronts(devnm_p parent,devnm_p child) /*proto*/
|
||||
{
|
||||
devf_p newfp;
|
||||
devf_p falias;
|
||||
devnm_p newfp;
|
||||
devnm_p falias;
|
||||
|
||||
DBPRINT((" devfs_add_fronts\n"));
|
||||
/***********************************************\
|
||||
* Find the frontnodes of the parent node *
|
||||
\***********************************************/
|
||||
for (falias = parent->fronts; falias; falias = falias->next_front)
|
||||
for (falias = parent->next_front; falias; falias = falias->next_front)
|
||||
{
|
||||
if(dev_findfront(falias->dnp,child->name))
|
||||
{
|
||||
|
@ -63,7 +63,7 @@ int devfs_add_fronts(devb_p parent,devb_p child) /*proto*/
|
|||
\***************************************************************/
|
||||
dn_p dev_findfront(dn_p dir,char *name) /*proto*/
|
||||
{
|
||||
devf_p newfp;
|
||||
devnm_p newfp;
|
||||
DBPRINT((" dev_findfront(%s)\n",name));
|
||||
if(dir->type != DEV_DIR) return 0;/*XXX*/ /* printf?*/
|
||||
|
||||
|
@ -101,18 +101,19 @@ dn_p dev_findfront(dn_p dir,char *name) /*proto*/
|
|||
* Must teach this to handle where there is no back node *
|
||||
* maybe split into two bits? *
|
||||
\***************************************************************/
|
||||
int dev_mk_front(dn_p parent,devb_p back,devf_p *devf_pp , struct devfsmount *dvm) /*proto*/
|
||||
int dev_mk_front(dn_p parent,devnm_p back,devnm_p *devnm_pp , struct devfsmount *dvm) /*proto*/
|
||||
{
|
||||
devf_p newfp;
|
||||
devnm_p newfp;
|
||||
struct devfsmount *dmt;
|
||||
devb_p newback;
|
||||
devf_p newfront;
|
||||
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(*newfp),M_DEVFSFRONT,M_NOWAIT)))
|
||||
if(!(newfp = malloc(sizeof(devnm_t),M_DEVFSFRONT,M_NOWAIT)))
|
||||
{
|
||||
return(ENOMEM);
|
||||
}
|
||||
|
@ -124,7 +125,6 @@ int dev_mk_front(dn_p parent,devb_p back,devf_p *devf_pp , struct devfsmount *dv
|
|||
* 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 *
|
||||
* Check the removal code for this! XXX *
|
||||
\*******************************************************/
|
||||
if(back->dnp->type == DEV_ALIAS)
|
||||
{
|
||||
|
@ -143,9 +143,9 @@ int dev_mk_front(dn_p parent,devb_p back,devf_p *devf_pp , struct devfsmount *dv
|
|||
newfp->dnp->links++; /* wherever it is.....*/
|
||||
break;
|
||||
case DEV_DIR:
|
||||
newfp->dnp = malloc(sizeof(devnode_t),
|
||||
dnp = newfp->dnp = malloc(sizeof(devnode_t),
|
||||
M_DEVFSNODE,M_NOWAIT);
|
||||
if(!(newfp->dnp))
|
||||
if(!(dnp))
|
||||
{
|
||||
free(newfp,M_DEVFSFRONT);
|
||||
return ENOMEM;
|
||||
|
@ -155,16 +155,16 @@ int dev_mk_front(dn_p parent,devb_p back,devf_p *devf_pp , struct devfsmount *dv
|
|||
* or bzero and reset or copy some items...
|
||||
*/
|
||||
bcopy(back->dnp,newfp->dnp,sizeof(devnode_t));
|
||||
newfp->dnp->links = 1; /* EXTRA from '.' */
|
||||
newfp->dnp->links++; /* wherever it is.....*/
|
||||
newfp->dnp->by.Dir.dirlast =
|
||||
&newfp->dnp->by.Dir.dirlist;
|
||||
newfp->dnp->by.Dir.dirlist = NULL;
|
||||
newfp->dnp->by.Dir.entrycount = 0;
|
||||
newfp->dnp->vn = NULL;
|
||||
newfp->dnp->vn_id = 0;
|
||||
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 */
|
||||
case DEV_SLNK: /* should never happen XXX (hmm might)*/
|
||||
default:
|
||||
printf("unknown DEV type\n");
|
||||
return EINVAL;
|
||||
|
@ -191,10 +191,11 @@ int dev_mk_front(dn_p parent,devb_p back,devf_p *devf_pp , struct devfsmount *dv
|
|||
/*
|
||||
* it's the root node, put in the dvm
|
||||
* and link it to itself...
|
||||
* we know it's a DIR
|
||||
*/
|
||||
newfp->dnp->by.Dir.parent = newfp->dnp;
|
||||
newfp->dnp->links++; /* extra for '..'*/
|
||||
newfp->dnp->dvm = dvm;
|
||||
dnp->by.Dir.parent = newfp->dnp;
|
||||
dnp->links++; /* extra for '..'*/
|
||||
dnp->dvm = dvm;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -207,12 +208,12 @@ int dev_mk_front(dn_p parent,devb_p back,devf_p *devf_pp , struct devfsmount *dv
|
|||
/*******************************************************\
|
||||
* Put it in the appropriate back/front list too. *
|
||||
\*******************************************************/
|
||||
newfp->next_front = *back->lastfront;
|
||||
newfp->prev_frontp = back->lastfront;
|
||||
*back->lastfront = newfp;
|
||||
back->lastfront = &(newfp->next_front);
|
||||
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->realthing = back;
|
||||
newfp->as.front.realthing = back;
|
||||
|
||||
/*
|
||||
* If it is a directory, then recurse down all the other
|
||||
|
@ -220,7 +221,7 @@ int dev_mk_front(dn_p parent,devb_p back,devf_p *devf_pp , struct devfsmount *dv
|
|||
*/
|
||||
if ( newfp->dnp->type == DEV_DIR)
|
||||
{
|
||||
for(newback = back->dnp->by.BackDir.dirlist;
|
||||
for(newback = back->dnp->by.Dir.dirlist;
|
||||
newback; newback = newback->next)
|
||||
{
|
||||
if(error = dev_mk_front(newfp->dnp,
|
||||
|
@ -230,7 +231,7 @@ int dev_mk_front(dn_p parent,devb_p back,devf_p *devf_pp , struct devfsmount *dv
|
|||
}
|
||||
}
|
||||
}
|
||||
*devf_pp = newfp;
|
||||
*devnm_pp = newfp;
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
@ -242,9 +243,9 @@ int dev_mk_front(dn_p parent,devb_p back,devf_p *devf_pp , struct devfsmount *dv
|
|||
*/
|
||||
int devfs_make_plane(struct devfsmount *devfs_mp_p) /*proto*/
|
||||
{
|
||||
devf_p parent;
|
||||
devf_p new;
|
||||
devb_p realthing;
|
||||
devnm_p parent;
|
||||
devnm_p new;
|
||||
devnm_p realthing;
|
||||
int error;
|
||||
|
||||
DBPRINT((" devfs_make_plane\n"));
|
||||
|
@ -260,7 +261,7 @@ int devfs_make_plane(struct devfsmount *devfs_mp_p) /*proto*/
|
|||
|
||||
void devfs_free_plane(struct devfsmount *devfs_mp_p) /*proto*/
|
||||
{
|
||||
devf_p devfp;
|
||||
devnm_p devfp;
|
||||
|
||||
DBPRINT((" devfs_free_plane\n"));
|
||||
devfp = devfs_mp_p->plane_root;
|
||||
|
@ -270,20 +271,20 @@ void devfs_free_plane(struct devfsmount *devfs_mp_p) /*proto*/
|
|||
/*
|
||||
* Remove all the front nodes associated with a backing node
|
||||
*/
|
||||
void devfs_remove_fronts(devb_p devbp) /*proto*/
|
||||
void devfs_remove_fronts(devnm_p devbp) /*proto*/
|
||||
{
|
||||
while(devbp->fronts)
|
||||
while(devbp->next_front)
|
||||
{
|
||||
dev_free_front(devbp->fronts);
|
||||
dev_free_front(devbp->next_front);
|
||||
}
|
||||
}
|
||||
/***************************************************************\
|
||||
* Free a front node (and any below it of it's a directory node) *
|
||||
\***************************************************************/
|
||||
void dev_free_front(devf_p devfp) /*proto*/
|
||||
void dev_free_front(devnm_p devfp) /*proto*/
|
||||
{
|
||||
dn_p parent = devfp->parent;
|
||||
devb_p back;
|
||||
devnm_p back;
|
||||
|
||||
DBPRINT((" dev_free_front\n"));
|
||||
if(devfp->dnp->type == DEV_DIR)
|
||||
|
@ -321,7 +322,7 @@ void dev_free_front(devf_p devfp) /*proto*/
|
|||
* from that..
|
||||
* Remember that we may not HAVE a backing node.
|
||||
*/
|
||||
if (back = devfp->realthing) /* yes an assign */
|
||||
if (back = devfp->as.front.realthing) /* yes an assign */
|
||||
{
|
||||
if( *devfp->prev_frontp = devfp->next_front)/* yes, assign */
|
||||
{
|
||||
|
@ -329,7 +330,7 @@ void dev_free_front(devf_p devfp) /*proto*/
|
|||
}
|
||||
else
|
||||
{
|
||||
back->lastfront = devfp->prev_frontp;
|
||||
back->prev_frontp = devfp->prev_frontp;
|
||||
}
|
||||
back->frontcount--;
|
||||
}
|
||||
|
@ -371,24 +372,20 @@ DBPRINT((" vntodn "));
|
|||
}
|
||||
|
||||
/***************************************************************\
|
||||
* Think about this: *
|
||||
* Though this routine uses a front node, it also uses a backing *
|
||||
* node indirectly, via the 'realthing' link. This may prove bad *
|
||||
* in the case of a user-added slink, where there migh not be a *
|
||||
* backing node. (e.g. if a slink points out of the fs it CAN'T *
|
||||
* have a backing node, unlike a hardlink which does..) *
|
||||
* we are going to have to think very carefully about slinks.. *
|
||||
* 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 front, struct vnode **vn_pp) /*proto*/
|
||||
int devfs_dntovn(dn_p dnp, struct vnode **vn_pp) /*proto*/
|
||||
{
|
||||
struct vnode *vn_p, *nvp;
|
||||
int error = 0;
|
||||
|
||||
vn_p = front->vn;
|
||||
vn_p = dnp->vn;
|
||||
DBPRINT(("dntovn "));
|
||||
if( vn_p)
|
||||
{
|
||||
if(vn_p->v_id != front->vn_id)
|
||||
if(vn_p->v_id != dnp->vn_id)
|
||||
{
|
||||
printf("bad-id ");
|
||||
goto skip;
|
||||
|
@ -398,12 +395,12 @@ DBPRINT(("dntovn "));
|
|||
printf("bad-tag ");
|
||||
goto skip;
|
||||
}
|
||||
if(vn_p->v_op != *(front->ops))
|
||||
if(vn_p->v_op != *(dnp->ops))
|
||||
{
|
||||
printf("bad-ops ");
|
||||
goto skip;
|
||||
}
|
||||
if((dn_p)(vn_p->v_data) != front)
|
||||
if((dn_p)(vn_p->v_data) != dnp)
|
||||
{
|
||||
printf("bad-rev_link ");
|
||||
goto skip;
|
||||
|
@ -422,20 +419,20 @@ DBPRINT(("dntovn "));
|
|||
vn_p = (struct vnode *) 0;
|
||||
}
|
||||
if(!(error = getnewvnode(VT_DEVFS,
|
||||
front->dvm->mount,
|
||||
*(front->ops),
|
||||
dnp->dvm->mount,
|
||||
*(dnp->ops),
|
||||
&vn_p)))
|
||||
{
|
||||
front->vn = vn_p;
|
||||
front->vn_id = vn_p->v_id;
|
||||
dnp->vn = vn_p;
|
||||
dnp->vn_id = vn_p->v_id;
|
||||
*vn_pp = vn_p;
|
||||
DBPRINT(("(New vnode)"));
|
||||
switch(front->type)
|
||||
switch(dnp->type)
|
||||
{
|
||||
case DEV_SLNK:
|
||||
break;
|
||||
case DEV_DIR:
|
||||
if(front->by.Dir.parent == front)
|
||||
if(dnp->by.Dir.parent == dnp)
|
||||
{
|
||||
vn_p->v_flag |= VROOT;
|
||||
}
|
||||
|
@ -444,7 +441,7 @@ DBPRINT(("(New vnode)"));
|
|||
case DEV_BDEV:
|
||||
vn_p->v_type = VBLK;
|
||||
if (nvp = checkalias(vn_p,
|
||||
front->by.Bdev.dev,
|
||||
dnp->by.Bdev.dev,
|
||||
(struct mount *)0))
|
||||
{
|
||||
vput(vn_p);
|
||||
|
@ -454,7 +451,7 @@ DBPRINT(("(New vnode)"));
|
|||
case DEV_CDEV:
|
||||
vn_p->v_type = VCHR;
|
||||
if (nvp = checkalias(vn_p,
|
||||
front->by.Cdev.dev,
|
||||
dnp->by.Cdev.dev,
|
||||
(struct mount *)0))
|
||||
{
|
||||
vput(vn_p);
|
||||
|
@ -466,16 +463,13 @@ DBPRINT(("(New vnode)"));
|
|||
}
|
||||
if ( vn_p)
|
||||
{
|
||||
vn_p->v_mount = front->dvm->mount;/* Duplicated */
|
||||
vn_p->v_mount = dnp->dvm->mount;/* XXX Duplicated */
|
||||
*vn_pp = vn_p;
|
||||
vn_p->v_data = (void *)front;
|
||||
/*XXX*/ /* maybe not.. I mean what if it's a dev... (vnode at back)*/
|
||||
vn_p->v_data = (void *)dnp;
|
||||
}
|
||||
else
|
||||
{
|
||||
error = EINVAL;
|
||||
}
|
||||
}
|
||||
return(error);
|
||||
}
|
||||
|
||||
return
|
|
@ -1,21 +1,21 @@
|
|||
void devfs_back_init() /*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, int entrytype, union typeinfo *by, devb_p *devb_pp) /*proto*/;
|
||||
int dev_remove(devb_p devbp) /*proto*/;
|
||||
int dev_touch(devb_p key) /* update the node for this dev */ /*proto*/;
|
||||
int dev_add_node(char *name, dn_p dirnode, int entrytype, union typeinfo *by, devnm_p *devnm_pp) /*proto*/;
|
||||
int dev_remove(devnm_p devbp) /*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*/;
|
||||
devb_p dev_add(char *path,char *name,caddr_t funct,int minor,int chrblk,uid_t uid,gid_t gid, int perms) /*proto*/;
|
||||
int devfs_add_fronts(devb_p parent,devb_p child) /*proto*/;
|
||||
devnm_p dev_add(char *path,char *name,caddr_t funct,int minor,int chrblk,uid_t uid,gid_t gid, int perms) /*proto*/;
|
||||
int devfs_add_fronts(devnm_p parent,devnm_p child) /*proto*/;
|
||||
dn_p dev_findfront(dn_p dir,char *name) /*proto*/;
|
||||
int dev_mk_front(dn_p parent,devb_p back,devf_p *devf_pp , struct devfsmount *dvm) /*proto*/;
|
||||
int dev_mk_front(dn_p parent,devnm_p back,devnm_p *devnm_pp , struct devfsmount *dvm) /*proto*/;
|
||||
int devfs_make_plane(struct devfsmount *devfs_mp_p) /*proto*/;
|
||||
void devfs_free_plane(struct devfsmount *devfs_mp_p) /*proto*/;
|
||||
void devfs_remove_fronts(devb_p devbp) /*proto*/;
|
||||
void dev_free_front(devf_p devfp) /*proto*/;
|
||||
void devfs_remove_fronts(devnm_p devbp) /*proto*/;
|
||||
void dev_free_front(devnm_p devfp) /*proto*/;
|
||||
int devfs_vntodn(struct vnode *vn_p, dn_p *dn_pp) /*proto*/;
|
||||
int devfs_dntovn(dn_p front, struct vnode **vn_pp) /*proto*/;
|
||||
int devfs_dntovn(dn_p dnp, struct vnode **vn_pp) /*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*/;
|
||||
|
|
|
@ -874,7 +874,7 @@ int devfs_readdir(ap)
|
|||
struct ucred *cred = ap->a_cred;
|
||||
struct dirent dirent;
|
||||
dn_p dir_node;
|
||||
devf_p name_node;
|
||||
devnm_p name_node;
|
||||
char *name;
|
||||
int error = 0;
|
||||
int reclen;
|
||||
|
|
|
@ -70,11 +70,10 @@
|
|||
extern int (**devfs_vnodeop_p)(); /* our own vector array for dirs */
|
||||
extern int (**dev_spec_vnodeop_p)(); /* our own vector array for devs */
|
||||
|
||||
typedef struct dev_back *devb_p;
|
||||
typedef struct dev_front *devf_p;
|
||||
typedef struct dev_name *devnm_p;
|
||||
typedef struct devnode *dn_p;
|
||||
|
||||
struct devnode
|
||||
struct devnode /* the equivalent of an INODE */
|
||||
{
|
||||
u_short type;
|
||||
int flags; /* more inode compatible for now *//*XXXkill*/
|
||||
|
@ -104,47 +103,52 @@ struct devnode
|
|||
int arg;
|
||||
}Ddev;
|
||||
struct {
|
||||
devf_p dirlist;
|
||||
devf_p *dirlast;
|
||||
devnm_p dirlist;
|
||||
devnm_p *dirlast;
|
||||
dn_p parent;
|
||||
devf_p myname;
|
||||
devnm_p myname;
|
||||
int entrycount;
|
||||
}Dir;
|
||||
struct {
|
||||
devb_p dirlist;
|
||||
devb_p *dirlast;
|
||||
dn_p parent;
|
||||
devb_p myname;
|
||||
int entrycount;
|
||||
}BackDir;
|
||||
struct {
|
||||
char *name; /* must be allocated separatly */
|
||||
int namelen;
|
||||
}Slnk;
|
||||
struct {
|
||||
devb_p realthing;
|
||||
devb_p next;
|
||||
devnm_p realthing;
|
||||
devnm_p next;
|
||||
}Alias;
|
||||
}by;
|
||||
};
|
||||
typedef struct devnode devnode_t;
|
||||
|
||||
struct dev_back
|
||||
struct dev_name
|
||||
{
|
||||
devb_p next; /* next object in this directory */
|
||||
devb_p *prevp; /* previous pointer in directory linked list */
|
||||
devb_p aliases; /* chain of aliases (kill if we are deleted)*/
|
||||
int alias_count; /* how many 'alias' nodes reference us. */
|
||||
devf_p fronts; /* the linked list of all our front nodes */
|
||||
devf_p *lastfront; /* the end of the front node chain */
|
||||
int frontcount; /* number of front nodes that reference us*/
|
||||
dn_p parent; /* backpointer to the directory itself */
|
||||
dn_p dnp; /* info a STAT would look at */
|
||||
/*-----------------------directory entry fields-------------*/
|
||||
char name[DEVMAXNAMESIZE];
|
||||
dn_p dnp; /* the "inode" (devnode) pointer */
|
||||
dn_p parent; /* backpointer to the directory itself */
|
||||
devnm_p next; /* next object in this directory */
|
||||
devnm_p *prevp; /* previous pointer in directory linked list */
|
||||
/*-----------------------aliases or backing nodes----------*/
|
||||
union {
|
||||
struct {
|
||||
devnm_p aliases; /* aliase chain (kill with us)*/
|
||||
int alias_count; /* # 'alias' nodes for us. */
|
||||
} back;
|
||||
struct {
|
||||
devnm_p realthing; /* ptr to the backing node */
|
||||
devnm_p file_node; /* our file node */
|
||||
|
||||
} front;
|
||||
} as;
|
||||
/*-----------------------the front-back chain-------------*/
|
||||
devnm_p next_front; /* the linked list of all our front nodes */
|
||||
devnm_p *prev_frontp; /* the end of the front node chain */
|
||||
int frontcount; /* number of front nodes that reference us*/
|
||||
};
|
||||
|
||||
typedef struct dev_back devb_t;
|
||||
extern struct dev_back *dev_root; /* always exists */
|
||||
typedef struct dev_name devnm_t;
|
||||
extern devnm_p dev_root;
|
||||
|
||||
|
||||
/*
|
||||
|
@ -154,21 +158,6 @@ extern struct dev_back *dev_root; /* always exists */
|
|||
* Device Nodes ALWAYS point to the devnode that is linked
|
||||
* to the Backing node. (with a ref count)
|
||||
*/
|
||||
struct dev_front
|
||||
{
|
||||
devf_p next; /* next item in this directory chain */
|
||||
devf_p *prevp; /* previous pointer in the directory */
|
||||
devf_p file_node; /* the file node this represents */
|
||||
devf_p next_front; /* pointer to next item for this object */
|
||||
devf_p *prev_frontp; /* previous pointer in object chain */
|
||||
devb_p realthing; /* backpointer to the backing object */
|
||||
dn_p parent; /* our PARENT directory node */
|
||||
dn_p dnp; /* info a STAT would look at */
|
||||
char name[DEVMAXNAMESIZE];
|
||||
};
|
||||
typedef struct dev_front devf_t;
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* DEVFS specific per/mount information, used to link a monted fs to a
|
||||
|
@ -177,15 +166,15 @@ typedef struct dev_front devf_t;
|
|||
struct devfsmount
|
||||
{
|
||||
struct mount *mount; /* vfs mount struct for this fs */
|
||||
devf_p plane_root; /* the root of this 'plane' */
|
||||
devnm_p plane_root; /* the root of this 'plane' */
|
||||
int flags; /* usefule some day 8-) */
|
||||
};
|
||||
|
||||
struct dev_vn_data
|
||||
{
|
||||
char magic[6]; /* = "devfs" if correct */
|
||||
devf_p front;
|
||||
devb_p back;
|
||||
devnm_p front;
|
||||
devnm_p back;
|
||||
};
|
||||
|
||||
extern struct vnodeops spec_vnodeops,devfs_vnodeops;
|
||||
|
|
Loading…
Reference in a new issue