1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-12-14 10:09:48 +00:00

Add VOP_IOCTL support, and fix a bug that would cause a panic if a file or

symlink lacked a filler function.
This commit is contained in:
Dag-Erling Smørgrav 2001-10-26 18:52:47 +00:00
parent 282873e2c0
commit 1831900053
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=85561
2 changed files with 58 additions and 4 deletions

View File

@ -108,6 +108,16 @@ struct pfs_bitmap; /* opaque */
int name(PFS_VIS_ARGS);
typedef int (*pfs_vis_t)(PFS_VIS_ARGS);
/*
* Ioctl callback
*/
#define PFS_IOCTL_ARGS \
struct thread *td, struct proc *p, struct pfs_node *pn, \
unsigned long cmd, caddr_t data
#define PFS_IOCTL_PROTO(name) \
int name(PFS_IOCTL_ARGS);
typedef int (*pfs_ioctl_t)(PFS_IOCTL_ARGS);
/*
* pfs_info: describes a pseudofs instance
*/
@ -135,7 +145,7 @@ struct pfs_node {
} u1;
#define pn_func u1._pn_func
#define pn_nodes u1._pn_nodes
/*pfs_ioctl_t pn_ioctl;*/
pfs_ioctl_t pn_ioctl;
pfs_attr_t pn_attr;
pfs_vis_t pn_vis;
void *pn_data;

View File

@ -182,6 +182,49 @@ pfs_getattr(struct vop_getattr_args *va)
PFS_RETURN (error);
}
/*
* Perform an ioctl
*/
static int
pfs_ioctl(struct vop_ioctl_args *va)
{
struct vnode *vn = va->a_vp;
struct pfs_vdata *pvd = (struct pfs_vdata *)vn->v_data;
struct pfs_node *pn = pvd->pvd_pn;
struct proc *proc = NULL;
int error;
PFS_TRACE(("%s: %d", pn->pn_name, va->a_com));
if (vn->v_type != VREG)
PFS_RETURN (EINVAL);
if (pn->pn_ioctl == NULL)
PFS_RETURN (ENOTTY);
/*
* This is necessary because either process' privileges may
* have changed since the open() call.
*/
if (!pfs_visible(curthread, pn, pvd->pvd_pid))
PFS_RETURN (EIO);
/* XXX duplicates bits of pfs_visible() */
if (pvd->pvd_pid != NO_PID) {
if ((proc = pfind(pvd->pvd_pid)) == NULL)
PFS_RETURN (EIO);
_PHOLD(proc);
PROC_UNLOCK(proc);
}
error = (pn->pn_ioctl)(curthread, proc, pn, va->a_command, va->a_data);
if (proc != NULL)
PRELE(proc);
PFS_RETURN (error);
}
/*
* Look up a file or directory
*/
@ -343,7 +386,7 @@ pfs_read(struct vop_read_args *va)
PFS_RETURN (EBADF);
if (pn->pn_func == NULL)
error = EIO;
PFS_RETURN (EIO);
/*
* This is necessary because either process' privileges may
@ -545,7 +588,7 @@ pfs_readlink(struct vop_readlink_args *va)
PFS_RETURN (EINVAL);
if (pn->pn_func == NULL)
error = EIO;
PFS_RETURN (EIO);
if (pvd->pvd_pid != NO_PID) {
if ((proc = pfind(pvd->pvd_pid)) == NULL)
@ -625,7 +668,7 @@ pfs_write(struct vop_read_args *va)
PFS_RETURN (EBADF);
if (pn->pn_func == NULL)
error = EIO;
PFS_RETURN (EIO);
/*
* This is necessary because either process' privileges may
@ -680,6 +723,7 @@ static struct vnodeopv_entry_desc pfs_vnodeop_entries[] = {
{ &vop_close_desc, (vop_t *)pfs_close },
{ &vop_create_desc, (vop_t *)pfs_badop },
{ &vop_getattr_desc, (vop_t *)pfs_getattr },
{ &vop_ioctl_desc, (vop_t *)pfs_ioctl },
{ &vop_link_desc, (vop_t *)pfs_badop },
{ &vop_lookup_desc, (vop_t *)pfs_lookup },
{ &vop_mkdir_desc, (vop_t *)pfs_badop },