summaryrefslogtreecommitdiff
path: root/lib9p/9p.c
diff options
context:
space:
mode:
authorLuke T. Shumaker <lukeshu@lukeshu.com>2025-01-13 23:20:13 -0700
committerLuke T. Shumaker <lukeshu@lukeshu.com>2025-02-12 20:55:19 -0700
commita24a60232204702fe245c312edb0c2c8041b17a8 (patch)
tree01cc4a46cad37087aa419b2b13c9aa27c568eea2 /lib9p/9p.c
parent1793bda7f3e445c5ad81cf108589f8b1edcda4eb (diff)
lib9p: Rewrite the marshalers to support zero-copy for data
Diffstat (limited to 'lib9p/9p.c')
-rw-r--r--lib9p/9p.c42
1 files changed, 29 insertions, 13 deletions
diff --git a/lib9p/9p.c b/lib9p/9p.c
index c54dae7..1caa01a 100644
--- a/lib9p/9p.c
+++ b/lib9p/9p.c
@@ -204,30 +204,42 @@ void lib9p_Rmsg_unmarshal(struct lib9p_ctx *ctx, uint8_t *net_bytes,
static
bool _lib9p_marshal(const struct _lib9p_send_tentry xxx_table[LIB9P_VER_NUM][0x80],
struct lib9p_ctx *ctx, enum lib9p_msg_type typ, void *body,
- uint8_t *ret_bytes) {
+ size_t *ret_iov_cnt, struct iovec *ret_iov, uint8_t *ret_copied) {
struct _marshal_ctx subctx = {
/* input */
- .ctx = ctx,
+ .ctx = ctx,
/* ouptut */
- .net_bytes = ret_bytes,
- .net_offset = 0,
+ .net_iov_cnt = 1,
+ .net_iov = ret_iov,
+ .net_copied_size = 0,
+ .net_copied = ret_copied,
};
struct _lib9p_send_tentry tentry = xxx_table[ctx->version][typ/2];
- return tentry.marshal(&subctx, body);
+ bool ret_erred = tentry.marshal(&subctx, body);
+ if (ret_iov[subctx.net_iov_cnt-1].iov_len == 0)
+ subctx.net_iov_cnt--;
+ *ret_iov_cnt = subctx.net_iov_cnt;
+ return ret_erred;
}
bool lib9p_Tmsg_marshal(struct lib9p_ctx *ctx, enum lib9p_msg_type typ, void *body,
- uint8_t *ret_bytes) {
+ struct lib9p_Tmsg_send_buf *ret) {
assert(typ % 2 == 0);
- return _lib9p_marshal(_lib9p_table_Tmsg_send, ctx, typ, body, ret_bytes);
+ memset(ret, 0, sizeof(*ret));
+ return _lib9p_marshal(_lib9p_table_Tmsg_send,
+ ctx, typ, body,
+ &ret->iov_cnt, ret->iov, ret->copied);
}
bool lib9p_Rmsg_marshal(struct lib9p_ctx *ctx, enum lib9p_msg_type typ, void *body,
- uint8_t *ret_bytes) {
+ struct lib9p_Rmsg_send_buf *ret) {
assert(typ % 2 == 1);
- return _lib9p_marshal(_lib9p_table_Rmsg_send, ctx, typ, body, ret_bytes);
+ memset(ret, 0, sizeof(*ret));
+ return _lib9p_marshal(_lib9p_table_Rmsg_send,
+ ctx, typ, body,
+ &ret->iov_cnt, ret->iov, ret->copied);
}
/* `struct lib9p_stat` helpers ************************************************/
@@ -273,15 +285,19 @@ uint32_t lib9p_stat_marshal(struct lib9p_ctx *ctx, uint32_t max_net_size, struct
uint8_t *ret_bytes) {
struct lib9p_ctx _ctx = *ctx;
_ctx.max_msg_size = max_net_size;
+
+ struct iovec iov = {0};
struct _marshal_ctx subctx = {
/* input */
- .ctx = &_ctx,
+ .ctx = &_ctx,
/* output */
- .net_bytes = ret_bytes,
- .net_offset = 0,
+ .net_iov_cnt = 1,
+ .net_iov = &iov,
+ .net_copied_size = 0,
+ .net_copied = ret_bytes,
};
if (_lib9p_stat_marshal(&subctx, obj))
return 0;
- return subctx.net_offset;
+ return subctx.net_iov[0].iov_len;
}