xnu-3248.60.10.tar.gz
[apple/xnu.git] / bsd / kern / sys_pipe.c
index 9aa8ac04c8987ed5e81290fff0e614dc7b464c72..1e64ce7378334adaff46a973580a962064ff1cea 100644 (file)
@@ -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@
  * 
 #include <libkern/OSAtomic.h>
 
 #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);