AquilaOS documentation
How it works, and its code
Loading...
Searching...
No Matches
iobuf.c
Go to the documentation of this file.
1
5
6#include <core/system.h>
7#include <core/string.h>
8#include <fs/iobuf.h>
9#include <sys/uaccess.h>
10
19void iobuf_init(struct iobuf *io, void *buf, size_t len, int user)
20{
21 io->one = (struct iobuf_seg) {.base = buf, .len = len};
22 io->seg = &io->one;
23 io->nseg = 1;
24 io->resid = len;
25 io->user = user;
26 io->fault = 0;
27}
28
36static ssize_t iobuf_copy(struct iobuf *io, char *kbuf, size_t n, int out)
37{
38 size_t done = 0;
39
40 if (io->fault)
41 return -EFAULT;
42
43 n = MIN(n, io->resid);
44
45 for (int i = 0; i < io->nseg && done < n; ++i) {
46 char *p = io->seg[i].base;
47 size_t len = MIN(n - done, io->seg[i].len);
48
49 if (!len)
50 continue;
51
52 if (!io->user) {
53 if (out)
54 memcpy(p, kbuf + done, len);
55 else
56 memcpy(kbuf + done, p, len);
57 } else {
58 size_t n = out ? copyout_upto(p, kbuf + done, len) : copyin_upto(kbuf + done, p, len);
59
60 /* what was copied before the fault counts */
61 if (n < len) {
62 io->fault = 1;
63 done += n;
64 return done ? (ssize_t) done : -EFAULT;
65 }
66 }
67
68 done += len;
69 }
70
71 return done;
72}
73
81size_t iobuf_skip(struct iobuf *io, size_t n)
82{
83 size_t done = 0;
84
85 n = MIN(n, io->resid);
86
87 while (done < n) {
88 size_t len = MIN(n - done, io->seg->len);
89
90 io->seg->base += len;
91 io->seg->len -= len;
92 done += len;
93
94 /* on to the next segment */
95 if (!io->seg->len && io->nseg > 1) {
96 io->seg++;
97 io->nseg--;
98 }
99 }
100
101 io->resid -= done;
102 return done;
103}
104
115ssize_t iobuf_out(struct iobuf *io, const void *src, size_t n)
116{
117 ssize_t r = iobuf_copy(io, (char *) src, n, 1);
118
119 if (r > 0)
120 iobuf_skip(io, r);
121
122 return r;
123}
124
135ssize_t iobuf_in(struct iobuf *io, void *dst, size_t n)
136{
137 ssize_t r = iobuf_copy(io, dst, n, 0);
138
139 if (r > 0)
140 iobuf_skip(io, r);
141
142 return r;
143}
144
154ssize_t iobuf_peek(struct iobuf *io, void *dst, size_t n)
155{
156 return iobuf_copy(io, dst, n, 0);
157}
158
167ssize_t iobuf_zero(struct iobuf *io, size_t n)
168{
169 static const char zero[256];
170 size_t done = 0;
171
172 n = MIN(n, io->resid);
173
174 while (done < n) {
175 size_t len = MIN(n - done, sizeof(zero));
176 ssize_t r = iobuf_out(io, zero, len);
177
178 if (r < 0)
179 return done ? (ssize_t) done : r;
180
181 done += r;
182
183 /* a fault stopped it */
184 if ((size_t) r < len)
185 break;
186 }
187
188 return done;
189}
#define MIN(a, b)
Definition system.h:11
static ssize_t iobuf_copy(struct iobuf *io, char *kbuf, size_t n, int out)
Copies up to n bytes between the iobuf's buffer, from where it is, and kbuf: into the buffer if out i...
Definition iobuf.c:36
ssize_t iobuf_out(struct iobuf *io, const void *src, size_t n)
Copies bytes from the kernel into the iobuf's buffer, and moves past them.
Definition iobuf.c:115
ssize_t iobuf_in(struct iobuf *io, void *dst, size_t n)
Copies bytes from the iobuf's buffer into the kernel, and moves past them.
Definition iobuf.c:135
ssize_t iobuf_zero(struct iobuf *io, size_t n)
Fills bytes of the iobuf's buffer with zeros, and moves past them.
Definition iobuf.c:167
size_t iobuf_skip(struct iobuf *io, size_t n)
Moves an iobuf past bytes, without copying them.
Definition iobuf.c:81
void iobuf_init(struct iobuf *io, void *buf, size_t len, int user)
Sets up an iobuf for one buffer.
Definition iobuf.c:19
ssize_t iobuf_peek(struct iobuf *io, void *dst, size_t n)
Copies bytes from the iobuf's buffer into the kernel, without moving past them.
Definition iobuf.c:154
void * memcpy(void *dst, const void *src, size_t n)
Copies n bytes; dst and src must not overlap.
Definition libc.c:11
A piece of an iobuf's memory.
Definition iobuf.h:28
size_t len
Definition iobuf.h:30
char * base
Definition iobuf.h:29
An iobuf.
Definition iobuf.h:35
int nseg
Definition iobuf.h:37
struct iobuf_seg one
Definition iobuf.h:41
int user
Definition iobuf.h:39
int fault
Definition iobuf.h:40
struct iobuf_seg * seg
Definition iobuf.h:36
size_t resid
Definition iobuf.h:38
long int ssize_t
Definition types.h:12