From 228b401dc8841ecde6fe4b281e31686684b29a82 Mon Sep 17 00:00:00 2001 From: Matthew Dillon Date: Fri, 19 May 2006 07:33:46 +0000 Subject: [PATCH] Convert most manual accesses to filedesc->fd_files[] into the appropriate holdfp() call. Fix a number of places where ops were being executed on the file pointer without holding a private reference to it (mainly fo_ioctl(), revoke(), and lseek()). Create procedures in kern_descrip.c to set and clear descriptor flags and to handle the bootstrap filedesc for proc0. Replace manual code elsewhere with calls to the new procedures. Move getvnode() to kern_descrip.c. Remove nsmb_getfp(). Use holdfp() instead. --- sys/emulation/ibcs2/i386/ibcs2_fcntl.c | 13 +- sys/emulation/ibcs2/i386/ibcs2_ioctl.c | 163 +++++++++++++++---------- sys/emulation/linux/linux_file.c | 26 ++-- sys/emulation/svr4/svr4_fcntl.c | 52 ++++---- sys/emulation/svr4/svr4_filio.c | 36 +++--- sys/emulation/svr4/svr4_ioctl.c | 23 ++-- sys/emulation/svr4/svr4_stream.c | 143 +++++++++++----------- sys/kern/imgact_elf.c | 14 ++- sys/kern/init_main.c | 11 +- sys/kern/kern_descrip.c | 55 ++++++++- sys/kern/kern_event.c | 20 ++- sys/kern/sys_generic.c | 52 ++++---- sys/kern/vfs_syscalls.c | 46 +++---- sys/netproto/smb/smb_dev.c | 51 ++++---- sys/sys/filedesc.h | 5 +- sys/vfs/fdesc/fdesc_vnops.c | 10 +- sys/vm/vm_mmap.c | 30 ++--- 17 files changed, 412 insertions(+), 338 deletions(-) diff --git a/sys/emulation/ibcs2/i386/ibcs2_fcntl.c b/sys/emulation/ibcs2/i386/ibcs2_fcntl.c index 9231815347..cba529172e 100644 --- a/sys/emulation/ibcs2/i386/ibcs2_fcntl.c +++ b/sys/emulation/ibcs2/i386/ibcs2_fcntl.c @@ -25,7 +25,7 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * $FreeBSD: src/sys/i386/ibcs2/ibcs2_fcntl.c,v 1.14 1999/09/19 17:00:14 green Exp $ - * $DragonFly: src/sys/emulation/ibcs2/i386/Attic/ibcs2_fcntl.c,v 1.12 2006/05/06 02:43:11 dillon Exp $ + * $DragonFly: src/sys/emulation/ibcs2/i386/Attic/ibcs2_fcntl.c,v 1.13 2006/05/19 07:33:41 dillon Exp $ */ #include "opt_spx_hack.h" @@ -186,12 +186,15 @@ ibcs2_open(struct ibcs2_open_args *uap) } else #endif /* SPX_HACK */ if (!ret && !noctty && p && SESS_LEADER(p) && !(p->p_flag & P_CONTROLT)) { - struct filedesc *fdp = p->p_fd; - struct file *fp = fdp->fd_files[uap->sysmsg_result].fp; + struct file *fp; /* ignore any error, just give it a try */ - if (fp->f_type == DTYPE_VNODE) - fo_ioctl(fp, TIOCSCTTY, (caddr_t) 0, p->p_ucred); + fp = holdfp(p->p_fd, uap->sysmsg_result, -1); + if (fp) { + if (fp->f_type == DTYPE_VNODE) + fo_ioctl(fp, TIOCSCTTY, NULL, p->p_ucred); + fdrop(fp); + } } return ret; } diff --git a/sys/emulation/ibcs2/i386/ibcs2_ioctl.c b/sys/emulation/ibcs2/i386/ibcs2_ioctl.c index 9ee75cdf5b..e1cd716ac3 100644 --- a/sys/emulation/ibcs2/i386/ibcs2_ioctl.c +++ b/sys/emulation/ibcs2/i386/ibcs2_ioctl.c @@ -26,7 +26,7 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * $FreeBSD: src/sys/i386/ibcs2/ibcs2_ioctl.c,v 1.13.2.1 2001/07/31 20:14:21 jon Exp $ - * $DragonFly: src/sys/emulation/ibcs2/i386/Attic/ibcs2_ioctl.c,v 1.11 2006/05/06 02:43:11 dillon Exp $ + * $DragonFly: src/sys/emulation/ibcs2/i386/Attic/ibcs2_ioctl.c,v 1.12 2006/05/19 07:33:41 dillon Exp $ */ #include @@ -334,23 +334,14 @@ ibcs2_ioctl(struct ibcs2_ioctl_args *uap) { struct thread *td = curthread; struct proc *p = td->td_proc; - struct filedesc *fdp; struct file *fp; int error; KKASSERT(p); - fdp = p->p_fd; - if (SCARG(uap, fd) < 0 || SCARG(uap, fd) >= fdp->fd_nfiles || - (fp = fdp->fd_files[SCARG(uap, fd)].fp) == NULL) { - DPRINTF(("ibcs2_ioctl(td=%p): bad fd %d ", td, SCARG(uap, fd))); + fp = holdfp(p->p_fd, SCARG(uap, fd), FREAD|FWRITE); + if (fp == NULL) return EBADF; - } - - if ((fp->f_flag & (FREAD|FWRITE)) == 0) { - DPRINTF(("ibcs2_ioctl(td=%p): bad fp flag ", td)); - return EBADF; - } switch (SCARG(uap, cmd)) { case IBCS2_TCGETA: @@ -362,7 +353,7 @@ ibcs2_ioctl(struct ibcs2_ioctl_args *uap) struct ibcs2_termio st; if ((error = fo_ioctl(fp, TIOCGETA, (caddr_t)&bts, p->p_ucred)) != 0) - return error; + break; btios2stios (&bts, &sts); if (SCARG(uap, cmd) == IBCS2_TCGETA) { @@ -374,10 +365,11 @@ ibcs2_ioctl(struct ibcs2_ioctl_args *uap) DPRINTF(("ibcs2_ioctl(%d): copyout failed ", p->p_pid)); #endif - return error; - } else - return copyout((caddr_t)&sts, SCARG(uap, data), + } else { + error = copyout((caddr_t)&sts, SCARG(uap, data), sizeof (sts)); + } + break; /*NOTREACHED*/ } @@ -393,14 +385,14 @@ ibcs2_ioctl(struct ibcs2_ioctl_args *uap) sizeof(st))) != 0) { DPRINTF(("ibcs2_ioctl(%d): TCSET copyin failed ", p->p_pid)); - return error; + break; } /* get full BSD termios so we don't lose information */ if ((error = fo_ioctl(fp, TIOCGETA, (caddr_t)&bts, p->p_ucred)) != 0) { DPRINTF(("ibcs2_ioctl(%d): TCSET ctl failed fd %d ", p->p_pid, SCARG(uap, fd))); - return error; + break; } /* @@ -411,8 +403,9 @@ ibcs2_ioctl(struct ibcs2_ioctl_args *uap) stio2stios(&st, &sts); stios2btios(&sts, &bts); - return fo_ioctl(fp, SCARG(uap, cmd) - IBCS2_TCSETA + TIOCSETA, + error = fo_ioctl(fp, SCARG(uap, cmd) - IBCS2_TCSETA + TIOCSETA, (caddr_t)&bts, p->p_ucred); + break; } case IBCS2_XCSETA: @@ -424,11 +417,12 @@ ibcs2_ioctl(struct ibcs2_ioctl_args *uap) if ((error = copyin(SCARG(uap, data), (caddr_t)&sts, sizeof (sts))) != 0) { - return error; + break; } stios2btios (&sts, &bts); - return fo_ioctl(fp, SCARG(uap, cmd) - IBCS2_XCSETA + TIOCSETA, - (caddr_t)&bts, p->p_ucred); + error = fo_ioctl(fp, SCARG(uap, cmd) - IBCS2_XCSETA + TIOCSETA, + (caddr_t)&bts, p->p_ucred); + break; } case IBCS2_OXCSETA: @@ -440,16 +434,18 @@ ibcs2_ioctl(struct ibcs2_ioctl_args *uap) if ((error = copyin(SCARG(uap, data), (caddr_t)&sts, sizeof (sts))) != 0) { - return error; + break; } stios2btios (&sts, &bts); - return fo_ioctl(fp, SCARG(uap, cmd) - IBCS2_OXCSETA + TIOCSETA, + error = fo_ioctl(fp, SCARG(uap, cmd) - IBCS2_OXCSETA + TIOCSETA, (caddr_t)&bts, p->p_ucred); + break; } case IBCS2_TCSBRK: DPRINTF(("ibcs2_ioctl(td=%p): TCSBRK ", td)); - return ENOSYS; + error = ENOSYS; + break; case IBCS2_TCXONC: { @@ -457,20 +453,26 @@ ibcs2_ioctl(struct ibcs2_ioctl_args *uap) case 0: case 1: DPRINTF(("ibcs2_ioctl(td=%p): TCXONC ", td)); - return ENOSYS; + error = ENOSYS; + break; case 2: - return fo_ioctl(fp, TIOCSTOP, (caddr_t)0, p->p_ucred); + error = fo_ioctl(fp, TIOCSTOP, (caddr_t)0, p->p_ucred); + break; case 3: - return fo_ioctl(fp, TIOCSTART, (caddr_t)1, p->p_ucred); + error = fo_ioctl(fp, TIOCSTART, (caddr_t)1, p->p_ucred); + break; default: - return EINVAL; + error = EINVAL; + break; } + break; } case IBCS2_TCFLSH: { int arg; + error = 0; switch ((int)SCARG(uap, data)) { case 0: arg = FREAD; @@ -482,22 +484,29 @@ ibcs2_ioctl(struct ibcs2_ioctl_args *uap) arg = FREAD | FWRITE; break; default: - return EINVAL; + error = EINVAL; + } + if (error == 0) { + error = fo_ioctl(fp, TIOCFLUSH, (caddr_t)&arg, + p->p_ucred); } - return fo_ioctl(fp, TIOCFLUSH, (caddr_t)&arg, p->p_ucred); + break; } case IBCS2_TIOCGWINSZ: SCARG(uap, cmd) = TIOCGWINSZ; - return ioctl((struct ioctl_args *)uap); + error = ioctl((struct ioctl_args *)uap); + break; case IBCS2_TIOCSWINSZ: SCARG(uap, cmd) = TIOCSWINSZ; - return ioctl((struct ioctl_args *)uap); + error = ioctl((struct ioctl_args *)uap); + break; case IBCS2_TIOCGPGRP: - return copyout((caddr_t)&p->p_pgrp->pg_id, SCARG(uap, data), + error = copyout((caddr_t)&p->p_pgrp->pg_id, SCARG(uap, data), sizeof(p->p_pgrp->pg_id)); + break; case IBCS2_TIOCSPGRP: /* XXX - is uap->data a pointer to pgid? */ { @@ -505,16 +514,17 @@ ibcs2_ioctl(struct ibcs2_ioctl_args *uap) SCARG(&sa, pid) = 0; SCARG(&sa, pgid) = (int)SCARG(uap, data); - if ((error = setpgid(&sa)) != 0) - return error; - return 0; + error = setpgid(&sa); + break; } case IBCS2_TCGETSC: /* SCO console - get scancode flags */ - return EINTR; /* ENOSYS; */ + error = EINTR; /* ENOSYS; */ + break; case IBCS2_TCSETSC: /* SCO console - set scancode flags */ - return 0; /* ENOSYS; */ + error = 0; /* ENOSYS; */ + break; case IBCS2_JWINSIZE: /* Unix to Jerq I/O control */ { @@ -531,105 +541,130 @@ ibcs2_ioctl(struct ibcs2_ioctl_args *uap) p->p_session->s_ttyp->t_winsize.ws_xpixel; ibcs2_jwinsize.bity = p->p_session->s_ttyp->t_winsize.ws_ypixel; - return copyout((caddr_t)&ibcs2_jwinsize, SCARG(uap, data), + error = copyout((caddr_t)&ibcs2_jwinsize, SCARG(uap, data), sizeof(ibcs2_jwinsize)); + break; } /* keyboard and display ioctl's -- type 'K' */ case IBCS2_KDGKBMODE: /* get keyboard translation mode */ SCARG(uap, cmd) = KDGKBMODE; /* printf("ioctl KDGKBMODE = %x\n", SCARG(uap, cmd));*/ - return ioctl((struct ioctl_args *)uap); + error = ioctl((struct ioctl_args *)uap); + break; case IBCS2_KDSKBMODE: /* set keyboard translation mode */ SCARG(uap, cmd) = KDSKBMODE; - return ioctl((struct ioctl_args *)uap); + error = ioctl((struct ioctl_args *)uap); + break; case IBCS2_KDMKTONE: /* sound tone */ SCARG(uap, cmd) = KDMKTONE; - return ioctl((struct ioctl_args *)uap); + error = ioctl((struct ioctl_args *)uap); + break; case IBCS2_KDGETMODE: /* get text/graphics mode */ SCARG(uap, cmd) = KDGETMODE; - return ioctl((struct ioctl_args *)uap); + error = ioctl((struct ioctl_args *)uap); + break; case IBCS2_KDSETMODE: /* set text/graphics mode */ SCARG(uap, cmd) = KDSETMODE; - return ioctl((struct ioctl_args *)uap); + error = ioctl((struct ioctl_args *)uap); + break; case IBCS2_KDSBORDER: /* set ega color border */ SCARG(uap, cmd) = KDSBORDER; - return ioctl((struct ioctl_args *)uap); + error = ioctl((struct ioctl_args *)uap); + break; case IBCS2_KDGKBSTATE: SCARG(uap, cmd) = KDGKBSTATE; - return ioctl((struct ioctl_args *)uap); + error = ioctl((struct ioctl_args *)uap); + break; case IBCS2_KDSETRAD: SCARG(uap, cmd) = KDSETRAD; - return ioctl((struct ioctl_args *)uap); + error = ioctl((struct ioctl_args *)uap); + break; case IBCS2_KDENABIO: /* enable direct I/O to ports */ SCARG(uap, cmd) = KDENABIO; - return ioctl((struct ioctl_args *)uap); + error = ioctl((struct ioctl_args *)uap); + break; case IBCS2_KDDISABIO: /* disable direct I/O to ports */ SCARG(uap, cmd) = KDDISABIO; - return ioctl((struct ioctl_args *)uap); + error = ioctl((struct ioctl_args *)uap); + break; case IBCS2_KIOCSOUND: /* start sound generation */ SCARG(uap, cmd) = KIOCSOUND; - return ioctl((struct ioctl_args *)uap); + error = ioctl((struct ioctl_args *)uap); + break; case IBCS2_KDGKBTYPE: /* get keyboard type */ SCARG(uap, cmd) = KDGKBTYPE; - return ioctl((struct ioctl_args *)uap); + error = ioctl((struct ioctl_args *)uap); + break; case IBCS2_KDGETLED: /* get keyboard LED status */ SCARG(uap, cmd) = KDGETLED; - return ioctl((struct ioctl_args *)uap); + error = ioctl((struct ioctl_args *)uap); + break; case IBCS2_KDSETLED: /* set keyboard LED status */ SCARG(uap, cmd) = KDSETLED; - return ioctl((struct ioctl_args *)uap); + error = ioctl((struct ioctl_args *)uap); + break; /* Xenix keyboard and display ioctl's from sys/kd.h -- type 'k' */ case IBCS2_GETFKEY: /* Get function key */ SCARG(uap, cmd) = GETFKEY; - return ioctl((struct ioctl_args *)uap); + error = ioctl((struct ioctl_args *)uap); + break; case IBCS2_SETFKEY: /* Set function key */ SCARG(uap, cmd) = SETFKEY; - return ioctl((struct ioctl_args *)uap); + error = ioctl((struct ioctl_args *)uap); + break; case IBCS2_GIO_SCRNMAP: /* Get screen output map table */ SCARG(uap, cmd) = GIO_SCRNMAP; - return ioctl((struct ioctl_args *)uap); + error = ioctl((struct ioctl_args *)uap); + break; case IBCS2_PIO_SCRNMAP: /* Set screen output map table */ SCARG(uap, cmd) = PIO_SCRNMAP; - return ioctl((struct ioctl_args *)uap); + error = ioctl((struct ioctl_args *)uap); + break; case IBCS2_GIO_KEYMAP: /* Get keyboard map table */ SCARG(uap, cmd) = GIO_KEYMAP; - return ioctl((struct ioctl_args *)uap); + error = ioctl((struct ioctl_args *)uap); + break; case IBCS2_PIO_KEYMAP: /* Set keyboard map table */ SCARG(uap, cmd) = PIO_KEYMAP; - return ioctl((struct ioctl_args *)uap); + error = ioctl((struct ioctl_args *)uap); + break; /* socksys */ case IBCS2_SIOCSOCKSYS: - return ibcs2_socksys((struct ibcs2_socksys_args *)uap); + error = ibcs2_socksys((struct ibcs2_socksys_args *)uap); + break; case IBCS2_I_NREAD: /* STREAMS */ SCARG(uap, cmd) = FIONREAD; - return ioctl((struct ioctl_args *)uap); + error = ioctl((struct ioctl_args *)uap); + break; default: DPRINTF(("ibcs2_ioctl(%d): unknown cmd 0x%lx ", p->p_pid, SCARG(uap, cmd))); - return ENOSYS; + error = ENOSYS; + break; } - return ENOSYS; + fdrop(fp); + return (error); } diff --git a/sys/emulation/linux/linux_file.c b/sys/emulation/linux/linux_file.c index aa2aa87431..912cf287b3 100644 --- a/sys/emulation/linux/linux_file.c +++ b/sys/emulation/linux/linux_file.c @@ -26,7 +26,7 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * $FreeBSD: src/sys/compat/linux/linux_file.c,v 1.41.2.6 2003/01/06 09:19:43 fjoe Exp $ - * $DragonFly: src/sys/emulation/linux/linux_file.c,v 1.28 2006/05/06 02:43:11 dillon Exp $ + * $DragonFly: src/sys/emulation/linux/linux_file.c,v 1.29 2006/05/19 07:33:43 dillon Exp $ */ #include "opt_compat.h" @@ -140,12 +140,15 @@ linux_open(struct linux_open_args *args) if (error == 0 && !(flags & O_NOCTTY) && SESS_LEADER(p) && !(p->p_flag & P_CONTROLT)) { - struct filedesc *fdp = p->p_fd; - struct file *fp = fdp->fd_files[args->sysmsg_result].fp; + struct file *fp; - if (fp->f_type == DTYPE_VNODE) - fo_ioctl(fp, TIOCSCTTY, (caddr_t) 0, p->p_ucred); - } + fp = holdfp(p->p_fd, args->sysmsg_result, -1); + if (fp) { + if (fp->f_type == DTYPE_VNODE) + fo_ioctl(fp, TIOCSCTTY, NULL, p->p_ucred); + fdrop(fp); + } + } #ifdef DEBUG if (ldebug(open)) printf(LMSG("open returns error %d"), error); @@ -992,7 +995,6 @@ linux_fcntl_common(struct linux_fcntl64_args *args) { struct proc *p = curproc; struct l_flock linux_flock; - struct filedesc *fdp; struct file *fp; union fcntl_dat dat; int error, cmd; @@ -1043,12 +1045,14 @@ linux_fcntl_common(struct linux_fcntl64_args *args) * significant effect for pipes (SIGIO is not delivered for * pipes under Linux-2.2.35 at least). */ - fdp = p->p_fd; - if ((u_int)args->fd >= fdp->fd_nfiles || - (fp = fdp->fd_files[args->fd].fp) == NULL) + fp = holdfp(p->p_fd, args->fd, -1); + if (fp == NULL) return (EBADF); - if (fp->f_type == DTYPE_PIPE) + if (fp->f_type == DTYPE_PIPE) { + fdrop(fp); return (EINVAL); + } + fdrop(fp); cmd = F_SETOWN; dat.fc_owner = args->arg; break; diff --git a/sys/emulation/svr4/svr4_fcntl.c b/sys/emulation/svr4/svr4_fcntl.c index e5849664d8..be924705d5 100644 --- a/sys/emulation/svr4/svr4_fcntl.c +++ b/sys/emulation/svr4/svr4_fcntl.c @@ -29,7 +29,7 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * $FreeBSD: src/sys/svr4/svr4_fcntl.c,v 1.7 1999/12/12 10:27:04 newton Exp $ - * $DragonFly: src/sys/emulation/svr4/Attic/svr4_fcntl.c,v 1.18 2006/05/06 02:43:12 dillon Exp $ + * $DragonFly: src/sys/emulation/svr4/Attic/svr4_fcntl.c,v 1.19 2006/05/19 07:33:44 dillon Exp $ */ #include #include @@ -235,7 +235,6 @@ static int fd_revoke(struct thread *td, int fd) { struct proc *p = td->td_proc; - struct filedesc *fdp; struct file *fp; struct vnode *vp; struct vattr vattr; @@ -243,17 +242,18 @@ fd_revoke(struct thread *td, int fd) KKASSERT(p); - fdp = p->p_fd; - if ((u_int)fd >= fdp->fd_nfiles || (fp = fdp->fd_files[fd].fp) == NULL) + fp = holdfp(p->p_fd, fd, -1); + if (fp == NULL) return EBADF; + if (fp->f_type != DTYPE_VNODE) { + error = EINVAL; + goto out2; + } - if (fp->f_type != DTYPE_VNODE) - return EINVAL; - - vp = (struct vnode *) fp->f_data; + vp = (struct vnode *)fp->f_data; if ((error = vx_get(vp)) != 0) - return (error); + goto out2; if (vp->v_type != VCHR && vp->v_type != VBLK) { error = EINVAL; @@ -271,6 +271,8 @@ fd_revoke(struct thread *td, int fd) VOP_REVOKE(vp, REVOKEALL); out: vx_put(vp); +out2: + fdrop(fp); return error; } @@ -279,7 +281,6 @@ static int fd_truncate(struct thread *td, int fd, struct flock *flp, int *retval) { struct proc *p = td->td_proc; - struct filedesc *fdp; struct file *fp; off_t start, length; struct vnode *vp; @@ -288,20 +289,22 @@ fd_truncate(struct thread *td, int fd, struct flock *flp, int *retval) struct ftruncate_args ft; KKASSERT(p); - fdp = p->p_fd; /* * We only support truncating the file. */ - if ((u_int)fd >= fdp->fd_nfiles || (fp = fdp->fd_files[fd].fp) == NULL) + fp = holdfp(p->p_fd, fd, -1); + if (fp == NULL) return EBADF; vp = (struct vnode *)fp->f_data; - if (fp->f_type != DTYPE_VNODE || vp->v_type == VFIFO) - return ESPIPE; + if (fp->f_type != DTYPE_VNODE || vp->v_type == VFIFO) { + error = ESPIPE; + goto done; + } if ((error = VOP_GETATTR(vp, &vattr)) != 0) - return error; + goto done; length = vattr.va_size; @@ -319,18 +322,22 @@ fd_truncate(struct thread *td, int fd, struct flock *flp, int *retval) break; default: - return EINVAL; + error = EINVAL; + goto done; } if (start + flp->l_len < length) { /* We don't support free'ing in the middle of the file */ - return EINVAL; + error = EINVAL; + goto done; } SCARG(&ft, fd) = fd; SCARG(&ft, length) = start; error = ftruncate(&ft); *retval = ft.sysmsg_result; +done: + fdrop(fp); return(error); } @@ -363,12 +370,15 @@ svr4_sys_open(struct svr4_sys_open_args *uap) if (!(SCARG(&cup, flags) & O_NOCTTY) && SESS_LEADER(p) && !(p->p_flag & P_CONTROLT)) { #if defined(NOTYET) - struct filedesc *fdp = p->p_fd; - struct file *fp = fdp->fd_files[retval].fp; + struct file *fp; /* ignore any error, just give it a try */ - if (fp->f_type == DTYPE_VNODE) - fo_ioctl(fp, TIOCSCTTY, (caddr_t) 0, cred); + fp = holdfp(p->p_fd, retval, -1); + if (fp) { + if (fp->f_type == DTYPE_VNODE) + fo_ioctl(fp, TIOCSCTTY, NULL, cred); + fdrop(fp); + } #endif } return error; diff --git a/sys/emulation/svr4/svr4_filio.c b/sys/emulation/svr4/svr4_filio.c index d9e3020bfa..369c60b49c 100644 --- a/sys/emulation/svr4/svr4_filio.c +++ b/sys/emulation/svr4/svr4_filio.c @@ -26,7 +26,7 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * $FreeBSD: src/sys/svr4/svr4_filio.c,v 1.8 2000/01/15 15:30:44 newton Exp $ - * $DragonFly: src/sys/emulation/svr4/Attic/svr4_filio.c,v 1.10 2006/05/06 02:43:12 dillon Exp $ + * $DragonFly: src/sys/emulation/svr4/Attic/svr4_filio.c,v 1.11 2006/05/19 07:33:44 dillon Exp $ */ #include @@ -95,7 +95,6 @@ int svr4_sys_read(struct svr4_sys_read_args *uap) { struct read_args ra; - struct filedesc *fdp = p->p_fd; struct file *fp; struct socket *so = NULL; int so_state; @@ -106,10 +105,9 @@ svr4_sys_read(struct svr4_sys_read_args *uap) SCARG(&ra, buf) = SCARG(uap, buf); SCARG(&ra, nbyte) = SCARG(uap, nbyte); - if ((fp = fdp->fd_files[SCARG(uap, fd)].fp) == NULL) { - DPRINTF(("Something fishy with the user-supplied file descriptor...\n")); + fp = holdfp(p->p_fd, SCARG(uap, fd), -1); + if (fp == NULL) return EBADF; - } if (fp->f_type == DTYPE_SOCKET) { so = (struct socket *)fp->f_data; @@ -123,6 +121,7 @@ svr4_sys_read(struct svr4_sys_read_args *uap) so->so_state &= ~SS_NBIO; #endif } + fdrop(fp); ra.sysmsg_result = 0; rv = read(&ra); @@ -152,8 +151,6 @@ int svr4_sys_write(struct svr4_sys_write_args *uap) { struct write_args wa; - struct filedesc *fdp; - struct file *fp; int rv; SCARG(&wa, fd) = SCARG(uap, fd); @@ -178,21 +175,18 @@ svr4_fil_ioctl(struct file *fp, struct thread *td, register_t *retval, struct proc *p = td->td_proc; int error; int num; - struct filedesc *fdp; KKASSERT(p); - fdp = p->p_fd; *retval = 0; switch (cmd) { case SVR4_FIOCLEX: - fdp->fd_files[fd].fileflags |= UF_EXCLOSE; - return 0; - + error = fsetfdflags(p->p_fd, fd, UF_EXCLOSE); + break; case SVR4_FIONCLEX: - fdp->fd_files[fd].fileflags &= ~UF_EXCLOSE; - return 0; + error = fclrfdflags(p->p_fd, fd, UF_EXCLOSE); + break; case SVR4_FIOGETOWN: case SVR4_FIOSETOWN: @@ -200,7 +194,7 @@ svr4_fil_ioctl(struct file *fp, struct thread *td, register_t *retval, case SVR4_FIONBIO: case SVR4_FIONREAD: if ((error = copyin(data, &num, sizeof(num))) != 0) - return error; + break; switch (cmd) { case SVR4_FIOGETOWN: cmd = FIOGETOWN; break; @@ -214,14 +208,14 @@ svr4_fil_ioctl(struct file *fp, struct thread *td, register_t *retval, if (cmd == FIOASYNC) DPRINTF(("FIOASYNC\n")); #endif error = fo_ioctl(fp, cmd, (caddr_t) &num, p->p_ucred); - - if (error) - return error; - - return copyout(&num, data, sizeof(num)); + if (error == 0) + error = copyout(&num, data, sizeof(num)); + break; default: DPRINTF(("Unknown svr4 filio %lx\n", cmd)); - return 0; /* ENOSYS really */ + error = 0; /* ENOSYS really */ + break; } + return (error); } diff --git a/sys/emulation/svr4/svr4_ioctl.c b/sys/emulation/svr4/svr4_ioctl.c index f8b79b7966..80fb7b9d6c 100644 --- a/sys/emulation/svr4/svr4_ioctl.c +++ b/sys/emulation/svr4/svr4_ioctl.c @@ -26,7 +26,7 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * $FreeBSD: src/sys/svr4/svr4_ioctl.c,v 1.6 1999/12/08 12:00:48 newton Exp $ - * $DragonFly: src/sys/emulation/svr4/Attic/svr4_ioctl.c,v 1.12 2005/06/22 01:33:29 dillon Exp $ + * $DragonFly: src/sys/emulation/svr4/Attic/svr4_ioctl.c,v 1.13 2006/05/19 07:33:44 dillon Exp $ */ #include @@ -87,7 +87,6 @@ svr4_sys_ioctl(struct svr4_sys_ioctl_args *uap) struct proc *p = td->td_proc; int *retval; struct file *fp; - struct filedesc *fdp; u_long cmd; int (*fun) (struct file *, struct thread *, register_t *, int, u_long, caddr_t); @@ -96,6 +95,7 @@ svr4_sys_ioctl(struct svr4_sys_ioctl_args *uap) char c; int num; int argsiz; + int error; KKASSERT(p); @@ -106,14 +106,10 @@ svr4_sys_ioctl(struct svr4_sys_ioctl_args *uap) dir, c, num, argsiz, SCARG(uap, data))); #endif retval = &uap->sysmsg_result; - fdp = p->p_fd; cmd = SCARG(uap, com); - if ((u_int)SCARG(uap, fd) >= fdp->fd_nfiles || - (fp = fdp->fd_files[SCARG(uap, fd)].fp) == NULL) - return EBADF; - - if ((fp->f_flag & (FREAD | FWRITE)) == 0) + fp = holdfp(p->p_fd, SCARG(uap, fd), FREAD|FWRITE); + if (fp == NULL) return EBADF; #if defined(DEBUG_SVR4) @@ -151,11 +147,13 @@ svr4_sys_ioctl(struct svr4_sys_ioctl_args *uap) case SVR4_XIOC: /* We do not support those */ - return EINVAL; + error = EINVAL; + goto done; default: DPRINTF(("Unimplemented ioctl %lx\n", cmd)); - return 0; /* XXX: really ENOSYS */ + error = 0; /* XXX: really ENOSYS */ + goto done; } #if defined(DEBUG_SVR4) if (fp->f_type == DTYPE_SOCKET) { @@ -163,5 +161,8 @@ svr4_sys_ioctl(struct svr4_sys_ioctl_args *uap) 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)); +done: + fdrop(fp); + return (error); } diff --git a/sys/emulation/svr4/svr4_stream.c b/sys/emulation/svr4/svr4_stream.c index 3865db5b3a..5be4b644a5 100644 --- a/sys/emulation/svr4/svr4_stream.c +++ b/sys/emulation/svr4/svr4_stream.c @@ -28,7 +28,7 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * $FreeBSD: src/sys/svr4/svr4_stream.c,v 1.12.2.2 2000/11/26 04:42:27 dillon Exp $ - * $DragonFly: src/sys/emulation/svr4/Attic/svr4_stream.c,v 1.18 2006/05/17 18:30:16 dillon Exp $ + * $DragonFly: src/sys/emulation/svr4/Attic/svr4_stream.c,v 1.19 2006/05/19 07:33:44 dillon Exp $ */ /* @@ -1631,7 +1631,6 @@ svr4_sys_putmsg(struct svr4_sys_putmsg_args *uap) { struct thread *td = curthread; struct proc *p = td->td_proc; - struct filedesc *fdp; struct file *fp; struct svr4_strbuf dat, ctl; struct svr4_strmcmd sc; @@ -1644,67 +1643,52 @@ svr4_sys_putmsg(struct svr4_sys_putmsg_args *uap) caddr_t sg; KKASSERT(p); - fdp = p->p_fd; retval = &uap->sysmsg_result; - fp = fdp->fd_files[SCARG(uap, fd)].fp; - if (((u_int)SCARG(uap, fd) >= fdp->fd_nfiles) || (fp == NULL)) { -#ifdef DEBUG_SVR4 - uprintf("putmsg: bad fp\n"); -#endif + fp = holdfp(p->p_fd, SCARG(uap, fd), -1); + if (fp == NULL) 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; - } if (SCARG(uap, ctl) != NULL) { if ((error = copyin(SCARG(uap, ctl), &ctl, sizeof(ctl))) != 0) { #ifdef DEBUG_SVR4 uprintf("putmsg: copyin(): %d\n", error); #endif - return error; + goto done; } + } else { + ctl.len = -1; } - else - ctl.len = -1; if (SCARG(uap, dat) != NULL) { if ((error = copyin(SCARG(uap, dat), &dat, sizeof(dat))) != 0) { #ifdef DEBUG_SVR4 uprintf("putmsg: copyin(): %d (2)\n", error); #endif - return error; + goto done; } + } else { + dat.len = -1; } - else - dat.len = -1; /* * Only for sockets for now. */ if ((st = svr4_stream_get(fp)) == NULL) { DPRINTF(("putmsg: bad file type\n")); - return EINVAL; + error = EINVAL; + goto done; } if (ctl.len > sizeof(sc)) { DPRINTF(("putmsg: Bad control size %d != %d\n", ctl.len, sizeof(struct svr4_strmcmd))); - return EINVAL; + error = EINVAL; + goto done; } if ((error = copyin(ctl.buf, &sc, ctl.len)) != 0) - return error; + goto done; switch (st->s_family) { case AF_INET: @@ -1728,15 +1712,16 @@ svr4_sys_putmsg(struct svr4_sys_putmsg_args *uap) error = write(&wa); *retval = wa.sysmsg_result; - return(error); + goto done; } DPRINTF(("putmsg: Invalid inet length %ld\n", sc.len)); - return EINVAL; + error = EINVAL; + goto done; } netaddr_to_sockaddr_in(&sain, &sc); skp = &sain; sasize = sizeof(sain); - error = sain.sin_family != st->s_family; + error = sain.sin_family != st->s_family; /* XXX error code thrown away??? */ break; case AF_LOCAL: @@ -1744,7 +1729,8 @@ svr4_sys_putmsg(struct svr4_sys_putmsg_args *uap) /* We are doing an accept; succeed */ DPRINTF(("putmsg: Do nothing\n")); *retval = 0; - return 0; + error = 0; + goto done; } else { /* Maybe we've been given a device/inode pair */ @@ -1763,14 +1749,15 @@ svr4_sys_putmsg(struct svr4_sys_putmsg_args *uap) default: DPRINTF(("putmsg: Unsupported address family %d\n", st->s_family)); - return ENOSYS; + error = ENOSYS; + goto done; } sg = stackgap_init(); sup = stackgap_alloc(&sg, sasize); if ((error = copyout(skp, sup, sasize)) != 0) - return error; + goto done; switch (st->s_cmd = sc.cmd) { case SVR4_TI_CONNECT_REQUEST: /* connect */ @@ -1784,7 +1771,7 @@ svr4_sys_putmsg(struct svr4_sys_putmsg_args *uap) error = connect(&co); *retval = co.sysmsg_result; - return(error); + break; } case SVR4_TI_SENDTO_REQUEST: /* sendto */ @@ -1808,13 +1795,17 @@ svr4_sys_putmsg(struct svr4_sys_putmsg_args *uap) SCARG(uap, flags), retval); DPRINTF(("sendto_request error: %d\n", error)); *retval = 0; - return error; + break; } default: DPRINTF(("putmsg: Unimplemented command %lx\n", sc.cmd)); - return ENOSYS; + error = ENOSYS; + break; } +done: + fdrop(fp); + return (error); } int @@ -1822,7 +1813,6 @@ svr4_sys_getmsg(struct svr4_sys_getmsg_args *uap) { struct thread *td = curthread; struct proc *p = td->td_proc; - struct filedesc *fdp; struct file *fp; struct getpeername_args ga; struct accept_args aa; @@ -1841,11 +1831,10 @@ svr4_sys_getmsg(struct svr4_sys_getmsg_args *uap) caddr_t sg; KKASSERT(p); - fdp = p->p_fd; - retval = &uap->sysmsg_result; - fp = fdp->fd_files[SCARG(uap, fd)].fp; - if (((u_int)SCARG(uap, fd) >= fdp->fd_nfiles) || (fp == NULL)) + retval = &uap->sysmsg_result; + fp = holdfp(p->p_fd, SCARG(uap, fd), -1); + if (fp == NULL) return EBADF; memset(&sc, 0, sizeof(sc)); @@ -1855,23 +1844,18 @@ svr4_sys_getmsg(struct svr4_sys_getmsg_args *uap) 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) - return error; - } - else { + goto done; + } else { ctl.len = -1; ctl.maxlen = 0; } if (SCARG(uap, dat) != NULL) { if ((error = copyin(SCARG(uap, dat), &dat, sizeof(dat))) != 0) - return error; - } - else { + goto done; + } else { dat.len = -1; dat.maxlen = 0; } @@ -1881,12 +1865,14 @@ svr4_sys_getmsg(struct svr4_sys_getmsg_args *uap) */ if ((st = svr4_stream_get(fp)) == NULL) { DPRINTF(("getmsg: bad file type\n")); - return EINVAL; + error = EINVAL; + goto done; } if (ctl.maxlen == -1 || dat.maxlen == -1) { DPRINTF(("getmsg: Cannot handle -1 maxlen (yet)\n")); - return ENOSYS; + error = ENOSYS; + goto done; } switch (st->s_family) { @@ -1903,7 +1889,8 @@ svr4_sys_getmsg(struct svr4_sys_getmsg_args *uap) default: DPRINTF(("getmsg: Unsupported address family %d\n", st->s_family)); - return ENOSYS; + error = ENOSYS; + goto done; } sg = stackgap_init(); @@ -1912,7 +1899,7 @@ svr4_sys_getmsg(struct svr4_sys_getmsg_args *uap) fl = sasize; if ((error = copyout(&fl, flen, sizeof(fl))) != 0) - return error; + goto done; switch (st->s_cmd) { case SVR4_TI_CONNECT_REQUEST: @@ -1943,11 +1930,11 @@ svr4_sys_getmsg(struct svr4_sys_getmsg_args *uap) if ((error = getpeername(&ga)) != 0) { DPRINTF(("getmsg: getpeername failed %d\n", error)); - return error; + goto done; } if ((error = copyin(sup, skp, sasize)) != 0) - return error; + goto done; sc.cmd = SVR4_TI_CONNECT_REPLY; sc.pad[0] = 0x4; @@ -1967,7 +1954,8 @@ svr4_sys_getmsg(struct svr4_sys_getmsg_args *uap) break; default: - return ENOSYS; + error = ENOSYS; + goto done; } ctl.len = 40; @@ -2002,7 +1990,7 @@ svr4_sys_getmsg(struct svr4_sys_getmsg_args *uap) if ((error = accept(&aa)) != 0) { DPRINTF(("getmsg: accept failed %d\n", error)); - return error; + goto done; } st->s_afd = *retval; @@ -2010,7 +1998,7 @@ svr4_sys_getmsg(struct svr4_sys_getmsg_args *uap) DPRINTF(("getmsg: Accept fd = %d\n", st->s_afd)); if ((error = copyin(sup, skp, sasize)) != 0) - return error; + goto done; sc.cmd = SVR4_TI_ACCEPT_REPLY; sc.offs = 0x18; @@ -2033,7 +2021,8 @@ svr4_sys_getmsg(struct svr4_sys_getmsg_args *uap) break; default: - return ENOSYS; + error = ENOSYS; + goto done; } dat.len = -1; @@ -2047,7 +2036,7 @@ svr4_sys_getmsg(struct svr4_sys_getmsg_args *uap) ctl.len = 36; if ((error = copyin(ctl.buf, &sc, ctl.len)) != 0) - return error; + goto done; switch (st->s_family) { case AF_INET: @@ -2059,7 +2048,8 @@ svr4_sys_getmsg(struct svr4_sys_getmsg_args *uap) break; default: - return ENOSYS; + error = ENOSYS; + goto done; } msg.msg_name = (caddr_t) sup; @@ -2075,11 +2065,11 @@ svr4_sys_getmsg(struct svr4_sys_getmsg_args *uap) if (error) { DPRINTF(("getmsg: recvit failed %d\n", error)); - return error; + goto done; } if ((error = copyin(msg.msg_name, skp, sasize)) != 0) - return error; + goto done; sc.cmd = SVR4_TI_RECVFROM_IND; @@ -2095,7 +2085,8 @@ svr4_sys_getmsg(struct svr4_sys_getmsg_args *uap) break; default: - return ENOSYS; + error = ENOSYS; + goto done; } dat.len = *retval; @@ -2123,7 +2114,7 @@ svr4_sys_getmsg(struct svr4_sys_getmsg_args *uap) SCARG(&ra, buf) = dat.buf; SCARG(&ra, nbyte) = dat.maxlen; if ((error = read(&ra)) != 0) { - return error; + goto done; } dat.len = *retval; *retval = 0; @@ -2131,34 +2122,38 @@ svr4_sys_getmsg(struct svr4_sys_getmsg_args *uap) break; } DPRINTF(("getmsg: Unknown state %x\n", st->s_cmd)); - return EINVAL; + error = EINVAL; + goto done; } if (SCARG(uap, ctl)) { if (ctl.len != -1) if ((error = copyout(&sc, ctl.buf, ctl.len)) != 0) - return error; + goto done; if ((error = copyout(&ctl, SCARG(uap, ctl), sizeof(ctl))) != 0) - return error; + goto done; } if (SCARG(uap, dat)) { if ((error = copyout(&dat, SCARG(uap, dat), sizeof(dat))) != 0) - return error; + goto done; } if (SCARG(uap, flags)) { /* XXX: Need translation */ if ((error = copyout(&fl, SCARG(uap, flags), sizeof(fl))) != 0) - return error; + goto done; } + error =0; *retval = 0; #ifdef DEBUG_SVR4 show_msg(" @@ -1415,17 +1415,22 @@ elf_putfiles(struct proc *p, elf_buf_t target) * ignore STDIN/STDERR/STDOUT. */ for (i = 3; error == 0 && i < p->p_fd->fd_nfiles; i++) { - if ((fp = p->p_fd->fd_files[i].fp) == NULL) + fp = holdfp(p->p_fd, i, -1); + if (fp == NULL) continue; /* * XXX Only checkpoint vnodes for now. */ - if (fp->f_type != DTYPE_VNODE) + if (fp->f_type != DTYPE_VNODE) { + fdrop(fp); continue; + } cfi = target_reserve(target, sizeof(struct ckpt_fileinfo), &error); - if (cfi == NULL) + if (cfi == NULL) { + fdrop(fp); continue; + } cfi->cfi_index = -1; cfi->cfi_type = fp->f_type; cfi->cfi_flags = fp->f_flag; @@ -1452,6 +1457,7 @@ elf_putfiles(struct proc *p, elf_buf_t target) default: break; } + fdrop(fp); } return(error); } diff --git a/sys/kern/init_main.c b/sys/kern/init_main.c index c3708ca6f2..c7380472b7 100644 --- a/sys/kern/init_main.c +++ b/sys/kern/init_main.c @@ -40,7 +40,7 @@ * * @(#)init_main.c 8.9 (Berkeley) 1/21/94 * $FreeBSD: src/sys/kern/init_main.c,v 1.134.2.8 2003/06/06 20:21:32 tegge Exp $ - * $DragonFly: src/sys/kern/init_main.c,v 1.52 2006/05/05 21:15:08 dillon Exp $ + * $DragonFly: src/sys/kern/init_main.c,v 1.53 2006/05/19 07:33:45 dillon Exp $ */ #include "opt_init_path.h" @@ -272,7 +272,6 @@ SYSINIT(leavecrit, SI_SUB_LEAVE_CRIT, SI_ORDER_ANY, leavecrit, NULL) static void proc0_init(void *dummy __unused) { - struct filedesc *fdp; struct proc *p; struct lwp *lp; unsigned i; @@ -336,13 +335,7 @@ proc0_init(void *dummy __unused) siginit(&proc0); /* Create the file descriptor table. */ - fdp = &filedesc0; - p->p_fd = fdp; - p->p_fdtol = NULL; - fdp->fd_refcnt = 1; - fdp->fd_cmask = cmask; - fdp->fd_files = fdp->fd_builtin_files; - fdp->fd_nfiles = NDFILE; + fdinit_bootstrap(p, &filedesc0, cmask); /* Create the limits structures. */ p->p_limit = &limit0; diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c index 183974afb6..a81ecc90e7 100644 --- a/sys/kern/kern_descrip.c +++ b/sys/kern/kern_descrip.c @@ -70,7 +70,7 @@ * * @(#)kern_descrip.c 8.6 (Berkeley) 4/19/94 * $FreeBSD: src/sys/kern/kern_descrip.c,v 1.81.2.19 2004/02/28 00:43:31 tegge Exp $ - * $DragonFly: src/sys/kern/kern_descrip.c,v 1.57 2006/05/19 05:15:34 dillon Exp $ + * $DragonFly: src/sys/kern/kern_descrip.c,v 1.58 2006/05/19 07:33:45 dillon Exp $ */ #include "opt_compat.h" @@ -1140,6 +1140,28 @@ funsetfd(struct filedesc *fdp, int fd) fdp->fd_freefile = fd; } +int +fsetfdflags(struct filedesc *fdp, int fd, int add_flags) +{ + if (((u_int)fd) >= fdp->fd_nfiles) + return (EBADF); + if (fdp->fd_files[fd].fp == NULL) + return (EBADF); + fdp->fd_files[fd].fileflags |= add_flags; + return (0); +} + +int +fclrfdflags(struct filedesc *fdp, int fd, int rem_flags) +{ + if (((u_int)fd) >= fdp->fd_nfiles) + return (EBADF); + if (fdp->fd_files[fd].fp == NULL) + return (EBADF); + fdp->fd_files[fd].fileflags &= ~rem_flags; + return (0); +} + void fsetcred(struct file *fp, struct ucred *cr) { @@ -1165,6 +1187,20 @@ ffree(struct file *fp) free(fp, M_FILE); } +/* + * called from init_main, initialize filedesc0 for proc0. + */ +void +fdinit_bootstrap(struct proc *p0, struct filedesc *fdp0, int cmask) +{ + p0->p_fd = fdp0; + p0->p_fdtol = NULL; + fdp0->fd_refcnt = 1; + fdp0->fd_cmask = cmask; + fdp0->fd_files = fdp0->fd_builtin_files; + fdp0->fd_nfiles = NDFILE; +} + /* * Build a new filedesc structure. */ @@ -1462,6 +1498,23 @@ holdsock(struct filedesc *fdp, int fdes, struct file **fpp) return (error); } +/* + * Convert a user file descriptor to a kernel file entry. + */ +int +getvnode(struct filedesc *fdp, int fd, struct file **fpp) +{ + struct file *fp; + + if ((u_int)fd >= fdp->fd_nfiles || + (fp = fdp->fd_files[fd].fp) == NULL) + return (EBADF); + if (fp->f_type != DTYPE_VNODE && fp->f_type != DTYPE_FIFO) + return (EINVAL); + *fpp = fp; + return (0); +} + /* * For setugid programs, we don't want to people to use that setugidness * to generate error messages which write to a file which otherwise would diff --git a/sys/kern/kern_event.c b/sys/kern/kern_event.c index 78f10d0b23..d1c2b4b83e 100644 --- a/sys/kern/kern_event.c +++ b/sys/kern/kern_event.c @@ -24,7 +24,7 @@ * SUCH DAMAGE. * * $FreeBSD: src/sys/kern/kern_event.c,v 1.2.2.10 2004/04/04 07:03:14 cperciva Exp $ - * $DragonFly: src/sys/kern/kern_event.c,v 1.22 2006/05/06 06:38:38 dillon Exp $ + * $DragonFly: src/sys/kern/kern_event.c,v 1.23 2006/05/19 07:33:45 dillon Exp $ */ #include @@ -391,7 +391,6 @@ kevent(struct kevent_args *uap) { struct thread *td = curthread; struct proc *p = td->td_proc; - struct filedesc *fdp; struct kevent *kevp; struct kqueue *kq; struct file *fp = NULL; @@ -399,14 +398,14 @@ kevent(struct kevent_args *uap) int i, n, nerrors, error; KKASSERT(p); - fdp = p->p_fd; - if (((u_int)uap->fd) >= fdp->fd_nfiles || - (fp = fdp->fd_files[uap->fd].fp) == NULL || - (fp->f_type != DTYPE_KQUEUE)) + fp = holdfp(p->p_fd, uap->fd, -1); + if (fp == NULL) return (EBADF); - - fhold(fp); + if (fp->f_type != DTYPE_KQUEUE) { + fdrop(fp); + return (EBADF); + } if (uap->timeout != NULL) { error = copyin(uap->timeout, &ts, sizeof(ts)); @@ -484,10 +483,9 @@ kqueue_register(struct kqueue *kq, struct kevent *kev, struct thread *td) if (fops->f_isfd) { /* validate descriptor */ - if ((u_int)kev->ident >= fdp->fd_nfiles || - (fp = fdp->fd_files[kev->ident].fp) == NULL) + fp = holdfp(fdp, kev->ident, -1); + if (fp == NULL) return (EBADF); - fhold(fp); if (kev->ident < fdp->fd_knlistsize) { SLIST_FOREACH(kn, &fdp->fd_knlist[kev->ident], kn_link) diff --git a/sys/kern/sys_generic.c b/sys/kern/sys_generic.c index 51c4bea6e0..94203b0e25 100644 --- a/sys/kern/sys_generic.c +++ b/sys/kern/sys_generic.c @@ -37,7 +37,7 @@ * * @(#)sys_generic.c 8.5 (Berkeley) 1/21/94 * $FreeBSD: src/sys/kern/sys_generic.c,v 1.55.2.10 2001/03/17 10:39:32 peter Exp $ - * $DragonFly: src/sys/kern/sys_generic.c,v 1.29 2006/05/19 05:15:34 dillon Exp $ + * $DragonFly: src/sys/kern/sys_generic.c,v 1.30 2006/05/19 07:33:45 dillon Exp $ */ #include "opt_ktrace.h" @@ -202,12 +202,11 @@ kern_preadv(int fd, struct uio *auio, int flags, int *res) struct thread *td = curthread; struct proc *p = td->td_proc; struct file *fp; - struct filedesc *fdp = p->p_fd; int error; KKASSERT(p); - fp = holdfp(fdp, fd, FREAD); + fp = holdfp(p->p_fd, fd, FREAD); if (fp == NULL) return (EBADF); if (flags & FOF_OFFSET && fp->f_type != DTYPE_VNODE) { @@ -390,12 +389,11 @@ kern_pwritev(int fd, struct uio *auio, int flags, int *res) struct thread *td = curthread; struct proc *p = td->td_proc; struct file *fp; - struct filedesc *fdp = p->p_fd; int error; KKASSERT(p); - fp = holdfp(fdp, fd, FWRITE); + fp = holdfp(p->p_fd, fd, FWRITE); if (fp == NULL) return (EBADF); else if ((flags & FOF_OFFSET) && fp->f_type != DTYPE_VNODE) { @@ -492,7 +490,6 @@ mapped_ioctl(int fd, u_long com, caddr_t uspc_data, struct ioctl_map *map) struct proc *p = td->td_proc; struct ucred *cred; struct file *fp; - struct filedesc *fdp; struct ioctl_map_range *iomc = NULL; int error; u_int size; @@ -507,12 +504,9 @@ mapped_ioctl(int fd, u_long com, caddr_t uspc_data, struct ioctl_map *map) KKASSERT(p); cred = p->p_ucred; - fdp = p->p_fd; - if ((u_int)fd >= fdp->fd_nfiles || - (fp = fdp->fd_files[fd].fp) == NULL) - return(EBADF); - if ((fp->f_flag & (FREAD | FWRITE)) == 0) + fp = holdfp(p->p_fd, fd, FREAD|FWRITE); + if (fp == NULL) return(EBADF); if (map != NULL) { /* obey translation map */ @@ -544,7 +538,8 @@ mapped_ioctl(int fd, u_long com, caddr_t uspc_data, struct ioctl_map *map) map->sys, fd, maskcmd, (int)((maskcmd >> 8) & 0xff), (int)(maskcmd & 0xff)); - return(EINVAL); + error = EINVAL; + goto done; } /* @@ -571,18 +566,19 @@ mapped_ioctl(int fd, u_long com, caddr_t uspc_data, struct ioctl_map *map) map->sys, fd, maskcmd, (int)((maskcmd >> 8) & 0xff), (int)(maskcmd & 0xff)); - return(EINVAL); + error = EINVAL; + goto done; } } } switch (com) { case FIONCLEX: - fdp->fd_files[fd].fileflags &= ~UF_EXCLOSE; - return(0); + error = fclrfdflags(p->p_fd, fd, UF_EXCLOSE); + goto done; case FIOCLEX: - fdp->fd_files[fd].fileflags |= UF_EXCLOSE; - return(0); + error = fsetfdflags(p->p_fd, fd, UF_EXCLOSE); + goto done; } /* @@ -590,10 +586,10 @@ mapped_ioctl(int fd, u_long com, caddr_t uspc_data, struct ioctl_map *map) * copied to/from the user's address space. */ size = IOCPARM_LEN(com); - if (size > IOCPARM_MAX) - return(ENOTTY); - - fhold(fp); + if (size > IOCPARM_MAX) { + error = ENOTTY; + goto done; + } memp = NULL; if (size > sizeof (ubuf.stkbuf)) { @@ -608,8 +604,7 @@ mapped_ioctl(int fd, u_long com, caddr_t uspc_data, struct ioctl_map *map) if (error) { if (memp != NULL) free(memp, M_IOCTLOPS); - fdrop(fp); - return(error); + goto done; } } else { *(caddr_t *)data = uspc_data; @@ -661,6 +656,7 @@ mapped_ioctl(int fd, u_long com, caddr_t uspc_data, struct ioctl_map *map) } if (memp != NULL) free(memp, M_IOCTLOPS); +done: fdrop(fp); return(error); } @@ -842,7 +838,6 @@ done: static int selscan(struct proc *p, fd_mask **ibits, fd_mask **obits, int nfd, int *res) { - struct filedesc *fdp = p->p_fd; int msk, i, fd; fd_mask bits; struct file *fp; @@ -859,7 +854,7 @@ selscan(struct proc *p, fd_mask **ibits, fd_mask **obits, int nfd, int *res) for (fd = i; bits && fd < nfd; fd++, bits >>= 1) { if (!(bits & 1)) continue; - fp = fdp->fd_files[fd].fp; + fp = holdfp(p->p_fd, fd, -1); if (fp == NULL) return (EBADF); if (fo_poll(fp, flag[msk], fp->f_cred)) { @@ -867,6 +862,7 @@ selscan(struct proc *p, fd_mask **ibits, fd_mask **obits, int nfd, int *res) ((fd_mask)1 << ((fd) % NFDBITS)); n++; } + fdrop(fp); } } } @@ -966,19 +962,18 @@ out: static int pollscan(struct proc *p, struct pollfd *fds, u_int nfd, int *res) { - struct filedesc *fdp = p->p_fd; int i; struct file *fp; int n = 0; for (i = 0; i < nfd; i++, fds++) { - if (fds->fd >= fdp->fd_nfiles) { + if (fds->fd >= p->p_fd->fd_nfiles) { fds->revents = POLLNVAL; n++; } else if (fds->fd < 0) { fds->revents = 0; } else { - fp = fdp->fd_files[fds->fd].fp; + fp = holdfp(p->p_fd, fds->fd, -1); if (fp == NULL) { fds->revents = POLLNVAL; n++; @@ -991,6 +986,7 @@ pollscan(struct proc *p, struct pollfd *fds, u_int nfd, int *res) fp->f_cred); if (fds->revents != 0) n++; + fdrop(fp); } } } diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c index b9f2abc36d..b41cb7609d 100644 --- a/sys/kern/vfs_syscalls.c +++ b/sys/kern/vfs_syscalls.c @@ -37,7 +37,7 @@ * * @(#)vfs_syscalls.c 8.13 (Berkeley) 4/15/94 * $FreeBSD: src/sys/kern/vfs_syscalls.c,v 1.151.2.18 2003/04/04 20:35:58 tegge Exp $ - * $DragonFly: src/sys/kern/vfs_syscalls.c,v 1.90 2006/05/19 05:15:35 dillon Exp $ + * $DragonFly: src/sys/kern/vfs_syscalls.c,v 1.91 2006/05/19 07:33:45 dillon Exp $ */ #include @@ -1800,34 +1800,40 @@ kern_lseek(int fd, off_t offset, int whence, off_t *res) { struct thread *td = curthread; struct proc *p = td->td_proc; - struct filedesc *fdp = p->p_fd; struct file *fp; struct vattr vattr; int error; - if ((u_int)fd >= fdp->fd_nfiles || - (fp = fdp->fd_files[fd].fp) == NULL) + fp = holdfp(p->p_fd, fd, -1); + if (fp == NULL) return (EBADF); - if (fp->f_type != DTYPE_VNODE) - return (ESPIPE); + if (fp->f_type != DTYPE_VNODE) { + error = ESPIPE; + goto done; + } + switch (whence) { case L_INCR: fp->f_offset += offset; + error = 0; break; case L_XTND: - error=VOP_GETATTR((struct vnode *)fp->f_data, &vattr); - if (error) - return (error); - fp->f_offset = offset + vattr.va_size; + error = VOP_GETATTR((struct vnode *)fp->f_data, &vattr); + if (error == 0) + fp->f_offset = offset + vattr.va_size; break; case L_SET: fp->f_offset = offset; + error = 0; break; default: - return (EINVAL); + error = EINVAL; + break; } *res = fp->f_offset; - return (0); +done: + fdrop(fp); + return (error); } /* @@ -3019,22 +3025,6 @@ revoke(struct revoke_args *uap) return (error); } -/* - * Convert a user file descriptor to a kernel file entry. - */ -int -getvnode(struct filedesc *fdp, int fd, struct file **fpp) -{ - struct file *fp; - - if ((u_int)fd >= fdp->fd_nfiles || - (fp = fdp->fd_files[fd].fp) == NULL) - return (EBADF); - if (fp->f_type != DTYPE_VNODE && fp->f_type != DTYPE_FIFO) - return (EINVAL); - *fpp = fp; - return (0); -} /* * getfh_args(char *fname, fhandle_t *fhp) * diff --git a/sys/netproto/smb/smb_dev.c b/sys/netproto/smb/smb_dev.c index 916b49d1d8..5786600f40 100644 --- a/sys/netproto/smb/smb_dev.c +++ b/sys/netproto/smb/smb_dev.c @@ -30,7 +30,7 @@ * SUCH DAMAGE. * * $FreeBSD: src/sys/netsmb/smb_dev.c,v 1.2.2.1 2001/05/22 08:32:33 bp Exp $ - * $DragonFly: src/sys/netproto/smb/smb_dev.c,v 1.11 2005/06/22 01:33:31 dillon Exp $ + * $DragonFly: src/sys/netproto/smb/smb_dev.c,v 1.12 2006/05/19 07:33:45 dillon Exp $ */ #include #include @@ -373,22 +373,6 @@ nsmb_dev_load(module_t mod, int cmd, void *arg) DEV_MODULE (dev_netsmb, nsmb_dev_load, 0); - -/* - * Convert a file descriptor to appropriate smb_share pointer - */ -static struct file* -nsmb_getfp(struct filedesc* fdp, int fd, int flag) -{ - struct file* fp; - - if (((u_int)fd) >= fdp->fd_nfiles || - (fp = fdp->fd_files[fd].fp) == NULL || - (fp->f_flag & flag) == 0) - return (NULL); - return (fp); -} - int smb_dev2share(int fd, int mode, struct smb_cred *scred, struct smb_share **sspp) @@ -402,24 +386,31 @@ smb_dev2share(int fd, int mode, struct smb_cred *scred, KKASSERT(scred->scr_td->td_proc); - if ((fp = nsmb_getfp(scred->scr_td->td_proc->p_fd, - fd, FREAD | FWRITE)) == NULL) { + fp = holdfp(scred->scr_td->td_proc->p_fd, fd, FREAD|FWRITE); + if (fp == NULL) return EBADF; - } + vp = (struct vnode*)fp->f_data; - if (vp == NULL) - return EBADF; + if (vp == NULL) { + error = EBADF; + goto done; + } dev = vn_todev(vp); - if (dev == NODEV) - return EBADF; + if (dev == NODEV) { + error = EBADF; + goto done; + } SMB_CHECKMINOR(dev); ssp = sdp->sd_share; - if (ssp == NULL) - return ENOTCONN; + if (ssp == NULL) { + error = ENOTCONN; + goto done; + } error = smb_share_get(ssp, LK_EXCLUSIVE, scred); - if (error) - return error; - *sspp = ssp; - return 0; + if (error == 0) + *sspp = ssp; +done: + fdrop(fp); + return (error); } diff --git a/sys/sys/filedesc.h b/sys/sys/filedesc.h index 3bc2bbfa6c..6fef3bed03 100644 --- a/sys/sys/filedesc.h +++ b/sys/sys/filedesc.h @@ -32,7 +32,7 @@ * * @(#)filedesc.h 8.1 (Berkeley) 6/2/93 * $FreeBSD: src/sys/sys/filedesc.h,v 1.19.2.5 2003/06/06 20:21:32 tegge Exp $ - * $DragonFly: src/sys/sys/filedesc.h,v 1.13 2006/05/19 05:15:36 dillon Exp $ + * $DragonFly: src/sys/sys/filedesc.h,v 1.14 2006/05/19 07:33:45 dillon Exp $ */ #ifndef _SYS_FILEDESC_H_ @@ -151,8 +151,11 @@ int fdavail (struct proc *p, int n); int falloc (struct proc *p, struct file **resultfp, int *resultfd); int fdealloc (struct proc *p, struct file *fp, int fd); int fsetfd (struct proc *p, struct file *fp, int *resultfd); +int fsetfdflags(struct filedesc *fdp, int fd, int add_flags); +int fclrfdflags(struct filedesc *fdp, int fd, int rem_flags); void fsetcred (struct file *fp, struct ucred *cr); void ffree (struct file *); +void fdinit_bootstrap(struct proc *p0, struct filedesc *fdp0, int cmask); struct filedesc *fdinit (struct proc *p); struct filedesc *fdshare (struct proc *p); struct filedesc *fdcopy (struct proc *p); diff --git a/sys/vfs/fdesc/fdesc_vnops.c b/sys/vfs/fdesc/fdesc_vnops.c index ab5c41d7db..f1f00907ee 100644 --- a/sys/vfs/fdesc/fdesc_vnops.c +++ b/sys/vfs/fdesc/fdesc_vnops.c @@ -36,7 +36,7 @@ * @(#)fdesc_vnops.c 8.9 (Berkeley) 1/21/94 * * $FreeBSD: src/sys/miscfs/fdesc/fdesc_vnops.c,v 1.47.2.1 2001/10/22 22:49:26 chris Exp $ - * $DragonFly: src/sys/vfs/fdesc/fdesc_vnops.c,v 1.28 2006/05/06 18:48:52 dillon Exp $ + * $DragonFly: src/sys/vfs/fdesc/fdesc_vnops.c,v 1.29 2006/05/19 07:33:46 dillon Exp $ */ /* @@ -272,14 +272,13 @@ fdesc_getattr(struct vop_getattr_args *ap) struct proc *p = curproc; struct vnode *vp = ap->a_vp; struct vattr *vap = ap->a_vap; - struct filedesc *fdp; struct file *fp; struct stat stb; u_int fd; int error = 0; KKASSERT(p); - fdp = p->p_fd; + switch (VTOFDESC(vp)->fd_type) { case Froot: VATTR_NULL(vap); @@ -305,11 +304,14 @@ fdesc_getattr(struct vop_getattr_args *ap) case Fdesc: fd = VTOFDESC(vp)->fd_fd; - if (fd >= fdp->fd_nfiles || (fp = fdp->fd_files[fd].fp) == NULL) + fp = holdfp(p->p_fd, fd, -1); + if (fp == NULL) return (EBADF); bzero(&stb, sizeof(stb)); error = fo_stat(fp, &stb, curproc->p_ucred); + fdrop(fp); + if (error == 0) { VATTR_NULL(vap); vap->va_type = IFTOVT(stb.st_mode); diff --git a/sys/vm/vm_mmap.c b/sys/vm/vm_mmap.c index 40f2750a27..c0904e9c4c 100644 --- a/sys/vm/vm_mmap.c +++ b/sys/vm/vm_mmap.c @@ -39,7 +39,7 @@ * * @(#)vm_mmap.c 8.4 (Berkeley) 1/12/94 * $FreeBSD: src/sys/vm/vm_mmap.c,v 1.108.2.6 2002/07/02 20:06:19 dillon Exp $ - * $DragonFly: src/sys/vm/vm_mmap.c,v 1.28 2006/05/18 18:58:28 dillon Exp $ + * $DragonFly: src/sys/vm/vm_mmap.c,v 1.29 2006/05/19 07:33:46 dillon Exp $ */ /* @@ -149,7 +149,6 @@ kern_mmap(caddr_t uaddr, size_t ulen, int uprot, int uflags, int fd, { struct thread *td = curthread; struct proc *p = td->td_proc; - struct filedesc *fdp = p->p_fd; struct file *fp = NULL; struct vnode *vp; vm_offset_t addr; @@ -242,11 +241,13 @@ kern_mmap(caddr_t uaddr, size_t ulen, int uprot, int uflags, int fd, * Mapping file, get fp for validation. Obtain vnode and make * sure it is of appropriate type. */ - if (((unsigned) fd) >= fdp->fd_nfiles || - (fp = fdp->fd_files[fd].fp) == NULL) + fp = holdfp(p->p_fd, fd, -1); + if (fp == NULL) return (EBADF); - if (fp->f_type != DTYPE_VNODE) - return (EINVAL); + if (fp->f_type != DTYPE_VNODE) { + error = EINVAL; + goto done; + } /* * POSIX shared-memory objects are defined to have * kernel persistence, and are not defined to support @@ -258,22 +259,21 @@ kern_mmap(caddr_t uaddr, size_t ulen, int uprot, int uflags, int fd, if (fp->f_flag & FPOSIXSHM) flags |= MAP_NOSYNC; vp = (struct vnode *) fp->f_data; - if (vp->v_type != VREG && vp->v_type != VCHR) - return (EINVAL); + if (vp->v_type != VREG && vp->v_type != VCHR) { + error = EINVAL; + goto done; + } if (vp->v_type == VREG) { /* * Get the proper underlying object */ - if ((obj = vp->v_object) == NULL) - return (EINVAL); + if ((obj = vp->v_object) == NULL) { + error = EINVAL; + goto done; + } KKASSERT(vp == (struct vnode *)obj->handle); } - /* - * don't let the descriptor disappear on us if we block - */ - fhold(fp); - /* * XXX hack to handle use of /dev/zero to map anon memory (ala * SunOS). -- 2.41.0