mirror of
https://github.com/opnsense/src.git
synced 2026-05-28 04:12:45 -04:00
Abstract UIO allocation and deallocation.
Introduce the allocuio() and freeuio() functions to allocate and deallocate struct uio. This hides the actual allocator interface, so it is easier to modify the sub-allocation layout of struct uio and the corresponding iovec array. Obtained from: CheriBSD Reviewed by: kib, markj MFC after: 2 weeks Sponsored by: CHaOS, EPSRC grant EP/V000292/1 Differential Revision: https://reviews.freebsd.org/D43711 (cherry picked from commit 61cc4830a7b16400efade3d884a59fda6d80d651)
This commit is contained in:
parent
c3751f89da
commit
2de742797b
14 changed files with 67 additions and 46 deletions
|
|
@ -106,7 +106,7 @@ linux_readv(struct thread *td, struct linux_readv_args *uap)
|
|||
if (error)
|
||||
return (error);
|
||||
error = kern_readv(td, uap->fd, auio);
|
||||
free(auio, M_IOV);
|
||||
freeuio(auio);
|
||||
return (error);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ uiocopy(void *p, size_t n, enum uio_rw rw, struct uio *uio, size_t *cbytes)
|
|||
error = vn_io_fault_uiomove(p, n, uio_clone);
|
||||
*cbytes = uio->uio_resid - uio_clone->uio_resid;
|
||||
if (uio_clone != &small_uio_clone)
|
||||
free(uio_clone, M_IOV);
|
||||
freeuio(uio_clone);
|
||||
return (error);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1196,32 +1196,29 @@ freebsd32_copyinuio(struct iovec32 *iovp, u_int iovcnt, struct uio **uiop)
|
|||
struct iovec32 iov32;
|
||||
struct iovec *iov;
|
||||
struct uio *uio;
|
||||
u_int iovlen;
|
||||
int error, i;
|
||||
|
||||
*uiop = NULL;
|
||||
if (iovcnt > UIO_MAXIOV)
|
||||
return (EINVAL);
|
||||
iovlen = iovcnt * sizeof(struct iovec);
|
||||
uio = malloc(iovlen + sizeof *uio, M_IOV, M_WAITOK);
|
||||
iov = (struct iovec *)(uio + 1);
|
||||
uio = allocuio(iovcnt);
|
||||
iov = uio->uio_iov;
|
||||
for (i = 0; i < iovcnt; i++) {
|
||||
error = copyin(&iovp[i], &iov32, sizeof(struct iovec32));
|
||||
if (error) {
|
||||
free(uio, M_IOV);
|
||||
freeuio(uio);
|
||||
return (error);
|
||||
}
|
||||
iov[i].iov_base = PTRIN(iov32.iov_base);
|
||||
iov[i].iov_len = iov32.iov_len;
|
||||
}
|
||||
uio->uio_iov = iov;
|
||||
uio->uio_iovcnt = iovcnt;
|
||||
uio->uio_segflg = UIO_USERSPACE;
|
||||
uio->uio_offset = -1;
|
||||
uio->uio_resid = 0;
|
||||
for (i = 0; i < iovcnt; i++) {
|
||||
if (iov->iov_len > INT_MAX - uio->uio_resid) {
|
||||
free(uio, M_IOV);
|
||||
freeuio(uio);
|
||||
return (EINVAL);
|
||||
}
|
||||
uio->uio_resid += iov->iov_len;
|
||||
|
|
@ -1241,7 +1238,7 @@ freebsd32_readv(struct thread *td, struct freebsd32_readv_args *uap)
|
|||
if (error)
|
||||
return (error);
|
||||
error = kern_readv(td, uap->fd, auio);
|
||||
free(auio, M_IOV);
|
||||
freeuio(auio);
|
||||
return (error);
|
||||
}
|
||||
|
||||
|
|
@ -1255,7 +1252,7 @@ freebsd32_writev(struct thread *td, struct freebsd32_writev_args *uap)
|
|||
if (error)
|
||||
return (error);
|
||||
error = kern_writev(td, uap->fd, auio);
|
||||
free(auio, M_IOV);
|
||||
freeuio(auio);
|
||||
return (error);
|
||||
}
|
||||
|
||||
|
|
@ -1269,7 +1266,7 @@ freebsd32_preadv(struct thread *td, struct freebsd32_preadv_args *uap)
|
|||
if (error)
|
||||
return (error);
|
||||
error = kern_preadv(td, uap->fd, auio, PAIR32TO64(off_t,uap->offset));
|
||||
free(auio, M_IOV);
|
||||
freeuio(auio);
|
||||
return (error);
|
||||
}
|
||||
|
||||
|
|
@ -1283,7 +1280,7 @@ freebsd32_pwritev(struct thread *td, struct freebsd32_pwritev_args *uap)
|
|||
if (error)
|
||||
return (error);
|
||||
error = kern_pwritev(td, uap->fd, auio, PAIR32TO64(off_t,uap->offset));
|
||||
free(auio, M_IOV);
|
||||
freeuio(auio);
|
||||
return (error);
|
||||
}
|
||||
|
||||
|
|
@ -2199,9 +2196,9 @@ freebsd32_do_sendfile(struct thread *td,
|
|||
|
||||
out:
|
||||
if (hdr_uio)
|
||||
free(hdr_uio, M_IOV);
|
||||
freeuio(hdr_uio);
|
||||
if (trl_uio)
|
||||
free(trl_uio, M_IOV);
|
||||
freeuio(trl_uio);
|
||||
return (error);
|
||||
}
|
||||
|
||||
|
|
@ -2780,7 +2777,7 @@ freebsd32_jail_set(struct thread *td, struct freebsd32_jail_set_args *uap)
|
|||
if (error)
|
||||
return (error);
|
||||
error = kern_jail_set(td, auio, uap->flags);
|
||||
free(auio, M_IOV);
|
||||
freeuio(auio);
|
||||
return (error);
|
||||
}
|
||||
|
||||
|
|
@ -2807,7 +2804,7 @@ freebsd32_jail_get(struct thread *td, struct freebsd32_jail_get_args *uap)
|
|||
if (error != 0)
|
||||
break;
|
||||
}
|
||||
free(auio, M_IOV);
|
||||
freeuio(auio);
|
||||
return (error);
|
||||
}
|
||||
|
||||
|
|
@ -3540,7 +3537,7 @@ freebsd32_nmount(struct thread *td,
|
|||
return (error);
|
||||
error = vfs_donmount(td, flags, auio);
|
||||
|
||||
free(auio, M_IOV);
|
||||
freeuio(auio);
|
||||
return error;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1038,7 +1038,7 @@ linux_preadv(struct thread *td, struct linux_preadv_args *uap)
|
|||
if (error != 0)
|
||||
return (error);
|
||||
error = kern_preadv(td, uap->fd, auio, offset);
|
||||
free(auio, M_IOV);
|
||||
freeuio(auio);
|
||||
return (error);
|
||||
}
|
||||
|
||||
|
|
@ -1065,7 +1065,7 @@ linux_pwritev(struct thread *td, struct linux_pwritev_args *uap)
|
|||
if (error != 0)
|
||||
return (error);
|
||||
error = kern_pwritev(td, uap->fd, auio, offset);
|
||||
free(auio, M_IOV);
|
||||
freeuio(auio);
|
||||
return (linux_enobufs2eagain(td, uap->fd, error));
|
||||
}
|
||||
|
||||
|
|
@ -1872,6 +1872,6 @@ linux_writev(struct thread *td, struct linux_writev_args *args)
|
|||
if (error != 0)
|
||||
return (error);
|
||||
error = kern_writev(td, args->fd, auio);
|
||||
free(auio, M_IOV);
|
||||
freeuio(auio);
|
||||
return (linux_enobufs2eagain(td, args->fd, error));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -534,7 +534,7 @@ sys_jail_set(struct thread *td, struct jail_set_args *uap)
|
|||
if (error)
|
||||
return (error);
|
||||
error = kern_jail_set(td, auio, uap->flags);
|
||||
free(auio, M_IOV);
|
||||
freeuio(auio);
|
||||
return (error);
|
||||
}
|
||||
|
||||
|
|
@ -2264,8 +2264,8 @@ sys_jail_get(struct thread *td, struct jail_get_args *uap)
|
|||
error = kern_jail_get(td, auio, uap->flags);
|
||||
if (error == 0)
|
||||
error = copyout(auio->uio_iov, uap->iovp,
|
||||
uap->iovcnt * sizeof (struct iovec));
|
||||
free(auio, M_IOV);
|
||||
uap->iovcnt * sizeof(struct iovec));
|
||||
freeuio(auio);
|
||||
return (error);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -770,7 +770,7 @@ ktrgenio(int fd, enum uio_rw rw, struct uio *uio, int error)
|
|||
char *buf;
|
||||
|
||||
if (error) {
|
||||
free(uio, M_IOV);
|
||||
freeuio(uio);
|
||||
return;
|
||||
}
|
||||
uio->uio_offset = 0;
|
||||
|
|
@ -778,7 +778,7 @@ ktrgenio(int fd, enum uio_rw rw, struct uio *uio, int error)
|
|||
datalen = MIN(uio->uio_resid, ktr_geniosize);
|
||||
buf = malloc(datalen, M_KTRACE, M_WAITOK);
|
||||
error = uiomove(buf, datalen, uio);
|
||||
free(uio, M_IOV);
|
||||
freeuio(uio);
|
||||
if (error) {
|
||||
free(buf, M_KTRACE);
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -1331,8 +1331,8 @@ sendfile(struct thread *td, struct sendfile_args *uap, int compat)
|
|||
(void)copyout(&sbytes, uap->sbytes, sizeof(off_t));
|
||||
|
||||
out:
|
||||
free(hdr_uio, M_IOV);
|
||||
free(trl_uio, M_IOV);
|
||||
freeuio(hdr_uio);
|
||||
freeuio(trl_uio);
|
||||
return (error);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -388,7 +388,7 @@ log_console(struct uio *uio)
|
|||
msglogstr(consbuffer, pri, /*filter_cr*/ 1);
|
||||
}
|
||||
msgbuftrigger = 1;
|
||||
free(uio, M_IOV);
|
||||
freeuio(uio);
|
||||
free(consbuffer, M_TEMP);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -376,21 +376,20 @@ copyinuio(const struct iovec *iovp, u_int iovcnt, struct uio **uiop)
|
|||
if (iovcnt > UIO_MAXIOV)
|
||||
return (EINVAL);
|
||||
iovlen = iovcnt * sizeof(struct iovec);
|
||||
uio = malloc(iovlen + sizeof(*uio), M_IOV, M_WAITOK);
|
||||
iov = (struct iovec *)(uio + 1);
|
||||
uio = allocuio(iovcnt);
|
||||
iov = uio->uio_iov;
|
||||
error = copyin(iovp, iov, iovlen);
|
||||
if (error) {
|
||||
free(uio, M_IOV);
|
||||
if (error != 0) {
|
||||
freeuio(uio);
|
||||
return (error);
|
||||
}
|
||||
uio->uio_iov = iov;
|
||||
uio->uio_iovcnt = iovcnt;
|
||||
uio->uio_segflg = UIO_USERSPACE;
|
||||
uio->uio_offset = -1;
|
||||
uio->uio_resid = 0;
|
||||
for (i = 0; i < iovcnt; i++) {
|
||||
if (iov->iov_len > IOSIZE_MAX - uio->uio_resid) {
|
||||
free(uio, M_IOV);
|
||||
freeuio(uio);
|
||||
return (EINVAL);
|
||||
}
|
||||
uio->uio_resid += iov->iov_len;
|
||||
|
|
@ -401,15 +400,38 @@ copyinuio(const struct iovec *iovp, u_int iovcnt, struct uio **uiop)
|
|||
}
|
||||
|
||||
struct uio *
|
||||
cloneuio(struct uio *uiop)
|
||||
allocuio(u_int iovcnt)
|
||||
{
|
||||
struct uio *uio;
|
||||
int iovlen;
|
||||
|
||||
iovlen = uiop->uio_iovcnt * sizeof(struct iovec);
|
||||
KASSERT(iovcnt <= UIO_MAXIOV,
|
||||
("Requested %u iovecs exceed UIO_MAXIOV", iovcnt));
|
||||
iovlen = iovcnt * sizeof(struct iovec);
|
||||
uio = malloc(iovlen + sizeof(*uio), M_IOV, M_WAITOK);
|
||||
*uio = *uiop;
|
||||
uio->uio_iov = (struct iovec *)(uio + 1);
|
||||
|
||||
return (uio);
|
||||
}
|
||||
|
||||
void
|
||||
freeuio(struct uio *uio)
|
||||
{
|
||||
free(uio, M_IOV);
|
||||
}
|
||||
|
||||
struct uio *
|
||||
cloneuio(struct uio *uiop)
|
||||
{
|
||||
struct iovec *iov;
|
||||
struct uio *uio;
|
||||
int iovlen;
|
||||
|
||||
iovlen = uiop->uio_iovcnt * sizeof(struct iovec);
|
||||
uio = allocuio(uiop->uio_iovcnt);
|
||||
iov = uio->uio_iov;
|
||||
*uio = *uiop;
|
||||
uio->uio_iov = iov;
|
||||
bcopy(uiop->uio_iov, uio->uio_iov, iovlen);
|
||||
return (uio);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -273,7 +273,7 @@ sys_readv(struct thread *td, struct readv_args *uap)
|
|||
if (error)
|
||||
return (error);
|
||||
error = kern_readv(td, uap->fd, auio);
|
||||
free(auio, M_IOV);
|
||||
freeuio(auio);
|
||||
return (error);
|
||||
}
|
||||
|
||||
|
|
@ -312,7 +312,7 @@ sys_preadv(struct thread *td, struct preadv_args *uap)
|
|||
if (error)
|
||||
return (error);
|
||||
error = kern_preadv(td, uap->fd, auio, uap->offset);
|
||||
free(auio, M_IOV);
|
||||
freeuio(auio);
|
||||
return (error);
|
||||
}
|
||||
|
||||
|
|
@ -475,7 +475,7 @@ sys_writev(struct thread *td, struct writev_args *uap)
|
|||
if (error)
|
||||
return (error);
|
||||
error = kern_writev(td, uap->fd, auio);
|
||||
free(auio, M_IOV);
|
||||
freeuio(auio);
|
||||
return (error);
|
||||
}
|
||||
|
||||
|
|
@ -514,7 +514,7 @@ sys_pwritev(struct thread *td, struct pwritev_args *uap)
|
|||
if (error)
|
||||
return (error);
|
||||
error = kern_pwritev(td, uap->fd, auio, uap->offset);
|
||||
free(auio, M_IOV);
|
||||
freeuio(auio);
|
||||
return (error);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -559,7 +559,7 @@ aio_free_entry(struct kaiocb *job)
|
|||
fdrop(job->fd_file, curthread);
|
||||
crfree(job->cred);
|
||||
if (job->uiop != &job->uio)
|
||||
free(job->uiop, M_IOV);
|
||||
freeuio(job->uiop);
|
||||
uma_zfree(aiocb_zone, job);
|
||||
AIO_LOCK(ki);
|
||||
|
||||
|
|
@ -1736,7 +1736,7 @@ err3:
|
|||
knlist_delete(&job->klist, curthread, 0);
|
||||
err2:
|
||||
if (job->uiop != &job->uio)
|
||||
free(job->uiop, M_IOV);
|
||||
freeuio(job->uiop);
|
||||
uma_zfree(aiocb_zone, job);
|
||||
err1:
|
||||
ops->store_error(ujob, error);
|
||||
|
|
|
|||
|
|
@ -474,7 +474,7 @@ sys_nmount(struct thread *td, struct nmount_args *uap)
|
|||
}
|
||||
error = vfs_donmount(td, flags, auio);
|
||||
|
||||
free(auio, M_IOV);
|
||||
freeuio(auio);
|
||||
return (error);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1444,7 +1444,7 @@ vn_io_fault1(struct vnode *vp, struct uio *uio, struct vn_io_fault_args *args,
|
|||
td->td_ma_cnt = prev_td_ma_cnt;
|
||||
curthread_pflags_restore(saveheld);
|
||||
out:
|
||||
free(uio_clone, M_IOV);
|
||||
freeuio(uio_clone);
|
||||
return (error);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -78,6 +78,8 @@ struct vm_object;
|
|||
struct vm_page;
|
||||
struct bus_dma_segment;
|
||||
|
||||
struct uio *allocuio(u_int iovcnt);
|
||||
void freeuio(struct uio *uio);
|
||||
struct uio *cloneuio(struct uio *uiop);
|
||||
int copyiniov(const struct iovec *iovp, u_int iovcnt, struct iovec **iov,
|
||||
int error);
|
||||
|
|
|
|||
Loading…
Reference in a new issue