mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-16 10:20:30 +00:00
Try to fix the mess I made of devname, with the minimal subset of the
larger minor/major patch which was posted for testing.
This commit is contained in:
parent
530a692468
commit
b43ab0e378
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=143381
@ -114,6 +114,8 @@ struct devfs_dirent **
|
||||
devfs_itode (struct devfs_mount *dm, int inode)
|
||||
{
|
||||
|
||||
if (inode < 0)
|
||||
return (NULL);
|
||||
if (inode < NDEVFSINO)
|
||||
return (&dm->dm_dirent[inode]);
|
||||
if (devfs_overflow == NULL)
|
||||
@ -127,6 +129,8 @@ struct cdev **
|
||||
devfs_itod (int inode)
|
||||
{
|
||||
|
||||
if (inode < 0)
|
||||
return (NULL);
|
||||
if (inode < NDEVFSINO)
|
||||
return (&devfs_inot[inode]);
|
||||
if (devfs_overflow == NULL)
|
||||
@ -270,10 +274,7 @@ devfs_populate(struct devfs_mount *dm)
|
||||
if (dev == NULL && de != NULL) {
|
||||
dd = de->de_dir;
|
||||
*dep = NULL;
|
||||
TAILQ_REMOVE(&dd->de_dlist, de, de_list);
|
||||
if (de->de_vnode)
|
||||
de->de_vnode->v_data = NULL;
|
||||
FREE(de, M_DEVFS);
|
||||
devfs_delete(dd, de);
|
||||
devfs_dropref(i);
|
||||
continue;
|
||||
}
|
||||
|
@ -61,6 +61,7 @@
|
||||
#include <sys/proc.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/sx.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/ttycom.h>
|
||||
#include <sys/unistd.h>
|
||||
@ -113,6 +114,25 @@ static vop_symlink_t devfs_symlink;
|
||||
extern struct vop_vector devfs_vnodeops;
|
||||
extern struct vop_vector devfs_specops;
|
||||
|
||||
static u_int
|
||||
devfs_random(void)
|
||||
{
|
||||
static u_int devfs_seed;
|
||||
|
||||
while (devfs_seed == 0) {
|
||||
/*
|
||||
* Make sure people don't make stupid assumptions
|
||||
* about device major/minor numbers in userspace.
|
||||
* We do this late to get entropy and for the same
|
||||
* reason we force a reseed, but it may not be
|
||||
* late enough for entropy to be available.
|
||||
*/
|
||||
arc4rand(&devfs_seed, sizeof devfs_seed, 1);
|
||||
devfs_seed &= 0xf0f;
|
||||
}
|
||||
return (devfs_seed);
|
||||
}
|
||||
|
||||
static int
|
||||
devfs_fp_check(struct file *fp, struct cdev **devp, struct cdevsw **dswp)
|
||||
{
|
||||
@ -441,7 +461,8 @@ devfs_getattr(ap)
|
||||
vap->va_mtime = dev->si_mtime;
|
||||
fix(dev->si_ctime);
|
||||
vap->va_ctime = dev->si_ctime;
|
||||
vap->va_rdev = dev->si_udev;
|
||||
|
||||
vap->va_rdev = de->de_inode ^ devfs_random();
|
||||
}
|
||||
vap->va_gen = 0;
|
||||
vap->va_flags = 0;
|
||||
@ -1432,6 +1453,43 @@ static struct vop_vector devfs_specops = {
|
||||
.vop_write = VOP_PANIC,
|
||||
};
|
||||
|
||||
dev_t
|
||||
dev2udev(struct cdev *x)
|
||||
{
|
||||
if (x == NULL)
|
||||
return (NODEV);
|
||||
return (x->si_inode ^ devfs_random());
|
||||
}
|
||||
|
||||
/*
|
||||
* Helper sysctl for devname(3). We're given a struct cdev * and return
|
||||
* the name, if any, registered by the device driver.
|
||||
*/
|
||||
static int
|
||||
sysctl_devname(SYSCTL_HANDLER_ARGS)
|
||||
{
|
||||
int error;
|
||||
dev_t ud;
|
||||
struct cdev *dev, **dp;
|
||||
|
||||
error = SYSCTL_IN(req, &ud, sizeof (ud));
|
||||
if (error)
|
||||
return (error);
|
||||
if (ud == NODEV)
|
||||
return(EINVAL);
|
||||
dp = devfs_itod(ud ^ devfs_random());
|
||||
if (dp == NULL)
|
||||
return(ENOENT);
|
||||
dev = *dp;
|
||||
if (dev == NULL)
|
||||
return(ENOENT);
|
||||
return(SYSCTL_OUT(req, dev->si_name, strlen(dev->si_name) + 1));
|
||||
return (error);
|
||||
}
|
||||
|
||||
SYSCTL_PROC(_kern, OID_AUTO, devname, CTLTYPE_OPAQUE|CTLFLAG_RW|CTLFLAG_ANYBODY,
|
||||
NULL, 0, sysctl_devname, "", "devname(3) handler");
|
||||
|
||||
/*
|
||||
* Our calling convention to the device drivers used to be that we passed
|
||||
* vnode.h IO_* flags to read()/write(), but we're moving to fcntl.h O_
|
||||
|
@ -317,14 +317,6 @@ freedev(struct cdev *dev)
|
||||
free(dev, M_DEVT);
|
||||
}
|
||||
|
||||
dev_t
|
||||
dev2udev(struct cdev *x)
|
||||
{
|
||||
if (x == NULL)
|
||||
return (NODEV);
|
||||
return (x->si_udev);
|
||||
}
|
||||
|
||||
struct cdev *
|
||||
findcdev(dev_t udev)
|
||||
{
|
||||
@ -792,30 +784,3 @@ clone_cleanup(struct clonedevs **cdp)
|
||||
free(cd, M_DEVBUF);
|
||||
*cdp = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Helper sysctl for devname(3). We're given a struct cdev * and return
|
||||
* the name, if any, registered by the device driver.
|
||||
*/
|
||||
static int
|
||||
sysctl_devname(SYSCTL_HANDLER_ARGS)
|
||||
{
|
||||
int error;
|
||||
dev_t ud;
|
||||
struct cdev *dev;
|
||||
|
||||
error = SYSCTL_IN(req, &ud, sizeof (ud));
|
||||
if (error)
|
||||
return (error);
|
||||
if (ud == NODEV)
|
||||
return(EINVAL);
|
||||
dev = findcdev(ud);
|
||||
if (dev == NULL)
|
||||
error = ENOENT;
|
||||
else
|
||||
error = SYSCTL_OUT(req, dev->si_name, strlen(dev->si_name) + 1);
|
||||
return (error);
|
||||
}
|
||||
|
||||
SYSCTL_PROC(_kern, OID_AUTO, devname, CTLTYPE_OPAQUE|CTLFLAG_RW|CTLFLAG_ANYBODY,
|
||||
NULL, 0, sysctl_devname, "", "devname(3) handler");
|
||||
|
Loading…
Reference in New Issue
Block a user