X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/316670eb35587141e969394ae8537d66b9211e80..7e41aa883dd258f888d0470250eead40a53ef1f5:/bsd/kern/sys_pipe.c diff --git a/bsd/kern/sys_pipe.c b/bsd/kern/sys_pipe.c index 9aa8ac04c..1e64ce737 100644 --- a/bsd/kern/sys_pipe.c +++ b/bsd/kern/sys_pipe.c @@ -17,7 +17,7 @@ * are met. */ /* - * Copyright (c) 2003-2007 Apple Inc. All rights reserved. + * Copyright (c) 2003-2014 Apple Inc. All rights reserved. * * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ * @@ -148,7 +148,6 @@ #include #define f_flag f_fglob->fg_flag -#define f_type f_fglob->fg_type #define f_msgcount f_fglob->fg_msgcount #define f_cred f_fglob->fg_cred #define f_ops f_fglob->fg_ops @@ -171,14 +170,16 @@ static int pipe_ioctl(struct fileproc *fp, u_long cmd, caddr_t data, vfs_context_t ctx); static int pipe_drain(struct fileproc *fp,vfs_context_t ctx); -struct fileops pipeops = - { pipe_read, - pipe_write, - pipe_ioctl, - pipe_select, - pipe_close, - pipe_kqfilter, - pipe_drain }; +static const struct fileops pipeops = { + DTYPE_PIPE, + pipe_read, + pipe_write, + pipe_ioctl, + pipe_select, + pipe_close, + pipe_kqfilter, + pipe_drain +}; static void filt_pipedetach(struct knote *kn); static int filt_piperead(struct knote *kn, long hint); @@ -200,7 +201,7 @@ static int nbigpipe; /* for compatibility sake. no longer used */ static int amountpipes; /* total number of pipes in system */ static int amountpipekva; /* total memory used by pipes */ -int maxpipekva = PIPE_KVAMAX; /* allowing 16MB max. */ +int maxpipekva __attribute__((used)) = PIPE_KVAMAX; /* allowing 16MB max. */ #if PIPE_SYSCTLS SYSCTL_DECL(_kern_ipc); @@ -316,7 +317,7 @@ pipe_touch(struct pipe *tpipe, int touch) } } -static const unsigned int pipesize_blocks[] = {128,256,1024,2048,PAGE_SIZE, PAGE_SIZE * 2, PIPE_SIZE , PIPE_SIZE * 4 }; +static const unsigned int pipesize_blocks[] = {512,1024,2048,4096, 4096 * 2, PIPE_SIZE , PIPE_SIZE * 4 }; /* * finds the right size from possible sizes in pipesize_blocks @@ -328,6 +329,12 @@ choose_pipespace(unsigned long current, unsigned long expected) int i = sizeof(pipesize_blocks)/sizeof(unsigned int) -1; unsigned long target; + /* + * assert that we always get an atomic transaction sized pipe buffer, + * even if the system pipe buffer high-water mark has been crossed. + */ + assert(PIPE_BUF == pipesize_blocks[0]); + if (expected > current) target = expected; else @@ -432,7 +439,6 @@ pipe(proc_t p, __unused struct pipe_args *uap, int32_t *retval) * this is what we've always supported.. */ rf->f_flag = FREAD; - rf->f_type = DTYPE_PIPE; rf->f_data = (caddr_t)rpipe; rf->f_ops = &pipeops; @@ -442,7 +448,6 @@ pipe(proc_t p, __unused struct pipe_args *uap, int32_t *retval) goto freepipes; } wf->f_flag = FWRITE; - wf->f_type = DTYPE_PIPE; wf->f_data = (caddr_t)wpipe; wf->f_ops = &pipeops; @@ -1217,7 +1222,7 @@ pipe_select(struct fileproc *fp, int which, void *wql, vfs_context_t ctx) wpipe->pipe_state |= PIPE_WSELECT; if (wpipe == NULL || (wpipe->pipe_state & (PIPE_DRAIN | PIPE_EOF)) || (((wpipe->pipe_state & PIPE_DIRECTW) == 0) && - (MAX_PIPESIZE(wpipe) - wpipe->pipe_buffer.cnt) > 0)) { + (MAX_PIPESIZE(wpipe) - wpipe->pipe_buffer.cnt) >= PIPE_BUF)) { retnum = 1; } else { @@ -1327,17 +1332,18 @@ pipeclose(struct pipe *cpipe) * free resources */ if (PIPE_MTX(cpipe) != NULL) { - if (ppipe != NULL) { - /* + if (ppipe != NULL) { + /* * since the mutex is shared and the peer is still * alive, we need to release the mutex, not free it */ - PIPE_UNLOCK(cpipe); + PIPE_UNLOCK(cpipe); } else { - /* + /* * peer is gone, so we're the sole party left with - * interest in this mutex... we can just free it + * interest in this mutex... unlock and free it */ + PIPE_UNLOCK(cpipe); lck_mtx_free(PIPE_MTX(cpipe), pipe_mtx_grp); } } @@ -1579,8 +1585,8 @@ fill_pipeinfo(struct pipe * cpipe, struct pipe_info * pinfo) * XXX (st_dev, st_ino) should be unique. */ - pinfo->pipe_handle = (uint64_t)((uintptr_t)cpipe); - pinfo->pipe_peerhandle = (uint64_t)((uintptr_t)(cpipe->pipe_peer)); + pinfo->pipe_handle = (uint64_t)VM_KERNEL_ADDRPERM((uintptr_t)cpipe); + pinfo->pipe_peerhandle = (uint64_t)VM_KERNEL_ADDRPERM((uintptr_t)(cpipe->pipe_peer)); pinfo->pipe_status = cpipe->pipe_state; PIPE_UNLOCK(cpipe);