root/kern/lib/uio.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. uiomove
  2. uiomovezeros
  3. uio_kinit

   1 /*
   2  * Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
   3  *      The President and Fellows of Harvard College.
   4  *
   5  * Redistribution and use in source and binary forms, with or without
   6  * modification, are permitted provided that the following conditions
   7  * are met:
   8  * 1. Redistributions of source code must retain the above copyright
   9  *    notice, this list of conditions and the following disclaimer.
  10  * 2. Redistributions in binary form must reproduce the above copyright
  11  *    notice, this list of conditions and the following disclaimer in the
  12  *    documentation and/or other materials provided with the distribution.
  13  * 3. Neither the name of the University nor the names of its contributors
  14  *    may be used to endorse or promote products derived from this software
  15  *    without specific prior written permission.
  16  *
  17  * THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
  18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
  21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  27  * SUCH DAMAGE.
  28  */
  29 
  30 #include <types.h>
  31 #include <lib.h>
  32 #include <uio.h>
  33 #include <proc.h>
  34 #include <current.h>
  35 #include <copyinout.h>
  36 
  37 /*
  38  * See uio.h for a description.
  39  */
  40 
  41 int
  42 uiomove(void *ptr, size_t n, struct uio *uio)
  43 {
  44         struct iovec *iov;
  45         size_t size;
  46         int result;
  47 
  48         if (uio->uio_rw != UIO_READ && uio->uio_rw != UIO_WRITE) {
  49                 panic("uiomove: Invalid uio_rw %d\n", (int) uio->uio_rw);
  50         }
  51         if (uio->uio_segflg==UIO_SYSSPACE) {
  52                 KASSERT(uio->uio_space == NULL);
  53         }
  54         else {
  55                 KASSERT(uio->uio_space == curproc_getas());
  56         }
  57 
  58         while (n > 0 && uio->uio_resid > 0) {
  59                 /* get the first iovec */
  60                 iov = uio->uio_iov;
  61                 size = iov->iov_len;
  62 
  63                 if (size > n) {
  64                         size = n;
  65                 }
  66 
  67                 if (size == 0) {
  68                         /* move to the next iovec and try again */
  69                         uio->uio_iov++;
  70                         uio->uio_iovcnt--;
  71                         if (uio->uio_iovcnt == 0) {
  72                                 /* 
  73                                  * This should only happen if you set
  74                                  * uio_resid incorrectly (to more than
  75                                  * the total length of buffers the uio
  76                                  * points to).
  77                                  */
  78                                 panic("uiomove: ran out of buffers\n");
  79                         }
  80                         continue;
  81                 }
  82 
  83                 switch (uio->uio_segflg) {
  84                     case UIO_SYSSPACE:
  85                             result = 0;
  86                             if (uio->uio_rw == UIO_READ) {
  87                                     memmove(iov->iov_kbase, ptr, size);
  88                             }
  89                             else {
  90                                     memmove(ptr, iov->iov_kbase, size);
  91                             }
  92                             iov->iov_kbase = ((char *)iov->iov_kbase+size);
  93                             break;
  94                     case UIO_USERSPACE:
  95                     case UIO_USERISPACE:
  96                             if (uio->uio_rw == UIO_READ) {
  97                                     result = copyout(ptr, iov->iov_ubase,size);
  98                             }
  99                             else {
 100                                     result = copyin(iov->iov_ubase, ptr, size);
 101                             }
 102                             if (result) {
 103                                     return result;
 104                             }
 105                             iov->iov_ubase += size;
 106                             break;
 107                     default:
 108                             panic("uiomove: Invalid uio_segflg %d\n",
 109                                   (int)uio->uio_segflg);
 110                 }
 111 
 112                 iov->iov_len -= size;
 113                 uio->uio_resid -= size;
 114                 uio->uio_offset += size;
 115                 ptr = ((char *)ptr + size);
 116                 n -= size;
 117         }
 118 
 119         return 0;
 120 }
 121 
 122 int
 123 uiomovezeros(size_t n, struct uio *uio)
 124 {
 125         /* static, so initialized as zero */
 126         static char zeros[16];
 127         size_t amt;
 128         int result;
 129 
 130         /* This only makes sense when reading */
 131         KASSERT(uio->uio_rw == UIO_READ);
 132 
 133         while (n > 0) {
 134                 amt = sizeof(zeros);
 135                 if (amt > n) {
 136                         amt = n;
 137                 }
 138                 result = uiomove(zeros, amt, uio);
 139                 if (result) {
 140                         return result;
 141                 }
 142                 n -= amt;
 143         }
 144 
 145         return 0;
 146 }
 147 
 148 /*
 149  * Convenience function to initialize an iovec and uio for kernel I/O.
 150  */
 151 
 152 void
 153 uio_kinit(struct iovec *iov, struct uio *u,
 154           void *kbuf, size_t len, off_t pos, enum uio_rw rw)
 155 {
 156         iov->iov_kbase = kbuf;
 157         iov->iov_len = len;
 158         u->uio_iov = iov;
 159         u->uio_iovcnt = 1;
 160         u->uio_offset = pos;
 161         u->uio_resid = len;
 162         u->uio_segflg = UIO_SYSSPACE;
 163         u->uio_rw = rw;
 164         u->uio_space = NULL;
 165 }

/* [<][>][^][v][top][bottom][index][help] */