summaryrefslogtreecommitdiffstats
path: root/sys/compat
diff options
context:
space:
mode:
authoralfred <alfred@FreeBSD.org>2002-01-13 11:58:06 +0000
committeralfred <alfred@FreeBSD.org>2002-01-13 11:58:06 +0000
commit844237b3960bfbf49070d6371a84f67f9e3366f6 (patch)
tree598e20df363e602313c7ad93de8f8c4b4240d61d /sys/compat
parent8cd61193307ff459ae72eb7aa6a734eb5e3b427e (diff)
downloadFreeBSD-src-844237b3960bfbf49070d6371a84f67f9e3366f6.zip
FreeBSD-src-844237b3960bfbf49070d6371a84f67f9e3366f6.tar.gz
SMP Lock struct file, filedesc and the global file list.
Seigo Tanimura (tanimura) posted the initial delta. I've polished it quite a bit reducing the need for locking and adapting it for KSE. Locks: 1 mutex in each filedesc protects all the fields. protects "struct file" initialization, while a struct file is being changed from &badfileops -> &pipeops or something the filedesc should be locked. 1 mutex in each struct file protects the refcount fields. doesn't protect anything else. the flags used for garbage collection have been moved to f_gcflag which was the FILLER short, this doesn't need locking because the garbage collection is a single threaded container. could likely be made to use a pool mutex. 1 sx lock for the global filelist. struct file * fhold(struct file *fp); /* increments reference count on a file */ struct file * fhold_locked(struct file *fp); /* like fhold but expects file to locked */ struct file * ffind_hold(struct thread *, int fd); /* finds the struct file in thread, adds one reference and returns it unlocked */ struct file * ffind_lock(struct thread *, int fd); /* ffind_hold, but returns file locked */ I still have to smp-safe the fget cruft, I'll get to that asap.
Diffstat (limited to 'sys/compat')
-rw-r--r--sys/compat/linux/linux_file.c34
-rw-r--r--sys/compat/linux/linux_ioctl.c278
-rw-r--r--sys/compat/linux/linux_stats.c15
-rw-r--r--sys/compat/svr4/svr4_fcntl.c39
-rw-r--r--sys/compat/svr4/svr4_filio.c11
-rw-r--r--sys/compat/svr4/svr4_ioctl.c21
-rw-r--r--sys/compat/svr4/svr4_misc.c37
-rw-r--r--sys/compat/svr4/svr4_stream.c79
8 files changed, 349 insertions, 165 deletions
diff --git a/sys/compat/linux/linux_file.c b/sys/compat/linux/linux_file.c
index 4609a1b..9e1156c 100644
--- a/sys/compat/linux/linux_file.c
+++ b/sys/compat/linux/linux_file.c
@@ -135,12 +135,13 @@ linux_open(struct thread *td, struct linux_open_args *args)
PROC_LOCK(p);
if (!error && !(bsd_open_args.flags & O_NOCTTY) &&
SESS_LEADER(p) && !(p->p_flag & P_CONTROLT)) {
- struct filedesc *fdp = p->p_fd;
- struct file *fp = fdp->fd_ofiles[td->td_retval[0]];
+ struct file *fp;
+ fp = ffind_hold(td, td->td_retval[0]);
PROC_UNLOCK(p);
if (fp->f_type == DTYPE_VNODE)
fo_ioctl(fp, TIOCSCTTY, (caddr_t) 0, td);
+ fdrop(fp, td);
} else
PROC_UNLOCK(p);
#ifdef DEBUG
@@ -270,21 +271,29 @@ getdents_common(struct thread *td, struct linux_getdents64_args *args,
if ((error = getvnode(td->td_proc->p_fd, args->fd, &fp)) != 0)
return (error);
- if ((fp->f_flag & FREAD) == 0)
+ if ((fp->f_flag & FREAD) == 0) {
+ fdrop(fp, td);
return (EBADF);
+ }
vp = (struct vnode *) fp->f_data;
- if (vp->v_type != VDIR)
+ if (vp->v_type != VDIR) {
+ fdrop(fp, td);
return (EINVAL);
+ }
- if ((error = VOP_GETATTR(vp, &va, td->td_proc->p_ucred, td)))
+ if ((error = VOP_GETATTR(vp, &va, td->td_proc->p_ucred, td))) {
+ fdrop(fp, td);
return (error);
+ }
nbytes = args->count;
if (nbytes == 1) {
/* readdir(2) case. Always struct dirent. */
- if (is64bit)
+ if (is64bit) {
+ fdrop(fp, td);
return (EINVAL);
+ }
nbytes = sizeof(linux_dirent);
justone = 1;
} else
@@ -435,6 +444,7 @@ out:
free(cookies, M_TEMP);
VOP_UNLOCK(vp, 0, td);
+ fdrop(fp, td);
free(buf, M_TEMP);
return (error);
}
@@ -987,12 +997,14 @@ fcntl_common(struct thread *td, struct linux_fcntl64_args *args)
* significant effect for pipes (SIGIO is not delivered for
* pipes under Linux-2.2.35 at least).
*/
- fdp = td->td_proc->p_fd;
- if ((u_int)args->fd >= fdp->fd_nfiles ||
- (fp = fdp->fd_ofiles[args->fd]) == NULL)
- return (EBADF);
- if (fp->f_type == DTYPE_PIPE)
+ fp = ffind_hold(td, args->fd);
+ if (fp == NULL)
+ return EBADF;
+ if (fp->f_type == DTYPE_PIPE) {
+ fdrop(fp, td);
return (EINVAL);
+ }
+ fdrop(fp, td);
fcntl_args.cmd = F_SETOWN;
fcntl_args.arg = args->arg;
diff --git a/sys/compat/linux/linux_ioctl.c b/sys/compat/linux/linux_ioctl.c
index f5ab820..baafb5b 100644
--- a/sys/compat/linux/linux_ioctl.c
+++ b/sys/compat/linux/linux_ioctl.c
@@ -105,19 +105,23 @@ static TAILQ_HEAD(, handler_element) handlers =
static int
linux_ioctl_disk(struct thread *td, struct linux_ioctl_args *args)
{
- struct file *fp = td->td_proc->p_fd->fd_ofiles[args->fd];
+ struct file *fp;
int error;
struct disklabel dl;
+ fp = ffind_hold(td, args->fd);
+ if (fp == NULL)
+ return (EBADF);
switch (args->cmd & 0xffff) {
case LINUX_BLKGETSIZE:
error = fo_ioctl(fp, DIOCGDINFO, (caddr_t)&dl, td);
+ fdrop(fp, td);
if (error)
return (error);
return (copyout(&(dl.d_secperunit), (caddr_t)args->arg,
sizeof(dl.d_secperunit)));
- break;
}
+ fdrop(fp, td);
return (ENOIOCTL);
}
@@ -548,66 +552,77 @@ linux_ioctl_termio(struct thread *td, struct linux_ioctl_args *args)
struct termios bios;
struct linux_termios lios;
struct linux_termio lio;
- struct file *fp = td->td_proc->p_fd->fd_ofiles[args->fd];
+ struct file *fp;
int error;
+ fp = ffind_hold(td, args->fd);
+ if (fp == NULL)
+ return (EBADF);
switch (args->cmd & 0xffff) {
case LINUX_TCGETS:
error = fo_ioctl(fp, TIOCGETA, (caddr_t)&bios, td);
if (error)
- return (error);
+ break;
bsd_to_linux_termios(&bios, &lios);
- return copyout(&lios, (caddr_t)args->arg, sizeof(lios));
+ error = copyout(&lios, (caddr_t)args->arg, sizeof(lios));
+ break;
case LINUX_TCSETS:
error = copyin((caddr_t)args->arg, &lios, sizeof(lios));
if (error)
- return (error);
+ break;
linux_to_bsd_termios(&lios, &bios);
- return (fo_ioctl(fp, TIOCSETA, (caddr_t)&bios, td));
+ error = (fo_ioctl(fp, TIOCSETA, (caddr_t)&bios, td));
+ break;
case LINUX_TCSETSW:
error = copyin((caddr_t)args->arg, &lios, sizeof(lios));
if (error)
- return (error);
+ break;
linux_to_bsd_termios(&lios, &bios);
- return (fo_ioctl(fp, TIOCSETAW, (caddr_t)&bios, td));
+ error = (fo_ioctl(fp, TIOCSETAW, (caddr_t)&bios, td));
+ break;
case LINUX_TCSETSF:
error = copyin((caddr_t)args->arg, &lios, sizeof(lios));
if (error)
- return (error);
+ break;
linux_to_bsd_termios(&lios, &bios);
- return (fo_ioctl(fp, TIOCSETAF, (caddr_t)&bios, td));
+ error = (fo_ioctl(fp, TIOCSETAF, (caddr_t)&bios, td));
+ break;
case LINUX_TCGETA:
error = fo_ioctl(fp, TIOCGETA, (caddr_t)&bios, td);
if (error)
- return (error);
+ break;
bsd_to_linux_termio(&bios, &lio);
- return (copyout(&lio, (caddr_t)args->arg, sizeof(lio)));
+ error = (copyout(&lio, (caddr_t)args->arg, sizeof(lio)));
+ break;
case LINUX_TCSETA:
error = copyin((caddr_t)args->arg, &lio, sizeof(lio));
if (error)
- return (error);
+ break;
linux_to_bsd_termio(&lio, &bios);
- return (fo_ioctl(fp, TIOCSETA, (caddr_t)&bios, td));
+ error = (fo_ioctl(fp, TIOCSETA, (caddr_t)&bios, td));
+ break;
case LINUX_TCSETAW:
error = copyin((caddr_t)args->arg, &lio, sizeof(lio));
if (error)
- return (error);
+ break;
linux_to_bsd_termio(&lio, &bios);
- return (fo_ioctl(fp, TIOCSETAW, (caddr_t)&bios, td));
+ error = (fo_ioctl(fp, TIOCSETAW, (caddr_t)&bios, td));
+ break;
case LINUX_TCSETAF:
error = copyin((caddr_t)args->arg, &lio, sizeof(lio));
if (error)
- return (error);
+ break;
linux_to_bsd_termio(&lio, &bios);
- return (fo_ioctl(fp, TIOCSETAF, (caddr_t)&bios, td));
+ error = (fo_ioctl(fp, TIOCSETAF, (caddr_t)&bios, td));
+ break;
/* LINUX_TCSBRK */
@@ -625,7 +640,8 @@ linux_ioctl_termio(struct thread *td, struct linux_ioctl_args *args)
struct write_args wr;
error = fo_ioctl(fp, TIOCGETA, (caddr_t)&bios, td);
if (error)
- return (error);
+ break;
+ fdrop(fp, td);
c = (args->arg == LINUX_TCIOFF) ? VSTOP : VSTART;
c = bios.c_cc[c];
if (c != _POSIX_VDISABLE) {
@@ -637,10 +653,12 @@ linux_ioctl_termio(struct thread *td, struct linux_ioctl_args *args)
return (0);
}
default:
+ fdrop(fp, td);
return (EINVAL);
}
args->arg = 0;
- return (ioctl(td, (struct ioctl_args *)args));
+ error = (ioctl(td, (struct ioctl_args *)args));
+ break;
}
case LINUX_TCFLSH: {
@@ -656,97 +674,115 @@ linux_ioctl_termio(struct thread *td, struct linux_ioctl_args *args)
args->arg = FREAD | FWRITE;
break;
default:
+ fdrop(fp, td);
return (EINVAL);
}
- return (ioctl(td, (struct ioctl_args *)args));
+ error = (ioctl(td, (struct ioctl_args *)args));
+ break;
}
case LINUX_TIOCEXCL:
args->cmd = TIOCEXCL;
- return (ioctl(td, (struct ioctl_args *)args));
+ error = (ioctl(td, (struct ioctl_args *)args));
+ break;
case LINUX_TIOCNXCL:
args->cmd = TIOCNXCL;
- return (ioctl(td, (struct ioctl_args *)args));
+ error = (ioctl(td, (struct ioctl_args *)args));
+ break;
/* LINUX_TIOCSCTTY */
case LINUX_TIOCGPGRP:
args->cmd = TIOCGPGRP;
- return (ioctl(td, (struct ioctl_args *)args));
+ error = (ioctl(td, (struct ioctl_args *)args));
+ break;
case LINUX_TIOCSPGRP:
args->cmd = TIOCSPGRP;
- return (ioctl(td, (struct ioctl_args *)args));
+ error = (ioctl(td, (struct ioctl_args *)args));
+ break;
/* LINUX_TIOCOUTQ */
/* LINUX_TIOCSTI */
case LINUX_TIOCGWINSZ:
args->cmd = TIOCGWINSZ;
- return (ioctl(td, (struct ioctl_args *)args));
+ error = (ioctl(td, (struct ioctl_args *)args));
+ break;
case LINUX_TIOCSWINSZ:
args->cmd = TIOCSWINSZ;
- return (ioctl(td, (struct ioctl_args *)args));
+ error = (ioctl(td, (struct ioctl_args *)args));
+ break;
case LINUX_TIOCMGET:
args->cmd = TIOCMGET;
- return (ioctl(td, (struct ioctl_args *)args));
+ error = (ioctl(td, (struct ioctl_args *)args));
+ break;
case LINUX_TIOCMBIS:
args->cmd = TIOCMBIS;
- return (ioctl(td, (struct ioctl_args *)args));
+ error = (ioctl(td, (struct ioctl_args *)args));
+ break;
case LINUX_TIOCMBIC:
args->cmd = TIOCMBIC;
- return (ioctl(td, (struct ioctl_args *)args));
+ error = (ioctl(td, (struct ioctl_args *)args));
+ break;
case LINUX_TIOCMSET:
args->cmd = TIOCMSET;
- return (ioctl(td, (struct ioctl_args *)args));
+ error = (ioctl(td, (struct ioctl_args *)args));
+ break;
/* TIOCGSOFTCAR */
/* TIOCSSOFTCAR */
case LINUX_FIONREAD: /* LINUX_TIOCINQ */
args->cmd = FIONREAD;
- return (ioctl(td, (struct ioctl_args *)args));
+ error = (ioctl(td, (struct ioctl_args *)args));
+ break;
/* LINUX_TIOCLINUX */
case LINUX_TIOCCONS:
args->cmd = TIOCCONS;
- return (ioctl(td, (struct ioctl_args *)args));
+ error = (ioctl(td, (struct ioctl_args *)args));
+ break;
case LINUX_TIOCGSERIAL: {
struct linux_serial_struct lss;
lss.type = LINUX_PORT_16550A;
lss.flags = 0;
lss.close_delay = 0;
- return copyout(&lss, (caddr_t)args->arg, sizeof(lss));
+ error = copyout(&lss, (caddr_t)args->arg, sizeof(lss));
+ break;
}
case LINUX_TIOCSSERIAL: {
struct linux_serial_struct lss;
error = copyin((caddr_t)args->arg, &lss, sizeof(lss));
if (error)
- return (error);
+ break;
/* XXX - It really helps to have an implementation that
* does nothing. NOT!
*/
- return (0);
+ error = 0;
+ break;
}
/* LINUX_TIOCPKT */
case LINUX_FIONBIO:
args->cmd = FIONBIO;
- return (ioctl(td, (struct ioctl_args *)args));
+ error = (ioctl(td, (struct ioctl_args *)args));
+ break;
case LINUX_TIOCNOTTY:
args->cmd = TIOCNOTTY;
- return (ioctl(td, (struct ioctl_args *)args));
+ error = (ioctl(td, (struct ioctl_args *)args));
+ break;
case LINUX_TIOCSETD: {
int line;
@@ -761,9 +797,11 @@ linux_ioctl_termio(struct thread *td, struct linux_ioctl_args *args)
line = PPPDISC;
break;
default:
+ fdrop(fp, td);
return (EINVAL);
}
- return (fo_ioctl(fp, TIOCSETD, (caddr_t)&line, td));
+ error = (fo_ioctl(fp, TIOCSETD, (caddr_t)&line, td));
+ break;
}
case LINUX_TIOCGETD: {
@@ -783,9 +821,11 @@ linux_ioctl_termio(struct thread *td, struct linux_ioctl_args *args)
linux_line = LINUX_N_PPP;
break;
default:
+ fdrop(fp, td);
return (EINVAL);
}
- return (copyout(&linux_line, (caddr_t)args->arg, sizeof(int)));
+ error = (copyout(&linux_line, (caddr_t)args->arg, sizeof(int)));
+ break;
}
/* LINUX_TCSBRKP */
@@ -793,15 +833,18 @@ linux_ioctl_termio(struct thread *td, struct linux_ioctl_args *args)
case LINUX_FIONCLEX:
args->cmd = FIONCLEX;
- return (ioctl(td, (struct ioctl_args *)args));
+ error = (ioctl(td, (struct ioctl_args *)args));
+ break;
case LINUX_FIOCLEX:
args->cmd = FIOCLEX;
- return (ioctl(td, (struct ioctl_args *)args));
+ error = (ioctl(td, (struct ioctl_args *)args));
+ break;
case LINUX_FIOASYNC:
args->cmd = FIOASYNC;
- return (ioctl(td, (struct ioctl_args *)args));
+ error = (ioctl(td, (struct ioctl_args *)args));
+ break;
/* LINUX_TIOCSERCONFIG */
/* LINUX_TIOCSERGWILD */
@@ -809,9 +852,13 @@ linux_ioctl_termio(struct thread *td, struct linux_ioctl_args *args)
/* LINUX_TIOCGLCKTRMIOS */
/* LINUX_TIOCSLCKTRMIOS */
+ default:
+ error = ENOIOCTL;
+ break;
}
- return (ENOIOCTL);
+ fdrop(fp, td);
+ return (error);
}
/*
@@ -1199,26 +1246,33 @@ bsd_to_linux_dvd_authinfo(struct dvd_authinfo *bp, l_dvd_authinfo *lp)
static int
linux_ioctl_cdrom(struct thread *td, struct linux_ioctl_args *args)
{
- struct file *fp = td->td_proc->p_fd->fd_ofiles[args->fd];
+ struct file *fp;
int error;
+ fp = ffind_hold(td, args->fd);
+ if (fp == NULL)
+ return (EBADF);
switch (args->cmd & 0xffff) {
case LINUX_CDROMPAUSE:
args->cmd = CDIOCPAUSE;
- return (ioctl(td, (struct ioctl_args *)args));
+ error = (ioctl(td, (struct ioctl_args *)args));
+ break;
case LINUX_CDROMRESUME:
args->cmd = CDIOCRESUME;
- return (ioctl(td, (struct ioctl_args *)args));
+ error = (ioctl(td, (struct ioctl_args *)args));
+ break;
case LINUX_CDROMPLAYMSF:
args->cmd = CDIOCPLAYMSF;
- return (ioctl(td, (struct ioctl_args *)args));
+ error = (ioctl(td, (struct ioctl_args *)args));
+ break;
case LINUX_CDROMPLAYTRKIND:
args->cmd = CDIOCPLAYTRACKS;
- return (ioctl(td, (struct ioctl_args *)args));
+ error = (ioctl(td, (struct ioctl_args *)args));
+ break;
case LINUX_CDROMREADTOCHDR: {
struct ioc_toc_header th;
@@ -1229,7 +1283,7 @@ linux_ioctl_cdrom(struct thread *td, struct linux_ioctl_args *args)
lth.cdth_trk1 = th.ending_track;
copyout(&lth, (caddr_t)args->arg, sizeof(lth));
}
- return (error);
+ break;
}
case LINUX_CDROMREADTOCENTRY: {
@@ -1247,20 +1301,23 @@ linux_ioctl_cdrom(struct thread *td, struct linux_ioctl_args *args)
&irtse.entry.addr, &lte.cdte_addr);
copyout(&lte, (caddr_t)args->arg, sizeof(lte));
}
- return (error);
+ break;
}
case LINUX_CDROMSTOP:
args->cmd = CDIOCSTOP;
- return (ioctl(td, (struct ioctl_args *)args));
+ error = (ioctl(td, (struct ioctl_args *)args));
+ break;
case LINUX_CDROMSTART:
args->cmd = CDIOCSTART;
- return (ioctl(td, (struct ioctl_args *)args));
+ error = (ioctl(td, (struct ioctl_args *)args));
+ break;
case LINUX_CDROMEJECT:
args->cmd = CDIOCEJECT;
- return (ioctl(td, (struct ioctl_args *)args));
+ error = (ioctl(td, (struct ioctl_args *)args));
+ break;
/* LINUX_CDROMVOLCTRL */
@@ -1278,11 +1335,11 @@ linux_ioctl_cdrom(struct thread *td, struct linux_ioctl_args *args)
bsdsc.data = bsdinfo;
error = fo_ioctl(fp, CDIOCREADSUBCHANNEL, (caddr_t)&bsdsc, td);
if (error)
- return (error);
+ break;
error = copyin((caddr_t)args->arg, &sc,
sizeof(struct linux_cdrom_subchnl));
if (error)
- return (error);
+ break;
sc.cdsc_audiostatus = bsdinfo->header.audio_status;
sc.cdsc_adr = bsdinfo->what.position.addr_type;
sc.cdsc_ctrl = bsdinfo->what.position.control;
@@ -1294,7 +1351,7 @@ linux_ioctl_cdrom(struct thread *td, struct linux_ioctl_args *args)
bsdinfo->what.position.reladdr.lba);
error = copyout(&sc, (caddr_t)args->arg,
sizeof(struct linux_cdrom_subchnl));
- return (error);
+ break;
}
/* LINUX_CDROMREADMODE2 */
@@ -1306,7 +1363,8 @@ linux_ioctl_cdrom(struct thread *td, struct linux_ioctl_args *args)
case LINUX_CDROMRESET:
args->cmd = CDIOCRESET;
- return (ioctl(td, (struct ioctl_args *)args));
+ error = (ioctl(td, (struct ioctl_args *)args));
+ break;
/* LINUX_CDROMVOLREAD */
/* LINUX_CDROMREADRAW */
@@ -1337,18 +1395,19 @@ linux_ioctl_cdrom(struct thread *td, struct linux_ioctl_args *args)
error = copyin((caddr_t)args->arg, &lds, sizeof(l_dvd_struct));
if (error)
- return (error);
+ break;
error = linux_to_bsd_dvd_struct(&lds, &bds);
if (error)
- return (error);
+ break;
error = fo_ioctl(fp, DVDIOCREADSTRUCTURE, (caddr_t)&bds, td);
if (error)
- return (error);
+ break;
error = bsd_to_linux_dvd_struct(&bds, &lds);
if (error)
- return (error);
- return (copyout(&lds, (caddr_t)args->arg,
- sizeof(l_dvd_struct)));
+ break;
+ error = copyout(&lds, (caddr_t)args->arg,
+ sizeof(l_dvd_struct));
+ break;
}
/* LINUX_DVD_WRITE_STRUCT */
@@ -1361,10 +1420,10 @@ linux_ioctl_cdrom(struct thread *td, struct linux_ioctl_args *args)
error = copyin((caddr_t)args->arg, &lda,
sizeof(l_dvd_authinfo));
if (error)
- return (error);
+ break;
error = linux_to_bsd_dvd_authinfo(&lda, &bcode, &bda);
if (error)
- return (error);
+ break;
error = fo_ioctl(fp, bcode, (caddr_t)&bda, td);
if (error) {
if (lda.type == LINUX_DVD_HOST_SEND_KEY2) {
@@ -1372,22 +1431,27 @@ linux_ioctl_cdrom(struct thread *td, struct linux_ioctl_args *args)
copyout(&lda, (caddr_t)args->arg,
sizeof(l_dvd_authinfo));
}
- return (error);
+ break;
}
error = bsd_to_linux_dvd_authinfo(&bda, &lda);
if (error)
- return (error);
- return (copyout(&lda, (caddr_t)args->arg,
- sizeof(l_dvd_authinfo)));
+ break;
+ error = copyout(&lda, (caddr_t)args->arg,
+ sizeof(l_dvd_authinfo));
+ break;
}
/* LINUX_CDROM_SEND_PACKET */
/* LINUX_CDROM_NEXT_WRITABLE */
/* LINUX_CDROM_LAST_WRITTEN */
+ default:
+ error = ENOIOCTL;
+ break;
}
- return (ENOIOCTL);
+ fdrop(fp, td);
+ return (error);
}
/*
@@ -1639,37 +1703,48 @@ linux_ioctl_sound(struct thread *td, struct linux_ioctl_args *args)
static int
linux_ioctl_console(struct thread *td, struct linux_ioctl_args *args)
{
- struct file *fp = td->td_proc->p_fd->fd_ofiles[args->fd];
+ struct file *fp;
+ int error;
+ fp = ffind_hold(td, args->fd);
+ if (fp == NULL)
+ return (EBADF);
switch (args->cmd & 0xffff) {
case LINUX_KIOCSOUND:
args->cmd = KIOCSOUND;
- return (ioctl(td, (struct ioctl_args *)args));
+ error = (ioctl(td, (struct ioctl_args *)args));
+ break;
case LINUX_KDMKTONE:
args->cmd = KDMKTONE;
- return (ioctl(td, (struct ioctl_args *)args));
+ error = (ioctl(td, (struct ioctl_args *)args));
+ break;
case LINUX_KDGETLED:
args->cmd = KDGETLED;
- return (ioctl(td, (struct ioctl_args *)args));
+ error = (ioctl(td, (struct ioctl_args *)args));
+ break;
case LINUX_KDSETLED:
args->cmd = KDSETLED;
- return (ioctl(td, (struct ioctl_args *)args));
+ error = (ioctl(td, (struct ioctl_args *)args));
+ break;
case LINUX_KDSETMODE:
args->cmd = KDSETMODE;
- return (ioctl(td, (struct ioctl_args *)args));
+ error = (ioctl(td, (struct ioctl_args *)args));
+ break;
case LINUX_KDGETMODE:
args->cmd = KDGETMODE;
- return (ioctl(td, (struct ioctl_args *)args));
+ error = (ioctl(td, (struct ioctl_args *)args));
+ break;
case LINUX_KDGKBMODE:
args->cmd = KDGKBMODE;
- return (ioctl(td, (struct ioctl_args *)args));
+ error = (ioctl(td, (struct ioctl_args *)args));
+ break;
case LINUX_KDSKBMODE: {
int kbdmode;
@@ -1684,18 +1759,22 @@ linux_ioctl_console(struct thread *td, struct linux_ioctl_args *args)
kbdmode = K_RAW;
break;
default:
+ fdrop(fp, td);
return (EINVAL);
}
- return (fo_ioctl(fp, KDSKBMODE, (caddr_t)&kbdmode, td));
+ error = (fo_ioctl(fp, KDSKBMODE, (caddr_t)&kbdmode, td));
+ break;
}
case LINUX_VT_OPENQRY:
args->cmd = VT_OPENQRY;
- return (ioctl(td, (struct ioctl_args *)args));
+ error = (ioctl(td, (struct ioctl_args *)args));
+ break;
case LINUX_VT_GETMODE:
args->cmd = VT_GETMODE;
- return (ioctl(td, (struct ioctl_args *)args));
+ error = (ioctl(td, (struct ioctl_args *)args));
+ break;
case LINUX_VT_SETMODE: {
struct vt_mode *mode;
@@ -1703,28 +1782,37 @@ linux_ioctl_console(struct thread *td, struct linux_ioctl_args *args)
mode = (struct vt_mode *)args->arg;
if (!ISSIGVALID(mode->frsig) && ISSIGVALID(mode->acqsig))
mode->frsig = mode->acqsig;
- return (ioctl(td, (struct ioctl_args *)args));
+ error = (ioctl(td, (struct ioctl_args *)args));
+ break;
}
case LINUX_VT_GETSTATE:
args->cmd = VT_GETACTIVE;
- return (ioctl(td, (struct ioctl_args *)args));
+ error = (ioctl(td, (struct ioctl_args *)args));
+ break;
case LINUX_VT_RELDISP:
args->cmd = VT_RELDISP;
- return (ioctl(td, (struct ioctl_args *)args));
+ error = (ioctl(td, (struct ioctl_args *)args));
+ break;
case LINUX_VT_ACTIVATE:
args->cmd = VT_ACTIVATE;
- return (ioctl(td, (struct ioctl_args *)args));
+ error = (ioctl(td, (struct ioctl_args *)args));
+ break;
case LINUX_VT_WAITACTIVE:
args->cmd = VT_WAITACTIVE;
- return (ioctl(td, (struct ioctl_args *)args));
+ error = (ioctl(td, (struct ioctl_args *)args));
+ break;
+ default:
+ error = ENOIOCTL;
+ break;
}
- return (ENOIOCTL);
+ fdrop(fp, td);
+ return (error);
}
/*
@@ -2161,7 +2249,6 @@ linux_ioctl_special(struct thread *td, struct linux_ioctl_args *args)
int
linux_ioctl(struct thread *td, struct linux_ioctl_args *args)
{
- struct filedesc *fdp;
struct file *fp;
struct handler_element *he;
int error, cmd;
@@ -2172,12 +2259,13 @@ linux_ioctl(struct thread *td, struct linux_ioctl_args *args)
(unsigned long)args->cmd);
#endif
- fdp = td->td_proc->p_fd;
- if ((unsigned)args->fd >= fdp->fd_nfiles)
+ fp = ffind_hold(td, args->fd);
+ if (fp == NULL)
return (EBADF);
- fp = fdp->fd_ofiles[args->fd];
- if (fp == NULL || (fp->f_flag & (FREAD|FWRITE)) == 0)
+ if ((fp->f_flag & (FREAD|FWRITE)) == 0) {
+ fdrop(fp, td);
return (EBADF);
+ }
/* Iterate over the ioctl handlers */
cmd = args->cmd & 0xffff;
@@ -2185,9 +2273,11 @@ linux_ioctl(struct thread *td, struct linux_ioctl_args *args)
if (cmd >= he->low && cmd <= he->high) {
error = (*he->func)(td, args);
if (error != ENOIOCTL)
+ fdrop(fp, td);
return (error);
}
}
+ fdrop(fp, td);
printf("linux: 'ioctl' fd=%d, cmd=0x%x ('%c',%d) not implemented\n",
args->fd, (int)(args->cmd & 0xffff),
diff --git a/sys/compat/linux/linux_stats.c b/sys/compat/linux/linux_stats.c
index f7d5b39..8f1799c 100644
--- a/sys/compat/linux/linux_stats.c
+++ b/sys/compat/linux/linux_stats.c
@@ -151,7 +151,6 @@ linux_newlstat(struct thread *td, struct linux_newlstat_args *args)
int
linux_newfstat(struct thread *td, struct linux_newfstat_args *args)
{
- struct filedesc *fdp;
struct file *fp;
struct stat buf;
int error;
@@ -161,12 +160,12 @@ linux_newfstat(struct thread *td, struct linux_newfstat_args *args)
printf(ARGS(newfstat, "%d, *"), args->fd);
#endif
- fdp = td->td_proc->p_fd;
- if ((unsigned)args->fd >= fdp->fd_nfiles ||
- (fp = fdp->fd_ofiles[args->fd]) == NULL)
+ fp = ffind_hold(td, args->fd);
+ if (fp == NULL)
return (EBADF);
error = fo_stat(fp, &buf, td);
+ fdrop(fp, td);
if (!error)
error = newstat_copyout(&buf, args->buf);
@@ -286,8 +285,10 @@ linux_fstatfs(struct thread *td, struct linux_fstatfs_args *args)
mp = ((struct vnode *)fp->f_data)->v_mount;
bsd_statfs = &mp->mnt_stat;
error = VFS_STATFS(mp, bsd_statfs, td);
- if (error)
+ if (error) {
+ fdrop(fp, td);
return error;
+ }
bsd_statfs->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
linux_statfs.f_type = bsd_to_linux_ftype(bsd_statfs->f_fstypename);
linux_statfs.f_bsize = bsd_statfs->f_bsize;
@@ -299,8 +300,10 @@ linux_fstatfs(struct thread *td, struct linux_fstatfs_args *args)
linux_statfs.f_fsid.val[0] = bsd_statfs->f_fsid.val[0];
linux_statfs.f_fsid.val[1] = bsd_statfs->f_fsid.val[1];
linux_statfs.f_namelen = MAXNAMLEN;
- return copyout((caddr_t)&linux_statfs, (caddr_t)args->buf,
+ error = copyout((caddr_t)&linux_statfs, (caddr_t)args->buf,
sizeof(linux_statfs));
+ fdrop(fp, td);
+ return error;
}
struct l_ustat
diff --git a/sys/compat/svr4/svr4_fcntl.c b/sys/compat/svr4/svr4_fcntl.c
index 465bae5..a13cd23 100644
--- a/sys/compat/svr4/svr4_fcntl.c
+++ b/sys/compat/svr4/svr4_fcntl.c
@@ -246,7 +246,6 @@ fd_revoke(td, fd)
struct thread *td;
int fd;
{
- struct filedesc *fdp = td->td_proc->p_fd;
struct file *fp;
struct vnode *vp;
struct mount *mp;
@@ -254,11 +253,14 @@ fd_revoke(td, fd)
int error, *retval;
retval = td->td_retval;
- if ((u_int)fd >= fdp->fd_nfiles || (fp = fdp->fd_ofiles[fd]) == NULL)
+ fp = ffind_hold(td, fd);
+ if (fp == NULL)
return EBADF;
- if (fp->f_type != DTYPE_VNODE)
+ if (fp->f_type != DTYPE_VNODE) {
+ fdrop(fp, td);
return EINVAL;
+ }
vp = (struct vnode *) fp->f_data;
@@ -281,6 +283,7 @@ fd_revoke(td, fd)
vn_finished_write(mp);
out:
vrele(vp);
+ fdrop(fp, td);
return error;
}
@@ -291,7 +294,6 @@ fd_truncate(td, fd, flp)
int fd;
struct flock *flp;
{
- struct filedesc *fdp = td->td_proc->p_fd;
struct file *fp;
off_t start, length;
struct vnode *vp;
@@ -304,15 +306,20 @@ fd_truncate(td, fd, flp)
/*
* We only support truncating the file.
*/
- if ((u_int)fd >= fdp->fd_nfiles || (fp = fdp->fd_ofiles[fd]) == NULL)
+ fp = ffind_hold(td, fd);
+ if (fp == NULL)
return EBADF;
vp = (struct vnode *)fp->f_data;
- if (fp->f_type != DTYPE_VNODE || vp->v_type == VFIFO)
+ if (fp->f_type != DTYPE_VNODE || vp->v_type == VFIFO) {
+ fdrop(fp, td);
return ESPIPE;
+ }
if ((error = VOP_GETATTR(vp, &vattr, td->td_proc->p_ucred, td)) != 0)
+ fdrop(fp, td);
return error;
+ }
length = vattr.va_size;
@@ -330,6 +337,7 @@ fd_truncate(td, fd, flp)
break;
default:
+ fdrop(fp, td);
return EINVAL;
}
@@ -341,7 +349,10 @@ fd_truncate(td, fd, flp)
SCARG(&ft, fd) = fd;
SCARG(&ft, length) = start;
- return ftruncate(td, &ft);
+ error = ftruncate(td, &ft);
+
+ fdrop(fp, td);
+ return (error);
}
int
@@ -373,15 +384,23 @@ svr4_sys_open(td, uap)
if (!(SCARG(&cup, flags) & O_NOCTTY) && SESS_LEADER(p) &&
!(td->td_proc->p_flag & P_CONTROLT)) {
#if defined(NOTYET)
- struct filedesc *fdp = td->td_proc->p_fd;
- struct file *fp = fdp->fd_ofiles[retval];
+ struct file *fp;
+ fp = ffind_hold(td, retval);
PROC_UNLOCK(p);
+ /*
+ * we may have lost a race the above open() and
+ * another thread issuing a close()
+ */
+ if (fp == NULL)
+ return (EBADF); /* XXX: correct errno? */
/* ignore any error, just give it a try */
if (fp->f_type == DTYPE_VNODE)
fo_ioctl(fp, TIOCSCTTY, (caddr_t) 0, td);
- } else
+ fdrop(fp, td);
+ } else {
PROC_UNLOCK(p);
+ }
#else
}
PROC_UNLOCK(p);
diff --git a/sys/compat/svr4/svr4_filio.c b/sys/compat/svr4/svr4_filio.c
index 8d24788..b24a039 100644
--- a/sys/compat/svr4/svr4_filio.c
+++ b/sys/compat/svr4/svr4_filio.c
@@ -97,7 +97,6 @@ svr4_sys_read(td, uap)
struct svr4_sys_read_args *uap;
{
struct read_args ra;
- struct filedesc *fdp = td->td_proc->p_fd;
struct file *fp;
struct socket *so = NULL;
int so_state;
@@ -108,7 +107,8 @@ svr4_sys_read(td, uap)
SCARG(&ra, buf) = SCARG(uap, buf);
SCARG(&ra, nbyte) = SCARG(uap, nbyte);
- if ((fp = fdp->fd_ofiles[SCARG(uap, fd)]) == NULL) {
+ fp = ffind_hold(td, uap->fd);
+ if (fp == NULL) {
DPRINTF(("Something fishy with the user-supplied file descriptor...\n"));
return EBADF;
}
@@ -142,6 +142,7 @@ svr4_sys_read(td, uap)
so->so_state = so_state;
}
#endif
+ fdrop(fp, td);
return(rv);
}
@@ -154,7 +155,6 @@ svr4_sys_write(td, uap)
struct svr4_sys_write_args *uap;
{
struct write_args wa;
- struct filedesc *fdp;
struct file *fp;
int rv;
@@ -186,13 +186,16 @@ svr4_fil_ioctl(fp, td, retval, fd, cmd, data)
*retval = 0;
+ FILEDESC_LOCK(fdp);
switch (cmd) {
case SVR4_FIOCLEX:
fdp->fd_ofileflags[fd] |= UF_EXCLOSE;
+ FILEDESC_UNLOCK(fdp);
return 0;
case SVR4_FIONCLEX:
fdp->fd_ofileflags[fd] &= ~UF_EXCLOSE;
+ FILEDESC_UNLOCK(fdp);
return 0;
case SVR4_FIOGETOWN:
@@ -200,6 +203,7 @@ svr4_fil_ioctl(fp, td, retval, fd, cmd, data)
case SVR4_FIOASYNC:
case SVR4_FIONBIO:
case SVR4_FIONREAD:
+ FILEDESC_UNLOCK(fdp);
if ((error = copyin(data, &num, sizeof(num))) != 0)
return error;
@@ -222,6 +226,7 @@ svr4_fil_ioctl(fp, td, retval, fd, cmd, data)
return copyout(&num, data, sizeof(num));
default:
+ FILEDESC_UNLOCK(fdp);
DPRINTF(("Unknown svr4 filio %lx\n", cmd));
return 0; /* ENOSYS really */
}
diff --git a/sys/compat/svr4/svr4_ioctl.c b/sys/compat/svr4/svr4_ioctl.c
index e153713..024c2e5 100644
--- a/sys/compat/svr4/svr4_ioctl.c
+++ b/sys/compat/svr4/svr4_ioctl.c
@@ -84,10 +84,10 @@ svr4_sys_ioctl(td, uap)
{
int *retval;
struct file *fp;
- struct filedesc *fdp;
u_long cmd;
int (*fun) __P((struct file *, struct thread *, register_t *,
int, u_long, caddr_t));
+ int error;
#ifdef DEBUG_SVR4
char dir[4];
char c;
@@ -100,15 +100,16 @@ svr4_sys_ioctl(td, uap)
dir, c, num, argsiz, SCARG(uap, data)));
#endif
retval = td->td_retval;
- fdp = td->td_proc->p_fd;
cmd = SCARG(uap, com);
- if ((u_int)SCARG(uap, fd) >= fdp->fd_nfiles ||
- (fp = fdp->fd_ofiles[SCARG(uap, fd)]) == NULL)
+ fp = ffind_hold(td, uap->fd);
+ if (fp == NULL)
return EBADF;
- if ((fp->f_flag & (FREAD | FWRITE)) == 0)
+ if ((fp->f_flag & (FREAD | FWRITE)) == 0) {
+ fdrop(fp, td);
return EBADF;
+ }
#if defined(DEBUG_SVR4)
if (fp->f_type == DTYPE_SOCKET) {
@@ -145,17 +146,23 @@ svr4_sys_ioctl(td, uap)
case SVR4_XIOC:
/* We do not support those */
+ fdrop(fp, td);
return EINVAL;
default:
+ fdrop(fp, td);
DPRINTF(("Unimplemented ioctl %lx\n", cmd));
return 0; /* XXX: really ENOSYS */
}
#if defined(DEBUG_SVR4)
if (fp->f_type == DTYPE_SOCKET) {
- struct socket *so = (struct socket *)fp->f_data;
+ struct socket *so;
+
+ so = (struct socket *)fp->f_data;
DPRINTF((">>> OUT: so_state = 0x%x\n", so->so_state));
}
#endif
- return (*fun)(fp, td, retval, SCARG(uap, fd), cmd, SCARG(uap, data));
+ error = (*fun)(fp, td, retval, SCARG(uap, fd), cmd, SCARG(uap, data));
+ fdrop(fp, td);
+ return (error);
}
diff --git a/sys/compat/svr4/svr4_misc.c b/sys/compat/svr4/svr4_misc.c
index 700be90..e83e6d5 100644
--- a/sys/compat/svr4/svr4_misc.c
+++ b/sys/compat/svr4/svr4_misc.c
@@ -263,15 +263,20 @@ svr4_sys_getdents64(td, uap)
return (error);
}
- if ((fp->f_flag & FREAD) == 0)
+ if ((fp->f_flag & FREAD) == 0) {
+ fdrop(fp, td);
return (EBADF);
+ }
vp = (struct vnode *) fp->f_data;
- if (vp->v_type != VDIR)
+ if (vp->v_type != VDIR) {
+ fdrop(fp, td);
return (EINVAL);
+ }
if ((error = VOP_GETATTR(vp, &va, td->td_proc->p_ucred, td))) {
+ fdrop(fp, td);
return error;
}
@@ -400,9 +405,10 @@ again:
eof:
td->td_retval[0] = nbytes - resid;
out:
+ VOP_UNLOCK(vp, 0, td);
+ fdrop(fp, td);
if (cookies)
free(cookies, M_TEMP);
- VOP_UNLOCK(vp, 0, td);
free(buf, M_TEMP);
return error;
}
@@ -431,12 +437,16 @@ svr4_sys_getdents(td, uap)
if ((error = getvnode(td->td_proc->p_fd, SCARG(uap, fd), &fp)) != 0)
return (error);
- if ((fp->f_flag & FREAD) == 0)
+ if ((fp->f_flag & FREAD) == 0) {
+ fdrop(fp, td);
return (EBADF);
+ }
vp = (struct vnode *)fp->f_data;
- if (vp->v_type != VDIR)
+ if (vp->v_type != VDIR) {
+ fdrop(fp, td);
return (EINVAL);
+ }
buflen = min(MAXBSIZE, SCARG(uap, nbytes));
buf = malloc(buflen, M_TEMP, M_WAITOK);
@@ -458,8 +468,9 @@ again:
*/
error = VOP_READDIR(vp, &auio, fp->f_cred, &eofflag, &ncookies,
&cookiebuf);
- if (error)
+ if (error) {
goto out;
+ }
inp = buf;
outp = SCARG(uap, buf);
@@ -515,6 +526,7 @@ eof:
*retval = SCARG(uap, nbytes) - resid;
out:
VOP_UNLOCK(vp, 0, td);
+ fdrop(fp, td);
if (cookiebuf)
free(cookiebuf, M_TEMP);
free(buf, M_TEMP);
@@ -607,11 +619,17 @@ svr4_sys_fchroot(td, uap)
error = VOP_ACCESS(vp, VEXEC, td->td_proc->p_ucred, td);
VOP_UNLOCK(vp, 0, td);
if (error)
+ fdrop(fp, td);
return error;
+ }
VREF(vp);
- if (fdp->fd_rdir != NULL)
- vrele(fdp->fd_rdir);
+ FILEDESC_LOCK(fdp);
+ vpold = fdp->fd_rdir;
fdp->fd_rdir = vp;
+ FILEDESC_UNLOCK(fdp);
+ if (vpold != NULL)
+ vrele(vpold);
+ fdrop(fp, td);
return 0;
}
@@ -1221,15 +1239,16 @@ loop:
nfound = 0;
sx_slock(&proctree_lock);
LIST_FOREACH(q, &td->td_proc->p_children, p_sibling) {
+ PROC_LOCK(q);
if (SCARG(uap, id) != WAIT_ANY &&
q->p_pid != SCARG(uap, id) &&
q->p_pgid != -SCARG(uap, id)) {
+ PROC_UNLOCK(q);
DPRINTF(("pid %d pgid %d != %d\n", q->p_pid,
q->p_pgid, SCARG(uap, id)));
continue;
}
nfound++;
- PROC_LOCK(q);
mtx_lock_spin(&sched_lock);
if (q->p_stat == SZOMB &&
((SCARG(uap, options) & (SVR4_WEXITED|SVR4_WTRAPPED)))) {
diff --git a/sys/compat/svr4/svr4_stream.c b/sys/compat/svr4/svr4_stream.c
index bf1c15a..6681acc 100644
--- a/sys/compat/svr4/svr4_stream.c
+++ b/sys/compat/svr4/svr4_stream.c
@@ -77,6 +77,10 @@
/* Utils */
static int clean_pipe __P((struct thread *, const char *));
static void getparm __P((struct file *, struct svr4_si_sockparms *));
+static int svr4_do_putmsg __P((struct proc *, struct svr4_sys_putmsg_args *,
+ struct file *));
+static int svr4_do_getmsg __P((struct proc *, struct svr4_sys_getmsg_args *,
+ struct file *));
/* Address Conversions */
static void sockaddr_to_netaddr_in __P((struct svr4_strmcmd *,
@@ -235,6 +239,7 @@ bad:
if (to)
FREE(to, M_SONAME);
done1:
+ fdrop(fp, td);
fputsock(so);
return (error);
}
@@ -359,6 +364,7 @@ out:
if (control)
m_freem(control);
done1:
+ fdrop(fp, td);
fputsock(so);
return (error);
}
@@ -619,12 +625,15 @@ getparm(fp, pa)
struct file *fp;
struct svr4_si_sockparms *pa;
{
- struct svr4_strm *st = svr4_stream_get(fp);
- struct socket *so = (struct socket *) fp->f_data;
+ struct svr4_strm *st;
+ struct socket *so;
+ st = svr4_stream_get(fp);
if (st == NULL)
return;
+ so = (struct socket *) fp->f_data;
+
pa->family = st->s_family;
switch (so->so_type) {
@@ -1705,8 +1714,27 @@ svr4_sys_putmsg(td, uap)
register struct thread *td;
struct svr4_sys_putmsg_args *uap;
{
- struct filedesc *fdp = td->td_proc->p_fd;
+ struct file *fp;
+ int error;
+
+ fp = ffind_hold(td, uap->fd);
+ if (fp == NULL) {
+#ifdef DEBUG_SVR4
+ uprintf("putmsg: bad fp\n");
+#endif
+ return EBADF;
+ }
+ error = svr4_do_putmsg(td, uap, fp);
+ fdrop(fp, td);
+ return (error);
+}
+
+static int
+svr4_do_putmsg(td, uap, fp)
+ struct thread *td;
+ struct svr4_sys_putmsg_args *uap;
struct file *fp;
+{
struct svr4_strbuf dat, ctl;
struct svr4_strmcmd sc;
struct sockaddr_in sain;
@@ -1718,26 +1746,13 @@ svr4_sys_putmsg(td, uap)
caddr_t sg;
retval = td->td_retval;
- fp = fdp->fd_ofiles[SCARG(uap, fd)];
-
- if (((u_int)SCARG(uap, fd) >= fdp->fd_nfiles) || (fp == NULL)) {
-#ifdef DEBUG_SVR4
- uprintf("putmsg: bad fp\n");
-#endif
- return EBADF;
- }
#ifdef DEBUG_SVR4
show_msg(">putmsg", SCARG(uap, fd), SCARG(uap, ctl),
SCARG(uap, dat), SCARG(uap, flags));
#endif /* DEBUG_SVR4 */
- if (((u_int)SCARG(uap, fd) >= fdp->fd_nfiles) || (fp == NULL)) {
-#ifdef DEBUG_SVR4
- uprintf("putmsg: bad fp(2)\n");
-#endif
- return EBADF;
- }
+ FILE_LOCK_ASSERT(fp, MA_NOTOWNED);
if (SCARG(uap, ctl) != NULL) {
if ((error = copyin(SCARG(uap, ctl), &ctl, sizeof(ctl))) != 0) {
@@ -1883,12 +1898,31 @@ svr4_sys_putmsg(td, uap)
}
int
+svr4_sys_getmsg(p, uap)
+ struct proc *p;
+ struct svr4_sys_getmsg_args *uap;
+{
+ struct file *fp;
+ int error;
+
+ fp = ffind_hold(td, uap->fd);
+ if (fp == NULL) {
+#ifdef DEBUG_SVR4
+ uprintf("getmsg: bad fp\n");
+#endif
+ return EBADF;
+ }
+ error = svr4_do_getmsg(p, uap, fp);
+ fdrop(fp, td);
+ return (error);
+}
+
+int
svr4_sys_getmsg(td, uap)
register struct thread *td;
struct svr4_sys_getmsg_args *uap;
+ struct file *fp;
{
- struct filedesc *fdp = td->td_proc->p_fd;
- struct file *fp;
struct getpeername_args ga;
struct accept_args aa;
struct svr4_strbuf dat, ctl;
@@ -1906,10 +1940,8 @@ svr4_sys_getmsg(td, uap)
caddr_t sg;
retval = td->td_retval;
- fp = fdp->fd_ofiles[SCARG(uap, fd)];
- if (((u_int)SCARG(uap, fd) >= fdp->fd_nfiles) || (fp == NULL))
- return EBADF;
+ FILE_LOCK_ASSERT(fp, MA_NOTOWNED);
memset(&sc, 0, sizeof(sc));
@@ -1917,9 +1949,6 @@ svr4_sys_getmsg(td, uap)
show_msg(">getmsg", SCARG(uap, fd), SCARG(uap, ctl),
SCARG(uap, dat), 0);
#endif /* DEBUG_SVR4 */
-
- if (((u_int)SCARG(uap, fd) >= fdp->fd_nfiles) || (fp == NULL))
- return EBADF;
if (SCARG(uap, ctl) != NULL) {
if ((error = copyin(SCARG(uap, ctl), &ctl, sizeof(ctl))) != 0)
OpenPOWER on IntegriCloud