make compat_linux struct file interlock friendly.

This commit is contained in:
yamt 2003-02-27 16:04:15 +00:00
parent 898beee0b0
commit da8d9f98f5
4 changed files with 98 additions and 70 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: linux_machdep.c,v 1.85 2003/01/18 08:02:47 thorpej Exp $ */
/* $NetBSD: linux_machdep.c,v 1.86 2003/02/27 16:04:15 yamt Exp $ */
/*-
* Copyright (c) 1995, 2000 The NetBSD Foundation, Inc.
@ -37,7 +37,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: linux_machdep.c,v 1.85 2003/01/18 08:02:47 thorpej Exp $");
__KERNEL_RCSID(0, "$NetBSD: linux_machdep.c,v 1.86 2003/02/27 16:04:15 yamt Exp $");
#if defined(_KERNEL_OPT)
#include "opt_vm86.h"
@ -845,6 +845,8 @@ linux_machdepioctl(p, v, retval)
if ((fp = fd_getfile(fdp, fd)) == NULL)
return (EBADF);
FILE_USE(fp);
switch (com) {
#if (NWSDISPLAY > 0)
case LINUX_KDGKBMODE:
@ -888,32 +890,34 @@ linux_machdepioctl(p, v, retval)
SCARG(&bia, com) = VT_GETMODE;
/* XXX NJWLWP */
if ((error = sys_ioctl(curlwp, &bia, retval)))
return error;
goto out;
if ((error = copyin(SCARG(uap, data), (caddr_t)&lvt,
sizeof (struct vt_mode))))
return error;
goto out;
lvt.relsig = native_to_linux_signo[lvt.relsig];
lvt.acqsig = native_to_linux_signo[lvt.acqsig];
lvt.frsig = native_to_linux_signo[lvt.frsig];
return copyout((caddr_t)&lvt, SCARG(uap, data),
error = copyout((caddr_t)&lvt, SCARG(uap, data),
sizeof (struct vt_mode));
goto out;
case LINUX_VT_SETMODE:
com = VT_SETMODE;
if ((error = copyin(SCARG(uap, data), (caddr_t)&lvt,
sizeof (struct vt_mode))))
return error;
goto out;
lvt.relsig = linux_to_native_signo[lvt.relsig];
lvt.acqsig = linux_to_native_signo[lvt.acqsig];
lvt.frsig = linux_to_native_signo[lvt.frsig];
sg = stackgap_init(p, 0);
bvtp = stackgap_alloc(p, &sg, sizeof (struct vt_mode));
if ((error = copyout(&lvt, bvtp, sizeof (struct vt_mode))))
return error;
goto out;
SCARG(&bia, data) = bvtp;
break;
case LINUX_VT_DISALLOCATE:
/* XXX should use WSDISPLAYIO_DELSCREEN */
return 0;
error = 0;
goto out;
case LINUX_VT_RELDISP:
com = VT_RELDISP;
break;
@ -928,7 +932,8 @@ linux_machdepioctl(p, v, retval)
break;
case LINUX_KDGKBTYPE:
/* This is what Linux does. */
return (subyte(SCARG(uap, data), KB_101));
error = subyte(SCARG(uap, data), KB_101);
goto out;
case LINUX_KDGKBENT:
/*
* The Linux KDGKBENT ioctl is different from the
@ -938,13 +943,16 @@ linux_machdepioctl(p, v, retval)
*/
if ((error = copyin(SCARG(uap, data), &kbe,
sizeof(struct kbentry))))
return (error);
goto out;
if (kbe.kb_table >= sizeof(linux_keytabs) / sizeof(u_short *)
|| kbe.kb_index >= NR_KEYS)
return (EINVAL);
|| kbe.kb_index >= NR_KEYS) {
error = EINVAL;
goto out;
}
kbe.kb_value = linux_keytabs[kbe.kb_table][kbe.kb_index];
return (copyout(&kbe, SCARG(uap, data),
sizeof(struct kbentry)));
error = copyout(&kbe, SCARG(uap, data),
sizeof(struct kbentry));
goto out;
#endif
case LINUX_HDIO_GETGEO:
case LINUX_HDIO_GETGEO_BIG:
@ -955,14 +963,14 @@ linux_machdepioctl(p, v, retval)
* the real geometry) if not found, by returning an
* error. See common/linux_hdio.c
*/
FILE_USE(fp);
bip = fd2biosinfo(p, fp);
ioctlf = fp->f_ops->fo_ioctl;
error = ioctlf(fp, DIOCGDEFLABEL, (caddr_t)&label, p);
error1 = ioctlf(fp, DIOCGPART, (caddr_t)&partp, p);
FILE_UNUSE(fp, p);
if (error != 0 && error1 != 0)
return error1;
if (error != 0 && error1 != 0) {
error = error1;
goto out;
}
labp = error != 0 ? &label : partp.disklab;
start = error1 != 0 ? partp.part->p_offset : 0;
if (bip != NULL && bip->bi_head != 0 && bip->bi_sec != 0
@ -985,14 +993,16 @@ linux_machdepioctl(p, v, retval)
hdg.heads = heads;
hdg.cylinders = cylinders;
hdg.sectors = sectors;
return copyout(&hdg, SCARG(uap, data), sizeof hdg);
error = copyout(&hdg, SCARG(uap, data), sizeof hdg);
goto out;
} else {
hdg_big.start = start;
hdg_big.heads = heads;
hdg_big.cylinders = cylinders;
hdg_big.sectors = sectors;
return copyout(&hdg_big, SCARG(uap, data),
error = copyout(&hdg_big, SCARG(uap, data),
sizeof hdg_big);
goto out;
}
default:
@ -1017,11 +1027,14 @@ linux_machdepioctl(p, v, retval)
if (error == ENOTTY)
DPRINTF(("linux_machdepioctl: invalid ioctl %08lx\n",
com));
return error;
goto out;
}
SCARG(&bia, com) = com;
/* XXX NJWLWP */
return sys_ioctl(curlwp, &bia, retval);
error = sys_ioctl(curlwp, &bia, retval);
out:
FILE_UNUSE(fp ,p);
return error;
}
/*

View File

@ -1,4 +1,4 @@
/* $NetBSD: linux_file.c,v 1.56 2003/01/18 08:02:52 thorpej Exp $ */
/* $NetBSD: linux_file.c,v 1.57 2003/02/27 16:04:16 yamt Exp $ */
/*-
* Copyright (c) 1995, 1998 The NetBSD Foundation, Inc.
@ -42,7 +42,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: linux_file.c,v 1.56 2003/01/18 08:02:52 thorpej Exp $");
__KERNEL_RCSID(0, "$NetBSD: linux_file.c,v 1.57 2003/02/27 16:04:16 yamt Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -214,8 +214,14 @@ linux_sys_open(l, v, retval)
fp = fd_getfile(fdp, *retval);
/* ignore any error, just give it a try */
if (fp != NULL && fp->f_type == DTYPE_VNODE)
(fp->f_ops->fo_ioctl) (fp, TIOCSCTTY, (caddr_t) 0, p);
if (fp != NULL) {
FILE_USE(fp);
if (fp->f_type == DTYPE_VNODE) {
(fp->f_ops->fo_ioctl) (fp, TIOCSCTTY,
(caddr_t) 0, p);
}
FILE_UNUSE(fp, p);
}
}
return 0;
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: linux_ioctl.c,v 1.31 2003/01/18 08:02:52 thorpej Exp $ */
/* $NetBSD: linux_ioctl.c,v 1.32 2003/02/27 16:04:16 yamt Exp $ */
/*-
* Copyright (c) 1995, 1998 The NetBSD Foundation, Inc.
@ -37,7 +37,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: linux_ioctl.c,v 1.31 2003/01/18 08:02:52 thorpej Exp $");
__KERNEL_RCSID(0, "$NetBSD: linux_ioctl.c,v 1.32 2003/02/27 16:04:16 yamt Exp $");
#if defined(_KERNEL_OPT)
#include "sequencer.h"
@ -115,21 +115,29 @@ linux_sys_ioctl(l, v, retval)
struct filedesc *fdp;
struct vnode *vp;
struct vattr va;
int error;
extern const struct cdevsw sequencer_cdevsw;
fdp = p->p_fd;
if ((fp = fd_getfile(fdp, SCARG(uap, fd))) == NULL)
return EBADF;
FILE_USE(fp);
if (fp->f_type == DTYPE_VNODE &&
(vp = (struct vnode *)fp->f_data) != NULL &&
vp->v_type == VCHR &&
VOP_GETATTR(vp, &va, p->p_ucred, p) == 0 &&
cdevsw_lookup(va.va_rdev) == &sequencer_cdevsw)
return oss_ioctl_sequencer(p, (void*)LINUX_TO_OSS(uap),
cdevsw_lookup(va.va_rdev) == &sequencer_cdevsw) {
error = oss_ioctl_sequencer(p, (void*)LINUX_TO_OSS(uap),
retval);
else
}
else {
error = linux_ioctl_termios(p, uap, retval);
}
FILE_UNUSE(fp, p);
return error;
#else
return linux_ioctl_termios(p, uap, retval);
#endif
return linux_ioctl_termios(p, uap, retval);
}
case 0x89:
return linux_ioctl_socket(p, uap, retval);

View File

@ -1,4 +1,4 @@
/* $NetBSD: linux_termios.c,v 1.16 2003/01/18 21:21:38 thorpej Exp $ */
/* $NetBSD: linux_termios.c,v 1.17 2003/02/27 16:04:16 yamt Exp $ */
/*-
* Copyright (c) 1995, 1998 The NetBSD Foundation, Inc.
@ -37,7 +37,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: linux_termios.c,v 1.16 2003/01/18 21:21:38 thorpej Exp $");
__KERNEL_RCSID(0, "$NetBSD: linux_termios.c,v 1.17 2003/02/27 16:04:16 yamt Exp $");
#include <sys/param.h>
#include <sys/proc.h>
@ -487,8 +487,12 @@ linux_ioctl_termios(p, uap, retval)
if ((fp = fd_getfile(fdp, SCARG(uap, fd))) == NULL)
return (EBADF);
if ((fp->f_flag & (FREAD | FWRITE)) == 0)
return (EBADF);
if ((fp->f_flag & (FREAD | FWRITE)) == 0) {
error = EBADF;
goto out;
}
FILE_USE(fp);
bsdioctl = fp->f_ops->fo_ioctl;
com = SCARG(uap, com);
@ -498,12 +502,10 @@ linux_ioctl_termios(p, uap, retval)
case LINUX_TCGETS:
error = (*bsdioctl)(fp, TIOCGETA, (caddr_t)&tmpbts, p);
if (error)
return error;
goto out;
bsd_termios_to_linux_termios(&tmpbts, &tmplts);
error = copyout(&tmplts, SCARG(uap, data), sizeof tmplts);
if (error)
return error;
return 0;
goto out;
case LINUX_TCSETS:
case LINUX_TCSETSW:
case LINUX_TCSETSF:
@ -513,10 +515,10 @@ linux_ioctl_termios(p, uap, retval)
*/
error = (*bsdioctl)(fp, TIOCGETA, (caddr_t)&tmpbts, p);
if (error)
return error;
goto out;
error = copyin(SCARG(uap, data), &tmplts, sizeof tmplts);
if (error)
return error;
goto out;
linux_termios_to_bsd_termios(&tmplts, &tmpbts);
switch (com) {
case LINUX_TCSETS:
@ -530,18 +532,14 @@ linux_ioctl_termios(p, uap, retval)
break;
}
error = (*bsdioctl)(fp, com, (caddr_t)&tmpbts, p);
if (error)
return error;
return 0;
goto out;
case LINUX_TCGETA:
error = (*bsdioctl)(fp, TIOCGETA, (caddr_t)&tmpbts, p);
if (error)
return error;
goto out;
bsd_termios_to_linux_termio(&tmpbts, &tmplt);
error = copyout(&tmplt, SCARG(uap, data), sizeof tmplt);
if (error)
return error;
return 0;
goto out;
case LINUX_TCSETA:
case LINUX_TCSETAW:
case LINUX_TCSETAF:
@ -551,10 +549,10 @@ linux_ioctl_termios(p, uap, retval)
*/
error = (*bsdioctl)(fp, TIOCGETA, (caddr_t)&tmpbts, p);
if (error)
return error;
goto out;
error = copyin(SCARG(uap, data), &tmplt, sizeof tmplt);
if (error)
return error;
goto out;
linux_termio_to_bsd_termios(&tmplt, &tmpbts);
switch (com) {
case LINUX_TCSETA:
@ -568,9 +566,7 @@ linux_ioctl_termios(p, uap, retval)
break;
}
error = (*bsdioctl)(fp, com, (caddr_t)&tmpbts, p);
if (error)
return error;
return 0;
goto out;
case LINUX_TCFLSH:
switch((u_long)SCARG(uap, data)) {
case 0:
@ -583,13 +579,15 @@ linux_ioctl_termios(p, uap, retval)
idat = 0;
break;
default:
return EINVAL;
error = EINVAL;
goto out;
}
return (*bsdioctl)(fp, TIOCFLUSH, (caddr_t)&idat, p);
error = (*bsdioctl)(fp, TIOCFLUSH, (caddr_t)&idat, p);
goto out;
case LINUX_TIOCGETD:
error = (*bsdioctl)(fp, TIOCGETD, (caddr_t)&idat, p);
if (error)
return error;
goto out;
switch (idat) {
case TTYDISC:
idat = LINUX_N_TTY;
@ -612,13 +610,11 @@ linux_ioctl_termios(p, uap, retval)
break;
}
error = copyout(&idat, SCARG(uap, data), sizeof idat);
if (error)
return error;
return 0;
goto out;
case LINUX_TIOCSETD:
error = copyin(SCARG(uap, data), &idat, sizeof idat);
if (error)
return error;
goto out;
switch (idat) {
case LINUX_N_TTY:
idat = TTYDISC;
@ -640,16 +636,15 @@ linux_ioctl_termios(p, uap, retval)
case LINUX_N_X25:
case LINUX_N_6PACK:
default:
return EINVAL;
error = EINVAL;
goto out;
}
error = (*bsdioctl)(fp, TIOCSETD, (caddr_t)&idat, p);
if (error)
return error;
return 0;
goto out;
case LINUX_TIOCLINUX:
error = copyin(SCARG(uap, data), &tioclinux, sizeof tioclinux);
if (error != 0)
return error;
goto out;
switch (tioclinux) {
case LINUX_TIOCLINUX_KERNMSG:
/*
@ -657,7 +652,8 @@ linux_ioctl_termios(p, uap, retval)
* try to use TIOCCONS, but the char argument
* specifies the VT #, not an fd.
*/
return 0;
error = 0;
goto out;
case LINUX_TIOCLINUX_COPY:
case LINUX_TIOCLINUX_PASTE:
case LINUX_TIOCLINUX_UNBLANK:
@ -666,7 +662,8 @@ linux_ioctl_termios(p, uap, retval)
case LINUX_TIOCLINUX_READMOUSE:
case LINUX_TIOCLINUX_VESABLANK:
case LINUX_TIOCLINUX_CURCONS: /* could use VT_GETACTIVE */
return EINVAL;
error = EINVAL;
goto out;
}
break;
case LINUX_TIOCGWINSZ:
@ -712,11 +709,15 @@ linux_ioctl_termios(p, uap, retval)
SCARG(&ia, com) = TIOCMSET;
break;
default:
return EINVAL;
error = EINVAL;
goto out;
}
SCARG(&ia, fd) = SCARG(uap, fd);
SCARG(&ia, data) = SCARG(uap, data);
/* XXX NJWLWP */
return sys_ioctl(curlwp, &ia, retval);
error = sys_ioctl(curlwp, &ia, retval);
out:
FILE_UNUSE(fp, p);
return error;
}