Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
script3r
GitHub Repository: script3r/os161
Path: blob/master/kern/lib/uio.c
2093 views
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 <thread.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 == curthread->t_addrspace);
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
}
166
167