Date: Wed, 5 Jul 2006 20:08:01 GMT From: John Baldwin <jhb@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 100651 for review Message-ID: <200607052008.k65K8196044539@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=100651 Change 100651 by jhb@jhb_mutex on 2006/07/05 20:07:11 Add a kern_ioctl() which assumes data points to a KVM buffer for ioctl's that act on buffers and use it in xenix_rdchk() to stop using stackgap. There might be several places that currently do fget() / fo_ioctl() / fdrop() themselves that might be able to be simplified slightly to just do kern_ioctl() now. Affected files ... .. //depot/projects/smpng/sys/i386/ibcs2/ibcs2_xenix.c#14 edit .. //depot/projects/smpng/sys/kern/sys_generic.c#44 edit .. //depot/projects/smpng/sys/sys/syscallsubr.h#40 edit Differences ... ==== //depot/projects/smpng/sys/i386/ibcs2/ibcs2_xenix.c#14 (text+ko) ==== @@ -84,18 +84,15 @@ struct thread *td; struct xenix_rdchk_args *uap; { - int error; - struct ioctl_args sa; - caddr_t sg = stackgap_init(); + int data, error; DPRINTF(("IBCS2: 'xenix rdchk'\n")); - sa.fd = uap->fd; - sa.com = FIONREAD; - sa.data = stackgap_alloc(&sg, sizeof(int)); - if ((error = ioctl(td, &sa)) != 0) - return error; - td->td_retval[0] = (*((int*)sa.data)) ? 1 : 0; - return 0; + + error = kern_ioctl(td, uap->fd, FIONREAD, &data); + if (error) + return (error); + td->td_retval[0] = data ? 1 : 0; + return (0); } int ==== //depot/projects/smpng/sys/kern/sys_generic.c#44 (text+ko) ==== @@ -523,13 +523,10 @@ int ioctl(struct thread *td, struct ioctl_args *uap) { - struct file *fp; - struct filedesc *fdp; u_long com; - int error = 0; + int error; u_int size; caddr_t data, memp; - int tmp; if (uap->com > 0xffffffff) { printf( @@ -537,27 +534,7 @@ td->td_proc->p_pid, td->td_proc->p_comm, uap->com); uap->com &= 0xffffffff; } - if ((error = fget(td, uap->fd, &fp)) != 0) - return (error); - if ((fp->f_flag & (FREAD | FWRITE)) == 0) { - fdrop(fp, td); - return (EBADF); - } - fdp = td->td_proc->p_fd; - switch (com = uap->com) { - case FIONCLEX: - FILEDESC_LOCK_FAST(fdp); - fdp->fd_ofileflags[uap->fd] &= ~UF_EXCLOSE; - FILEDESC_UNLOCK_FAST(fdp); - fdrop(fp, td); - return (0); - case FIOCLEX: - FILEDESC_LOCK_FAST(fdp); - fdp->fd_ofileflags[uap->fd] |= UF_EXCLOSE; - FILEDESC_UNLOCK_FAST(fdp); - fdrop(fp, td); - return (0); - } + com = uap->com; /* * Interpret high order word to find amount of data to be @@ -571,10 +548,8 @@ #else ((com & (IOC_IN | IOC_OUT)) && size == 0) || #endif - ((com & IOC_VOID) && size > 0)) { - fdrop(fp, td); + ((com & IOC_VOID) && size > 0)) return (ENOTTY); - } if (size > 0) { memp = malloc((u_long)size, M_IOCTLOPS, M_WAITOK); @@ -587,7 +562,6 @@ error = copyin(uap->data, data, (u_int)size); if (error) { free(memp, M_IOCTLOPS); - fdrop(fp, td); return (error); } } else if (com & IOC_OUT) { @@ -598,7 +572,43 @@ bzero(data, size); } - if (com == FIONBIO) { + error = kern_ioctl(td, uap->fd, com, data); + + if (error == 0 && (com & IOC_OUT)) + error = copyout(data, uap->data, (u_int)size); + + if (memp != NULL) + free(memp, M_IOCTLOPS); + return (error); +} + +int +kern_ioctl(struct thread *td, int fd, u_long com, caddr_t data) +{ + struct file *fp; + struct filedesc *fdp; + int error; + int tmp; + + if ((error = fget(td, fd, &fp)) != 0) + return (error); + if ((fp->f_flag & (FREAD | FWRITE)) == 0) { + fdrop(fp, td); + return (EBADF); + } + fdp = td->td_proc->p_fd; + switch (com) { + case FIONCLEX: + FILEDESC_LOCK_FAST(fdp); + fdp->fd_ofileflags[fd] &= ~UF_EXCLOSE; + FILEDESC_UNLOCK_FAST(fdp); + goto out; + case FIOCLEX: + FILEDESC_LOCK_FAST(fdp); + fdp->fd_ofileflags[fd] |= UF_EXCLOSE; + FILEDESC_UNLOCK_FAST(fdp); + goto out; + case FIONBIO: FILE_LOCK(fp); if ((tmp = *(int *)data)) fp->f_flag |= FNONBLOCK; @@ -606,7 +616,8 @@ fp->f_flag &= ~FNONBLOCK; FILE_UNLOCK(fp); data = (void *)&tmp; - } else if (com == FIOASYNC) { + break; + case FIOASYNC: FILE_LOCK(fp); if ((tmp = *(int *)data)) fp->f_flag |= FASYNC; @@ -614,15 +625,11 @@ fp->f_flag &= ~FASYNC; FILE_UNLOCK(fp); data = (void *)&tmp; + break; } error = fo_ioctl(fp, com, data, td->td_ucred, td); - - if (error == 0 && (com & IOC_OUT)) - error = copyout(data, uap->data, (u_int)size); - - if (memp != NULL) - free(memp, M_IOCTLOPS); +out: fdrop(fp, td); return (error); } ==== //depot/projects/smpng/sys/sys/syscallsubr.h#40 (text+ko) ==== @@ -92,6 +92,7 @@ socklen_t *alen); int kern_getsockopt(struct thread *td, int s, int level, int name, void *optval, enum uio_seg valseg, socklen_t *valsize); +int kern_ioctl(struct thread *td, int fd, u_long com, caddr_t data); int kern_kevent(struct thread *td, int fd, int nchanges, int nevents, struct kevent_copyops *k_ops, const struct timespec *timeout); int kern_kldload(struct thread *td, const char *file, int *fileid);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200607052008.k65K8196044539>