2 #include "kvm/virtio-9p.h"
7 #include <linux/compiler.h>
10 static void virtio_p9_pdu_read(struct p9_pdu
*pdu
, void *data
, size_t size
)
14 u16 iov_cnt
= pdu
->out_iov_cnt
;
15 size_t offset
= pdu
->read_offset
;
16 struct iovec
*iov
= pdu
->out_iov
;
18 for (i
= 0; i
< iov_cnt
&& size
; i
++) {
19 if (offset
>= iov
[i
].iov_len
) {
20 offset
-= iov
[i
].iov_len
;
23 len
= MIN(iov
[i
].iov_len
- offset
, size
);
24 memcpy(data
, iov
[i
].iov_base
+ offset
, len
);
31 pdu
->read_offset
+= copied
;
34 static void virtio_p9_pdu_write(struct p9_pdu
*pdu
,
35 const void *data
, size_t size
)
39 u16 iov_cnt
= pdu
->in_iov_cnt
;
40 size_t offset
= pdu
->write_offset
;
41 struct iovec
*iov
= pdu
->in_iov
;
43 for (i
= 0; i
< iov_cnt
&& size
; i
++) {
44 if (offset
>= iov
[i
].iov_len
) {
45 offset
-= iov
[i
].iov_len
;
48 len
= MIN(iov
[i
].iov_len
- offset
, size
);
49 memcpy(iov
[i
].iov_base
+ offset
, data
, len
);
56 pdu
->write_offset
+= copied
;
59 static void virtio_p9_wstat_free(struct p9_wstat
*stbuf
)
67 static int virtio_p9_decode(struct p9_pdu
*pdu
, const char *fmt
, va_list ap
)
72 for (ptr
= fmt
; *ptr
; ptr
++) {
76 int8_t *val
= va_arg(ap
, int8_t *);
77 virtio_p9_pdu_read(pdu
, val
, sizeof(*val
));
83 int16_t *val
= va_arg(ap
, int16_t *);
84 virtio_p9_pdu_read(pdu
, &le_val
, sizeof(le_val
));
85 *val
= le16toh(le_val
);
91 int32_t *val
= va_arg(ap
, int32_t *);
92 virtio_p9_pdu_read(pdu
, &le_val
, sizeof(le_val
));
93 *val
= le32toh(le_val
);
99 int64_t *val
= va_arg(ap
, int64_t *);
100 virtio_p9_pdu_read(pdu
, &le_val
, sizeof(le_val
));
101 *val
= le64toh(le_val
);
107 char **str
= va_arg(ap
, char **);
109 virtio_p9_pdu_readf(pdu
, "w", &len
);
110 *str
= malloc(len
+ 1);
115 virtio_p9_pdu_read(pdu
, *str
, len
);
121 struct p9_qid
*qid
= va_arg(ap
, struct p9_qid
*);
122 retval
= virtio_p9_pdu_readf(pdu
, "bdq",
123 &qid
->type
, &qid
->version
,
129 struct p9_wstat
*stbuf
= va_arg(ap
, struct p9_wstat
*);
130 memset(stbuf
, 0, sizeof(struct p9_wstat
));
131 stbuf
->n_uid
= stbuf
->n_gid
= stbuf
->n_muid
= -1;
132 retval
= virtio_p9_pdu_readf(pdu
, "wwdQdddqssss",
133 &stbuf
->size
, &stbuf
->type
,
134 &stbuf
->dev
, &stbuf
->qid
,
135 &stbuf
->mode
, &stbuf
->atime
,
136 &stbuf
->mtime
, &stbuf
->length
,
137 &stbuf
->name
, &stbuf
->uid
,
138 &stbuf
->gid
, &stbuf
->muid
);
140 virtio_p9_wstat_free(stbuf
);
145 struct p9_iattr_dotl
*p9attr
= va_arg(ap
,
146 struct p9_iattr_dotl
*);
148 retval
= virtio_p9_pdu_readf(pdu
, "ddddqqqqq",
157 &p9attr
->mtime_nsec
);
168 static int virtio_p9_pdu_encode(struct p9_pdu
*pdu
, const char *fmt
, va_list ap
)
173 for (ptr
= fmt
; *ptr
; ptr
++) {
177 int8_t val
= va_arg(ap
, int);
178 virtio_p9_pdu_write(pdu
, &val
, sizeof(val
));
183 int16_t val
= htole16(va_arg(ap
, int));
184 virtio_p9_pdu_write(pdu
, &val
, sizeof(val
));
189 int32_t val
= htole32(va_arg(ap
, int32_t));
190 virtio_p9_pdu_write(pdu
, &val
, sizeof(val
));
195 int64_t val
= htole64(va_arg(ap
, int64_t));
196 virtio_p9_pdu_write(pdu
, &val
, sizeof(val
));
202 const char *s
= va_arg(ap
, char *);
204 len
= MIN(strlen(s
), USHRT_MAX
);
205 virtio_p9_pdu_writef(pdu
, "w", len
);
206 virtio_p9_pdu_write(pdu
, s
, len
);
211 struct p9_qid
*qid
= va_arg(ap
, struct p9_qid
*);
212 retval
= virtio_p9_pdu_writef(pdu
, "bdq",
213 qid
->type
, qid
->version
,
219 struct p9_wstat
*stbuf
= va_arg(ap
, struct p9_wstat
*);
220 retval
= virtio_p9_pdu_writef(pdu
, "wwdQdddqssss",
221 stbuf
->size
, stbuf
->type
,
222 stbuf
->dev
, &stbuf
->qid
,
223 stbuf
->mode
, stbuf
->atime
,
224 stbuf
->mtime
, stbuf
->length
,
225 stbuf
->name
, stbuf
->uid
,
226 stbuf
->gid
, stbuf
->muid
);
231 struct p9_stat_dotl
*stbuf
= va_arg(ap
,
232 struct p9_stat_dotl
*);
233 retval
= virtio_p9_pdu_writef(pdu
,
234 "qQdddqqqqqqqqqqqqqqq",
235 stbuf
->st_result_mask
,
246 stbuf
->st_atime_nsec
,
248 stbuf
->st_mtime_nsec
,
250 stbuf
->st_ctime_nsec
,
252 stbuf
->st_btime_nsec
,
254 stbuf
->st_data_version
);
265 int virtio_p9_pdu_readf(struct p9_pdu
*pdu
, const char *fmt
, ...)
271 ret
= virtio_p9_decode(pdu
, fmt
, ap
);
277 int virtio_p9_pdu_writef(struct p9_pdu
*pdu
, const char *fmt
, ...)
283 ret
= virtio_p9_pdu_encode(pdu
, fmt
, ap
);