/* [<][>][^][v][top][bottom][index][help] */
DEFINITIONS
This source file includes following definitions.
- uiomove
- uiomovezeros
- 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 }