summaryrefslogtreecommitdiffstats
path: root/sys/kern/sys_generic.c
diff options
context:
space:
mode:
authoralc <alc@FreeBSD.org>2002-05-09 02:30:41 +0000
committeralc <alc@FreeBSD.org>2002-05-09 02:30:41 +0000
commiteff7d935338f3a558b05c829782f6205c4912c65 (patch)
treeb17dd197ca2c975298d9ef4adb1530ee6962951f /sys/kern/sys_generic.c
parent928dd0df4b092e9cafb77476c7cb8f238409e606 (diff)
downloadFreeBSD-src-eff7d935338f3a558b05c829782f6205c4912c65.zip
FreeBSD-src-eff7d935338f3a558b05c829782f6205c4912c65.tar.gz
o Correct an error made in revision 1.65: In readv(), if uap->iovcnt is
out-of-range, drop the file reference before returning. (This error also exists in the RELENG_4 branch.) o Eliminate the acquisition and release of Giant in readv() now that malloc() and free() are callable without Giant.
Diffstat (limited to 'sys/kern/sys_generic.c')
-rw-r--r--sys/kern/sys_generic.c15
1 files changed, 6 insertions, 9 deletions
diff --git a/sys/kern/sys_generic.c b/sys/kern/sys_generic.c
index 66ee891..f3352b9 100644
--- a/sys/kern/sys_generic.c
+++ b/sys/kern/sys_generic.c
@@ -232,29 +232,28 @@ readv(td, uap)
struct iovec *iov;
struct iovec *needfree;
struct iovec aiov[UIO_SMALLIOV];
- long i, cnt, error = 0;
+ long i, cnt;
+ int error;
u_int iovlen;
#ifdef KTRACE
struct iovec *ktriov = NULL;
struct uio ktruio;
#endif
- mtx_lock(&Giant);
if ((error = fget_read(td, uap->fd, &fp)) != 0)
- goto done2;
+ return (error);
+ needfree = NULL;
/* note: can't use iovlen until iovcnt is validated */
iovlen = uap->iovcnt * sizeof (struct iovec);
if (uap->iovcnt > UIO_SMALLIOV) {
if (uap->iovcnt > UIO_MAXIOV) {
error = EINVAL;
- goto done2;
+ goto done;
}
MALLOC(iov, struct iovec *, iovlen, M_IOV, M_WAITOK);
needfree = iov;
- } else {
+ } else
iov = aiov;
- needfree = NULL;
- }
auio.uio_iov = iov;
auio.uio_iovcnt = uap->iovcnt;
auio.uio_rw = UIO_READ;
@@ -305,8 +304,6 @@ done:
fdrop(fp, td);
if (needfree)
FREE(needfree, M_IOV);
-done2:
- mtx_unlock(&Giant);
return (error);
}
OpenPOWER on IntegriCloud