summaryrefslogtreecommitdiff
path: root/lib9p
diff options
context:
space:
mode:
authorLuke T. Shumaker <lukeshu@lukeshu.com>2025-02-12 20:55:47 -0700
committerLuke T. Shumaker <lukeshu@lukeshu.com>2025-02-12 20:55:47 -0700
commit4ba0b95dc825a83748b7cb2aa528411026d5bada (patch)
tree29b04d56a5bb46273676e827a152d17602b96cae /lib9p
parentd148555bd86e323a51734b7881f92d09e2f08425 (diff)
parent6759a952978ea011dbc08a13b8f97a7c97572d16 (diff)
Merge branch 'lukeshu/9p-small-pt1'
Diffstat (limited to 'lib9p')
-rw-r--r--lib9p/9p.c42
-rw-r--r--lib9p/9p.generated.c2796
-rwxr-xr-xlib9p/idl.gen750
-rw-r--r--lib9p/include/lib9p/9p.generated.h283
-rw-r--r--lib9p/include/lib9p/9p.h4
-rw-r--r--lib9p/internal.h7
-rw-r--r--lib9p/srv.c101
7 files changed, 2499 insertions, 1484 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;
}
diff --git a/lib9p/9p.generated.c b/lib9p/9p.generated.c
index 1188c73..eca0666 100644
--- a/lib9p/9p.generated.c
+++ b/lib9p/9p.generated.c
@@ -431,7 +431,7 @@ LM_ALWAYS_INLINE static bool validate_s(struct _validate_ctx *ctx) {
uint16_t len;
return false
|| (validate_2(ctx) || ({ len = uint16le_decode(&ctx->net_bytes[ctx->net_offset-2]); false; }))
- || _validate_list(ctx, len, validate_1, sizeof(uint8_t))
+ || _validate_size_net(ctx, len)
|| ({ (!is_valid_utf8_without_nul(&ctx->net_bytes[ctx->net_offset-len], len)) && lib9p_error(ctx->ctx, LINUX_EBADMSG, "message contains invalid UTF-8"); })
;
}
@@ -561,7 +561,7 @@ LM_FLATTEN static bool validate_Rread(struct _validate_ctx *ctx) {
|| (validate_1(ctx) || ({ typ = ctx->net_bytes[ctx->net_offset-1]; false; }))
|| validate_tag(ctx)
|| (validate_4(ctx) || ({ count = uint32le_decode(&ctx->net_bytes[ctx->net_offset-4]); false; }))
- || _validate_list(ctx, count, validate_1, sizeof(uint8_t))
+ || _validate_size_net(ctx, count)
|| ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) &&
lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); })
|| ({ uint8_t exp = 117; (((uint8_t)typ) != exp) &&
@@ -750,7 +750,7 @@ LM_FLATTEN static bool validate_Rreaddir(struct _validate_ctx *ctx) {
|| (validate_1(ctx) || ({ typ = ctx->net_bytes[ctx->net_offset-1]; false; }))
|| validate_tag(ctx)
|| (validate_4(ctx) || ({ count = uint32le_decode(&ctx->net_bytes[ctx->net_offset-4]); false; }))
- || _validate_list(ctx, count, validate_1, sizeof(uint8_t))
+ || _validate_size_net(ctx, count)
|| ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) &&
lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); })
|| ({ uint8_t exp = 41; (((uint8_t)typ) != exp) &&
@@ -861,7 +861,7 @@ LM_FLATTEN static bool validate_Rsread(struct _validate_ctx *ctx) {
|| (validate_1(ctx) || ({ typ = ctx->net_bytes[ctx->net_offset-1]; false; }))
|| validate_tag(ctx)
|| (validate_4(ctx) || ({ count = uint32le_decode(&ctx->net_bytes[ctx->net_offset-4]); false; }))
- || _validate_list(ctx, count, validate_1, sizeof(uint8_t))
+ || _validate_size_net(ctx, count)
|| ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) &&
lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); })
|| ({ uint8_t exp = 153; (((uint8_t)typ) != exp) &&
@@ -924,7 +924,7 @@ LM_FLATTEN static bool validate_Twrite(struct _validate_ctx *ctx) {
|| validate_fid(ctx)
|| (validate_8(ctx) || ({ offset = uint64le_decode(&ctx->net_bytes[ctx->net_offset-8]); false; }))
|| (validate_4(ctx) || ({ count = uint32le_decode(&ctx->net_bytes[ctx->net_offset-4]); false; }))
- || _validate_list(ctx, count, validate_1, sizeof(uint8_t))
+ || _validate_size_net(ctx, count)
|| ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) &&
lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); })
|| ({ uint8_t exp = 118; (((uint8_t)typ) != exp) &&
@@ -1353,7 +1353,7 @@ LM_FLATTEN static bool validate_Tswrite(struct _validate_ctx *ctx) {
|| (validate_2(ctx) || ({ nwname = uint16le_decode(&ctx->net_bytes[ctx->net_offset-2]); false; }))
|| _validate_list(ctx, nwname, validate_s, sizeof(struct lib9p_s))
|| (validate_4(ctx) || ({ count = uint32le_decode(&ctx->net_bytes[ctx->net_offset-4]); false; }))
- || _validate_list(ctx, count, validate_1, sizeof(uint8_t))
+ || _validate_size_net(ctx, count)
|| ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) &&
lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); })
|| ({ uint8_t exp = 154; (((uint8_t)typ) != exp) &&
@@ -1972,10 +1972,8 @@ LM_ALWAYS_INLINE static void unmarshal_fid(struct _unmarshal_ctx *ctx, lib9p_fid
LM_ALWAYS_INLINE static void unmarshal_s(struct _unmarshal_ctx *ctx, struct lib9p_s *out) {
memset(out, 0, sizeof(*out));
unmarshal_2(ctx, &out->len);
- out->utf8 = ctx->extra;
- ctx->extra += sizeof(out->utf8[0]) * out->len;
- for (typeof(out->len) i = 0; i < out->len; i++)
- unmarshal_1(ctx, (uint8_t *)&out->utf8[i]);
+ out->utf8 = (char *)&ctx->net_bytes[ctx->net_offset];
+ ctx->net_offset += out->len;
}
#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */
@@ -2047,10 +2045,8 @@ LM_FLATTEN static void unmarshal_Rread(struct _unmarshal_ctx *ctx, struct lib9p_
ctx->net_offset += 1;
unmarshal_tag(ctx, &out->tag);
unmarshal_4(ctx, &out->count);
- out->data = ctx->extra;
- ctx->extra += sizeof(out->data[0]) * out->count;
- for (typeof(out->count) i = 0; i < out->count; i++)
- unmarshal_1(ctx, (uint8_t *)&out->data[i]);
+ out->data = (char *)&ctx->net_bytes[ctx->net_offset];
+ ctx->net_offset += out->count;
}
LM_FLATTEN static void unmarshal_Rwrite(struct _unmarshal_ctx *ctx, struct lib9p_msg_Rwrite *out) {
@@ -2145,10 +2141,8 @@ LM_FLATTEN static void unmarshal_Rreaddir(struct _unmarshal_ctx *ctx, struct lib
ctx->net_offset += 1;
unmarshal_tag(ctx, &out->tag);
unmarshal_4(ctx, &out->count);
- out->data = ctx->extra;
- ctx->extra += sizeof(out->data[0]) * out->count;
- for (typeof(out->count) i = 0; i < out->count; i++)
- unmarshal_1(ctx, (uint8_t *)&out->data[i]);
+ out->data = (char *)&ctx->net_bytes[ctx->net_offset];
+ ctx->net_offset += out->count;
}
LM_FLATTEN static void unmarshal_Rfsync(struct _unmarshal_ctx *ctx, struct lib9p_msg_Rfsync *out) {
@@ -2202,10 +2196,8 @@ LM_FLATTEN static void unmarshal_Rsread(struct _unmarshal_ctx *ctx, struct lib9p
ctx->net_offset += 1;
unmarshal_tag(ctx, &out->tag);
unmarshal_4(ctx, &out->count);
- out->data = ctx->extra;
- ctx->extra += sizeof(out->data[0]) * out->count;
- for (typeof(out->count) i = 0; i < out->count; i++)
- unmarshal_1(ctx, (uint8_t *)&out->data[i]);
+ out->data = (char *)&ctx->net_bytes[ctx->net_offset];
+ ctx->net_offset += out->count;
}
LM_FLATTEN static void unmarshal_Rswrite(struct _unmarshal_ctx *ctx, struct lib9p_msg_Rswrite *out) {
@@ -2236,10 +2228,8 @@ LM_FLATTEN static void unmarshal_Twrite(struct _unmarshal_ctx *ctx, struct lib9p
unmarshal_fid(ctx, &out->fid);
unmarshal_8(ctx, &out->offset);
unmarshal_4(ctx, &out->count);
- out->data = ctx->extra;
- ctx->extra += sizeof(out->data[0]) * out->count;
- for (typeof(out->count) i = 0; i < out->count; i++)
- unmarshal_1(ctx, (uint8_t *)&out->data[i]);
+ out->data = (char *)&ctx->net_bytes[ctx->net_offset];
+ ctx->net_offset += out->count;
}
LM_FLATTEN static void unmarshal_Tclunk(struct _unmarshal_ctx *ctx, struct lib9p_msg_Tclunk *out) {
@@ -2483,10 +2473,8 @@ LM_FLATTEN static void unmarshal_Tswrite(struct _unmarshal_ctx *ctx, struct lib9
for (typeof(out->nwname) i = 0; i < out->nwname; i++)
unmarshal_s(ctx, &out->wname[i]);
unmarshal_4(ctx, &out->count);
- out->data = ctx->extra;
- ctx->extra += sizeof(out->data[0]) * out->count;
- for (typeof(out->count) i = 0; i < out->count; i++)
- unmarshal_1(ctx, (uint8_t *)&out->data[i]);
+ out->data = (char *)&ctx->net_bytes[ctx->net_offset];
+ ctx->net_offset += out->count;
}
#endif /* CONFIG_9P_ENABLE_9P2000_e */
@@ -2838,1311 +2826,1777 @@ LM_FLATTEN static void unmarshal_Twstat(struct _unmarshal_ctx *ctx, struct lib9p
/* marshal_* ******************************************************************/
-LM_ALWAYS_INLINE static bool _marshal_too_large(struct _marshal_ctx *ctx) {
- lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s too large to marshal into %s limit (limit=%"PRIu32")",
- (ctx->net_bytes[4] % 2 == 0) ? "T-message" : "R-message",
- ctx->ctx->version ? "negotiated" : ((ctx->net_bytes[4] % 2 == 0) ? "client" : "server"),
- ctx->ctx->max_msg_size);
- return true;
-}
+#define MARSHAL_BYTES_ZEROCOPY(ctx, data, len) \
+ if (ctx->net_iov[ctx->net_iov_cnt-1].iov_len) \
+ ctx->net_iov_cnt++; \
+ ctx->net_iov[ctx->net_iov_cnt-1].iov_base = data; \
+ ctx->net_iov[ctx->net_iov_cnt-1].iov_len = len; \
+ ctx->net_iov_cnt++;
+#define MARSHAL_BYTES(ctx, data, len) \
+ if (!ctx->net_iov[ctx->net_iov_cnt-1].iov_base) \
+ ctx->net_iov[ctx->net_iov_cnt-1].iov_base = &ctx->net_copied[ctx->net_copied_size]; \
+ memcpy(&ctx->net_copied[ctx->net_copied_size], data, len); \
+ ctx->net_copied_size += len; \
+ ctx->net_iov[ctx->net_iov_cnt-1].iov_len += len;
+#define MARSHAL_U8LE(ctx, val) \
+ if (!ctx->net_iov[ctx->net_iov_cnt-1].iov_base) \
+ ctx->net_iov[ctx->net_iov_cnt-1].iov_base = &ctx->net_copied[ctx->net_copied_size]; \
+ ctx->net_copied[ctx->net_copied_size] = val; \
+ ctx->net_copied_size += 1; \
+ ctx->net_iov[ctx->net_iov_cnt-1].iov_len += 1;
+#define MARSHAL_U16LE(ctx, val) \
+ if (!ctx->net_iov[ctx->net_iov_cnt-1].iov_base) \
+ ctx->net_iov[ctx->net_iov_cnt-1].iov_base = &ctx->net_copied[ctx->net_copied_size]; \
+ uint16le_encode(&ctx->net_copied[ctx->net_copied_size], val); \
+ ctx->net_copied_size += 2; \
+ ctx->net_iov[ctx->net_iov_cnt-1].iov_len += 2;
+#define MARSHAL_U32LE(ctx, val) \
+ if (!ctx->net_iov[ctx->net_iov_cnt-1].iov_base) \
+ ctx->net_iov[ctx->net_iov_cnt-1].iov_base = &ctx->net_copied[ctx->net_copied_size]; \
+ uint32le_encode(&ctx->net_copied[ctx->net_copied_size], val); \
+ ctx->net_copied_size += 4; \
+ ctx->net_iov[ctx->net_iov_cnt-1].iov_len += 4;
+#define MARSHAL_U64LE(ctx, val) \
+ if (!ctx->net_iov[ctx->net_iov_cnt-1].iov_base) \
+ ctx->net_iov[ctx->net_iov_cnt-1].iov_base = &ctx->net_copied[ctx->net_copied_size]; \
+ uint64le_encode(&ctx->net_copied[ctx->net_copied_size], val); \
+ ctx->net_copied_size += 8; \
+ ctx->net_iov[ctx->net_iov_cnt-1].iov_len += 8;
-LM_ALWAYS_INLINE static bool marshal_1(struct _marshal_ctx *ctx, uint8_t *val) {
- if (ctx->net_offset + 1 > ctx->ctx->max_msg_size)
- return _marshal_too_large(ctx);
- ctx->net_bytes[ctx->net_offset] = *val;
- ctx->net_offset += 1;
+#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u
+static bool marshal_stat(struct _marshal_ctx *ctx, struct lib9p_stat *val) {
+ uint32_t needed_size = 49 + val->file_name.len + val->file_owner_uid.len + val->file_owner_gid.len + val->file_last_modified_uid.len;
+#if CONFIG_9P_ENABLE_9P2000_u
+ if is_ver(ctx, 9P2000_u) {
+ needed_size += 14 + val->file_extension.len;
+ }
+#endif /* CONFIG_9P_ENABLE_9P2000_u */
+ if (needed_size > ctx->ctx->max_msg_size) {
+ return true;
+ }
+ uint32_t offsetof_end = needed_size;
+ uint32_t offsetof_kern_type = 2;
+ MARSHAL_U16LE(ctx, offsetof_end - offsetof_kern_type);
+ MARSHAL_U16LE(ctx, val->kern_type);
+ MARSHAL_U32LE(ctx, val->kern_dev);
+ MARSHAL_U8LE(ctx, val->file_qid.type & qt_masks[ctx->ctx->version]);
+ MARSHAL_U32LE(ctx, val->file_qid.vers);
+ MARSHAL_U64LE(ctx, val->file_qid.path);
+ MARSHAL_U32LE(ctx, val->file_mode & dm_masks[ctx->ctx->version]);
+ MARSHAL_U32LE(ctx, val->file_atime);
+ MARSHAL_U32LE(ctx, val->file_mtime);
+ MARSHAL_U64LE(ctx, val->file_size);
+ MARSHAL_U16LE(ctx, val->file_name.len);
+ MARSHAL_BYTES(ctx, val->file_name.utf8, val->file_name.len);
+ MARSHAL_U16LE(ctx, val->file_owner_uid.len);
+ MARSHAL_BYTES(ctx, val->file_owner_uid.utf8, val->file_owner_uid.len);
+ MARSHAL_U16LE(ctx, val->file_owner_gid.len);
+ MARSHAL_BYTES(ctx, val->file_owner_gid.utf8, val->file_owner_gid.len);
+ MARSHAL_U16LE(ctx, val->file_last_modified_uid.len);
+ MARSHAL_BYTES(ctx, val->file_last_modified_uid.utf8, val->file_last_modified_uid.len);
+#if CONFIG_9P_ENABLE_9P2000_u
+ if (is_ver(ctx, 9P2000_u)) {
+ MARSHAL_U16LE(ctx, val->file_extension.len);
+ MARSHAL_BYTES(ctx, val->file_extension.utf8, val->file_extension.len);
+ }
+#endif /* CONFIG_9P_ENABLE_9P2000_u */
+#if CONFIG_9P_ENABLE_9P2000_u
+ if (is_ver(ctx, 9P2000_u)) {
+ MARSHAL_U32LE(ctx, val->file_owner_n_uid);
+ }
+#endif /* CONFIG_9P_ENABLE_9P2000_u */
+#if CONFIG_9P_ENABLE_9P2000_u
+ if (is_ver(ctx, 9P2000_u)) {
+ MARSHAL_U32LE(ctx, val->file_owner_n_gid);
+ }
+#endif /* CONFIG_9P_ENABLE_9P2000_u */
+#if CONFIG_9P_ENABLE_9P2000_u
+ if (is_ver(ctx, 9P2000_u)) {
+ MARSHAL_U32LE(ctx, val->file_last_modified_n_uid);
+ }
+#endif /* CONFIG_9P_ENABLE_9P2000_u */
return false;
}
-LM_ALWAYS_INLINE static bool marshal_2(struct _marshal_ctx *ctx, uint16_t *val) {
- if (ctx->net_offset + 2 > ctx->ctx->max_msg_size)
- return _marshal_too_large(ctx);
- uint16le_encode(&ctx->net_bytes[ctx->net_offset], *val);
- ctx->net_offset += 2;
+#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */
+#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u
+static bool marshal_Tversion(struct _marshal_ctx *ctx, struct lib9p_msg_Tversion *val) {
+ uint32_t needed_size = 13 + val->version.len;
+ if (needed_size > ctx->ctx->max_msg_size) {
+ lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%PRIu32)",
+ "Tversion",
+ ctx->ctx->version ? "negotiated" : "client",
+ ctx->ctx->max_msg_size);
+ return true;
+ }
+ uint32_t offsetof_end = needed_size;
+ uint32_t offsetof_size = 0;
+ MARSHAL_U32LE(ctx, offsetof_end - offsetof_size);
+ MARSHAL_U8LE(ctx, 100);
+ MARSHAL_U16LE(ctx, val->tag);
+ MARSHAL_U32LE(ctx, val->max_msg_size);
+ MARSHAL_U16LE(ctx, val->version.len);
+ MARSHAL_BYTES_ZEROCOPY(ctx, val->version.utf8, val->version.len);
return false;
}
-LM_ALWAYS_INLINE static bool marshal_4(struct _marshal_ctx *ctx, uint32_t *val) {
- if (ctx->net_offset + 4 > ctx->ctx->max_msg_size)
+static bool marshal_Rversion(struct _marshal_ctx *ctx, struct lib9p_msg_Rversion *val) {
+ uint32_t needed_size = 13 + val->version.len;
+ if (needed_size > ctx->ctx->max_msg_size) {
+ lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%PRIu32)",
+ "Rversion",
+ ctx->ctx->version ? "negotiated" : "server",
+ ctx->ctx->max_msg_size);
return true;
- uint32le_encode(&ctx->net_bytes[ctx->net_offset], *val);
- ctx->net_offset += 4;
+ }
+ uint32_t offsetof_end = needed_size;
+ uint32_t offsetof_size = 0;
+ MARSHAL_U32LE(ctx, offsetof_end - offsetof_size);
+ MARSHAL_U8LE(ctx, 101);
+ MARSHAL_U16LE(ctx, val->tag);
+ MARSHAL_U32LE(ctx, val->max_msg_size);
+ MARSHAL_U16LE(ctx, val->version.len);
+ MARSHAL_BYTES_ZEROCOPY(ctx, val->version.utf8, val->version.len);
return false;
}
-LM_ALWAYS_INLINE static bool marshal_8(struct _marshal_ctx *ctx, uint64_t *val) {
- if (ctx->net_offset + 8 > ctx->ctx->max_msg_size)
+static bool marshal_Tauth(struct _marshal_ctx *ctx, struct lib9p_msg_Tauth *val) {
+ uint32_t needed_size = 15 + val->uname.len + val->aname.len;
+#if CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_u
+ if ( is_ver(ctx, 9P2000_L) || is_ver(ctx, 9P2000_u) ) {
+ needed_size += 4;
+ }
+#endif /* CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_u */
+ if (needed_size > ctx->ctx->max_msg_size) {
+ lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%PRIu32)",
+ "Tauth",
+ ctx->ctx->version ? "negotiated" : "client",
+ ctx->ctx->max_msg_size);
return true;
- uint64le_encode(&ctx->net_bytes[ctx->net_offset], *val);
- ctx->net_offset += 8;
+ }
+ uint32_t offsetof_end = needed_size;
+ uint32_t offsetof_size = 0;
+ MARSHAL_U32LE(ctx, offsetof_end - offsetof_size);
+ MARSHAL_U8LE(ctx, 102);
+ MARSHAL_U16LE(ctx, val->tag);
+ MARSHAL_U32LE(ctx, val->afid);
+ MARSHAL_U16LE(ctx, val->uname.len);
+ MARSHAL_BYTES_ZEROCOPY(ctx, val->uname.utf8, val->uname.len);
+ MARSHAL_U16LE(ctx, val->aname.len);
+ MARSHAL_BYTES_ZEROCOPY(ctx, val->aname.utf8, val->aname.len);
+#if CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_u
+ if (( is_ver(ctx, 9P2000_L) || is_ver(ctx, 9P2000_u) )) {
+ MARSHAL_U32LE(ctx, val->n_uid);
+ }
+#endif /* CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_u */
return false;
}
-#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u
-LM_ALWAYS_INLINE static bool marshal_tag(struct _marshal_ctx *ctx, lib9p_tag_t *val) {
- return marshal_2(ctx, (uint16_t *)val);
-}
-
-LM_ALWAYS_INLINE static bool marshal_fid(struct _marshal_ctx *ctx, lib9p_fid_t *val) {
- return marshal_4(ctx, (uint32_t *)val);
-}
-
-LM_ALWAYS_INLINE static bool marshal_s(struct _marshal_ctx *ctx, struct lib9p_s *val) {
- return false
- || marshal_2(ctx, &val->len)
- || ({ bool err = false;
- for (typeof(val->len) i = 0; i < val->len && !err; i++)
- err = marshal_1(ctx, (uint8_t *)&val->utf8[i]);
- err; })
- ;
-}
-
-#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */
-#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u
-LM_ALWAYS_INLINE static bool marshal_dm(struct _marshal_ctx *ctx, lib9p_dm_t *val) {
- lib9p_dm_t masked_val = *val & dm_masks[ctx->ctx->version];
- return marshal_4(ctx, (uint32_t *)&masked_val);
-}
-
-#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */
-#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u
-LM_ALWAYS_INLINE static bool marshal_qt(struct _marshal_ctx *ctx, lib9p_qt_t *val) {
- lib9p_qt_t masked_val = *val & qt_masks[ctx->ctx->version];
- return marshal_1(ctx, (uint8_t *)&masked_val);
+static bool marshal_Rauth(struct _marshal_ctx *ctx, struct lib9p_msg_Rauth *val) {
+ uint32_t needed_size = 20;
+ if (needed_size > ctx->ctx->max_msg_size) {
+ lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%PRIu32)",
+ "Rauth",
+ ctx->ctx->version ? "negotiated" : "server",
+ ctx->ctx->max_msg_size);
+ return true;
+ }
+ uint32_t offsetof_end = needed_size;
+ uint32_t offsetof_size = 0;
+ MARSHAL_U32LE(ctx, offsetof_end - offsetof_size);
+ MARSHAL_U8LE(ctx, 103);
+ MARSHAL_U16LE(ctx, val->tag);
+ MARSHAL_U8LE(ctx, val->aqid.type & qt_masks[ctx->ctx->version]);
+ MARSHAL_U32LE(ctx, val->aqid.vers);
+ MARSHAL_U64LE(ctx, val->aqid.path);
+ return false;
}
-#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */
+static bool marshal_Tattach(struct _marshal_ctx *ctx, struct lib9p_msg_Tattach *val) {
+ uint32_t needed_size = 19 + val->uname.len + val->aname.len;
#if CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_u
-LM_ALWAYS_INLINE static bool marshal_nuid(struct _marshal_ctx *ctx, lib9p_nuid_t *val) {
- return marshal_4(ctx, (uint32_t *)val);
-}
-
+ if ( is_ver(ctx, 9P2000_L) || is_ver(ctx, 9P2000_u) ) {
+ needed_size += 4;
+ }
#endif /* CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_u */
-#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u
-LM_ALWAYS_INLINE static bool marshal_o(struct _marshal_ctx *ctx, lib9p_o_t *val) {
- lib9p_o_t masked_val = *val & o_masks[ctx->ctx->version];
- return marshal_1(ctx, (uint8_t *)&masked_val);
-}
-
-#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */
-#if CONFIG_9P_ENABLE_9P2000_L
-LM_ALWAYS_INLINE static bool marshal_getattr(struct _marshal_ctx *ctx, lib9p_getattr_t *val) {
- lib9p_getattr_t masked_val = *val & getattr_masks[ctx->ctx->version];
- return marshal_8(ctx, (uint64_t *)&masked_val);
-}
-
-LM_ALWAYS_INLINE static bool marshal_setattr(struct _marshal_ctx *ctx, lib9p_setattr_t *val) {
- lib9p_setattr_t masked_val = *val & setattr_masks[ctx->ctx->version];
- return marshal_4(ctx, (uint32_t *)&masked_val);
-}
-
-LM_ALWAYS_INLINE static bool marshal_lock_type(struct _marshal_ctx *ctx, lib9p_lock_type_t *val) {
- return marshal_1(ctx, (uint8_t *)val);
-}
-
-LM_ALWAYS_INLINE static bool marshal_lock_flags(struct _marshal_ctx *ctx, lib9p_lock_flags_t *val) {
- lib9p_lock_flags_t masked_val = *val & lock_flags_masks[ctx->ctx->version];
- return marshal_4(ctx, (uint32_t *)&masked_val);
-}
-
-LM_ALWAYS_INLINE static bool marshal_lock_status(struct _marshal_ctx *ctx, lib9p_lock_status_t *val) {
- return marshal_1(ctx, (uint8_t *)val);
+ if (needed_size > ctx->ctx->max_msg_size) {
+ lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%PRIu32)",
+ "Tattach",
+ ctx->ctx->version ? "negotiated" : "client",
+ ctx->ctx->max_msg_size);
+ return true;
+ }
+ uint32_t offsetof_end = needed_size;
+ uint32_t offsetof_size = 0;
+ MARSHAL_U32LE(ctx, offsetof_end - offsetof_size);
+ MARSHAL_U8LE(ctx, 104);
+ MARSHAL_U16LE(ctx, val->tag);
+ MARSHAL_U32LE(ctx, val->fid);
+ MARSHAL_U32LE(ctx, val->afid);
+ MARSHAL_U16LE(ctx, val->uname.len);
+ MARSHAL_BYTES_ZEROCOPY(ctx, val->uname.utf8, val->uname.len);
+ MARSHAL_U16LE(ctx, val->aname.len);
+ MARSHAL_BYTES_ZEROCOPY(ctx, val->aname.utf8, val->aname.len);
+#if CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_u
+ if (( is_ver(ctx, 9P2000_L) || is_ver(ctx, 9P2000_u) )) {
+ MARSHAL_U32LE(ctx, val->n_uid);
+ }
+#endif /* CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_u */
+ return false;
}
-#endif /* CONFIG_9P_ENABLE_9P2000_L */
-#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u
-LM_FLATTEN static bool marshal_Tflush(struct _marshal_ctx *ctx, struct lib9p_msg_Tflush *val) {
- uint32_t _size_offset;
- uint32_t _typ_offset;
- return false
- || ({ _size_offset = ctx->net_offset; ({ ctx->net_offset += 4; false; }); })
- || ({ _typ_offset = ctx->net_offset; ({ ctx->net_offset += 1; false; }); })
- || marshal_tag(ctx, &val->tag)
- || marshal_2(ctx, &val->oldtag)
- || ({ uint32le_encode(&ctx->net_bytes[_size_offset], ctx->net_offset - _size_offset); false; })
- || ({ ctx->net_bytes[_typ_offset] = 108; false; })
- ;
+static bool marshal_Rattach(struct _marshal_ctx *ctx, struct lib9p_msg_Rattach *val) {
+ uint32_t needed_size = 20;
+ if (needed_size > ctx->ctx->max_msg_size) {
+ lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%PRIu32)",
+ "Rattach",
+ ctx->ctx->version ? "negotiated" : "server",
+ ctx->ctx->max_msg_size);
+ return true;
+ }
+ uint32_t offsetof_end = needed_size;
+ uint32_t offsetof_size = 0;
+ MARSHAL_U32LE(ctx, offsetof_end - offsetof_size);
+ MARSHAL_U8LE(ctx, 105);
+ MARSHAL_U16LE(ctx, val->tag);
+ MARSHAL_U8LE(ctx, val->qid.type & qt_masks[ctx->ctx->version]);
+ MARSHAL_U32LE(ctx, val->qid.vers);
+ MARSHAL_U64LE(ctx, val->qid.path);
+ return false;
}
-LM_FLATTEN static bool marshal_Rflush(struct _marshal_ctx *ctx, struct lib9p_msg_Rflush *val) {
- uint32_t _size_offset;
- uint32_t _typ_offset;
- return false
- || ({ _size_offset = ctx->net_offset; ({ ctx->net_offset += 4; false; }); })
- || ({ _typ_offset = ctx->net_offset; ({ ctx->net_offset += 1; false; }); })
- || marshal_tag(ctx, &val->tag)
- || ({ uint32le_encode(&ctx->net_bytes[_size_offset], ctx->net_offset - _size_offset); false; })
- || ({ ctx->net_bytes[_typ_offset] = 109; false; })
- ;
+static bool marshal_Rerror(struct _marshal_ctx *ctx, struct lib9p_msg_Rerror *val) {
+ uint32_t needed_size = 9 + val->ename.len;
+#if CONFIG_9P_ENABLE_9P2000_u
+ if is_ver(ctx, 9P2000_u) {
+ needed_size += 4;
+ }
+#endif /* CONFIG_9P_ENABLE_9P2000_u */
+ if (needed_size > ctx->ctx->max_msg_size) {
+ lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%PRIu32)",
+ "Rerror",
+ ctx->ctx->version ? "negotiated" : "server",
+ ctx->ctx->max_msg_size);
+ return true;
+ }
+ uint32_t offsetof_end = needed_size;
+ uint32_t offsetof_size = 0;
+ MARSHAL_U32LE(ctx, offsetof_end - offsetof_size);
+ MARSHAL_U8LE(ctx, 107);
+ MARSHAL_U16LE(ctx, val->tag);
+ MARSHAL_U16LE(ctx, val->ename.len);
+ MARSHAL_BYTES_ZEROCOPY(ctx, val->ename.utf8, val->ename.len);
+#if CONFIG_9P_ENABLE_9P2000_u
+ if (is_ver(ctx, 9P2000_u)) {
+ MARSHAL_U32LE(ctx, val->errno);
+ }
+#endif /* CONFIG_9P_ENABLE_9P2000_u */
+ return false;
}
-LM_FLATTEN static bool marshal_Rread(struct _marshal_ctx *ctx, struct lib9p_msg_Rread *val) {
- uint32_t _size_offset;
- uint32_t _typ_offset;
- return false
- || ({ _size_offset = ctx->net_offset; ({ ctx->net_offset += 4; false; }); })
- || ({ _typ_offset = ctx->net_offset; ({ ctx->net_offset += 1; false; }); })
- || marshal_tag(ctx, &val->tag)
- || marshal_4(ctx, &val->count)
- || ({ bool err = false;
- for (typeof(val->count) i = 0; i < val->count && !err; i++)
- err = marshal_1(ctx, (uint8_t *)&val->data[i]);
- err; })
- || ({ uint32le_encode(&ctx->net_bytes[_size_offset], ctx->net_offset - _size_offset); false; })
- || ({ ctx->net_bytes[_typ_offset] = 117; false; })
- ;
+static bool marshal_Tflush(struct _marshal_ctx *ctx, struct lib9p_msg_Tflush *val) {
+ uint32_t needed_size = 9;
+ if (needed_size > ctx->ctx->max_msg_size) {
+ lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%PRIu32)",
+ "Tflush",
+ ctx->ctx->version ? "negotiated" : "client",
+ ctx->ctx->max_msg_size);
+ return true;
+ }
+ uint32_t offsetof_end = needed_size;
+ uint32_t offsetof_size = 0;
+ MARSHAL_U32LE(ctx, offsetof_end - offsetof_size);
+ MARSHAL_U8LE(ctx, 108);
+ MARSHAL_U16LE(ctx, val->tag);
+ MARSHAL_U16LE(ctx, val->oldtag);
+ return false;
}
-LM_FLATTEN static bool marshal_Rwrite(struct _marshal_ctx *ctx, struct lib9p_msg_Rwrite *val) {
- uint32_t _size_offset;
- uint32_t _typ_offset;
- return false
- || ({ _size_offset = ctx->net_offset; ({ ctx->net_offset += 4; false; }); })
- || ({ _typ_offset = ctx->net_offset; ({ ctx->net_offset += 1; false; }); })
- || marshal_tag(ctx, &val->tag)
- || marshal_4(ctx, &val->count)
- || ({ uint32le_encode(&ctx->net_bytes[_size_offset], ctx->net_offset - _size_offset); false; })
- || ({ ctx->net_bytes[_typ_offset] = 119; false; })
- ;
+static bool marshal_Rflush(struct _marshal_ctx *ctx, struct lib9p_msg_Rflush *val) {
+ uint32_t needed_size = 7;
+ if (needed_size > ctx->ctx->max_msg_size) {
+ lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%PRIu32)",
+ "Rflush",
+ ctx->ctx->version ? "negotiated" : "server",
+ ctx->ctx->max_msg_size);
+ return true;
+ }
+ uint32_t offsetof_end = needed_size;
+ uint32_t offsetof_size = 0;
+ MARSHAL_U32LE(ctx, offsetof_end - offsetof_size);
+ MARSHAL_U8LE(ctx, 109);
+ MARSHAL_U16LE(ctx, val->tag);
+ return false;
}
-LM_FLATTEN static bool marshal_Rclunk(struct _marshal_ctx *ctx, struct lib9p_msg_Rclunk *val) {
- uint32_t _size_offset;
- uint32_t _typ_offset;
- return false
- || ({ _size_offset = ctx->net_offset; ({ ctx->net_offset += 4; false; }); })
- || ({ _typ_offset = ctx->net_offset; ({ ctx->net_offset += 1; false; }); })
- || marshal_tag(ctx, &val->tag)
- || ({ uint32le_encode(&ctx->net_bytes[_size_offset], ctx->net_offset - _size_offset); false; })
- || ({ ctx->net_bytes[_typ_offset] = 121; false; })
- ;
+static bool marshal_Twalk(struct _marshal_ctx *ctx, struct lib9p_msg_Twalk *val) {
+ uint32_t needed_size = 17;
+ for (uint16_t i = 0; i < val->nwname; i++) {
+ needed_size += 2 + val->wname[i].len;
+ }
+ if (needed_size > ctx->ctx->max_msg_size) {
+ lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%PRIu32)",
+ "Twalk",
+ ctx->ctx->version ? "negotiated" : "client",
+ ctx->ctx->max_msg_size);
+ return true;
+ }
+ uint32_t offsetof_end = needed_size;
+ uint32_t offsetof_size = 0;
+ MARSHAL_U32LE(ctx, offsetof_end - offsetof_size);
+ MARSHAL_U8LE(ctx, 110);
+ MARSHAL_U16LE(ctx, val->tag);
+ MARSHAL_U32LE(ctx, val->fid);
+ MARSHAL_U32LE(ctx, val->newfid);
+ MARSHAL_U16LE(ctx, val->nwname);
+ for (uint16_t i = 0; i < val->nwname; i++) {
+ MARSHAL_U16LE(ctx, val->wname[i].len);
+ MARSHAL_BYTES_ZEROCOPY(ctx, val->wname[i].utf8, val->wname[i].len);
+ }
+ return false;
}
-LM_FLATTEN static bool marshal_Rremove(struct _marshal_ctx *ctx, struct lib9p_msg_Rremove *val) {
- uint32_t _size_offset;
- uint32_t _typ_offset;
- return false
- || ({ _size_offset = ctx->net_offset; ({ ctx->net_offset += 4; false; }); })
- || ({ _typ_offset = ctx->net_offset; ({ ctx->net_offset += 1; false; }); })
- || marshal_tag(ctx, &val->tag)
- || ({ uint32le_encode(&ctx->net_bytes[_size_offset], ctx->net_offset - _size_offset); false; })
- || ({ ctx->net_bytes[_typ_offset] = 123; false; })
- ;
+static bool marshal_Rwalk(struct _marshal_ctx *ctx, struct lib9p_msg_Rwalk *val) {
+ uint32_t needed_size = 9 + (val->nwqid)*13;
+ if (needed_size > ctx->ctx->max_msg_size) {
+ lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%PRIu32)",
+ "Rwalk",
+ ctx->ctx->version ? "negotiated" : "server",
+ ctx->ctx->max_msg_size);
+ return true;
+ }
+ uint32_t offsetof_end = needed_size;
+ uint32_t offsetof_size = 0;
+ MARSHAL_U32LE(ctx, offsetof_end - offsetof_size);
+ MARSHAL_U8LE(ctx, 111);
+ MARSHAL_U16LE(ctx, val->tag);
+ MARSHAL_U16LE(ctx, val->nwqid);
+ for (uint16_t i = 0; i < val->nwqid; i++) {
+ MARSHAL_U8LE(ctx, val->wqid[i].type & qt_masks[ctx->ctx->version]);
+ MARSHAL_U32LE(ctx, val->wqid[i].vers);
+ MARSHAL_U64LE(ctx, val->wqid[i].path);
+ }
+ return false;
}
#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */
#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u
-LM_FLATTEN static bool marshal_Rwstat(struct _marshal_ctx *ctx, struct lib9p_msg_Rwstat *val) {
- uint32_t _size_offset;
- uint32_t _typ_offset;
- return false
- || ({ _size_offset = ctx->net_offset; ({ ctx->net_offset += 4; false; }); })
- || ({ _typ_offset = ctx->net_offset; ({ ctx->net_offset += 1; false; }); })
- || marshal_tag(ctx, &val->tag)
- || ({ uint32le_encode(&ctx->net_bytes[_size_offset], ctx->net_offset - _size_offset); false; })
- || ({ ctx->net_bytes[_typ_offset] = 127; false; })
- ;
-}
-
-#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */
-#if CONFIG_9P_ENABLE_9P2000_L
-LM_FLATTEN static bool marshal_Rlerror(struct _marshal_ctx *ctx, struct lib9p_msg_Rlerror *val) {
- uint32_t _size_offset;
- uint32_t _typ_offset;
- return false
- || ({ _size_offset = ctx->net_offset; ({ ctx->net_offset += 4; false; }); })
- || ({ _typ_offset = ctx->net_offset; ({ ctx->net_offset += 1; false; }); })
- || marshal_tag(ctx, &val->tag)
- || marshal_4(ctx, &val->ecode)
- || ({ uint32le_encode(&ctx->net_bytes[_size_offset], ctx->net_offset - _size_offset); false; })
- || ({ ctx->net_bytes[_typ_offset] = 7; false; })
- ;
-}
-
-LM_FLATTEN static bool marshal_Rstatfs(struct _marshal_ctx *ctx, struct lib9p_msg_Rstatfs *val) {
- uint32_t _size_offset;
- uint32_t _typ_offset;
- return false
- || ({ _size_offset = ctx->net_offset; ({ ctx->net_offset += 4; false; }); })
- || ({ _typ_offset = ctx->net_offset; ({ ctx->net_offset += 1; false; }); })
- || marshal_tag(ctx, &val->tag)
- || marshal_4(ctx, &val->type)
- || marshal_4(ctx, &val->bsize)
- || marshal_8(ctx, &val->blocks)
- || marshal_8(ctx, &val->bfree)
- || marshal_8(ctx, &val->bavail)
- || marshal_8(ctx, &val->files)
- || marshal_8(ctx, &val->ffree)
- || marshal_8(ctx, &val->fsid)
- || marshal_4(ctx, &val->namelen)
- || ({ uint32le_encode(&ctx->net_bytes[_size_offset], ctx->net_offset - _size_offset); false; })
- || ({ ctx->net_bytes[_typ_offset] = 9; false; })
- ;
-}
-
-LM_FLATTEN static bool marshal_Rrename(struct _marshal_ctx *ctx, struct lib9p_msg_Rrename *val) {
- uint32_t _size_offset;
- uint32_t _typ_offset;
- return false
- || ({ _size_offset = ctx->net_offset; ({ ctx->net_offset += 4; false; }); })
- || ({ _typ_offset = ctx->net_offset; ({ ctx->net_offset += 1; false; }); })
- || marshal_tag(ctx, &val->tag)
- || ({ uint32le_encode(&ctx->net_bytes[_size_offset], ctx->net_offset - _size_offset); false; })
- || ({ ctx->net_bytes[_typ_offset] = 21; false; })
- ;
+static bool marshal_Topen(struct _marshal_ctx *ctx, struct lib9p_msg_Topen *val) {
+ uint32_t needed_size = 12;
+ if (needed_size > ctx->ctx->max_msg_size) {
+ lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%PRIu32)",
+ "Topen",
+ ctx->ctx->version ? "negotiated" : "client",
+ ctx->ctx->max_msg_size);
+ return true;
+ }
+ uint32_t offsetof_end = needed_size;
+ uint32_t offsetof_size = 0;
+ MARSHAL_U32LE(ctx, offsetof_end - offsetof_size);
+ MARSHAL_U8LE(ctx, 112);
+ MARSHAL_U16LE(ctx, val->tag);
+ MARSHAL_U32LE(ctx, val->fid);
+ MARSHAL_U8LE(ctx, val->mode & o_masks[ctx->ctx->version]);
+ return false;
}
-LM_FLATTEN static bool marshal_Rsetattr(struct _marshal_ctx *ctx, struct lib9p_msg_Rsetattr *val) {
- uint32_t _size_offset;
- uint32_t _typ_offset;
- return false
- || ({ _size_offset = ctx->net_offset; ({ ctx->net_offset += 4; false; }); })
- || ({ _typ_offset = ctx->net_offset; ({ ctx->net_offset += 1; false; }); })
- || marshal_tag(ctx, &val->tag)
- || ({ uint32le_encode(&ctx->net_bytes[_size_offset], ctx->net_offset - _size_offset); false; })
- || ({ ctx->net_bytes[_typ_offset] = 27; false; })
- ;
+static bool marshal_Ropen(struct _marshal_ctx *ctx, struct lib9p_msg_Ropen *val) {
+ uint32_t needed_size = 24;
+ if (needed_size > ctx->ctx->max_msg_size) {
+ lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%PRIu32)",
+ "Ropen",
+ ctx->ctx->version ? "negotiated" : "server",
+ ctx->ctx->max_msg_size);
+ return true;
+ }
+ uint32_t offsetof_end = needed_size;
+ uint32_t offsetof_size = 0;
+ MARSHAL_U32LE(ctx, offsetof_end - offsetof_size);
+ MARSHAL_U8LE(ctx, 113);
+ MARSHAL_U16LE(ctx, val->tag);
+ MARSHAL_U8LE(ctx, val->qid.type & qt_masks[ctx->ctx->version]);
+ MARSHAL_U32LE(ctx, val->qid.vers);
+ MARSHAL_U64LE(ctx, val->qid.path);
+ MARSHAL_U32LE(ctx, val->iounit);
+ return false;
}
-LM_FLATTEN static bool marshal_Rxattrwalk(struct _marshal_ctx *ctx, struct lib9p_msg_Rxattrwalk *val) {
- uint32_t _size_offset;
- uint32_t _typ_offset;
- return false
- || ({ _size_offset = ctx->net_offset; ({ ctx->net_offset += 4; false; }); })
- || ({ _typ_offset = ctx->net_offset; ({ ctx->net_offset += 1; false; }); })
- || marshal_tag(ctx, &val->tag)
- || marshal_8(ctx, &val->attr_size)
- || ({ uint32le_encode(&ctx->net_bytes[_size_offset], ctx->net_offset - _size_offset); false; })
- || ({ ctx->net_bytes[_typ_offset] = 31; false; })
- ;
+static bool marshal_Tcreate(struct _marshal_ctx *ctx, struct lib9p_msg_Tcreate *val) {
+ uint32_t needed_size = 18 + val->name.len;
+ if (needed_size > ctx->ctx->max_msg_size) {
+ lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%PRIu32)",
+ "Tcreate",
+ ctx->ctx->version ? "negotiated" : "client",
+ ctx->ctx->max_msg_size);
+ return true;
+ }
+ uint32_t offsetof_end = needed_size;
+ uint32_t offsetof_size = 0;
+ MARSHAL_U32LE(ctx, offsetof_end - offsetof_size);
+ MARSHAL_U8LE(ctx, 114);
+ MARSHAL_U16LE(ctx, val->tag);
+ MARSHAL_U32LE(ctx, val->fid);
+ MARSHAL_U16LE(ctx, val->name.len);
+ MARSHAL_BYTES_ZEROCOPY(ctx, val->name.utf8, val->name.len);
+ MARSHAL_U32LE(ctx, val->perm & dm_masks[ctx->ctx->version]);
+ MARSHAL_U8LE(ctx, val->mode & o_masks[ctx->ctx->version]);
+ return false;
}
-LM_FLATTEN static bool marshal_Rxattrcreate(struct _marshal_ctx *ctx, struct lib9p_msg_Rxattrcreate *val) {
- uint32_t _size_offset;
- uint32_t _typ_offset;
- return false
- || ({ _size_offset = ctx->net_offset; ({ ctx->net_offset += 4; false; }); })
- || ({ _typ_offset = ctx->net_offset; ({ ctx->net_offset += 1; false; }); })
- || marshal_tag(ctx, &val->tag)
- || ({ uint32le_encode(&ctx->net_bytes[_size_offset], ctx->net_offset - _size_offset); false; })
- || ({ ctx->net_bytes[_typ_offset] = 33; false; })
- ;
+static bool marshal_Rcreate(struct _marshal_ctx *ctx, struct lib9p_msg_Rcreate *val) {
+ uint32_t needed_size = 24;
+ if (needed_size > ctx->ctx->max_msg_size) {
+ lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%PRIu32)",
+ "Rcreate",
+ ctx->ctx->version ? "negotiated" : "server",
+ ctx->ctx->max_msg_size);
+ return true;
+ }
+ uint32_t offsetof_end = needed_size;
+ uint32_t offsetof_size = 0;
+ MARSHAL_U32LE(ctx, offsetof_end - offsetof_size);
+ MARSHAL_U8LE(ctx, 115);
+ MARSHAL_U16LE(ctx, val->tag);
+ MARSHAL_U8LE(ctx, val->qid.type & qt_masks[ctx->ctx->version]);
+ MARSHAL_U32LE(ctx, val->qid.vers);
+ MARSHAL_U64LE(ctx, val->qid.path);
+ MARSHAL_U32LE(ctx, val->iounit);
+ return false;
}
-LM_FLATTEN static bool marshal_Rreaddir(struct _marshal_ctx *ctx, struct lib9p_msg_Rreaddir *val) {
- uint32_t _size_offset;
- uint32_t _typ_offset;
- return false
- || ({ _size_offset = ctx->net_offset; ({ ctx->net_offset += 4; false; }); })
- || ({ _typ_offset = ctx->net_offset; ({ ctx->net_offset += 1; false; }); })
- || marshal_tag(ctx, &val->tag)
- || marshal_4(ctx, &val->count)
- || ({ bool err = false;
- for (typeof(val->count) i = 0; i < val->count && !err; i++)
- err = marshal_1(ctx, (uint8_t *)&val->data[i]);
- err; })
- || ({ uint32le_encode(&ctx->net_bytes[_size_offset], ctx->net_offset - _size_offset); false; })
- || ({ ctx->net_bytes[_typ_offset] = 41; false; })
- ;
+#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */
+#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u
+static bool marshal_Tread(struct _marshal_ctx *ctx, struct lib9p_msg_Tread *val) {
+ uint32_t needed_size = 23;
+ if (needed_size > ctx->ctx->max_msg_size) {
+ lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%PRIu32)",
+ "Tread",
+ ctx->ctx->version ? "negotiated" : "client",
+ ctx->ctx->max_msg_size);
+ return true;
+ }
+ uint32_t offsetof_end = needed_size;
+ uint32_t offsetof_size = 0;
+ MARSHAL_U32LE(ctx, offsetof_end - offsetof_size);
+ MARSHAL_U8LE(ctx, 116);
+ MARSHAL_U16LE(ctx, val->tag);
+ MARSHAL_U32LE(ctx, val->fid);
+ MARSHAL_U64LE(ctx, val->offset);
+ MARSHAL_U32LE(ctx, val->count);
+ return false;
}
-LM_FLATTEN static bool marshal_Rfsync(struct _marshal_ctx *ctx, struct lib9p_msg_Rfsync *val) {
- uint32_t _size_offset;
- uint32_t _typ_offset;
- return false
- || ({ _size_offset = ctx->net_offset; ({ ctx->net_offset += 4; false; }); })
- || ({ _typ_offset = ctx->net_offset; ({ ctx->net_offset += 1; false; }); })
- || marshal_tag(ctx, &val->tag)
- || ({ uint32le_encode(&ctx->net_bytes[_size_offset], ctx->net_offset - _size_offset); false; })
- || ({ ctx->net_bytes[_typ_offset] = 51; false; })
- ;
+static bool marshal_Rread(struct _marshal_ctx *ctx, struct lib9p_msg_Rread *val) {
+ uint32_t needed_size = 11 + val->count;
+ if (needed_size > ctx->ctx->max_msg_size) {
+ lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%PRIu32)",
+ "Rread",
+ ctx->ctx->version ? "negotiated" : "server",
+ ctx->ctx->max_msg_size);
+ return true;
+ }
+ uint32_t offsetof_end = needed_size;
+ uint32_t offsetof_size = 0;
+ MARSHAL_U32LE(ctx, offsetof_end - offsetof_size);
+ MARSHAL_U8LE(ctx, 117);
+ MARSHAL_U16LE(ctx, val->tag);
+ MARSHAL_U32LE(ctx, val->count);
+ MARSHAL_BYTES_ZEROCOPY(ctx, val->data, val->count);
+ return false;
}
-LM_FLATTEN static bool marshal_Rlink(struct _marshal_ctx *ctx, struct lib9p_msg_Rlink *val) {
- uint32_t _size_offset;
- uint32_t _typ_offset;
- return false
- || ({ _size_offset = ctx->net_offset; ({ ctx->net_offset += 4; false; }); })
- || ({ _typ_offset = ctx->net_offset; ({ ctx->net_offset += 1; false; }); })
- || marshal_tag(ctx, &val->tag)
- || ({ uint32le_encode(&ctx->net_bytes[_size_offset], ctx->net_offset - _size_offset); false; })
- || ({ ctx->net_bytes[_typ_offset] = 71; false; })
- ;
+static bool marshal_Twrite(struct _marshal_ctx *ctx, struct lib9p_msg_Twrite *val) {
+ uint32_t needed_size = 23 + val->count;
+ if (needed_size > ctx->ctx->max_msg_size) {
+ lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%PRIu32)",
+ "Twrite",
+ ctx->ctx->version ? "negotiated" : "client",
+ ctx->ctx->max_msg_size);
+ return true;
+ }
+ uint32_t offsetof_end = needed_size;
+ uint32_t offsetof_size = 0;
+ MARSHAL_U32LE(ctx, offsetof_end - offsetof_size);
+ MARSHAL_U8LE(ctx, 118);
+ MARSHAL_U16LE(ctx, val->tag);
+ MARSHAL_U32LE(ctx, val->fid);
+ MARSHAL_U64LE(ctx, val->offset);
+ MARSHAL_U32LE(ctx, val->count);
+ MARSHAL_BYTES_ZEROCOPY(ctx, val->data, val->count);
+ return false;
}
-LM_FLATTEN static bool marshal_Rrenameat(struct _marshal_ctx *ctx, struct lib9p_msg_Rrenameat *val) {
- uint32_t _size_offset;
- uint32_t _typ_offset;
- return false
- || ({ _size_offset = ctx->net_offset; ({ ctx->net_offset += 4; false; }); })
- || ({ _typ_offset = ctx->net_offset; ({ ctx->net_offset += 1; false; }); })
- || marshal_tag(ctx, &val->tag)
- || ({ uint32le_encode(&ctx->net_bytes[_size_offset], ctx->net_offset - _size_offset); false; })
- || ({ ctx->net_bytes[_typ_offset] = 75; false; })
- ;
+static bool marshal_Rwrite(struct _marshal_ctx *ctx, struct lib9p_msg_Rwrite *val) {
+ uint32_t needed_size = 11;
+ if (needed_size > ctx->ctx->max_msg_size) {
+ lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%PRIu32)",
+ "Rwrite",
+ ctx->ctx->version ? "negotiated" : "server",
+ ctx->ctx->max_msg_size);
+ return true;
+ }
+ uint32_t offsetof_end = needed_size;
+ uint32_t offsetof_size = 0;
+ MARSHAL_U32LE(ctx, offsetof_end - offsetof_size);
+ MARSHAL_U8LE(ctx, 119);
+ MARSHAL_U16LE(ctx, val->tag);
+ MARSHAL_U32LE(ctx, val->count);
+ return false;
}
-LM_FLATTEN static bool marshal_Runlinkat(struct _marshal_ctx *ctx, struct lib9p_msg_Runlinkat *val) {
- uint32_t _size_offset;
- uint32_t _typ_offset;
- return false
- || ({ _size_offset = ctx->net_offset; ({ ctx->net_offset += 4; false; }); })
- || ({ _typ_offset = ctx->net_offset; ({ ctx->net_offset += 1; false; }); })
- || marshal_tag(ctx, &val->tag)
- || ({ uint32le_encode(&ctx->net_bytes[_size_offset], ctx->net_offset - _size_offset); false; })
- || ({ ctx->net_bytes[_typ_offset] = 77; false; })
- ;
+static bool marshal_Tclunk(struct _marshal_ctx *ctx, struct lib9p_msg_Tclunk *val) {
+ uint32_t needed_size = 11;
+ if (needed_size > ctx->ctx->max_msg_size) {
+ lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%PRIu32)",
+ "Tclunk",
+ ctx->ctx->version ? "negotiated" : "client",
+ ctx->ctx->max_msg_size);
+ return true;
+ }
+ uint32_t offsetof_end = needed_size;
+ uint32_t offsetof_size = 0;
+ MARSHAL_U32LE(ctx, offsetof_end - offsetof_size);
+ MARSHAL_U8LE(ctx, 120);
+ MARSHAL_U16LE(ctx, val->tag);
+ MARSHAL_U32LE(ctx, val->fid);
+ return false;
}
-#endif /* CONFIG_9P_ENABLE_9P2000_L */
-#if CONFIG_9P_ENABLE_9P2000_e
-LM_FLATTEN static bool marshal_Tsession(struct _marshal_ctx *ctx, struct lib9p_msg_Tsession *val) {
- uint32_t _size_offset;
- uint32_t _typ_offset;
- return false
- || ({ _size_offset = ctx->net_offset; ({ ctx->net_offset += 4; false; }); })
- || ({ _typ_offset = ctx->net_offset; ({ ctx->net_offset += 1; false; }); })
- || marshal_tag(ctx, &val->tag)
- || marshal_8(ctx, &val->key)
- || ({ uint32le_encode(&ctx->net_bytes[_size_offset], ctx->net_offset - _size_offset); false; })
- || ({ ctx->net_bytes[_typ_offset] = 150; false; })
- ;
+static bool marshal_Rclunk(struct _marshal_ctx *ctx, struct lib9p_msg_Rclunk *val) {
+ uint32_t needed_size = 7;
+ if (needed_size > ctx->ctx->max_msg_size) {
+ lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%PRIu32)",
+ "Rclunk",
+ ctx->ctx->version ? "negotiated" : "server",
+ ctx->ctx->max_msg_size);
+ return true;
+ }
+ uint32_t offsetof_end = needed_size;
+ uint32_t offsetof_size = 0;
+ MARSHAL_U32LE(ctx, offsetof_end - offsetof_size);
+ MARSHAL_U8LE(ctx, 121);
+ MARSHAL_U16LE(ctx, val->tag);
+ return false;
}
-LM_FLATTEN static bool marshal_Rsession(struct _marshal_ctx *ctx, struct lib9p_msg_Rsession *val) {
- uint32_t _size_offset;
- uint32_t _typ_offset;
- return false
- || ({ _size_offset = ctx->net_offset; ({ ctx->net_offset += 4; false; }); })
- || ({ _typ_offset = ctx->net_offset; ({ ctx->net_offset += 1; false; }); })
- || marshal_tag(ctx, &val->tag)
- || ({ uint32le_encode(&ctx->net_bytes[_size_offset], ctx->net_offset - _size_offset); false; })
- || ({ ctx->net_bytes[_typ_offset] = 151; false; })
- ;
+static bool marshal_Tremove(struct _marshal_ctx *ctx, struct lib9p_msg_Tremove *val) {
+ uint32_t needed_size = 11;
+ if (needed_size > ctx->ctx->max_msg_size) {
+ lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%PRIu32)",
+ "Tremove",
+ ctx->ctx->version ? "negotiated" : "client",
+ ctx->ctx->max_msg_size);
+ return true;
+ }
+ uint32_t offsetof_end = needed_size;
+ uint32_t offsetof_size = 0;
+ MARSHAL_U32LE(ctx, offsetof_end - offsetof_size);
+ MARSHAL_U8LE(ctx, 122);
+ MARSHAL_U16LE(ctx, val->tag);
+ MARSHAL_U32LE(ctx, val->fid);
+ return false;
}
-LM_FLATTEN static bool marshal_Rsread(struct _marshal_ctx *ctx, struct lib9p_msg_Rsread *val) {
- uint32_t _size_offset;
- uint32_t _typ_offset;
- return false
- || ({ _size_offset = ctx->net_offset; ({ ctx->net_offset += 4; false; }); })
- || ({ _typ_offset = ctx->net_offset; ({ ctx->net_offset += 1; false; }); })
- || marshal_tag(ctx, &val->tag)
- || marshal_4(ctx, &val->count)
- || ({ bool err = false;
- for (typeof(val->count) i = 0; i < val->count && !err; i++)
- err = marshal_1(ctx, (uint8_t *)&val->data[i]);
- err; })
- || ({ uint32le_encode(&ctx->net_bytes[_size_offset], ctx->net_offset - _size_offset); false; })
- || ({ ctx->net_bytes[_typ_offset] = 153; false; })
- ;
+static bool marshal_Rremove(struct _marshal_ctx *ctx, struct lib9p_msg_Rremove *val) {
+ uint32_t needed_size = 7;
+ if (needed_size > ctx->ctx->max_msg_size) {
+ lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%PRIu32)",
+ "Rremove",
+ ctx->ctx->version ? "negotiated" : "server",
+ ctx->ctx->max_msg_size);
+ return true;
+ }
+ uint32_t offsetof_end = needed_size;
+ uint32_t offsetof_size = 0;
+ MARSHAL_U32LE(ctx, offsetof_end - offsetof_size);
+ MARSHAL_U8LE(ctx, 123);
+ MARSHAL_U16LE(ctx, val->tag);
+ return false;
}
-LM_FLATTEN static bool marshal_Rswrite(struct _marshal_ctx *ctx, struct lib9p_msg_Rswrite *val) {
- uint32_t _size_offset;
- uint32_t _typ_offset;
- return false
- || ({ _size_offset = ctx->net_offset; ({ ctx->net_offset += 4; false; }); })
- || ({ _typ_offset = ctx->net_offset; ({ ctx->net_offset += 1; false; }); })
- || marshal_tag(ctx, &val->tag)
- || marshal_4(ctx, &val->count)
- || ({ uint32le_encode(&ctx->net_bytes[_size_offset], ctx->net_offset - _size_offset); false; })
- || ({ ctx->net_bytes[_typ_offset] = 155; false; })
- ;
+#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */
+#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u
+static bool marshal_Tstat(struct _marshal_ctx *ctx, struct lib9p_msg_Tstat *val) {
+ uint32_t needed_size = 11;
+ if (needed_size > ctx->ctx->max_msg_size) {
+ lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%PRIu32)",
+ "Tstat",
+ ctx->ctx->version ? "negotiated" : "client",
+ ctx->ctx->max_msg_size);
+ return true;
+ }
+ uint32_t offsetof_end = needed_size;
+ uint32_t offsetof_size = 0;
+ MARSHAL_U32LE(ctx, offsetof_end - offsetof_size);
+ MARSHAL_U8LE(ctx, 124);
+ MARSHAL_U16LE(ctx, val->tag);
+ MARSHAL_U32LE(ctx, val->fid);
+ return false;
}
-#endif /* CONFIG_9P_ENABLE_9P2000_e */
-#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u
-LM_FLATTEN static bool marshal_Tread(struct _marshal_ctx *ctx, struct lib9p_msg_Tread *val) {
- uint32_t _size_offset;
- uint32_t _typ_offset;
- return false
- || ({ _size_offset = ctx->net_offset; ({ ctx->net_offset += 4; false; }); })
- || ({ _typ_offset = ctx->net_offset; ({ ctx->net_offset += 1; false; }); })
- || marshal_tag(ctx, &val->tag)
- || marshal_fid(ctx, &val->fid)
- || marshal_8(ctx, &val->offset)
- || marshal_4(ctx, &val->count)
- || ({ uint32le_encode(&ctx->net_bytes[_size_offset], ctx->net_offset - _size_offset); false; })
- || ({ ctx->net_bytes[_typ_offset] = 116; false; })
- ;
+static bool marshal_Rstat(struct _marshal_ctx *ctx, struct lib9p_msg_Rstat *val) {
+ uint32_t needed_size = 58 + val->stat.file_name.len + val->stat.file_owner_uid.len + val->stat.file_owner_gid.len + val->stat.file_last_modified_uid.len;
+#if CONFIG_9P_ENABLE_9P2000_u
+ if is_ver(ctx, 9P2000_u) {
+ needed_size += 14 + val->stat.file_extension.len;
+ }
+#endif /* CONFIG_9P_ENABLE_9P2000_u */
+ if (needed_size > ctx->ctx->max_msg_size) {
+ lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%PRIu32)",
+ "Rstat",
+ ctx->ctx->version ? "negotiated" : "server",
+ ctx->ctx->max_msg_size);
+ return true;
+ }
+ uint32_t offsetof_end = needed_size;
+ uint32_t offsetof_size = 0;
+ uint32_t offsetof_stat = 9;
+ MARSHAL_U32LE(ctx, offsetof_end - offsetof_size);
+ MARSHAL_U8LE(ctx, 125);
+ MARSHAL_U16LE(ctx, val->tag);
+ MARSHAL_U16LE(ctx, offsetof_end - offsetof_stat);
+ uint32_t offsetof_stat_end = 49 + val->stat.file_name.len + val->stat.file_owner_uid.len + val->stat.file_owner_gid.len + val->stat.file_last_modified_uid.len;
+#if CONFIG_9P_ENABLE_9P2000_u
+ if is_ver(ctx, 9P2000_u) {
+ offsetof_stat_end += 14 + val->stat.file_extension.len;
+ }
+#endif /* CONFIG_9P_ENABLE_9P2000_u */
+ uint32_t offsetof_stat_kern_type = 2;
+ MARSHAL_U16LE(ctx, offsetof_stat_end - offsetof_stat_kern_type);
+ MARSHAL_U16LE(ctx, val->stat.kern_type);
+ MARSHAL_U32LE(ctx, val->stat.kern_dev);
+ MARSHAL_U8LE(ctx, val->stat.file_qid.type & qt_masks[ctx->ctx->version]);
+ MARSHAL_U32LE(ctx, val->stat.file_qid.vers);
+ MARSHAL_U64LE(ctx, val->stat.file_qid.path);
+ MARSHAL_U32LE(ctx, val->stat.file_mode & dm_masks[ctx->ctx->version]);
+ MARSHAL_U32LE(ctx, val->stat.file_atime);
+ MARSHAL_U32LE(ctx, val->stat.file_mtime);
+ MARSHAL_U64LE(ctx, val->stat.file_size);
+ MARSHAL_U16LE(ctx, val->stat.file_name.len);
+ MARSHAL_BYTES_ZEROCOPY(ctx, val->stat.file_name.utf8, val->stat.file_name.len);
+ MARSHAL_U16LE(ctx, val->stat.file_owner_uid.len);
+ MARSHAL_BYTES_ZEROCOPY(ctx, val->stat.file_owner_uid.utf8, val->stat.file_owner_uid.len);
+ MARSHAL_U16LE(ctx, val->stat.file_owner_gid.len);
+ MARSHAL_BYTES_ZEROCOPY(ctx, val->stat.file_owner_gid.utf8, val->stat.file_owner_gid.len);
+ MARSHAL_U16LE(ctx, val->stat.file_last_modified_uid.len);
+ MARSHAL_BYTES_ZEROCOPY(ctx, val->stat.file_last_modified_uid.utf8, val->stat.file_last_modified_uid.len);
+#if CONFIG_9P_ENABLE_9P2000_u
+ if (is_ver(ctx, 9P2000_u)) {
+ MARSHAL_U16LE(ctx, val->stat.file_extension.len);
+ MARSHAL_BYTES_ZEROCOPY(ctx, val->stat.file_extension.utf8, val->stat.file_extension.len);
+ }
+#endif /* CONFIG_9P_ENABLE_9P2000_u */
+#if CONFIG_9P_ENABLE_9P2000_u
+ if (is_ver(ctx, 9P2000_u)) {
+ MARSHAL_U32LE(ctx, val->stat.file_owner_n_uid);
+ }
+#endif /* CONFIG_9P_ENABLE_9P2000_u */
+#if CONFIG_9P_ENABLE_9P2000_u
+ if (is_ver(ctx, 9P2000_u)) {
+ MARSHAL_U32LE(ctx, val->stat.file_owner_n_gid);
+ }
+#endif /* CONFIG_9P_ENABLE_9P2000_u */
+#if CONFIG_9P_ENABLE_9P2000_u
+ if (is_ver(ctx, 9P2000_u)) {
+ MARSHAL_U32LE(ctx, val->stat.file_last_modified_n_uid);
+ }
+#endif /* CONFIG_9P_ENABLE_9P2000_u */
+ return false;
}
-LM_FLATTEN static bool marshal_Twrite(struct _marshal_ctx *ctx, struct lib9p_msg_Twrite *val) {
- uint32_t _size_offset;
- uint32_t _typ_offset;
- return false
- || ({ _size_offset = ctx->net_offset; ({ ctx->net_offset += 4; false; }); })
- || ({ _typ_offset = ctx->net_offset; ({ ctx->net_offset += 1; false; }); })
- || marshal_tag(ctx, &val->tag)
- || marshal_fid(ctx, &val->fid)
- || marshal_8(ctx, &val->offset)
- || marshal_4(ctx, &val->count)
- || ({ bool err = false;
- for (typeof(val->count) i = 0; i < val->count && !err; i++)
- err = marshal_1(ctx, (uint8_t *)&val->data[i]);
- err; })
- || ({ uint32le_encode(&ctx->net_bytes[_size_offset], ctx->net_offset - _size_offset); false; })
- || ({ ctx->net_bytes[_typ_offset] = 118; false; })
- ;
+static bool marshal_Twstat(struct _marshal_ctx *ctx, struct lib9p_msg_Twstat *val) {
+ uint32_t needed_size = 62 + val->stat.file_name.len + val->stat.file_owner_uid.len + val->stat.file_owner_gid.len + val->stat.file_last_modified_uid.len;
+#if CONFIG_9P_ENABLE_9P2000_u
+ if is_ver(ctx, 9P2000_u) {
+ needed_size += 14 + val->stat.file_extension.len;
+ }
+#endif /* CONFIG_9P_ENABLE_9P2000_u */
+ if (needed_size > ctx->ctx->max_msg_size) {
+ lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%PRIu32)",
+ "Twstat",
+ ctx->ctx->version ? "negotiated" : "client",
+ ctx->ctx->max_msg_size);
+ return true;
+ }
+ uint32_t offsetof_end = needed_size;
+ uint32_t offsetof_size = 0;
+ uint32_t offsetof_stat = 13;
+ MARSHAL_U32LE(ctx, offsetof_end - offsetof_size);
+ MARSHAL_U8LE(ctx, 126);
+ MARSHAL_U16LE(ctx, val->tag);
+ MARSHAL_U32LE(ctx, val->fid);
+ MARSHAL_U16LE(ctx, offsetof_end - offsetof_stat);
+ uint32_t offsetof_stat_end = 49 + val->stat.file_name.len + val->stat.file_owner_uid.len + val->stat.file_owner_gid.len + val->stat.file_last_modified_uid.len;
+#if CONFIG_9P_ENABLE_9P2000_u
+ if is_ver(ctx, 9P2000_u) {
+ offsetof_stat_end += 14 + val->stat.file_extension.len;
+ }
+#endif /* CONFIG_9P_ENABLE_9P2000_u */
+ uint32_t offsetof_stat_kern_type = 2;
+ MARSHAL_U16LE(ctx, offsetof_stat_end - offsetof_stat_kern_type);
+ MARSHAL_U16LE(ctx, val->stat.kern_type);
+ MARSHAL_U32LE(ctx, val->stat.kern_dev);
+ MARSHAL_U8LE(ctx, val->stat.file_qid.type & qt_masks[ctx->ctx->version]);
+ MARSHAL_U32LE(ctx, val->stat.file_qid.vers);
+ MARSHAL_U64LE(ctx, val->stat.file_qid.path);
+ MARSHAL_U32LE(ctx, val->stat.file_mode & dm_masks[ctx->ctx->version]);
+ MARSHAL_U32LE(ctx, val->stat.file_atime);
+ MARSHAL_U32LE(ctx, val->stat.file_mtime);
+ MARSHAL_U64LE(ctx, val->stat.file_size);
+ MARSHAL_U16LE(ctx, val->stat.file_name.len);
+ MARSHAL_BYTES_ZEROCOPY(ctx, val->stat.file_name.utf8, val->stat.file_name.len);
+ MARSHAL_U16LE(ctx, val->stat.file_owner_uid.len);
+ MARSHAL_BYTES_ZEROCOPY(ctx, val->stat.file_owner_uid.utf8, val->stat.file_owner_uid.len);
+ MARSHAL_U16LE(ctx, val->stat.file_owner_gid.len);
+ MARSHAL_BYTES_ZEROCOPY(ctx, val->stat.file_owner_gid.utf8, val->stat.file_owner_gid.len);
+ MARSHAL_U16LE(ctx, val->stat.file_last_modified_uid.len);
+ MARSHAL_BYTES_ZEROCOPY(ctx, val->stat.file_last_modified_uid.utf8, val->stat.file_last_modified_uid.len);
+#if CONFIG_9P_ENABLE_9P2000_u
+ if (is_ver(ctx, 9P2000_u)) {
+ MARSHAL_U16LE(ctx, val->stat.file_extension.len);
+ MARSHAL_BYTES_ZEROCOPY(ctx, val->stat.file_extension.utf8, val->stat.file_extension.len);
+ }
+#endif /* CONFIG_9P_ENABLE_9P2000_u */
+#if CONFIG_9P_ENABLE_9P2000_u
+ if (is_ver(ctx, 9P2000_u)) {
+ MARSHAL_U32LE(ctx, val->stat.file_owner_n_uid);
+ }
+#endif /* CONFIG_9P_ENABLE_9P2000_u */
+#if CONFIG_9P_ENABLE_9P2000_u
+ if (is_ver(ctx, 9P2000_u)) {
+ MARSHAL_U32LE(ctx, val->stat.file_owner_n_gid);
+ }
+#endif /* CONFIG_9P_ENABLE_9P2000_u */
+#if CONFIG_9P_ENABLE_9P2000_u
+ if (is_ver(ctx, 9P2000_u)) {
+ MARSHAL_U32LE(ctx, val->stat.file_last_modified_n_uid);
+ }
+#endif /* CONFIG_9P_ENABLE_9P2000_u */
+ return false;
}
-LM_FLATTEN static bool marshal_Tclunk(struct _marshal_ctx *ctx, struct lib9p_msg_Tclunk *val) {
- uint32_t _size_offset;
- uint32_t _typ_offset;
- return false
- || ({ _size_offset = ctx->net_offset; ({ ctx->net_offset += 4; false; }); })
- || ({ _typ_offset = ctx->net_offset; ({ ctx->net_offset += 1; false; }); })
- || marshal_tag(ctx, &val->tag)
- || marshal_fid(ctx, &val->fid)
- || ({ uint32le_encode(&ctx->net_bytes[_size_offset], ctx->net_offset - _size_offset); false; })
- || ({ ctx->net_bytes[_typ_offset] = 120; false; })
- ;
+static bool marshal_Rwstat(struct _marshal_ctx *ctx, struct lib9p_msg_Rwstat *val) {
+ uint32_t needed_size = 7;
+ if (needed_size > ctx->ctx->max_msg_size) {
+ lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%PRIu32)",
+ "Rwstat",
+ ctx->ctx->version ? "negotiated" : "server",
+ ctx->ctx->max_msg_size);
+ return true;
+ }
+ uint32_t offsetof_end = needed_size;
+ uint32_t offsetof_size = 0;
+ MARSHAL_U32LE(ctx, offsetof_end - offsetof_size);
+ MARSHAL_U8LE(ctx, 127);
+ MARSHAL_U16LE(ctx, val->tag);
+ return false;
}
-LM_FLATTEN static bool marshal_Tremove(struct _marshal_ctx *ctx, struct lib9p_msg_Tremove *val) {
- uint32_t _size_offset;
- uint32_t _typ_offset;
- return false
- || ({ _size_offset = ctx->net_offset; ({ ctx->net_offset += 4; false; }); })
- || ({ _typ_offset = ctx->net_offset; ({ ctx->net_offset += 1; false; }); })
- || marshal_tag(ctx, &val->tag)
- || marshal_fid(ctx, &val->fid)
- || ({ uint32le_encode(&ctx->net_bytes[_size_offset], ctx->net_offset - _size_offset); false; })
- || ({ ctx->net_bytes[_typ_offset] = 122; false; })
- ;
+#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */
+#if CONFIG_9P_ENABLE_9P2000_p9p
+static bool marshal_Topenfd(struct _marshal_ctx *ctx, struct lib9p_msg_Topenfd *val) {
+ uint32_t needed_size = 12;
+ if (needed_size > ctx->ctx->max_msg_size) {
+ lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%PRIu32)",
+ "Topenfd",
+ ctx->ctx->version ? "negotiated" : "client",
+ ctx->ctx->max_msg_size);
+ return true;
+ }
+ uint32_t offsetof_end = needed_size;
+ uint32_t offsetof_size = 0;
+ MARSHAL_U32LE(ctx, offsetof_end - offsetof_size);
+ MARSHAL_U8LE(ctx, 98);
+ MARSHAL_U16LE(ctx, val->tag);
+ MARSHAL_U32LE(ctx, val->fid);
+ MARSHAL_U8LE(ctx, val->mode & o_masks[ctx->ctx->version]);
+ return false;
}
-#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */
-#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u
-LM_FLATTEN static bool marshal_Tstat(struct _marshal_ctx *ctx, struct lib9p_msg_Tstat *val) {
- uint32_t _size_offset;
- uint32_t _typ_offset;
- return false
- || ({ _size_offset = ctx->net_offset; ({ ctx->net_offset += 4; false; }); })
- || ({ _typ_offset = ctx->net_offset; ({ ctx->net_offset += 1; false; }); })
- || marshal_tag(ctx, &val->tag)
- || marshal_fid(ctx, &val->fid)
- || ({ uint32le_encode(&ctx->net_bytes[_size_offset], ctx->net_offset - _size_offset); false; })
- || ({ ctx->net_bytes[_typ_offset] = 124; false; })
- ;
+static bool marshal_Ropenfd(struct _marshal_ctx *ctx, struct lib9p_msg_Ropenfd *val) {
+ uint32_t needed_size = 28;
+ if (needed_size > ctx->ctx->max_msg_size) {
+ lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%PRIu32)",
+ "Ropenfd",
+ ctx->ctx->version ? "negotiated" : "server",
+ ctx->ctx->max_msg_size);
+ return true;
+ }
+ uint32_t offsetof_end = needed_size;
+ uint32_t offsetof_size = 0;
+ MARSHAL_U32LE(ctx, offsetof_end - offsetof_size);
+ MARSHAL_U8LE(ctx, 99);
+ MARSHAL_U16LE(ctx, val->tag);
+ MARSHAL_U8LE(ctx, val->qid.type & qt_masks[ctx->ctx->version]);
+ MARSHAL_U32LE(ctx, val->qid.vers);
+ MARSHAL_U64LE(ctx, val->qid.path);
+ MARSHAL_U32LE(ctx, val->iounit);
+ MARSHAL_U32LE(ctx, val->unixfd);
+ return false;
}
-#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */
+#endif /* CONFIG_9P_ENABLE_9P2000_p9p */
#if CONFIG_9P_ENABLE_9P2000_L
-LM_FLATTEN static bool marshal_Tstatfs(struct _marshal_ctx *ctx, struct lib9p_msg_Tstatfs *val) {
- uint32_t _size_offset;
- uint32_t _typ_offset;
- return false
- || ({ _size_offset = ctx->net_offset; ({ ctx->net_offset += 4; false; }); })
- || ({ _typ_offset = ctx->net_offset; ({ ctx->net_offset += 1; false; }); })
- || marshal_tag(ctx, &val->tag)
- || marshal_fid(ctx, &val->fid)
- || ({ uint32le_encode(&ctx->net_bytes[_size_offset], ctx->net_offset - _size_offset); false; })
- || ({ ctx->net_bytes[_typ_offset] = 8; false; })
- ;
-}
-
-LM_FLATTEN static bool marshal_Tlopen(struct _marshal_ctx *ctx, struct lib9p_msg_Tlopen *val) {
- uint32_t _size_offset;
- uint32_t _typ_offset;
- return false
- || ({ _size_offset = ctx->net_offset; ({ ctx->net_offset += 4; false; }); })
- || ({ _typ_offset = ctx->net_offset; ({ ctx->net_offset += 1; false; }); })
- || marshal_tag(ctx, &val->tag)
- || marshal_fid(ctx, &val->fid)
- || marshal_4(ctx, &val->flags)
- || ({ uint32le_encode(&ctx->net_bytes[_size_offset], ctx->net_offset - _size_offset); false; })
- || ({ ctx->net_bytes[_typ_offset] = 12; false; })
- ;
+static bool marshal_Rlerror(struct _marshal_ctx *ctx, struct lib9p_msg_Rlerror *val) {
+ uint32_t needed_size = 11;
+ if (needed_size > ctx->ctx->max_msg_size) {
+ lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%PRIu32)",
+ "Rlerror",
+ ctx->ctx->version ? "negotiated" : "server",
+ ctx->ctx->max_msg_size);
+ return true;
+ }
+ uint32_t offsetof_end = needed_size;
+ uint32_t offsetof_size = 0;
+ MARSHAL_U32LE(ctx, offsetof_end - offsetof_size);
+ MARSHAL_U8LE(ctx, 7);
+ MARSHAL_U16LE(ctx, val->tag);
+ MARSHAL_U32LE(ctx, val->ecode);
+ return false;
}
-LM_FLATTEN static bool marshal_Treadlink(struct _marshal_ctx *ctx, struct lib9p_msg_Treadlink *val) {
- uint32_t _size_offset;
- uint32_t _typ_offset;
- return false
- || ({ _size_offset = ctx->net_offset; ({ ctx->net_offset += 4; false; }); })
- || ({ _typ_offset = ctx->net_offset; ({ ctx->net_offset += 1; false; }); })
- || marshal_tag(ctx, &val->tag)
- || marshal_fid(ctx, &val->fid)
- || ({ uint32le_encode(&ctx->net_bytes[_size_offset], ctx->net_offset - _size_offset); false; })
- || ({ ctx->net_bytes[_typ_offset] = 22; false; })
- ;
+static bool marshal_Tstatfs(struct _marshal_ctx *ctx, struct lib9p_msg_Tstatfs *val) {
+ uint32_t needed_size = 11;
+ if (needed_size > ctx->ctx->max_msg_size) {
+ lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%PRIu32)",
+ "Tstatfs",
+ ctx->ctx->version ? "negotiated" : "client",
+ ctx->ctx->max_msg_size);
+ return true;
+ }
+ uint32_t offsetof_end = needed_size;
+ uint32_t offsetof_size = 0;
+ MARSHAL_U32LE(ctx, offsetof_end - offsetof_size);
+ MARSHAL_U8LE(ctx, 8);
+ MARSHAL_U16LE(ctx, val->tag);
+ MARSHAL_U32LE(ctx, val->fid);
+ return false;
}
-LM_FLATTEN static bool marshal_Treaddir(struct _marshal_ctx *ctx, struct lib9p_msg_Treaddir *val) {
- uint32_t _size_offset;
- uint32_t _typ_offset;
- return false
- || ({ _size_offset = ctx->net_offset; ({ ctx->net_offset += 4; false; }); })
- || ({ _typ_offset = ctx->net_offset; ({ ctx->net_offset += 1; false; }); })
- || marshal_tag(ctx, &val->tag)
- || marshal_fid(ctx, &val->fid)
- || marshal_8(ctx, &val->offset)
- || marshal_4(ctx, &val->count)
- || ({ uint32le_encode(&ctx->net_bytes[_size_offset], ctx->net_offset - _size_offset); false; })
- || ({ ctx->net_bytes[_typ_offset] = 40; false; })
- ;
+static bool marshal_Rstatfs(struct _marshal_ctx *ctx, struct lib9p_msg_Rstatfs *val) {
+ uint32_t needed_size = 67;
+ if (needed_size > ctx->ctx->max_msg_size) {
+ lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%PRIu32)",
+ "Rstatfs",
+ ctx->ctx->version ? "negotiated" : "server",
+ ctx->ctx->max_msg_size);
+ return true;
+ }
+ uint32_t offsetof_end = needed_size;
+ uint32_t offsetof_size = 0;
+ MARSHAL_U32LE(ctx, offsetof_end - offsetof_size);
+ MARSHAL_U8LE(ctx, 9);
+ MARSHAL_U16LE(ctx, val->tag);
+ MARSHAL_U32LE(ctx, val->type);
+ MARSHAL_U32LE(ctx, val->bsize);
+ MARSHAL_U64LE(ctx, val->blocks);
+ MARSHAL_U64LE(ctx, val->bfree);
+ MARSHAL_U64LE(ctx, val->bavail);
+ MARSHAL_U64LE(ctx, val->files);
+ MARSHAL_U64LE(ctx, val->ffree);
+ MARSHAL_U64LE(ctx, val->fsid);
+ MARSHAL_U32LE(ctx, val->namelen);
+ return false;
}
-LM_FLATTEN static bool marshal_Tfsync(struct _marshal_ctx *ctx, struct lib9p_msg_Tfsync *val) {
- uint32_t _size_offset;
- uint32_t _typ_offset;
- return false
- || ({ _size_offset = ctx->net_offset; ({ ctx->net_offset += 4; false; }); })
- || ({ _typ_offset = ctx->net_offset; ({ ctx->net_offset += 1; false; }); })
- || marshal_tag(ctx, &val->tag)
- || marshal_fid(ctx, &val->fid)
- || marshal_4(ctx, &val->datasync)
- || ({ uint32le_encode(&ctx->net_bytes[_size_offset], ctx->net_offset - _size_offset); false; })
- || ({ ctx->net_bytes[_typ_offset] = 50; false; })
- ;
+static bool marshal_Tlopen(struct _marshal_ctx *ctx, struct lib9p_msg_Tlopen *val) {
+ uint32_t needed_size = 15;
+ if (needed_size > ctx->ctx->max_msg_size) {
+ lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%PRIu32)",
+ "Tlopen",
+ ctx->ctx->version ? "negotiated" : "client",
+ ctx->ctx->max_msg_size);
+ return true;
+ }
+ uint32_t offsetof_end = needed_size;
+ uint32_t offsetof_size = 0;
+ MARSHAL_U32LE(ctx, offsetof_end - offsetof_size);
+ MARSHAL_U8LE(ctx, 12);
+ MARSHAL_U16LE(ctx, val->tag);
+ MARSHAL_U32LE(ctx, val->fid);
+ MARSHAL_U32LE(ctx, val->flags);
+ return false;
}
-#endif /* CONFIG_9P_ENABLE_9P2000_L */
-#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u
-LM_FLATTEN static bool marshal_Tversion(struct _marshal_ctx *ctx, struct lib9p_msg_Tversion *val) {
- uint32_t _size_offset;
- uint32_t _typ_offset;
- return false
- || ({ _size_offset = ctx->net_offset; ({ ctx->net_offset += 4; false; }); })
- || ({ _typ_offset = ctx->net_offset; ({ ctx->net_offset += 1; false; }); })
- || marshal_tag(ctx, &val->tag)
- || marshal_4(ctx, &val->max_msg_size)
- || marshal_s(ctx, &val->version)
- || ({ uint32le_encode(&ctx->net_bytes[_size_offset], ctx->net_offset - _size_offset); false; })
- || ({ ctx->net_bytes[_typ_offset] = 100; false; })
- ;
+static bool marshal_Rlopen(struct _marshal_ctx *ctx, struct lib9p_msg_Rlopen *val) {
+ uint32_t needed_size = 24;
+ if (needed_size > ctx->ctx->max_msg_size) {
+ lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%PRIu32)",
+ "Rlopen",
+ ctx->ctx->version ? "negotiated" : "server",
+ ctx->ctx->max_msg_size);
+ return true;
+ }
+ uint32_t offsetof_end = needed_size;
+ uint32_t offsetof_size = 0;
+ MARSHAL_U32LE(ctx, offsetof_end - offsetof_size);
+ MARSHAL_U8LE(ctx, 13);
+ MARSHAL_U16LE(ctx, val->tag);
+ MARSHAL_U8LE(ctx, val->qid.type & qt_masks[ctx->ctx->version]);
+ MARSHAL_U32LE(ctx, val->qid.vers);
+ MARSHAL_U64LE(ctx, val->qid.path);
+ MARSHAL_U32LE(ctx, val->iounit);
+ return false;
}
-LM_FLATTEN static bool marshal_Rversion(struct _marshal_ctx *ctx, struct lib9p_msg_Rversion *val) {
- uint32_t _size_offset;
- uint32_t _typ_offset;
- return false
- || ({ _size_offset = ctx->net_offset; ({ ctx->net_offset += 4; false; }); })
- || ({ _typ_offset = ctx->net_offset; ({ ctx->net_offset += 1; false; }); })
- || marshal_tag(ctx, &val->tag)
- || marshal_4(ctx, &val->max_msg_size)
- || marshal_s(ctx, &val->version)
- || ({ uint32le_encode(&ctx->net_bytes[_size_offset], ctx->net_offset - _size_offset); false; })
- || ({ ctx->net_bytes[_typ_offset] = 101; false; })
- ;
+static bool marshal_Tlcreate(struct _marshal_ctx *ctx, struct lib9p_msg_Tlcreate *val) {
+ uint32_t needed_size = 25 + val->name.len;
+ if (needed_size > ctx->ctx->max_msg_size) {
+ lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%PRIu32)",
+ "Tlcreate",
+ ctx->ctx->version ? "negotiated" : "client",
+ ctx->ctx->max_msg_size);
+ return true;
+ }
+ uint32_t offsetof_end = needed_size;
+ uint32_t offsetof_size = 0;
+ MARSHAL_U32LE(ctx, offsetof_end - offsetof_size);
+ MARSHAL_U8LE(ctx, 14);
+ MARSHAL_U16LE(ctx, val->tag);
+ MARSHAL_U32LE(ctx, val->fid);
+ MARSHAL_U16LE(ctx, val->name.len);
+ MARSHAL_BYTES_ZEROCOPY(ctx, val->name.utf8, val->name.len);
+ MARSHAL_U32LE(ctx, val->flags);
+ MARSHAL_U32LE(ctx, val->mode);
+ MARSHAL_U32LE(ctx, val->gid);
+ return false;
}
-LM_FLATTEN static bool marshal_Rerror(struct _marshal_ctx *ctx, struct lib9p_msg_Rerror *val) {
- uint32_t _size_offset;
- uint32_t _typ_offset;
- return false
- || ({ _size_offset = ctx->net_offset; ({ ctx->net_offset += 4; false; }); })
- || ({ _typ_offset = ctx->net_offset; ({ ctx->net_offset += 1; false; }); })
- || marshal_tag(ctx, &val->tag)
- || marshal_s(ctx, &val->ename)
-#if CONFIG_9P_ENABLE_9P2000_u
- || ( is_ver(ctx, 9P2000_u) && marshal_4(ctx, &val->errno) )
-#endif /* CONFIG_9P_ENABLE_9P2000_u */
- || ({ uint32le_encode(&ctx->net_bytes[_size_offset], ctx->net_offset - _size_offset); false; })
- || ({ ctx->net_bytes[_typ_offset] = 107; false; })
- ;
+static bool marshal_Rlcreate(struct _marshal_ctx *ctx, struct lib9p_msg_Rlcreate *val) {
+ uint32_t needed_size = 24;
+ if (needed_size > ctx->ctx->max_msg_size) {
+ lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%PRIu32)",
+ "Rlcreate",
+ ctx->ctx->version ? "negotiated" : "server",
+ ctx->ctx->max_msg_size);
+ return true;
+ }
+ uint32_t offsetof_end = needed_size;
+ uint32_t offsetof_size = 0;
+ MARSHAL_U32LE(ctx, offsetof_end - offsetof_size);
+ MARSHAL_U8LE(ctx, 15);
+ MARSHAL_U16LE(ctx, val->tag);
+ MARSHAL_U8LE(ctx, val->qid.type & qt_masks[ctx->ctx->version]);
+ MARSHAL_U32LE(ctx, val->qid.vers);
+ MARSHAL_U64LE(ctx, val->qid.path);
+ MARSHAL_U32LE(ctx, val->iounit);
+ return false;
}
-LM_FLATTEN static bool marshal_Twalk(struct _marshal_ctx *ctx, struct lib9p_msg_Twalk *val) {
- uint32_t _size_offset;
- uint32_t _typ_offset;
- return false
- || ({ _size_offset = ctx->net_offset; ({ ctx->net_offset += 4; false; }); })
- || ({ _typ_offset = ctx->net_offset; ({ ctx->net_offset += 1; false; }); })
- || marshal_tag(ctx, &val->tag)
- || marshal_fid(ctx, &val->fid)
- || marshal_fid(ctx, &val->newfid)
- || marshal_2(ctx, &val->nwname)
- || ({ bool err = false;
- for (typeof(val->nwname) i = 0; i < val->nwname && !err; i++)
- err = marshal_s(ctx, &val->wname[i]);
- err; })
- || ({ uint32le_encode(&ctx->net_bytes[_size_offset], ctx->net_offset - _size_offset); false; })
- || ({ ctx->net_bytes[_typ_offset] = 110; false; })
- ;
+static bool marshal_Tsymlink(struct _marshal_ctx *ctx, struct lib9p_msg_Tsymlink *val) {
+ uint32_t needed_size = 19 + val->name.len + val->symtgt.len;
+ if (needed_size > ctx->ctx->max_msg_size) {
+ lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%PRIu32)",
+ "Tsymlink",
+ ctx->ctx->version ? "negotiated" : "client",
+ ctx->ctx->max_msg_size);
+ return true;
+ }
+ uint32_t offsetof_end = needed_size;
+ uint32_t offsetof_size = 0;
+ MARSHAL_U32LE(ctx, offsetof_end - offsetof_size);
+ MARSHAL_U8LE(ctx, 16);
+ MARSHAL_U16LE(ctx, val->tag);
+ MARSHAL_U32LE(ctx, val->fid);
+ MARSHAL_U16LE(ctx, val->name.len);
+ MARSHAL_BYTES_ZEROCOPY(ctx, val->name.utf8, val->name.len);
+ MARSHAL_U16LE(ctx, val->symtgt.len);
+ MARSHAL_BYTES_ZEROCOPY(ctx, val->symtgt.utf8, val->symtgt.len);
+ MARSHAL_U32LE(ctx, val->gid);
+ return false;
}
-#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */
-#if CONFIG_9P_ENABLE_9P2000_L
-LM_FLATTEN static bool marshal_Trename(struct _marshal_ctx *ctx, struct lib9p_msg_Trename *val) {
- uint32_t _size_offset;
- uint32_t _typ_offset;
- return false
- || ({ _size_offset = ctx->net_offset; ({ ctx->net_offset += 4; false; }); })
- || ({ _typ_offset = ctx->net_offset; ({ ctx->net_offset += 1; false; }); })
- || marshal_tag(ctx, &val->tag)
- || marshal_fid(ctx, &val->fid)
- || marshal_fid(ctx, &val->dfid)
- || marshal_s(ctx, &val->name)
- || ({ uint32le_encode(&ctx->net_bytes[_size_offset], ctx->net_offset - _size_offset); false; })
- || ({ ctx->net_bytes[_typ_offset] = 20; false; })
- ;
+static bool marshal_Rsymlink(struct _marshal_ctx *ctx, struct lib9p_msg_Rsymlink *val) {
+ uint32_t needed_size = 20;
+ if (needed_size > ctx->ctx->max_msg_size) {
+ lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%PRIu32)",
+ "Rsymlink",
+ ctx->ctx->version ? "negotiated" : "server",
+ ctx->ctx->max_msg_size);
+ return true;
+ }
+ uint32_t offsetof_end = needed_size;
+ uint32_t offsetof_size = 0;
+ MARSHAL_U32LE(ctx, offsetof_end - offsetof_size);
+ MARSHAL_U8LE(ctx, 17);
+ MARSHAL_U16LE(ctx, val->tag);
+ MARSHAL_U8LE(ctx, val->qid.type & qt_masks[ctx->ctx->version]);
+ MARSHAL_U32LE(ctx, val->qid.vers);
+ MARSHAL_U64LE(ctx, val->qid.path);
+ return false;
}
-LM_FLATTEN static bool marshal_Rreadlink(struct _marshal_ctx *ctx, struct lib9p_msg_Rreadlink *val) {
- uint32_t _size_offset;
- uint32_t _typ_offset;
- return false
- || ({ _size_offset = ctx->net_offset; ({ ctx->net_offset += 4; false; }); })
- || ({ _typ_offset = ctx->net_offset; ({ ctx->net_offset += 1; false; }); })
- || marshal_tag(ctx, &val->tag)
- || marshal_s(ctx, &val->target)
- || ({ uint32le_encode(&ctx->net_bytes[_size_offset], ctx->net_offset - _size_offset); false; })
- || ({ ctx->net_bytes[_typ_offset] = 23; false; })
- ;
+static bool marshal_Tmknod(struct _marshal_ctx *ctx, struct lib9p_msg_Tmknod *val) {
+ uint32_t needed_size = 29 + val->name.len;
+ if (needed_size > ctx->ctx->max_msg_size) {
+ lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%PRIu32)",
+ "Tmknod",
+ ctx->ctx->version ? "negotiated" : "client",
+ ctx->ctx->max_msg_size);
+ return true;
+ }
+ uint32_t offsetof_end = needed_size;
+ uint32_t offsetof_size = 0;
+ MARSHAL_U32LE(ctx, offsetof_end - offsetof_size);
+ MARSHAL_U8LE(ctx, 18);
+ MARSHAL_U16LE(ctx, val->tag);
+ MARSHAL_U32LE(ctx, val->dfid);
+ MARSHAL_U16LE(ctx, val->name.len);
+ MARSHAL_BYTES_ZEROCOPY(ctx, val->name.utf8, val->name.len);
+ MARSHAL_U32LE(ctx, val->mode);
+ MARSHAL_U32LE(ctx, val->major);
+ MARSHAL_U32LE(ctx, val->minor);
+ MARSHAL_U32LE(ctx, val->gid);
+ return false;
}
-LM_FLATTEN static bool marshal_Txattrwalk(struct _marshal_ctx *ctx, struct lib9p_msg_Txattrwalk *val) {
- uint32_t _size_offset;
- uint32_t _typ_offset;
- return false
- || ({ _size_offset = ctx->net_offset; ({ ctx->net_offset += 4; false; }); })
- || ({ _typ_offset = ctx->net_offset; ({ ctx->net_offset += 1; false; }); })
- || marshal_tag(ctx, &val->tag)
- || marshal_fid(ctx, &val->fid)
- || marshal_fid(ctx, &val->newfid)
- || marshal_s(ctx, &val->name)
- || ({ uint32le_encode(&ctx->net_bytes[_size_offset], ctx->net_offset - _size_offset); false; })
- || ({ ctx->net_bytes[_typ_offset] = 30; false; })
- ;
+static bool marshal_Rmknod(struct _marshal_ctx *ctx, struct lib9p_msg_Rmknod *val) {
+ uint32_t needed_size = 20;
+ if (needed_size > ctx->ctx->max_msg_size) {
+ lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%PRIu32)",
+ "Rmknod",
+ ctx->ctx->version ? "negotiated" : "server",
+ ctx->ctx->max_msg_size);
+ return true;
+ }
+ uint32_t offsetof_end = needed_size;
+ uint32_t offsetof_size = 0;
+ MARSHAL_U32LE(ctx, offsetof_end - offsetof_size);
+ MARSHAL_U8LE(ctx, 19);
+ MARSHAL_U16LE(ctx, val->tag);
+ MARSHAL_U8LE(ctx, val->qid.type & qt_masks[ctx->ctx->version]);
+ MARSHAL_U32LE(ctx, val->qid.vers);
+ MARSHAL_U64LE(ctx, val->qid.path);
+ return false;
}
-LM_FLATTEN static bool marshal_Txattrcreate(struct _marshal_ctx *ctx, struct lib9p_msg_Txattrcreate *val) {
- uint32_t _size_offset;
- uint32_t _typ_offset;
- return false
- || ({ _size_offset = ctx->net_offset; ({ ctx->net_offset += 4; false; }); })
- || ({ _typ_offset = ctx->net_offset; ({ ctx->net_offset += 1; false; }); })
- || marshal_tag(ctx, &val->tag)
- || marshal_fid(ctx, &val->fid)
- || marshal_s(ctx, &val->name)
- || marshal_8(ctx, &val->attr_size)
- || marshal_4(ctx, &val->flags)
- || ({ uint32le_encode(&ctx->net_bytes[_size_offset], ctx->net_offset - _size_offset); false; })
- || ({ ctx->net_bytes[_typ_offset] = 32; false; })
- ;
+static bool marshal_Trename(struct _marshal_ctx *ctx, struct lib9p_msg_Trename *val) {
+ uint32_t needed_size = 17 + val->name.len;
+ if (needed_size > ctx->ctx->max_msg_size) {
+ lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%PRIu32)",
+ "Trename",
+ ctx->ctx->version ? "negotiated" : "client",
+ ctx->ctx->max_msg_size);
+ return true;
+ }
+ uint32_t offsetof_end = needed_size;
+ uint32_t offsetof_size = 0;
+ MARSHAL_U32LE(ctx, offsetof_end - offsetof_size);
+ MARSHAL_U8LE(ctx, 20);
+ MARSHAL_U16LE(ctx, val->tag);
+ MARSHAL_U32LE(ctx, val->fid);
+ MARSHAL_U32LE(ctx, val->dfid);
+ MARSHAL_U16LE(ctx, val->name.len);
+ MARSHAL_BYTES_ZEROCOPY(ctx, val->name.utf8, val->name.len);
+ return false;
}
-LM_FLATTEN static bool marshal_Tgetlock(struct _marshal_ctx *ctx, struct lib9p_msg_Tgetlock *val) {
- uint32_t _size_offset;
- uint32_t _typ_offset;
- return false
- || ({ _size_offset = ctx->net_offset; ({ ctx->net_offset += 4; false; }); })
- || ({ _typ_offset = ctx->net_offset; ({ ctx->net_offset += 1; false; }); })
- || marshal_tag(ctx, &val->tag)
- || marshal_fid(ctx, &val->fid)
- || marshal_1(ctx, &val->type)
- || marshal_8(ctx, &val->start)
- || marshal_8(ctx, &val->length)
- || marshal_4(ctx, &val->proc_id)
- || marshal_s(ctx, &val->client_id)
- || ({ uint32le_encode(&ctx->net_bytes[_size_offset], ctx->net_offset - _size_offset); false; })
- || ({ ctx->net_bytes[_typ_offset] = 54; false; })
- ;
+static bool marshal_Rrename(struct _marshal_ctx *ctx, struct lib9p_msg_Rrename *val) {
+ uint32_t needed_size = 7;
+ if (needed_size > ctx->ctx->max_msg_size) {
+ lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%PRIu32)",
+ "Rrename",
+ ctx->ctx->version ? "negotiated" : "server",
+ ctx->ctx->max_msg_size);
+ return true;
+ }
+ uint32_t offsetof_end = needed_size;
+ uint32_t offsetof_size = 0;
+ MARSHAL_U32LE(ctx, offsetof_end - offsetof_size);
+ MARSHAL_U8LE(ctx, 21);
+ MARSHAL_U16LE(ctx, val->tag);
+ return false;
}
-LM_FLATTEN static bool marshal_Rgetlock(struct _marshal_ctx *ctx, struct lib9p_msg_Rgetlock *val) {
- uint32_t _size_offset;
- uint32_t _typ_offset;
- return false
- || ({ _size_offset = ctx->net_offset; ({ ctx->net_offset += 4; false; }); })
- || ({ _typ_offset = ctx->net_offset; ({ ctx->net_offset += 1; false; }); })
- || marshal_tag(ctx, &val->tag)
- || marshal_1(ctx, &val->type)
- || marshal_8(ctx, &val->start)
- || marshal_8(ctx, &val->length)
- || marshal_4(ctx, &val->proc_id)
- || marshal_s(ctx, &val->client_id)
- || ({ uint32le_encode(&ctx->net_bytes[_size_offset], ctx->net_offset - _size_offset); false; })
- || ({ ctx->net_bytes[_typ_offset] = 55; false; })
- ;
+static bool marshal_Treadlink(struct _marshal_ctx *ctx, struct lib9p_msg_Treadlink *val) {
+ uint32_t needed_size = 11;
+ if (needed_size > ctx->ctx->max_msg_size) {
+ lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%PRIu32)",
+ "Treadlink",
+ ctx->ctx->version ? "negotiated" : "client",
+ ctx->ctx->max_msg_size);
+ return true;
+ }
+ uint32_t offsetof_end = needed_size;
+ uint32_t offsetof_size = 0;
+ MARSHAL_U32LE(ctx, offsetof_end - offsetof_size);
+ MARSHAL_U8LE(ctx, 22);
+ MARSHAL_U16LE(ctx, val->tag);
+ MARSHAL_U32LE(ctx, val->fid);
+ return false;
}
-LM_FLATTEN static bool marshal_Tlink(struct _marshal_ctx *ctx, struct lib9p_msg_Tlink *val) {
- uint32_t _size_offset;
- uint32_t _typ_offset;
- return false
- || ({ _size_offset = ctx->net_offset; ({ ctx->net_offset += 4; false; }); })
- || ({ _typ_offset = ctx->net_offset; ({ ctx->net_offset += 1; false; }); })
- || marshal_tag(ctx, &val->tag)
- || marshal_fid(ctx, &val->dfid)
- || marshal_fid(ctx, &val->fid)
- || marshal_s(ctx, &val->name)
- || ({ uint32le_encode(&ctx->net_bytes[_size_offset], ctx->net_offset - _size_offset); false; })
- || ({ ctx->net_bytes[_typ_offset] = 70; false; })
- ;
+static bool marshal_Rreadlink(struct _marshal_ctx *ctx, struct lib9p_msg_Rreadlink *val) {
+ uint32_t needed_size = 9 + val->target.len;
+ if (needed_size > ctx->ctx->max_msg_size) {
+ lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%PRIu32)",
+ "Rreadlink",
+ ctx->ctx->version ? "negotiated" : "server",
+ ctx->ctx->max_msg_size);
+ return true;
+ }
+ uint32_t offsetof_end = needed_size;
+ uint32_t offsetof_size = 0;
+ MARSHAL_U32LE(ctx, offsetof_end - offsetof_size);
+ MARSHAL_U8LE(ctx, 23);
+ MARSHAL_U16LE(ctx, val->tag);
+ MARSHAL_U16LE(ctx, val->target.len);
+ MARSHAL_BYTES_ZEROCOPY(ctx, val->target.utf8, val->target.len);
+ return false;
}
-LM_FLATTEN static bool marshal_Trenameat(struct _marshal_ctx *ctx, struct lib9p_msg_Trenameat *val) {
- uint32_t _size_offset;
- uint32_t _typ_offset;
- return false
- || ({ _size_offset = ctx->net_offset; ({ ctx->net_offset += 4; false; }); })
- || ({ _typ_offset = ctx->net_offset; ({ ctx->net_offset += 1; false; }); })
- || marshal_tag(ctx, &val->tag)
- || marshal_fid(ctx, &val->olddirfid)
- || marshal_s(ctx, &val->oldname)
- || marshal_fid(ctx, &val->newdirfid)
- || marshal_s(ctx, &val->newname)
- || ({ uint32le_encode(&ctx->net_bytes[_size_offset], ctx->net_offset - _size_offset); false; })
- || ({ ctx->net_bytes[_typ_offset] = 74; false; })
- ;
+static bool marshal_Tgetattr(struct _marshal_ctx *ctx, struct lib9p_msg_Tgetattr *val) {
+ uint32_t needed_size = 19;
+ if (needed_size > ctx->ctx->max_msg_size) {
+ lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%PRIu32)",
+ "Tgetattr",
+ ctx->ctx->version ? "negotiated" : "client",
+ ctx->ctx->max_msg_size);
+ return true;
+ }
+ uint32_t offsetof_end = needed_size;
+ uint32_t offsetof_size = 0;
+ MARSHAL_U32LE(ctx, offsetof_end - offsetof_size);
+ MARSHAL_U8LE(ctx, 24);
+ MARSHAL_U16LE(ctx, val->tag);
+ MARSHAL_U32LE(ctx, val->fid);
+ MARSHAL_U64LE(ctx, val->request_mask & getattr_masks[ctx->ctx->version]);
+ return false;
}
-LM_FLATTEN static bool marshal_Tunlinkat(struct _marshal_ctx *ctx, struct lib9p_msg_Tunlinkat *val) {
- uint32_t _size_offset;
- uint32_t _typ_offset;
- return false
- || ({ _size_offset = ctx->net_offset; ({ ctx->net_offset += 4; false; }); })
- || ({ _typ_offset = ctx->net_offset; ({ ctx->net_offset += 1; false; }); })
- || marshal_tag(ctx, &val->tag)
- || marshal_fid(ctx, &val->dirfd)
- || marshal_s(ctx, &val->name)
- || marshal_4(ctx, &val->flags)
- || ({ uint32le_encode(&ctx->net_bytes[_size_offset], ctx->net_offset - _size_offset); false; })
- || ({ ctx->net_bytes[_typ_offset] = 76; false; })
- ;
+static bool marshal_Rgetattr(struct _marshal_ctx *ctx, struct lib9p_msg_Rgetattr *val) {
+ uint32_t needed_size = 160;
+ if (needed_size > ctx->ctx->max_msg_size) {
+ lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%PRIu32)",
+ "Rgetattr",
+ ctx->ctx->version ? "negotiated" : "server",
+ ctx->ctx->max_msg_size);
+ return true;
+ }
+ uint32_t offsetof_end = needed_size;
+ uint32_t offsetof_size = 0;
+ MARSHAL_U32LE(ctx, offsetof_end - offsetof_size);
+ MARSHAL_U8LE(ctx, 25);
+ MARSHAL_U16LE(ctx, val->tag);
+ MARSHAL_U64LE(ctx, val->valid);
+ MARSHAL_U8LE(ctx, val->qid.type & qt_masks[ctx->ctx->version]);
+ MARSHAL_U32LE(ctx, val->qid.vers);
+ MARSHAL_U64LE(ctx, val->qid.path);
+ MARSHAL_U32LE(ctx, val->mode);
+ MARSHAL_U32LE(ctx, val->uid);
+ MARSHAL_U32LE(ctx, val->gid);
+ MARSHAL_U64LE(ctx, val->nlink);
+ MARSHAL_U64LE(ctx, val->rdev);
+ MARSHAL_U64LE(ctx, val->filesize);
+ MARSHAL_U64LE(ctx, val->blksize);
+ MARSHAL_U64LE(ctx, val->blocks);
+ MARSHAL_U64LE(ctx, val->atime_sec);
+ MARSHAL_U64LE(ctx, val->atime_nsec);
+ MARSHAL_U64LE(ctx, val->mtime_sec);
+ MARSHAL_U64LE(ctx, val->mtime_nsec);
+ MARSHAL_U64LE(ctx, val->ctime_sec);
+ MARSHAL_U64LE(ctx, val->ctime_nsec);
+ MARSHAL_U64LE(ctx, val->btime_sec);
+ MARSHAL_U64LE(ctx, val->btime_nsec);
+ MARSHAL_U64LE(ctx, val->gen);
+ MARSHAL_U64LE(ctx, val->data_version);
+ return false;
}
-#endif /* CONFIG_9P_ENABLE_9P2000_L */
-#if CONFIG_9P_ENABLE_9P2000_e
-LM_FLATTEN static bool marshal_Tsread(struct _marshal_ctx *ctx, struct lib9p_msg_Tsread *val) {
- uint32_t _size_offset;
- uint32_t _typ_offset;
- return false
- || ({ _size_offset = ctx->net_offset; ({ ctx->net_offset += 4; false; }); })
- || ({ _typ_offset = ctx->net_offset; ({ ctx->net_offset += 1; false; }); })
- || marshal_tag(ctx, &val->tag)
- || marshal_4(ctx, &val->fid)
- || marshal_2(ctx, &val->nwname)
- || ({ bool err = false;
- for (typeof(val->nwname) i = 0; i < val->nwname && !err; i++)
- err = marshal_s(ctx, &val->wname[i]);
- err; })
- || ({ uint32le_encode(&ctx->net_bytes[_size_offset], ctx->net_offset - _size_offset); false; })
- || ({ ctx->net_bytes[_typ_offset] = 152; false; })
- ;
+static bool marshal_Tsetattr(struct _marshal_ctx *ctx, struct lib9p_msg_Tsetattr *val) {
+ uint32_t needed_size = 67;
+ if (needed_size > ctx->ctx->max_msg_size) {
+ lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%PRIu32)",
+ "Tsetattr",
+ ctx->ctx->version ? "negotiated" : "client",
+ ctx->ctx->max_msg_size);
+ return true;
+ }
+ uint32_t offsetof_end = needed_size;
+ uint32_t offsetof_size = 0;
+ MARSHAL_U32LE(ctx, offsetof_end - offsetof_size);
+ MARSHAL_U8LE(ctx, 26);
+ MARSHAL_U16LE(ctx, val->tag);
+ MARSHAL_U32LE(ctx, val->fid);
+ MARSHAL_U32LE(ctx, val->valid & setattr_masks[ctx->ctx->version]);
+ MARSHAL_U32LE(ctx, val->mode);
+ MARSHAL_U32LE(ctx, val->uid);
+ MARSHAL_U32LE(ctx, val->gid);
+ MARSHAL_U64LE(ctx, val->filesize);
+ MARSHAL_U64LE(ctx, val->atime_sec);
+ MARSHAL_U64LE(ctx, val->atime_nsec);
+ MARSHAL_U64LE(ctx, val->mtime_sec);
+ MARSHAL_U64LE(ctx, val->mtime_nsec);
+ return false;
}
-LM_FLATTEN static bool marshal_Tswrite(struct _marshal_ctx *ctx, struct lib9p_msg_Tswrite *val) {
- uint32_t _size_offset;
- uint32_t _typ_offset;
- return false
- || ({ _size_offset = ctx->net_offset; ({ ctx->net_offset += 4; false; }); })
- || ({ _typ_offset = ctx->net_offset; ({ ctx->net_offset += 1; false; }); })
- || marshal_tag(ctx, &val->tag)
- || marshal_4(ctx, &val->fid)
- || marshal_2(ctx, &val->nwname)
- || ({ bool err = false;
- for (typeof(val->nwname) i = 0; i < val->nwname && !err; i++)
- err = marshal_s(ctx, &val->wname[i]);
- err; })
- || marshal_4(ctx, &val->count)
- || ({ bool err = false;
- for (typeof(val->count) i = 0; i < val->count && !err; i++)
- err = marshal_1(ctx, (uint8_t *)&val->data[i]);
- err; })
- || ({ uint32le_encode(&ctx->net_bytes[_size_offset], ctx->net_offset - _size_offset); false; })
- || ({ ctx->net_bytes[_typ_offset] = 154; false; })
- ;
+static bool marshal_Rsetattr(struct _marshal_ctx *ctx, struct lib9p_msg_Rsetattr *val) {
+ uint32_t needed_size = 7;
+ if (needed_size > ctx->ctx->max_msg_size) {
+ lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%PRIu32)",
+ "Rsetattr",
+ ctx->ctx->version ? "negotiated" : "server",
+ ctx->ctx->max_msg_size);
+ return true;
+ }
+ uint32_t offsetof_end = needed_size;
+ uint32_t offsetof_size = 0;
+ MARSHAL_U32LE(ctx, offsetof_end - offsetof_size);
+ MARSHAL_U8LE(ctx, 27);
+ MARSHAL_U16LE(ctx, val->tag);
+ return false;
}
-#endif /* CONFIG_9P_ENABLE_9P2000_e */
-#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u
-LM_ALWAYS_INLINE static bool marshal_qid(struct _marshal_ctx *ctx, struct lib9p_qid *val) {
- return false
- || marshal_qt(ctx, &val->type)
- || marshal_4(ctx, &val->vers)
- || marshal_8(ctx, &val->path)
- ;
+static bool marshal_Txattrwalk(struct _marshal_ctx *ctx, struct lib9p_msg_Txattrwalk *val) {
+ uint32_t needed_size = 17 + val->name.len;
+ if (needed_size > ctx->ctx->max_msg_size) {
+ lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%PRIu32)",
+ "Txattrwalk",
+ ctx->ctx->version ? "negotiated" : "client",
+ ctx->ctx->max_msg_size);
+ return true;
+ }
+ uint32_t offsetof_end = needed_size;
+ uint32_t offsetof_size = 0;
+ MARSHAL_U32LE(ctx, offsetof_end - offsetof_size);
+ MARSHAL_U8LE(ctx, 30);
+ MARSHAL_U16LE(ctx, val->tag);
+ MARSHAL_U32LE(ctx, val->fid);
+ MARSHAL_U32LE(ctx, val->newfid);
+ MARSHAL_U16LE(ctx, val->name.len);
+ MARSHAL_BYTES_ZEROCOPY(ctx, val->name.utf8, val->name.len);
+ return false;
}
-LM_FLATTEN static bool marshal_Tauth(struct _marshal_ctx *ctx, struct lib9p_msg_Tauth *val) {
- uint32_t _size_offset;
- uint32_t _typ_offset;
- return false
- || ({ _size_offset = ctx->net_offset; ({ ctx->net_offset += 4; false; }); })
- || ({ _typ_offset = ctx->net_offset; ({ ctx->net_offset += 1; false; }); })
- || marshal_tag(ctx, &val->tag)
- || marshal_fid(ctx, &val->afid)
- || marshal_s(ctx, &val->uname)
- || marshal_s(ctx, &val->aname)
-#if CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_u
- || ( ( is_ver(ctx, 9P2000_L) || is_ver(ctx, 9P2000_u) ) && marshal_nuid(ctx, &val->n_uid) )
-#endif /* CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_u */
- || ({ uint32le_encode(&ctx->net_bytes[_size_offset], ctx->net_offset - _size_offset); false; })
- || ({ ctx->net_bytes[_typ_offset] = 102; false; })
- ;
+static bool marshal_Rxattrwalk(struct _marshal_ctx *ctx, struct lib9p_msg_Rxattrwalk *val) {
+ uint32_t needed_size = 15;
+ if (needed_size > ctx->ctx->max_msg_size) {
+ lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%PRIu32)",
+ "Rxattrwalk",
+ ctx->ctx->version ? "negotiated" : "server",
+ ctx->ctx->max_msg_size);
+ return true;
+ }
+ uint32_t offsetof_end = needed_size;
+ uint32_t offsetof_size = 0;
+ MARSHAL_U32LE(ctx, offsetof_end - offsetof_size);
+ MARSHAL_U8LE(ctx, 31);
+ MARSHAL_U16LE(ctx, val->tag);
+ MARSHAL_U64LE(ctx, val->attr_size);
+ return false;
}
-LM_FLATTEN static bool marshal_Tattach(struct _marshal_ctx *ctx, struct lib9p_msg_Tattach *val) {
- uint32_t _size_offset;
- uint32_t _typ_offset;
- return false
- || ({ _size_offset = ctx->net_offset; ({ ctx->net_offset += 4; false; }); })
- || ({ _typ_offset = ctx->net_offset; ({ ctx->net_offset += 1; false; }); })
- || marshal_tag(ctx, &val->tag)
- || marshal_fid(ctx, &val->fid)
- || marshal_fid(ctx, &val->afid)
- || marshal_s(ctx, &val->uname)
- || marshal_s(ctx, &val->aname)
-#if CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_u
- || ( ( is_ver(ctx, 9P2000_L) || is_ver(ctx, 9P2000_u) ) && marshal_nuid(ctx, &val->n_uid) )
-#endif /* CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_u */
- || ({ uint32le_encode(&ctx->net_bytes[_size_offset], ctx->net_offset - _size_offset); false; })
- || ({ ctx->net_bytes[_typ_offset] = 104; false; })
- ;
+static bool marshal_Txattrcreate(struct _marshal_ctx *ctx, struct lib9p_msg_Txattrcreate *val) {
+ uint32_t needed_size = 25 + val->name.len;
+ if (needed_size > ctx->ctx->max_msg_size) {
+ lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%PRIu32)",
+ "Txattrcreate",
+ ctx->ctx->version ? "negotiated" : "client",
+ ctx->ctx->max_msg_size);
+ return true;
+ }
+ uint32_t offsetof_end = needed_size;
+ uint32_t offsetof_size = 0;
+ MARSHAL_U32LE(ctx, offsetof_end - offsetof_size);
+ MARSHAL_U8LE(ctx, 32);
+ MARSHAL_U16LE(ctx, val->tag);
+ MARSHAL_U32LE(ctx, val->fid);
+ MARSHAL_U16LE(ctx, val->name.len);
+ MARSHAL_BYTES_ZEROCOPY(ctx, val->name.utf8, val->name.len);
+ MARSHAL_U64LE(ctx, val->attr_size);
+ MARSHAL_U32LE(ctx, val->flags);
+ return false;
}
-#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */
-#if CONFIG_9P_ENABLE_9P2000_L
-LM_FLATTEN static bool marshal_Tlcreate(struct _marshal_ctx *ctx, struct lib9p_msg_Tlcreate *val) {
- uint32_t _size_offset;
- uint32_t _typ_offset;
- return false
- || ({ _size_offset = ctx->net_offset; ({ ctx->net_offset += 4; false; }); })
- || ({ _typ_offset = ctx->net_offset; ({ ctx->net_offset += 1; false; }); })
- || marshal_tag(ctx, &val->tag)
- || marshal_fid(ctx, &val->fid)
- || marshal_s(ctx, &val->name)
- || marshal_4(ctx, &val->flags)
- || marshal_4(ctx, &val->mode)
- || marshal_nuid(ctx, &val->gid)
- || ({ uint32le_encode(&ctx->net_bytes[_size_offset], ctx->net_offset - _size_offset); false; })
- || ({ ctx->net_bytes[_typ_offset] = 14; false; })
- ;
+static bool marshal_Rxattrcreate(struct _marshal_ctx *ctx, struct lib9p_msg_Rxattrcreate *val) {
+ uint32_t needed_size = 7;
+ if (needed_size > ctx->ctx->max_msg_size) {
+ lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%PRIu32)",
+ "Rxattrcreate",
+ ctx->ctx->version ? "negotiated" : "server",
+ ctx->ctx->max_msg_size);
+ return true;
+ }
+ uint32_t offsetof_end = needed_size;
+ uint32_t offsetof_size = 0;
+ MARSHAL_U32LE(ctx, offsetof_end - offsetof_size);
+ MARSHAL_U8LE(ctx, 33);
+ MARSHAL_U16LE(ctx, val->tag);
+ return false;
}
-LM_FLATTEN static bool marshal_Tsymlink(struct _marshal_ctx *ctx, struct lib9p_msg_Tsymlink *val) {
- uint32_t _size_offset;
- uint32_t _typ_offset;
- return false
- || ({ _size_offset = ctx->net_offset; ({ ctx->net_offset += 4; false; }); })
- || ({ _typ_offset = ctx->net_offset; ({ ctx->net_offset += 1; false; }); })
- || marshal_tag(ctx, &val->tag)
- || marshal_fid(ctx, &val->fid)
- || marshal_s(ctx, &val->name)
- || marshal_s(ctx, &val->symtgt)
- || marshal_nuid(ctx, &val->gid)
- || ({ uint32le_encode(&ctx->net_bytes[_size_offset], ctx->net_offset - _size_offset); false; })
- || ({ ctx->net_bytes[_typ_offset] = 16; false; })
- ;
+static bool marshal_Treaddir(struct _marshal_ctx *ctx, struct lib9p_msg_Treaddir *val) {
+ uint32_t needed_size = 23;
+ if (needed_size > ctx->ctx->max_msg_size) {
+ lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%PRIu32)",
+ "Treaddir",
+ ctx->ctx->version ? "negotiated" : "client",
+ ctx->ctx->max_msg_size);
+ return true;
+ }
+ uint32_t offsetof_end = needed_size;
+ uint32_t offsetof_size = 0;
+ MARSHAL_U32LE(ctx, offsetof_end - offsetof_size);
+ MARSHAL_U8LE(ctx, 40);
+ MARSHAL_U16LE(ctx, val->tag);
+ MARSHAL_U32LE(ctx, val->fid);
+ MARSHAL_U64LE(ctx, val->offset);
+ MARSHAL_U32LE(ctx, val->count);
+ return false;
}
-LM_FLATTEN static bool marshal_Tmknod(struct _marshal_ctx *ctx, struct lib9p_msg_Tmknod *val) {
- uint32_t _size_offset;
- uint32_t _typ_offset;
- return false
- || ({ _size_offset = ctx->net_offset; ({ ctx->net_offset += 4; false; }); })
- || ({ _typ_offset = ctx->net_offset; ({ ctx->net_offset += 1; false; }); })
- || marshal_tag(ctx, &val->tag)
- || marshal_fid(ctx, &val->dfid)
- || marshal_s(ctx, &val->name)
- || marshal_4(ctx, &val->mode)
- || marshal_4(ctx, &val->major)
- || marshal_4(ctx, &val->minor)
- || marshal_nuid(ctx, &val->gid)
- || ({ uint32le_encode(&ctx->net_bytes[_size_offset], ctx->net_offset - _size_offset); false; })
- || ({ ctx->net_bytes[_typ_offset] = 18; false; })
- ;
+static bool marshal_Rreaddir(struct _marshal_ctx *ctx, struct lib9p_msg_Rreaddir *val) {
+ uint64_t needed_size = 11 + val->count;
+ if (needed_size > (uint64_t)(ctx->ctx->max_msg_size)) {
+ lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%PRIu32)",
+ "Rreaddir",
+ ctx->ctx->version ? "negotiated" : "server",
+ ctx->ctx->max_msg_size);
+ return true;
+ }
+ uint32_t offsetof_end = (uint32_t)needed_size;
+ uint32_t offsetof_size = 0;
+ MARSHAL_U32LE(ctx, offsetof_end - offsetof_size);
+ MARSHAL_U8LE(ctx, 41);
+ MARSHAL_U16LE(ctx, val->tag);
+ MARSHAL_U32LE(ctx, val->count);
+ MARSHAL_BYTES_ZEROCOPY(ctx, val->data, val->count);
+ return false;
}
-LM_FLATTEN static bool marshal_Tmkdir(struct _marshal_ctx *ctx, struct lib9p_msg_Tmkdir *val) {
- uint32_t _size_offset;
- uint32_t _typ_offset;
- return false
- || ({ _size_offset = ctx->net_offset; ({ ctx->net_offset += 4; false; }); })
- || ({ _typ_offset = ctx->net_offset; ({ ctx->net_offset += 1; false; }); })
- || marshal_tag(ctx, &val->tag)
- || marshal_fid(ctx, &val->dfid)
- || marshal_s(ctx, &val->name)
- || marshal_4(ctx, &val->mode)
- || marshal_nuid(ctx, &val->gid)
- || ({ uint32le_encode(&ctx->net_bytes[_size_offset], ctx->net_offset - _size_offset); false; })
- || ({ ctx->net_bytes[_typ_offset] = 72; false; })
- ;
+static bool marshal_Tfsync(struct _marshal_ctx *ctx, struct lib9p_msg_Tfsync *val) {
+ uint32_t needed_size = 15;
+ if (needed_size > ctx->ctx->max_msg_size) {
+ lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%PRIu32)",
+ "Tfsync",
+ ctx->ctx->version ? "negotiated" : "client",
+ ctx->ctx->max_msg_size);
+ return true;
+ }
+ uint32_t offsetof_end = needed_size;
+ uint32_t offsetof_size = 0;
+ MARSHAL_U32LE(ctx, offsetof_end - offsetof_size);
+ MARSHAL_U8LE(ctx, 50);
+ MARSHAL_U16LE(ctx, val->tag);
+ MARSHAL_U32LE(ctx, val->fid);
+ MARSHAL_U32LE(ctx, val->datasync);
+ return false;
}
-#endif /* CONFIG_9P_ENABLE_9P2000_L */
-#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u
-LM_FLATTEN static bool marshal_Topen(struct _marshal_ctx *ctx, struct lib9p_msg_Topen *val) {
- uint32_t _size_offset;
- uint32_t _typ_offset;
- return false
- || ({ _size_offset = ctx->net_offset; ({ ctx->net_offset += 4; false; }); })
- || ({ _typ_offset = ctx->net_offset; ({ ctx->net_offset += 1; false; }); })
- || marshal_tag(ctx, &val->tag)
- || marshal_fid(ctx, &val->fid)
- || marshal_o(ctx, &val->mode)
- || ({ uint32le_encode(&ctx->net_bytes[_size_offset], ctx->net_offset - _size_offset); false; })
- || ({ ctx->net_bytes[_typ_offset] = 112; false; })
- ;
+static bool marshal_Rfsync(struct _marshal_ctx *ctx, struct lib9p_msg_Rfsync *val) {
+ uint32_t needed_size = 7;
+ if (needed_size > ctx->ctx->max_msg_size) {
+ lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%PRIu32)",
+ "Rfsync",
+ ctx->ctx->version ? "negotiated" : "server",
+ ctx->ctx->max_msg_size);
+ return true;
+ }
+ uint32_t offsetof_end = needed_size;
+ uint32_t offsetof_size = 0;
+ MARSHAL_U32LE(ctx, offsetof_end - offsetof_size);
+ MARSHAL_U8LE(ctx, 51);
+ MARSHAL_U16LE(ctx, val->tag);
+ return false;
}
-LM_FLATTEN static bool marshal_Tcreate(struct _marshal_ctx *ctx, struct lib9p_msg_Tcreate *val) {
- uint32_t _size_offset;
- uint32_t _typ_offset;
- return false
- || ({ _size_offset = ctx->net_offset; ({ ctx->net_offset += 4; false; }); })
- || ({ _typ_offset = ctx->net_offset; ({ ctx->net_offset += 1; false; }); })
- || marshal_tag(ctx, &val->tag)
- || marshal_fid(ctx, &val->fid)
- || marshal_s(ctx, &val->name)
- || marshal_dm(ctx, &val->perm)
- || marshal_o(ctx, &val->mode)
- || ({ uint32le_encode(&ctx->net_bytes[_size_offset], ctx->net_offset - _size_offset); false; })
- || ({ ctx->net_bytes[_typ_offset] = 114; false; })
- ;
+static bool marshal_Tlock(struct _marshal_ctx *ctx, struct lib9p_msg_Tlock *val) {
+ uint32_t needed_size = 38 + val->client_id.len;
+ if (needed_size > ctx->ctx->max_msg_size) {
+ lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%PRIu32)",
+ "Tlock",
+ ctx->ctx->version ? "negotiated" : "client",
+ ctx->ctx->max_msg_size);
+ return true;
+ }
+ uint32_t offsetof_end = needed_size;
+ uint32_t offsetof_size = 0;
+ MARSHAL_U32LE(ctx, offsetof_end - offsetof_size);
+ MARSHAL_U8LE(ctx, 52);
+ MARSHAL_U16LE(ctx, val->tag);
+ MARSHAL_U32LE(ctx, val->fid);
+ MARSHAL_U8LE(ctx, val->type);
+ MARSHAL_U32LE(ctx, val->flags & lock_flags_masks[ctx->ctx->version]);
+ MARSHAL_U64LE(ctx, val->start);
+ MARSHAL_U64LE(ctx, val->length);
+ MARSHAL_U32LE(ctx, val->proc_id);
+ MARSHAL_U16LE(ctx, val->client_id.len);
+ MARSHAL_BYTES_ZEROCOPY(ctx, val->client_id.utf8, val->client_id.len);
+ return false;
}
-#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */
-#if CONFIG_9P_ENABLE_9P2000_p9p
-LM_FLATTEN static bool marshal_Topenfd(struct _marshal_ctx *ctx, struct lib9p_msg_Topenfd *val) {
- uint32_t _size_offset;
- uint32_t _typ_offset;
- return false
- || ({ _size_offset = ctx->net_offset; ({ ctx->net_offset += 4; false; }); })
- || ({ _typ_offset = ctx->net_offset; ({ ctx->net_offset += 1; false; }); })
- || marshal_tag(ctx, &val->tag)
- || marshal_fid(ctx, &val->fid)
- || marshal_o(ctx, &val->mode)
- || ({ uint32le_encode(&ctx->net_bytes[_size_offset], ctx->net_offset - _size_offset); false; })
- || ({ ctx->net_bytes[_typ_offset] = 98; false; })
- ;
+static bool marshal_Rlock(struct _marshal_ctx *ctx, struct lib9p_msg_Rlock *val) {
+ uint32_t needed_size = 8;
+ if (needed_size > ctx->ctx->max_msg_size) {
+ lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%PRIu32)",
+ "Rlock",
+ ctx->ctx->version ? "negotiated" : "server",
+ ctx->ctx->max_msg_size);
+ return true;
+ }
+ uint32_t offsetof_end = needed_size;
+ uint32_t offsetof_size = 0;
+ MARSHAL_U32LE(ctx, offsetof_end - offsetof_size);
+ MARSHAL_U8LE(ctx, 53);
+ MARSHAL_U16LE(ctx, val->tag);
+ MARSHAL_U8LE(ctx, val->status);
+ return false;
}
-#endif /* CONFIG_9P_ENABLE_9P2000_p9p */
-#if CONFIG_9P_ENABLE_9P2000_L
-LM_FLATTEN static bool marshal_Tgetattr(struct _marshal_ctx *ctx, struct lib9p_msg_Tgetattr *val) {
- uint32_t _size_offset;
- uint32_t _typ_offset;
- return false
- || ({ _size_offset = ctx->net_offset; ({ ctx->net_offset += 4; false; }); })
- || ({ _typ_offset = ctx->net_offset; ({ ctx->net_offset += 1; false; }); })
- || marshal_tag(ctx, &val->tag)
- || marshal_fid(ctx, &val->fid)
- || marshal_getattr(ctx, &val->request_mask)
- || ({ uint32le_encode(&ctx->net_bytes[_size_offset], ctx->net_offset - _size_offset); false; })
- || ({ ctx->net_bytes[_typ_offset] = 24; false; })
- ;
+static bool marshal_Tgetlock(struct _marshal_ctx *ctx, struct lib9p_msg_Tgetlock *val) {
+ uint32_t needed_size = 34 + val->client_id.len;
+ if (needed_size > ctx->ctx->max_msg_size) {
+ lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%PRIu32)",
+ "Tgetlock",
+ ctx->ctx->version ? "negotiated" : "client",
+ ctx->ctx->max_msg_size);
+ return true;
+ }
+ uint32_t offsetof_end = needed_size;
+ uint32_t offsetof_size = 0;
+ MARSHAL_U32LE(ctx, offsetof_end - offsetof_size);
+ MARSHAL_U8LE(ctx, 54);
+ MARSHAL_U16LE(ctx, val->tag);
+ MARSHAL_U32LE(ctx, val->fid);
+ MARSHAL_U8LE(ctx, val->type);
+ MARSHAL_U64LE(ctx, val->start);
+ MARSHAL_U64LE(ctx, val->length);
+ MARSHAL_U32LE(ctx, val->proc_id);
+ MARSHAL_U16LE(ctx, val->client_id.len);
+ MARSHAL_BYTES_ZEROCOPY(ctx, val->client_id.utf8, val->client_id.len);
+ return false;
}
-LM_FLATTEN static bool marshal_Tsetattr(struct _marshal_ctx *ctx, struct lib9p_msg_Tsetattr *val) {
- uint32_t _size_offset;
- uint32_t _typ_offset;
- return false
- || ({ _size_offset = ctx->net_offset; ({ ctx->net_offset += 4; false; }); })
- || ({ _typ_offset = ctx->net_offset; ({ ctx->net_offset += 1; false; }); })
- || marshal_tag(ctx, &val->tag)
- || marshal_fid(ctx, &val->fid)
- || marshal_setattr(ctx, &val->valid)
- || marshal_4(ctx, &val->mode)
- || marshal_nuid(ctx, &val->uid)
- || marshal_nuid(ctx, &val->gid)
- || marshal_8(ctx, &val->filesize)
- || marshal_8(ctx, &val->atime_sec)
- || marshal_8(ctx, &val->atime_nsec)
- || marshal_8(ctx, &val->mtime_sec)
- || marshal_8(ctx, &val->mtime_nsec)
- || ({ uint32le_encode(&ctx->net_bytes[_size_offset], ctx->net_offset - _size_offset); false; })
- || ({ ctx->net_bytes[_typ_offset] = 26; false; })
- ;
+static bool marshal_Rgetlock(struct _marshal_ctx *ctx, struct lib9p_msg_Rgetlock *val) {
+ uint32_t needed_size = 30 + val->client_id.len;
+ if (needed_size > ctx->ctx->max_msg_size) {
+ lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%PRIu32)",
+ "Rgetlock",
+ ctx->ctx->version ? "negotiated" : "server",
+ ctx->ctx->max_msg_size);
+ return true;
+ }
+ uint32_t offsetof_end = needed_size;
+ uint32_t offsetof_size = 0;
+ MARSHAL_U32LE(ctx, offsetof_end - offsetof_size);
+ MARSHAL_U8LE(ctx, 55);
+ MARSHAL_U16LE(ctx, val->tag);
+ MARSHAL_U8LE(ctx, val->type);
+ MARSHAL_U64LE(ctx, val->start);
+ MARSHAL_U64LE(ctx, val->length);
+ MARSHAL_U32LE(ctx, val->proc_id);
+ MARSHAL_U16LE(ctx, val->client_id.len);
+ MARSHAL_BYTES_ZEROCOPY(ctx, val->client_id.utf8, val->client_id.len);
+ return false;
}
-LM_FLATTEN static bool marshal_Tlock(struct _marshal_ctx *ctx, struct lib9p_msg_Tlock *val) {
- uint32_t _size_offset;
- uint32_t _typ_offset;
- return false
- || ({ _size_offset = ctx->net_offset; ({ ctx->net_offset += 4; false; }); })
- || ({ _typ_offset = ctx->net_offset; ({ ctx->net_offset += 1; false; }); })
- || marshal_tag(ctx, &val->tag)
- || marshal_fid(ctx, &val->fid)
- || marshal_lock_type(ctx, &val->type)
- || marshal_lock_flags(ctx, &val->flags)
- || marshal_8(ctx, &val->start)
- || marshal_8(ctx, &val->length)
- || marshal_4(ctx, &val->proc_id)
- || marshal_s(ctx, &val->client_id)
- || ({ uint32le_encode(&ctx->net_bytes[_size_offset], ctx->net_offset - _size_offset); false; })
- || ({ ctx->net_bytes[_typ_offset] = 52; false; })
- ;
+static bool marshal_Tlink(struct _marshal_ctx *ctx, struct lib9p_msg_Tlink *val) {
+ uint32_t needed_size = 17 + val->name.len;
+ if (needed_size > ctx->ctx->max_msg_size) {
+ lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%PRIu32)",
+ "Tlink",
+ ctx->ctx->version ? "negotiated" : "client",
+ ctx->ctx->max_msg_size);
+ return true;
+ }
+ uint32_t offsetof_end = needed_size;
+ uint32_t offsetof_size = 0;
+ MARSHAL_U32LE(ctx, offsetof_end - offsetof_size);
+ MARSHAL_U8LE(ctx, 70);
+ MARSHAL_U16LE(ctx, val->tag);
+ MARSHAL_U32LE(ctx, val->dfid);
+ MARSHAL_U32LE(ctx, val->fid);
+ MARSHAL_U16LE(ctx, val->name.len);
+ MARSHAL_BYTES_ZEROCOPY(ctx, val->name.utf8, val->name.len);
+ return false;
}
-LM_FLATTEN static bool marshal_Rlock(struct _marshal_ctx *ctx, struct lib9p_msg_Rlock *val) {
- uint32_t _size_offset;
- uint32_t _typ_offset;
- return false
- || ({ _size_offset = ctx->net_offset; ({ ctx->net_offset += 4; false; }); })
- || ({ _typ_offset = ctx->net_offset; ({ ctx->net_offset += 1; false; }); })
- || marshal_tag(ctx, &val->tag)
- || marshal_lock_status(ctx, &val->status)
- || ({ uint32le_encode(&ctx->net_bytes[_size_offset], ctx->net_offset - _size_offset); false; })
- || ({ ctx->net_bytes[_typ_offset] = 53; false; })
- ;
+static bool marshal_Rlink(struct _marshal_ctx *ctx, struct lib9p_msg_Rlink *val) {
+ uint32_t needed_size = 7;
+ if (needed_size > ctx->ctx->max_msg_size) {
+ lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%PRIu32)",
+ "Rlink",
+ ctx->ctx->version ? "negotiated" : "server",
+ ctx->ctx->max_msg_size);
+ return true;
+ }
+ uint32_t offsetof_end = needed_size;
+ uint32_t offsetof_size = 0;
+ MARSHAL_U32LE(ctx, offsetof_end - offsetof_size);
+ MARSHAL_U8LE(ctx, 71);
+ MARSHAL_U16LE(ctx, val->tag);
+ return false;
}
-#endif /* CONFIG_9P_ENABLE_9P2000_L */
-#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u
-LM_ALWAYS_INLINE static bool marshal_stat(struct _marshal_ctx *ctx, struct lib9p_stat *val) {
- uint32_t _stat_size_offset;
- uint32_t _kern_type_offset;
- return false
- || ({ _stat_size_offset = ctx->net_offset; ({ ctx->net_offset += 2; false; }); })
- || ({ _kern_type_offset = ctx->net_offset; marshal_2(ctx, &val->kern_type); })
- || marshal_4(ctx, &val->kern_dev)
- || marshal_qid(ctx, &val->file_qid)
- || marshal_dm(ctx, &val->file_mode)
- || marshal_4(ctx, &val->file_atime)
- || marshal_4(ctx, &val->file_mtime)
- || marshal_8(ctx, &val->file_size)
- || marshal_s(ctx, &val->file_name)
- || marshal_s(ctx, &val->file_owner_uid)
- || marshal_s(ctx, &val->file_owner_gid)
- || marshal_s(ctx, &val->file_last_modified_uid)
-#if CONFIG_9P_ENABLE_9P2000_u
- || ( is_ver(ctx, 9P2000_u) && marshal_s(ctx, &val->file_extension) )
- || ( is_ver(ctx, 9P2000_u) && marshal_nuid(ctx, &val->file_owner_n_uid) )
- || ( is_ver(ctx, 9P2000_u) && marshal_nuid(ctx, &val->file_owner_n_gid) )
- || ( is_ver(ctx, 9P2000_u) && marshal_nuid(ctx, &val->file_last_modified_n_uid) )
-#endif /* CONFIG_9P_ENABLE_9P2000_u */
- || ({ uint16le_encode(&ctx->net_bytes[_stat_size_offset], ctx->net_offset - _kern_type_offset); false; })
- ;
+static bool marshal_Tmkdir(struct _marshal_ctx *ctx, struct lib9p_msg_Tmkdir *val) {
+ uint32_t needed_size = 21 + val->name.len;
+ if (needed_size > ctx->ctx->max_msg_size) {
+ lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%PRIu32)",
+ "Tmkdir",
+ ctx->ctx->version ? "negotiated" : "client",
+ ctx->ctx->max_msg_size);
+ return true;
+ }
+ uint32_t offsetof_end = needed_size;
+ uint32_t offsetof_size = 0;
+ MARSHAL_U32LE(ctx, offsetof_end - offsetof_size);
+ MARSHAL_U8LE(ctx, 72);
+ MARSHAL_U16LE(ctx, val->tag);
+ MARSHAL_U32LE(ctx, val->dfid);
+ MARSHAL_U16LE(ctx, val->name.len);
+ MARSHAL_BYTES_ZEROCOPY(ctx, val->name.utf8, val->name.len);
+ MARSHAL_U32LE(ctx, val->mode);
+ MARSHAL_U32LE(ctx, val->gid);
+ return false;
}
-#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */
-#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u
-LM_FLATTEN static bool marshal_Rauth(struct _marshal_ctx *ctx, struct lib9p_msg_Rauth *val) {
- uint32_t _size_offset;
- uint32_t _typ_offset;
- return false
- || ({ _size_offset = ctx->net_offset; ({ ctx->net_offset += 4; false; }); })
- || ({ _typ_offset = ctx->net_offset; ({ ctx->net_offset += 1; false; }); })
- || marshal_tag(ctx, &val->tag)
- || marshal_qid(ctx, &val->aqid)
- || ({ uint32le_encode(&ctx->net_bytes[_size_offset], ctx->net_offset - _size_offset); false; })
- || ({ ctx->net_bytes[_typ_offset] = 103; false; })
- ;
+static bool marshal_Rmkdir(struct _marshal_ctx *ctx, struct lib9p_msg_Rmkdir *val) {
+ uint32_t needed_size = 20;
+ if (needed_size > ctx->ctx->max_msg_size) {
+ lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%PRIu32)",
+ "Rmkdir",
+ ctx->ctx->version ? "negotiated" : "server",
+ ctx->ctx->max_msg_size);
+ return true;
+ }
+ uint32_t offsetof_end = needed_size;
+ uint32_t offsetof_size = 0;
+ MARSHAL_U32LE(ctx, offsetof_end - offsetof_size);
+ MARSHAL_U8LE(ctx, 73);
+ MARSHAL_U16LE(ctx, val->tag);
+ MARSHAL_U8LE(ctx, val->qid.type & qt_masks[ctx->ctx->version]);
+ MARSHAL_U32LE(ctx, val->qid.vers);
+ MARSHAL_U64LE(ctx, val->qid.path);
+ return false;
}
-LM_FLATTEN static bool marshal_Rattach(struct _marshal_ctx *ctx, struct lib9p_msg_Rattach *val) {
- uint32_t _size_offset;
- uint32_t _typ_offset;
- return false
- || ({ _size_offset = ctx->net_offset; ({ ctx->net_offset += 4; false; }); })
- || ({ _typ_offset = ctx->net_offset; ({ ctx->net_offset += 1; false; }); })
- || marshal_tag(ctx, &val->tag)
- || marshal_qid(ctx, &val->qid)
- || ({ uint32le_encode(&ctx->net_bytes[_size_offset], ctx->net_offset - _size_offset); false; })
- || ({ ctx->net_bytes[_typ_offset] = 105; false; })
- ;
+static bool marshal_Trenameat(struct _marshal_ctx *ctx, struct lib9p_msg_Trenameat *val) {
+ uint32_t needed_size = 19 + val->oldname.len + val->newname.len;
+ if (needed_size > ctx->ctx->max_msg_size) {
+ lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%PRIu32)",
+ "Trenameat",
+ ctx->ctx->version ? "negotiated" : "client",
+ ctx->ctx->max_msg_size);
+ return true;
+ }
+ uint32_t offsetof_end = needed_size;
+ uint32_t offsetof_size = 0;
+ MARSHAL_U32LE(ctx, offsetof_end - offsetof_size);
+ MARSHAL_U8LE(ctx, 74);
+ MARSHAL_U16LE(ctx, val->tag);
+ MARSHAL_U32LE(ctx, val->olddirfid);
+ MARSHAL_U16LE(ctx, val->oldname.len);
+ MARSHAL_BYTES_ZEROCOPY(ctx, val->oldname.utf8, val->oldname.len);
+ MARSHAL_U32LE(ctx, val->newdirfid);
+ MARSHAL_U16LE(ctx, val->newname.len);
+ MARSHAL_BYTES_ZEROCOPY(ctx, val->newname.utf8, val->newname.len);
+ return false;
}
-LM_FLATTEN static bool marshal_Rwalk(struct _marshal_ctx *ctx, struct lib9p_msg_Rwalk *val) {
- uint32_t _size_offset;
- uint32_t _typ_offset;
- return false
- || ({ _size_offset = ctx->net_offset; ({ ctx->net_offset += 4; false; }); })
- || ({ _typ_offset = ctx->net_offset; ({ ctx->net_offset += 1; false; }); })
- || marshal_tag(ctx, &val->tag)
- || marshal_2(ctx, &val->nwqid)
- || ({ bool err = false;
- for (typeof(val->nwqid) i = 0; i < val->nwqid && !err; i++)
- err = marshal_qid(ctx, &val->wqid[i]);
- err; })
- || ({ uint32le_encode(&ctx->net_bytes[_size_offset], ctx->net_offset - _size_offset); false; })
- || ({ ctx->net_bytes[_typ_offset] = 111; false; })
- ;
+static bool marshal_Rrenameat(struct _marshal_ctx *ctx, struct lib9p_msg_Rrenameat *val) {
+ uint32_t needed_size = 7;
+ if (needed_size > ctx->ctx->max_msg_size) {
+ lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%PRIu32)",
+ "Rrenameat",
+ ctx->ctx->version ? "negotiated" : "server",
+ ctx->ctx->max_msg_size);
+ return true;
+ }
+ uint32_t offsetof_end = needed_size;
+ uint32_t offsetof_size = 0;
+ MARSHAL_U32LE(ctx, offsetof_end - offsetof_size);
+ MARSHAL_U8LE(ctx, 75);
+ MARSHAL_U16LE(ctx, val->tag);
+ return false;
}
-#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */
-#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u
-LM_FLATTEN static bool marshal_Ropen(struct _marshal_ctx *ctx, struct lib9p_msg_Ropen *val) {
- uint32_t _size_offset;
- uint32_t _typ_offset;
- return false
- || ({ _size_offset = ctx->net_offset; ({ ctx->net_offset += 4; false; }); })
- || ({ _typ_offset = ctx->net_offset; ({ ctx->net_offset += 1; false; }); })
- || marshal_tag(ctx, &val->tag)
- || marshal_qid(ctx, &val->qid)
- || marshal_4(ctx, &val->iounit)
- || ({ uint32le_encode(&ctx->net_bytes[_size_offset], ctx->net_offset - _size_offset); false; })
- || ({ ctx->net_bytes[_typ_offset] = 113; false; })
- ;
+static bool marshal_Tunlinkat(struct _marshal_ctx *ctx, struct lib9p_msg_Tunlinkat *val) {
+ uint32_t needed_size = 17 + val->name.len;
+ if (needed_size > ctx->ctx->max_msg_size) {
+ lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%PRIu32)",
+ "Tunlinkat",
+ ctx->ctx->version ? "negotiated" : "client",
+ ctx->ctx->max_msg_size);
+ return true;
+ }
+ uint32_t offsetof_end = needed_size;
+ uint32_t offsetof_size = 0;
+ MARSHAL_U32LE(ctx, offsetof_end - offsetof_size);
+ MARSHAL_U8LE(ctx, 76);
+ MARSHAL_U16LE(ctx, val->tag);
+ MARSHAL_U32LE(ctx, val->dirfd);
+ MARSHAL_U16LE(ctx, val->name.len);
+ MARSHAL_BYTES_ZEROCOPY(ctx, val->name.utf8, val->name.len);
+ MARSHAL_U32LE(ctx, val->flags);
+ return false;
}
-LM_FLATTEN static bool marshal_Rcreate(struct _marshal_ctx *ctx, struct lib9p_msg_Rcreate *val) {
- uint32_t _size_offset;
- uint32_t _typ_offset;
- return false
- || ({ _size_offset = ctx->net_offset; ({ ctx->net_offset += 4; false; }); })
- || ({ _typ_offset = ctx->net_offset; ({ ctx->net_offset += 1; false; }); })
- || marshal_tag(ctx, &val->tag)
- || marshal_qid(ctx, &val->qid)
- || marshal_4(ctx, &val->iounit)
- || ({ uint32le_encode(&ctx->net_bytes[_size_offset], ctx->net_offset - _size_offset); false; })
- || ({ ctx->net_bytes[_typ_offset] = 115; false; })
- ;
+static bool marshal_Runlinkat(struct _marshal_ctx *ctx, struct lib9p_msg_Runlinkat *val) {
+ uint32_t needed_size = 7;
+ if (needed_size > ctx->ctx->max_msg_size) {
+ lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%PRIu32)",
+ "Runlinkat",
+ ctx->ctx->version ? "negotiated" : "server",
+ ctx->ctx->max_msg_size);
+ return true;
+ }
+ uint32_t offsetof_end = needed_size;
+ uint32_t offsetof_size = 0;
+ MARSHAL_U32LE(ctx, offsetof_end - offsetof_size);
+ MARSHAL_U8LE(ctx, 77);
+ MARSHAL_U16LE(ctx, val->tag);
+ return false;
}
-#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */
-#if CONFIG_9P_ENABLE_9P2000_p9p
-LM_FLATTEN static bool marshal_Ropenfd(struct _marshal_ctx *ctx, struct lib9p_msg_Ropenfd *val) {
- uint32_t _size_offset;
- uint32_t _typ_offset;
- return false
- || ({ _size_offset = ctx->net_offset; ({ ctx->net_offset += 4; false; }); })
- || ({ _typ_offset = ctx->net_offset; ({ ctx->net_offset += 1; false; }); })
- || marshal_tag(ctx, &val->tag)
- || marshal_qid(ctx, &val->qid)
- || marshal_4(ctx, &val->iounit)
- || marshal_4(ctx, &val->unixfd)
- || ({ uint32le_encode(&ctx->net_bytes[_size_offset], ctx->net_offset - _size_offset); false; })
- || ({ ctx->net_bytes[_typ_offset] = 99; false; })
- ;
+#endif /* CONFIG_9P_ENABLE_9P2000_L */
+#if CONFIG_9P_ENABLE_9P2000_e
+static bool marshal_Tsession(struct _marshal_ctx *ctx, struct lib9p_msg_Tsession *val) {
+ uint32_t needed_size = 15;
+ if (needed_size > ctx->ctx->max_msg_size) {
+ lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%PRIu32)",
+ "Tsession",
+ ctx->ctx->version ? "negotiated" : "client",
+ ctx->ctx->max_msg_size);
+ return true;
+ }
+ uint32_t offsetof_end = needed_size;
+ uint32_t offsetof_size = 0;
+ MARSHAL_U32LE(ctx, offsetof_end - offsetof_size);
+ MARSHAL_U8LE(ctx, 150);
+ MARSHAL_U16LE(ctx, val->tag);
+ MARSHAL_U64LE(ctx, val->key);
+ return false;
}
-#endif /* CONFIG_9P_ENABLE_9P2000_p9p */
-#if CONFIG_9P_ENABLE_9P2000_L
-LM_FLATTEN static bool marshal_Rlopen(struct _marshal_ctx *ctx, struct lib9p_msg_Rlopen *val) {
- uint32_t _size_offset;
- uint32_t _typ_offset;
- return false
- || ({ _size_offset = ctx->net_offset; ({ ctx->net_offset += 4; false; }); })
- || ({ _typ_offset = ctx->net_offset; ({ ctx->net_offset += 1; false; }); })
- || marshal_tag(ctx, &val->tag)
- || marshal_qid(ctx, &val->qid)
- || marshal_4(ctx, &val->iounit)
- || ({ uint32le_encode(&ctx->net_bytes[_size_offset], ctx->net_offset - _size_offset); false; })
- || ({ ctx->net_bytes[_typ_offset] = 13; false; })
- ;
+static bool marshal_Rsession(struct _marshal_ctx *ctx, struct lib9p_msg_Rsession *val) {
+ uint32_t needed_size = 7;
+ if (needed_size > ctx->ctx->max_msg_size) {
+ lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%PRIu32)",
+ "Rsession",
+ ctx->ctx->version ? "negotiated" : "server",
+ ctx->ctx->max_msg_size);
+ return true;
+ }
+ uint32_t offsetof_end = needed_size;
+ uint32_t offsetof_size = 0;
+ MARSHAL_U32LE(ctx, offsetof_end - offsetof_size);
+ MARSHAL_U8LE(ctx, 151);
+ MARSHAL_U16LE(ctx, val->tag);
+ return false;
}
-LM_FLATTEN static bool marshal_Rlcreate(struct _marshal_ctx *ctx, struct lib9p_msg_Rlcreate *val) {
- uint32_t _size_offset;
- uint32_t _typ_offset;
- return false
- || ({ _size_offset = ctx->net_offset; ({ ctx->net_offset += 4; false; }); })
- || ({ _typ_offset = ctx->net_offset; ({ ctx->net_offset += 1; false; }); })
- || marshal_tag(ctx, &val->tag)
- || marshal_qid(ctx, &val->qid)
- || marshal_4(ctx, &val->iounit)
- || ({ uint32le_encode(&ctx->net_bytes[_size_offset], ctx->net_offset - _size_offset); false; })
- || ({ ctx->net_bytes[_typ_offset] = 15; false; })
- ;
+static bool marshal_Tsread(struct _marshal_ctx *ctx, struct lib9p_msg_Tsread *val) {
+ uint64_t needed_size = 13;
+ for (uint16_t i = 0; i < val->nwname; i++) {
+ needed_size += 2 + val->wname[i].len;
+ }
+ if (needed_size > (uint64_t)(ctx->ctx->max_msg_size)) {
+ lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%PRIu32)",
+ "Tsread",
+ ctx->ctx->version ? "negotiated" : "client",
+ ctx->ctx->max_msg_size);
+ return true;
+ }
+ uint32_t offsetof_end = (uint32_t)needed_size;
+ uint32_t offsetof_size = 0;
+ MARSHAL_U32LE(ctx, offsetof_end - offsetof_size);
+ MARSHAL_U8LE(ctx, 152);
+ MARSHAL_U16LE(ctx, val->tag);
+ MARSHAL_U32LE(ctx, val->fid);
+ MARSHAL_U16LE(ctx, val->nwname);
+ for (uint16_t i = 0; i < val->nwname; i++) {
+ MARSHAL_U16LE(ctx, val->wname[i].len);
+ MARSHAL_BYTES_ZEROCOPY(ctx, val->wname[i].utf8, val->wname[i].len);
+ }
+ return false;
}
-LM_FLATTEN static bool marshal_Rsymlink(struct _marshal_ctx *ctx, struct lib9p_msg_Rsymlink *val) {
- uint32_t _size_offset;
- uint32_t _typ_offset;
- return false
- || ({ _size_offset = ctx->net_offset; ({ ctx->net_offset += 4; false; }); })
- || ({ _typ_offset = ctx->net_offset; ({ ctx->net_offset += 1; false; }); })
- || marshal_tag(ctx, &val->tag)
- || marshal_qid(ctx, &val->qid)
- || ({ uint32le_encode(&ctx->net_bytes[_size_offset], ctx->net_offset - _size_offset); false; })
- || ({ ctx->net_bytes[_typ_offset] = 17; false; })
- ;
+static bool marshal_Rsread(struct _marshal_ctx *ctx, struct lib9p_msg_Rsread *val) {
+ uint64_t needed_size = 11 + val->count;
+ if (needed_size > (uint64_t)(ctx->ctx->max_msg_size)) {
+ lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%PRIu32)",
+ "Rsread",
+ ctx->ctx->version ? "negotiated" : "server",
+ ctx->ctx->max_msg_size);
+ return true;
+ }
+ uint32_t offsetof_end = (uint32_t)needed_size;
+ uint32_t offsetof_size = 0;
+ MARSHAL_U32LE(ctx, offsetof_end - offsetof_size);
+ MARSHAL_U8LE(ctx, 153);
+ MARSHAL_U16LE(ctx, val->tag);
+ MARSHAL_U32LE(ctx, val->count);
+ MARSHAL_BYTES_ZEROCOPY(ctx, val->data, val->count);
+ return false;
}
-LM_FLATTEN static bool marshal_Rmknod(struct _marshal_ctx *ctx, struct lib9p_msg_Rmknod *val) {
- uint32_t _size_offset;
- uint32_t _typ_offset;
- return false
- || ({ _size_offset = ctx->net_offset; ({ ctx->net_offset += 4; false; }); })
- || ({ _typ_offset = ctx->net_offset; ({ ctx->net_offset += 1; false; }); })
- || marshal_tag(ctx, &val->tag)
- || marshal_qid(ctx, &val->qid)
- || ({ uint32le_encode(&ctx->net_bytes[_size_offset], ctx->net_offset - _size_offset); false; })
- || ({ ctx->net_bytes[_typ_offset] = 19; false; })
- ;
+static bool marshal_Tswrite(struct _marshal_ctx *ctx, struct lib9p_msg_Tswrite *val) {
+ uint64_t needed_size = 17 + val->count;
+ for (uint16_t i = 0; i < val->nwname; i++) {
+ needed_size += 2 + val->wname[i].len;
+ }
+ if (needed_size > (uint64_t)(ctx->ctx->max_msg_size)) {
+ lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%PRIu32)",
+ "Tswrite",
+ ctx->ctx->version ? "negotiated" : "client",
+ ctx->ctx->max_msg_size);
+ return true;
+ }
+ uint32_t offsetof_end = (uint32_t)needed_size;
+ uint32_t offsetof_size = 0;
+ MARSHAL_U32LE(ctx, offsetof_end - offsetof_size);
+ MARSHAL_U8LE(ctx, 154);
+ MARSHAL_U16LE(ctx, val->tag);
+ MARSHAL_U32LE(ctx, val->fid);
+ MARSHAL_U16LE(ctx, val->nwname);
+ for (uint16_t i = 0; i < val->nwname; i++) {
+ MARSHAL_U16LE(ctx, val->wname[i].len);
+ MARSHAL_BYTES_ZEROCOPY(ctx, val->wname[i].utf8, val->wname[i].len);
+ }
+ MARSHAL_U32LE(ctx, val->count);
+ MARSHAL_BYTES_ZEROCOPY(ctx, val->data, val->count);
+ return false;
}
-LM_FLATTEN static bool marshal_Rgetattr(struct _marshal_ctx *ctx, struct lib9p_msg_Rgetattr *val) {
- uint32_t _size_offset;
- uint32_t _typ_offset;
- return false
- || ({ _size_offset = ctx->net_offset; ({ ctx->net_offset += 4; false; }); })
- || ({ _typ_offset = ctx->net_offset; ({ ctx->net_offset += 1; false; }); })
- || marshal_tag(ctx, &val->tag)
- || marshal_8(ctx, &val->valid)
- || marshal_qid(ctx, &val->qid)
- || marshal_4(ctx, &val->mode)
- || marshal_nuid(ctx, &val->uid)
- || marshal_nuid(ctx, &val->gid)
- || marshal_8(ctx, &val->nlink)
- || marshal_8(ctx, &val->rdev)
- || marshal_8(ctx, &val->filesize)
- || marshal_8(ctx, &val->blksize)
- || marshal_8(ctx, &val->blocks)
- || marshal_8(ctx, &val->atime_sec)
- || marshal_8(ctx, &val->atime_nsec)
- || marshal_8(ctx, &val->mtime_sec)
- || marshal_8(ctx, &val->mtime_nsec)
- || marshal_8(ctx, &val->ctime_sec)
- || marshal_8(ctx, &val->ctime_nsec)
- || marshal_8(ctx, &val->btime_sec)
- || marshal_8(ctx, &val->btime_nsec)
- || marshal_8(ctx, &val->gen)
- || marshal_8(ctx, &val->data_version)
- || ({ uint32le_encode(&ctx->net_bytes[_size_offset], ctx->net_offset - _size_offset); false; })
- || ({ ctx->net_bytes[_typ_offset] = 25; false; })
- ;
+static bool marshal_Rswrite(struct _marshal_ctx *ctx, struct lib9p_msg_Rswrite *val) {
+ uint32_t needed_size = 11;
+ if (needed_size > ctx->ctx->max_msg_size) {
+ lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%PRIu32)",
+ "Rswrite",
+ ctx->ctx->version ? "negotiated" : "server",
+ ctx->ctx->max_msg_size);
+ return true;
+ }
+ uint32_t offsetof_end = needed_size;
+ uint32_t offsetof_size = 0;
+ MARSHAL_U32LE(ctx, offsetof_end - offsetof_size);
+ MARSHAL_U8LE(ctx, 155);
+ MARSHAL_U16LE(ctx, val->tag);
+ MARSHAL_U32LE(ctx, val->count);
+ return false;
}
+#endif /* CONFIG_9P_ENABLE_9P2000_e */
-LM_FLATTEN static bool marshal_Rmkdir(struct _marshal_ctx *ctx, struct lib9p_msg_Rmkdir *val) {
- uint32_t _size_offset;
- uint32_t _typ_offset;
- return false
- || ({ _size_offset = ctx->net_offset; ({ ctx->net_offset += 4; false; }); })
- || ({ _typ_offset = ctx->net_offset; ({ ctx->net_offset += 1; false; }); })
- || marshal_tag(ctx, &val->tag)
- || marshal_qid(ctx, &val->qid)
- || ({ uint32le_encode(&ctx->net_bytes[_size_offset], ctx->net_offset - _size_offset); false; })
- || ({ ctx->net_bytes[_typ_offset] = 73; false; })
- ;
-}
+/* function tables ************************************************************/
+const uint32_t _lib9p_table_msg_min_size[LIB9P_VER_NUM] = {
+ [LIB9P_VER_unknown] = 9,
+#if CONFIG_9P_ENABLE_9P2000
+ [LIB9P_VER_9P2000] = 9,
+#endif /* CONFIG_9P_ENABLE_9P2000 */
+#if CONFIG_9P_ENABLE_9P2000_L
+ [LIB9P_VER_9P2000_L] = 9,
#endif /* CONFIG_9P_ENABLE_9P2000_L */
-#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u
-LM_FLATTEN static bool marshal_Rstat(struct _marshal_ctx *ctx, struct lib9p_msg_Rstat *val) {
- uint32_t _size_offset;
- uint32_t _typ_offset;
- uint32_t _nstat_offset;
- uint32_t _stat_offset;
- return false
- || ({ _size_offset = ctx->net_offset; ({ ctx->net_offset += 4; false; }); })
- || ({ _typ_offset = ctx->net_offset; ({ ctx->net_offset += 1; false; }); })
- || marshal_tag(ctx, &val->tag)
- || ({ _nstat_offset = ctx->net_offset; ({ ctx->net_offset += 2; false; }); })
- || ({ _stat_offset = ctx->net_offset; marshal_stat(ctx, &val->stat); })
- || ({ uint32le_encode(&ctx->net_bytes[_size_offset], ctx->net_offset - _size_offset); false; })
- || ({ ctx->net_bytes[_typ_offset] = 125; false; })
- || ({ uint16le_encode(&ctx->net_bytes[_nstat_offset], ctx->net_offset - _stat_offset); false; })
- ;
-}
-
-LM_FLATTEN static bool marshal_Twstat(struct _marshal_ctx *ctx, struct lib9p_msg_Twstat *val) {
- uint32_t _size_offset;
- uint32_t _typ_offset;
- uint32_t _nstat_offset;
- uint32_t _stat_offset;
- return false
- || ({ _size_offset = ctx->net_offset; ({ ctx->net_offset += 4; false; }); })
- || ({ _typ_offset = ctx->net_offset; ({ ctx->net_offset += 1; false; }); })
- || marshal_tag(ctx, &val->tag)
- || marshal_fid(ctx, &val->fid)
- || ({ _nstat_offset = ctx->net_offset; ({ ctx->net_offset += 2; false; }); })
- || ({ _stat_offset = ctx->net_offset; marshal_stat(ctx, &val->stat); })
- || ({ uint32le_encode(&ctx->net_bytes[_size_offset], ctx->net_offset - _size_offset); false; })
- || ({ ctx->net_bytes[_typ_offset] = 126; false; })
- || ({ uint16le_encode(&ctx->net_bytes[_nstat_offset], ctx->net_offset - _stat_offset); false; })
- ;
-}
-#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */
-
-/* function tables ************************************************************/
+#if CONFIG_9P_ENABLE_9P2000_e
+ [LIB9P_VER_9P2000_e] = 9,
+#endif /* CONFIG_9P_ENABLE_9P2000_e */
+#if CONFIG_9P_ENABLE_9P2000_p9p
+ [LIB9P_VER_9P2000_p9p] = 9,
+#endif /* CONFIG_9P_ENABLE_9P2000_p9p */
+#if CONFIG_9P_ENABLE_9P2000_u
+ [LIB9P_VER_9P2000_u] = 13,
+#endif /* CONFIG_9P_ENABLE_9P2000_u */
+};
#define _MSG_RECV(typ) [LIB9P_TYP_##typ/2] = { \
.basesize = sizeof(struct lib9p_msg_##typ), \
diff --git a/lib9p/idl.gen b/lib9p/idl.gen
index adb15ce..f2b4f13 100755
--- a/lib9p/idl.gen
+++ b/lib9p/idl.gen
@@ -5,6 +5,7 @@
# Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com>
# SPDX-License-Identifier: AGPL-3.0-or-later
+import enum
import graphlib
import os.path
import sys
@@ -145,6 +146,9 @@ def ifdef_pop(n: int) -> str:
return ret
+# topo_sorted() ################################################################
+
+
def topo_sorted(typs: list[idl.Type]) -> typing.Iterable[idl.Type]:
ts: graphlib.TopologicalSorter[idl.Type] = graphlib.TopologicalSorter()
for typ in typs:
@@ -163,6 +167,189 @@ def topo_sorted(typs: list[idl.Type]) -> typing.Iterable[idl.Type]:
return ts.static_order()
+# walk() #######################################################################
+
+
+class Path:
+ root: idl.Type
+ elems: list[idl.StructMember]
+
+ def __init__(
+ self, root: idl.Type, elems: list[idl.StructMember] | None = None
+ ) -> None:
+ self.root = root
+ self.elems = elems if elems is not None else []
+
+ def add(self, elem: idl.StructMember) -> "Path":
+ return Path(self.root, self.elems + [elem])
+
+ def parent(self) -> "Path":
+ return Path(self.root, self.elems[:-1])
+
+ def c_str(self, base: str, loopdepth: int = 0) -> str:
+ ret = base
+ for i, elem in enumerate(self.elems):
+ if i > 0:
+ ret += "."
+ ret += elem.name
+ if elem.cnt:
+ ret += f"[{chr(ord('i')+loopdepth)}]"
+ loopdepth += 1
+ return ret
+
+ def __str__(self) -> str:
+ return self.c_str(self.root.name + "->")
+
+
+class WalkCmd(enum.Enum):
+ KEEP_GOING = 1
+ DONT_RECURSE = 2
+ ABORT = 3
+
+
+type WalkHandler = typing.Callable[
+ [Path], tuple[WalkCmd, typing.Callable[[], None] | None]
+]
+
+
+def _walk(path: Path, handle: WalkHandler) -> WalkCmd:
+ typ = path.elems[-1].typ if path.elems else path.root
+
+ ret, atexit = handle(path)
+
+ if isinstance(typ, idl.Struct):
+ match ret:
+ case WalkCmd.KEEP_GOING:
+ for member in typ.members:
+ if _walk(path.add(member), handle) == WalkCmd.ABORT:
+ ret = WalkCmd.ABORT
+ break
+ case WalkCmd.DONT_RECURSE:
+ ret = WalkCmd.KEEP_GOING
+ case WalkCmd.ABORT:
+ ret = WalkCmd.ABORT
+ case _:
+ assert False, f"invalid cmd: {ret}"
+
+ if atexit:
+ atexit()
+ return ret
+
+
+def walk(typ: idl.Type, handle: WalkHandler) -> None:
+ _walk(Path(typ), handle)
+
+
+# get_buffer_size() ############################################################
+
+
+class BufferSize:
+ min_size: int # really just here to sanity-check against typ.min_size(version)
+ exp_size: int # "expected" or max-reasonable size
+ max_size: int # really just here to sanity-check against typ.max_size(version)
+ max_copy: int
+ max_copy_extra: str
+ max_iov: int
+ max_iov_extra: str
+ _starts_with_copy: bool
+ _ends_with_copy: bool
+
+ def __init__(self) -> None:
+ self.min_size = 0
+ self.exp_size = 0
+ self.max_size = 0
+ self.max_copy = 0
+ self.max_copy_extra = ""
+ self.max_iov = 0
+ self.max_iov_extra = ""
+ self._starts_with_copy = False
+ self._ends_with_copy = False
+
+
+def get_buffer_size(typ: idl.Type, version: str) -> BufferSize:
+ assert isinstance(typ, idl.Primitive) or (version in typ.in_versions)
+
+ ret = BufferSize()
+
+ if not isinstance(typ, idl.Struct):
+ assert typ.static_size
+ ret.min_size = typ.static_size
+ ret.exp_size = typ.static_size
+ ret.max_size = typ.static_size
+ ret.max_copy = typ.static_size
+ ret.max_iov = 1
+ ret._starts_with_copy = True
+ ret._ends_with_copy = True
+ return ret
+
+ def handle(path: Path) -> tuple[WalkCmd, None]:
+ nonlocal ret
+ if path.elems:
+ child = path.elems[-1]
+ if version not in child.in_versions:
+ return WalkCmd.DONT_RECURSE, None
+ if child.cnt:
+ if child.typ.static_size == 1: # SPECIAL (zerocopy)
+ ret.max_iov += 1
+ # HEURISTIC: 27 for strings (max-strlen from 9P1), 8KiB for other data
+ ret.exp_size += 27 if child.name == "utf8" else 8192
+ ret.max_size += child.max_cnt
+ ret._ends_with_copy = False
+ return WalkCmd.DONT_RECURSE, None
+ sub = get_buffer_size(child.typ, version)
+ ret.exp_size += sub.exp_size * 16 # HEURISTIC: MAXWELEM
+ ret.max_size += sub.max_size * child.max_cnt
+ if child.name == "wname" and path.root.name in (
+ "Tsread",
+ "Tswrite",
+ ): # SPECIAL (9P2000.e)
+ assert ret._ends_with_copy
+ assert sub._starts_with_copy
+ assert not sub._ends_with_copy
+ ret.max_copy_extra = (
+ f" + (CONFIG_9P_MAX_9P2000_e_WELEM * {sub.max_copy})"
+ )
+ ret.max_iov_extra = (
+ f" + (CONFIG_9P_MAX_9P2000_e_WELEM * {sub.max_iov})"
+ )
+ ret.max_iov -= 1
+ else:
+ ret.max_copy += sub.max_copy * child.max_cnt
+ if sub.max_iov == 1 and sub._starts_with_copy: # is purely copy
+ ret.max_iov += 1
+ else: # contains zero-copy segments
+ ret.max_iov += sub.max_iov * child.max_cnt
+ if ret._ends_with_copy and sub._starts_with_copy:
+ # we can merge this one
+ ret.max_iov -= 1
+ if (
+ sub._ends_with_copy
+ and sub._starts_with_copy
+ and sub.max_iov > 1
+ ):
+ # we can merge these
+ ret.max_iov -= child.max_cnt - 1
+ ret._ends_with_copy = sub._ends_with_copy
+ return WalkCmd.DONT_RECURSE, None
+ elif not isinstance(child.typ, idl.Struct):
+ assert child.typ.static_size
+ if not ret._ends_with_copy:
+ if ret.max_size == 0:
+ ret._starts_with_copy = True
+ ret.max_iov += 1
+ ret._ends_with_copy = True
+ ret.min_size += child.typ.static_size
+ ret.exp_size += child.typ.static_size
+ ret.max_size += child.typ.static_size
+ ret.max_copy += child.typ.static_size
+ return WalkCmd.KEEP_GOING, None
+
+ walk(typ, handle)
+ assert ret.min_size == typ.min_size(version)
+ assert ret.max_size == typ.max_size(version)
+ return ret
+
+
# Generate .h ##################################################################
@@ -177,6 +364,8 @@ def gen_h(versions: set[str], typs: list[idl.Type]) -> str:
#endif
#include <stdint.h> /* for uint{{n}}_t types */
+
+#include <libhw/generic/net.h> /* for struct iovec */
"""
id2typ: dict[int, idl.Message] = {}
@@ -192,6 +381,14 @@ def gen_h(versions: set[str], typs: list[idl.Type]) -> str:
ret += "\n"
ret += f"#ifndef {c_ver_ifdef({ver})}\n"
ret += f"\t#error config.h must define {c_ver_ifdef({ver})}\n"
+ if ver == "9P2000.e": # SPECIAL (9P2000.e)
+ ret += "#else\n"
+ ret += f"\t#if {c_ver_ifdef({ver})}\n"
+ ret += "\t\t#ifndef(CONFIG_9P_MAX_9P2000_e_WELEM)\n"
+ ret += f"\t\t\t#error if {c_ver_ifdef({ver})} then config.h must define CONFIG_9P_MAX_9P2000_e_WELEM\n"
+ ret += "\t\t#endif\n"
+ ret += "\t\tstatic_assert(CONFIG_9P_MAX_9P2000_e_WELEM > 0);\n"
+ ret += "\t#endif\n"
ret += "#endif\n"
ret += f"""
@@ -251,16 +448,20 @@ enum {idprefix}version {{
ret += ifdef_push(1, c_ver_ifdef(typ.in_versions))
def sum_size(typ: idl.Type, version: str) -> str:
- min_size = typ.min_size(version)
- max_size = typ.max_size(version)
- assert min_size <= max_size and max_size < u64max
+ sz = get_buffer_size(typ, version)
+ assert (
+ sz.min_size <= sz.exp_size
+ and sz.exp_size <= sz.max_size
+ and sz.max_size < u64max
+ )
ret = ""
- if min_size == max_size:
- ret += f"size = {min_size:,}"
+ if sz.min_size == sz.max_size:
+ ret += f"size = {sz.min_size:,}"
else:
- ret += f"min_size = {min_size:,} ; max_size = {max_size:,}"
- if max_size > u32max:
+ ret += f"min_size = {sz.min_size:,} ; exp_size = {sz.exp_size:,} ; max_size = {sz.max_size:,}"
+ if sz.max_size > u32max:
ret += " (warning: >UINT32_MAX)"
+ ret += f" ; max_iov = {sz.max_iov:,}{sz.max_iov_extra} ; max_copy = {sz.max_copy:,}{sz.max_copy_extra}"
return ret
ret += per_version_comment(typ, sum_size)
@@ -331,6 +532,87 @@ enum {idprefix}version {{
ret += "};\n"
ret += ifdef_pop(0)
+ ret += """
+/* containers *****************************************************************/
+"""
+ ret += "\n"
+ ret += f"#define _{idprefix.upper()}MAX(a, b) ((a) > (b)) ? (a) : (b)\n"
+
+ tmsg_max_iov: dict[str, int] = {}
+ tmsg_max_copy: dict[str, int] = {}
+ rmsg_max_iov: dict[str, int] = {}
+ rmsg_max_copy: dict[str, int] = {}
+ for typ in typs:
+ if not isinstance(typ, idl.Message):
+ continue
+ if typ.name in ("Tsread", "Tswrite"): # SPECIAL (9P2000.e)
+ continue
+ max_iov = tmsg_max_iov if typ.msgid % 2 == 0 else rmsg_max_iov
+ max_copy = tmsg_max_copy if typ.msgid % 2 == 0 else rmsg_max_copy
+ for version in typ.in_versions:
+ if version not in max_iov:
+ max_iov[version] = 0
+ max_copy[version] = 0
+ sz = get_buffer_size(typ, version)
+ if sz.max_iov > max_iov[version]:
+ max_iov[version] = sz.max_iov
+ if sz.max_copy > max_copy[version]:
+ max_copy[version] = sz.max_copy
+
+ for name, table in [
+ ("tmsg_max_iov", tmsg_max_iov),
+ ("tmsg_max_copy", tmsg_max_copy),
+ ("rmsg_max_iov", rmsg_max_iov),
+ ("rmsg_max_copy", rmsg_max_copy),
+ ]:
+ inv: dict[int, set[str]] = {}
+ for version, maxval in table.items():
+ if maxval not in inv:
+ inv[maxval] = set()
+ inv[maxval].add(version)
+
+ ret += "\n"
+ directive = "if"
+ seen_e = False # SPECIAL (9P2000.e)
+ for maxval in sorted(inv, reverse=True):
+ ret += f"#{directive} {c_ver_ifdef(inv[maxval])}\n"
+ indent = 1
+ if name.startswith("tmsg") and not seen_e: # SPECIAL (9P2000.e)
+ typ = next(typ for typ in typs if typ.name == "Tswrite")
+ sz = get_buffer_size(typ, "9P2000.e")
+ match name:
+ case "tmsg_max_iov":
+ maxexpr = f"{sz.max_iov}{sz.max_iov_extra}"
+ case "tmsg_max_copy":
+ maxexpr = f"{sz.max_copy}{sz.max_copy_extra}"
+ case _:
+ assert False
+ ret += f"\t#if {c_ver_ifdef({"9P2000.e"})}\n"
+ ret += f"\t\t#define {idprefix.upper()}{name.upper()} _{idprefix.upper()}MAX({maxval}, {maxexpr})\n"
+ ret += f"\t#else\n"
+ indent += 1
+ ret += f"{'\t'*indent}#define {idprefix.upper()}{name.upper()} {maxval}\n"
+ if name.startswith("tmsg") and not seen_e: # SPECIAL (9P2000.e)
+ ret += "\t#endif\n"
+ if "9P2000.e" in inv[maxval]:
+ seen_e = True
+ directive = "elif"
+ ret += "#endif\n"
+
+ ret += "\n"
+ ret += f"struct {idprefix}Tmsg_send_buf {{\n"
+ ret += f"\tsize_t iov_cnt;\n"
+ ret += f"\tstruct iovec iov[{idprefix.upper()}TMSG_MAX_IOV];\n"
+ ret += f"\tuint8_t copied[{idprefix.upper()}TMSG_MAX_COPY];\n"
+ ret += "};\n"
+
+ ret += "\n"
+ ret += f"struct {idprefix}Rmsg_send_buf {{\n"
+ ret += f"\tsize_t iov_cnt;\n"
+ ret += f"\tstruct iovec iov[{idprefix.upper()}RMSG_MAX_IOV];\n"
+ ret += f"\tuint8_t copied[{idprefix.upper()}RMSG_MAX_COPY];\n"
+ ret += "};\n"
+
return ret
@@ -549,7 +831,10 @@ LM_ALWAYS_INLINE static bool validate_8(struct _validate_ctx *ctx) { return _val
if member.in_versions != typ.in_versions:
ret += "( " + c_ver_cond(member.in_versions) + " && "
if member.cnt is not None:
- ret += f"_validate_list(ctx, {member.cnt.name}, validate_{member.typ.name}, sizeof({c_typename(member.typ)}))"
+ if member.typ.static_size == 1: # SPECIAL (zerocopy)
+ ret += f"_validate_size_net(ctx, {member.cnt.name})"
+ else:
+ ret += f"_validate_list(ctx, {member.cnt.name}, validate_{member.typ.name}, sizeof({c_typename(member.typ)}))"
if typ.name == "s": # SPECIAL (string)
ret += f'\n\t || ({{ (!is_valid_utf8_without_nul(&ctx->net_bytes[ctx->net_offset-len], len)) && lib9p_error(ctx->ctx, LINUX_EBADMSG, "message contains invalid UTF-8"); }})'
else:
@@ -653,13 +938,15 @@ LM_ALWAYS_INLINE static void unmarshal_8(struct _unmarshal_ctx *ctx, uint64_t *o
if member.in_versions != typ.in_versions:
ret += "{\n"
ret += prefix
- ret += f"out->{member.name} = ctx->extra;\n"
- ret += f"{prefix}ctx->extra += sizeof(out->{member.name}[0]) * out->{member.cnt.name};\n"
- ret += f"{prefix}for (typeof(out->{member.cnt.name}) i = 0; i < out->{member.cnt.name}; i++)\n"
- if member.typ.static_size == 1: # SPECIAL (string)
- # Special-case is that we cast from `char` to `uint8_t`.
- ret += f"{prefix}\tunmarshal_{member.typ.name}(ctx, (uint8_t *)&out->{member.name}[i]);\n"
+ if member.typ.static_size == 1: # SPECIAL (string, zerocopy)
+ ret += f"out->{member.name} = (char *)&ctx->net_bytes[ctx->net_offset];\n"
+ ret += (
+ f"{prefix}ctx->net_offset += out->{member.cnt.name};\n"
+ )
else:
+ ret += f"out->{member.name} = ctx->extra;\n"
+ ret += f"{prefix}ctx->extra += sizeof(out->{member.name}[0]) * out->{member.cnt.name};\n"
+ ret += f"{prefix}for (typeof(out->{member.cnt.name}) i = 0; i < out->{member.cnt.name}; i++)\n"
ret += f"{prefix}\tunmarshal_{member.typ.name}(ctx, &out->{member.name}[i]);\n"
if member.in_versions != typ.in_versions:
ret += "\t}\n"
@@ -675,139 +962,346 @@ LM_ALWAYS_INLINE static void unmarshal_8(struct _unmarshal_ctx *ctx, uint64_t *o
ret += """
/* marshal_* ******************************************************************/
-LM_ALWAYS_INLINE static bool _marshal_too_large(struct _marshal_ctx *ctx) {
-\tlib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s too large to marshal into %s limit (limit=%"PRIu32")",
-\t\t(ctx->net_bytes[4] % 2 == 0) ? "T-message" : "R-message",
-\t\tctx->ctx->version ? "negotiated" : ((ctx->net_bytes[4] % 2 == 0) ? "client" : "server"),
-\t\tctx->ctx->max_msg_size);
-\treturn true;
-}
+"""
+ ret += c_macro(
+ "#define MARSHAL_BYTES_ZEROCOPY(ctx, data, len)\n"
+ "\tif (ctx->net_iov[ctx->net_iov_cnt-1].iov_len)\n"
+ "\t\tctx->net_iov_cnt++;\n"
+ "\tctx->net_iov[ctx->net_iov_cnt-1].iov_base = data;\n"
+ "\tctx->net_iov[ctx->net_iov_cnt-1].iov_len = len;\n"
+ "\tctx->net_iov_cnt++;\n"
+ )
+ ret += c_macro(
+ "#define MARSHAL_BYTES(ctx, data, len)\n"
+ "\tif (!ctx->net_iov[ctx->net_iov_cnt-1].iov_base)\n"
+ "\t\tctx->net_iov[ctx->net_iov_cnt-1].iov_base = &ctx->net_copied[ctx->net_copied_size];\n"
+ "\tmemcpy(&ctx->net_copied[ctx->net_copied_size], data, len);\n"
+ "\tctx->net_copied_size += len;\n"
+ "\tctx->net_iov[ctx->net_iov_cnt-1].iov_len += len;\n"
+ )
+ ret += c_macro(
+ "#define MARSHAL_U8LE(ctx, val)\n"
+ "\tif (!ctx->net_iov[ctx->net_iov_cnt-1].iov_base)\n"
+ "\t\tctx->net_iov[ctx->net_iov_cnt-1].iov_base = &ctx->net_copied[ctx->net_copied_size];\n"
+ "\tctx->net_copied[ctx->net_copied_size] = val;\n"
+ "\tctx->net_copied_size += 1;\n"
+ "\tctx->net_iov[ctx->net_iov_cnt-1].iov_len += 1;\n"
+ )
+ ret += c_macro(
+ "#define MARSHAL_U16LE(ctx, val)\n"
+ "\tif (!ctx->net_iov[ctx->net_iov_cnt-1].iov_base)\n"
+ "\t\tctx->net_iov[ctx->net_iov_cnt-1].iov_base = &ctx->net_copied[ctx->net_copied_size];\n"
+ "\tuint16le_encode(&ctx->net_copied[ctx->net_copied_size], val);\n"
+ "\tctx->net_copied_size += 2;\n"
+ "\tctx->net_iov[ctx->net_iov_cnt-1].iov_len += 2;\n"
+ )
+ ret += c_macro(
+ "#define MARSHAL_U32LE(ctx, val)\n"
+ "\tif (!ctx->net_iov[ctx->net_iov_cnt-1].iov_base)\n"
+ "\t\tctx->net_iov[ctx->net_iov_cnt-1].iov_base = &ctx->net_copied[ctx->net_copied_size];\n"
+ "\tuint32le_encode(&ctx->net_copied[ctx->net_copied_size], val);\n"
+ "\tctx->net_copied_size += 4;\n"
+ "\tctx->net_iov[ctx->net_iov_cnt-1].iov_len += 4;\n"
+ )
+ ret += c_macro(
+ "#define MARSHAL_U64LE(ctx, val)\n"
+ "\tif (!ctx->net_iov[ctx->net_iov_cnt-1].iov_base)\n"
+ "\t\tctx->net_iov[ctx->net_iov_cnt-1].iov_base = &ctx->net_copied[ctx->net_copied_size];\n"
+ "\tuint64le_encode(&ctx->net_copied[ctx->net_copied_size], val);\n"
+ "\tctx->net_copied_size += 8;\n"
+ "\tctx->net_iov[ctx->net_iov_cnt-1].iov_len += 8;\n"
+ )
-LM_ALWAYS_INLINE static bool marshal_1(struct _marshal_ctx *ctx, uint8_t *val) {
-\tif (ctx->net_offset + 1 > ctx->ctx->max_msg_size)
-\t\treturn _marshal_too_large(ctx);
-\tctx->net_bytes[ctx->net_offset] = *val;
-\tctx->net_offset += 1;
-\treturn false;
-}
+ class OffsetExpr:
+ static: int
+ cond: dict[frozenset[str], "OffsetExpr"]
+ rep: list[tuple[Path, "OffsetExpr"]]
+
+ def __init__(self) -> None:
+ self.static = 0
+ self.rep = []
+ self.cond = {}
+
+ def add(self, other: "OffsetExpr") -> None:
+ self.static += other.static
+ self.rep += other.rep
+ for k, v in other.cond.items():
+ if k in self.cond:
+ self.cond[k].add(v)
+ else:
+ self.cond[k] = v
+
+ def gen_c(
+ self,
+ dsttyp: str,
+ dstvar: str,
+ root: str,
+ indent_depth: int,
+ loop_depth: int,
+ ) -> str:
+ oneline: list[str] = []
+ multiline = ""
+ if self.static:
+ oneline.append(str(self.static))
+ for cnt, sub in self.rep:
+ if not sub.cond and not sub.rep:
+ if sub.static == 1:
+ oneline.append(cnt.c_str(root))
+ else:
+ oneline.append(f"({cnt.c_str(root)})*{sub.static}")
+ continue
+ loopvar = chr(ord("i") + loop_depth)
+ multiline += f"{'\t'*indent_depth}for ({c_typename(cnt.elems[-1].typ)} {loopvar} = 0; {loopvar} < {cnt.c_str(root)}; {loopvar}++) {{\n"
+ multiline += sub.gen_c(
+ "", dstvar, root, indent_depth + 1, loop_depth + 1
+ )
+ multiline += f"{'\t'*indent_depth}}}\n"
+ for vers, sub in self.cond.items():
+ multiline += ifdef_push(indent_depth + 1, c_ver_ifdef(vers))
+ multiline += f"{'\t'*indent_depth}if {c_ver_cond(vers)} {{\n"
+ multiline += sub.gen_c("", dstvar, root, indent_depth + 1, loop_depth)
+ multiline += f"{'\t'*indent_depth}}}\n"
+ multiline += ifdef_pop(indent_depth)
+ if dsttyp:
+ if not oneline:
+ oneline.append("0")
+ ret = f"{'\t'*indent_depth}{dsttyp} {dstvar} = {' + '.join(oneline)};\n"
+ elif oneline:
+ ret = f"{'\t'*indent_depth}{dstvar} += {' + '.join(oneline)};\n"
+ ret += multiline
+ return ret
-LM_ALWAYS_INLINE static bool marshal_2(struct _marshal_ctx *ctx, uint16_t *val) {
-\tif (ctx->net_offset + 2 > ctx->ctx->max_msg_size)
-\t\treturn _marshal_too_large(ctx);
-\tuint16le_encode(&ctx->net_bytes[ctx->net_offset], *val);
-\tctx->net_offset += 2;
-\treturn false;
-}
+ type OffsetExprRecursion = typing.Callable[[Path], WalkCmd]
-LM_ALWAYS_INLINE static bool marshal_4(struct _marshal_ctx *ctx, uint32_t *val) {
-\tif (ctx->net_offset + 4 > ctx->ctx->max_msg_size)
-\t\treturn true;
-\tuint32le_encode(&ctx->net_bytes[ctx->net_offset], *val);
-\tctx->net_offset += 4;
-\treturn false;
-}
+ def get_offset_expr(typ: idl.Type, recurse: OffsetExprRecursion) -> OffsetExpr:
+ if not isinstance(typ, idl.Struct):
+ assert typ.static_size
+ ret = OffsetExpr()
+ ret.static = typ.static_size
+ return ret
-LM_ALWAYS_INLINE static bool marshal_8(struct _marshal_ctx *ctx, uint64_t *val) {
-\tif (ctx->net_offset + 8 > ctx->ctx->max_msg_size)
-\t\treturn true;
-\tuint64le_encode(&ctx->net_bytes[ctx->net_offset], *val);
-\tctx->net_offset += 8;
-\treturn false;
-}
-"""
- for typ in topo_sorted(typs):
- inline = "LM_FLATTEN" if isinstance(typ, idl.Message) else "LM_ALWAYS_INLINE"
- argfn = unused if (isinstance(typ, idl.Struct) and not typ.members) else used
+ stack: list[tuple[Path, OffsetExpr, typing.Callable[[], None]]]
+
+ def pop_root() -> None:
+ assert False
+
+ def pop_cond() -> None:
+ nonlocal stack
+ key = frozenset(stack[-1][0].elems[-1].in_versions)
+ if key in stack[-2][1].cond:
+ stack[-2][1].cond[key].add(stack[-1][1])
+ else:
+ stack[-2][1].cond[key] = stack[-1][1]
+ stack = stack[:-1]
+
+ def pop_rep() -> None:
+ nonlocal stack
+ member_path = stack[-1][0]
+ member = member_path.elems[-1]
+ assert member.cnt
+ cnt_path = member_path.parent().add(member.cnt)
+ stack[-2][1].rep.append((cnt_path, stack[-1][1]))
+ stack = stack[:-1]
+
+ def handle(path: Path) -> tuple[WalkCmd, typing.Callable[[], None] | None]:
+ nonlocal recurse
+
+ ret = recurse(path)
+ if ret != WalkCmd.KEEP_GOING:
+ return ret, None
+
+ nonlocal stack
+ stack_len = len(stack)
+
+ def pop() -> None:
+ nonlocal stack
+ nonlocal stack_len
+ while len(stack) > stack_len:
+ stack[-1][2]()
+
+ if path.elems:
+ child = path.elems[-1]
+ parent = path.elems[-2].typ if len(path.elems) > 1 else path.root
+ if child.in_versions < parent.in_versions:
+ stack.append((path, OffsetExpr(), pop_cond))
+ if child.cnt:
+ stack.append((path, OffsetExpr(), pop_rep))
+ if not isinstance(child.typ, idl.Struct):
+ assert child.typ.static_size
+ stack[-1][1].static += child.typ.static_size
+ return ret, pop
+
+ stack = [(Path(typ), OffsetExpr(), pop_root)]
+ walk(typ, handle)
+ return stack[0][1]
+
+ def go_to_end(path: Path) -> WalkCmd:
+ return WalkCmd.KEEP_GOING
+
+ def go_to_tok(name: str) -> typing.Callable[[Path], WalkCmd]:
+ def ret(path: Path) -> WalkCmd:
+ if len(path.elems) == 1 and path.elems[0].name == name:
+ return WalkCmd.ABORT
+ return WalkCmd.KEEP_GOING
+
+ return ret
+
+ for typ in typs:
+ if not (
+ isinstance(typ, idl.Message) or typ.name == "stat"
+ ): # SPECIAL (include stat)
+ continue
+ assert isinstance(typ, idl.Struct)
ret += "\n"
ret += ifdef_push(1, c_ver_ifdef(typ.in_versions))
- ret += f"{inline} static bool marshal_{typ.name}(struct _marshal_ctx *{argfn('ctx')}, {c_typename(typ)} *{argfn('val')}) {{\n"
- match typ:
- case idl.Number():
- ret += f"\treturn marshal_{typ.prim.name}(ctx, ({c_typename(typ.prim)} *)val);\n"
- case idl.Bitfield():
- ret += f"\t{c_typename(typ)} masked_val = *val & {typ.name}_masks[ctx->ctx->version];\n"
- ret += f"\treturn marshal_{typ.prim.name}(ctx, ({c_typename(typ.prim)} *)&masked_val);\n"
- case idl.Struct():
- if len(typ.members) == 0:
- ret += "\treturn false;\n"
- ret += "}\n"
- continue
+ ret += f"static bool marshal_{typ.name}(struct _marshal_ctx *ctx, {c_typename(typ)} *val) {{\n"
- # Pass 1 - declare offset variables
- mark_offset = set()
- for member in typ.members:
- if member.val:
- if member.name not in mark_offset:
- ret += f"\tuint32_t _{member.name}_offset;\n"
- mark_offset.add(member.name)
- for tok in member.val.tokens:
- if isinstance(tok, idl.ExprSym) and tok.name.startswith("&"):
- if tok.name[1:] not in mark_offset:
- ret += f"\tuint32_t _{tok.name[1:]}_offset;\n"
- mark_offset.add(tok.name[1:])
+ # Pass 1 - check size
+ max_size = max(typ.max_size(v) for v in typ.in_versions)
- # Pass 2 - main pass
- ret += "\treturn false\n"
- for member in typ.members:
- ret += ifdef_push(2, c_ver_ifdef(member.in_versions))
- ret += "\t || "
- if member.in_versions != typ.in_versions:
- ret += "( " + c_ver_cond(member.in_versions) + " && "
- if member.name in mark_offset:
- ret += f"({{ _{member.name}_offset = ctx->net_offset; "
- if member.cnt:
- ret += "({ bool err = false;\n"
- ret += f"\t for (typeof(val->{member.cnt.name}) i = 0; i < val->{member.cnt.name} && !err; i++)\n"
- ret += "\t \terr = "
- if member.typ.static_size == 1: # SPECIAL (string)
- # Special-case is that we cast from `char` to `uint8_t`.
- ret += f"marshal_{member.typ.name}(ctx, (uint8_t *)&val->{member.name}[i]);\n"
- else:
- ret += f"marshal_{member.typ.name}(ctx, &val->{member.name}[i]);\n"
- ret += f"\t err; }})"
- elif member.val:
- # Just increment net_offset, don't actually marshal anything (yet).
- assert member.static_size
- ret += (
- f"({{ ctx->net_offset += {member.static_size}; false; }})"
- )
+ if max_size > u32max: # SPECIAL (9P2000.e)
+ ret += get_offset_expr(typ, go_to_end).gen_c(
+ "uint64_t", "needed_size", "val->", 1, 0
+ )
+ ret += "\tif (needed_size > (uint64_t)(ctx->ctx->max_msg_size)) {\n"
+ else:
+ ret += get_offset_expr(typ, go_to_end).gen_c(
+ "uint32_t", "needed_size", "val->", 1, 0
+ )
+ ret += "\tif (needed_size > ctx->ctx->max_msg_size) {\n"
+ if isinstance(typ, idl.Message): # SPECIAL (disable for stat)
+ ret += f'\t\tlib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%PRIu32)",\n'
+ ret += f'\t\t\t"{typ.name}",\n'
+ ret += f'\t\t\tctx->ctx->version ? "negotiated" : "{'client' if typ.msgid % 2 == 0 else 'server'}",\n'
+ ret += "\t\t\tctx->ctx->max_msg_size);\n"
+ ret += "\t\treturn true;\n"
+ ret += "\t}\n"
+
+ # Pass 2 - write data
+ ifdef_depth = 1
+ stack: list[tuple[Path, bool]] = [(Path(typ), False)]
+
+ def handle(path: Path) -> tuple[WalkCmd, typing.Callable[[], None]]:
+ nonlocal ret
+ nonlocal ifdef_depth
+ nonlocal stack
+ stack_len = len(stack)
+
+ def pop() -> None:
+ nonlocal ret
+ nonlocal ifdef_depth
+ nonlocal stack
+ nonlocal stack_len
+ while len(stack) > stack_len:
+ ret += f"{'\t'*(len(stack)-1)}}}\n"
+ if stack[-1][1]:
+ ifdef_depth -= 1
+ ret += ifdef_pop(ifdef_depth)
+ stack = stack[:-1]
+
+ loopdepth = sum(1 for elem in path.elems if elem.cnt)
+ struct = path.elems[-1].typ if path.elems else path.root
+ if isinstance(struct, idl.Struct):
+ offsets: list[str] = []
+ for member in struct.members:
+ if not member.val:
+ continue
+ for tok in member.val.tokens:
+ if not isinstance(tok, idl.ExprSym):
+ continue
+ if tok.name == "end" or tok.name.startswith("&"):
+ if tok.name not in offsets:
+ offsets.append(tok.name)
+ for name in offsets:
+ name_prefix = "offsetof_" + "".join(
+ m.name + "_" for m in path.elems
+ )
+ if name == "end":
+ if not path.elems:
+ nonlocal max_size
+ if max_size > u32max:
+ ret += f"{'\t'*len(stack)}uint32_t {name_prefix}end = (uint32_t)needed_size;\n"
+ else:
+ ret += f"{'\t'*len(stack)}uint32_t {name_prefix}end = needed_size;\n"
+ continue
+ recurse: OffsetExprRecursion = go_to_end
else:
- ret += f"marshal_{member.typ.name}(ctx, &val->{member.name})"
- if member.name in mark_offset:
- ret += "; })"
- if member.in_versions != typ.in_versions:
- ret += " )"
- ret += "\n"
-
- # Pass 3 - marshal ,val= members
- for member in typ.members:
- if member.val:
- assert member.static_size
- ret += ifdef_push(2, c_ver_ifdef(member.in_versions))
+ assert name.startswith("&")
+ name = name[1:]
+ recurse = go_to_tok(name)
+ expr = get_offset_expr(struct, recurse)
+ expr_prefix = path.c_str("val->", loopdepth)
+ if not expr_prefix.endswith(">"):
+ expr_prefix += "."
+ ret += expr.gen_c(
+ "uint32_t",
+ name_prefix + name,
+ expr_prefix,
+ len(stack),
+ loopdepth,
+ )
+ if path.elems:
+ child = path.elems[-1]
+ parent = path.elems[-2].typ if len(path.elems) > 1 else path.root
+ if child.in_versions < parent.in_versions:
+ ret += ifdef_push(ifdef_depth + 1, c_ver_ifdef(child.in_versions))
+ ifdef_depth += 1
+ ret += f"{'\t'*len(stack)}if ({c_ver_cond(child.in_versions)}) {{\n"
+ stack.append((path, True))
+ if child.cnt:
+ cnt_path = path.parent().add(child.cnt)
+ if child.typ.static_size == 1: # SPECIAL (zerocopy)
+ if path.root.name == "stat": # SPECIAL (stat)
+ ret += f"{'\t'*len(stack)}MARSHAL_BYTES(ctx, {path.c_str('val->')[:-3]}, {cnt_path.c_str('val->')});\n"
+ else:
+ ret += f"{'\t'*len(stack)}MARSHAL_BYTES_ZEROCOPY(ctx, {path.c_str('val->')[:-3]}, {cnt_path.c_str('val->')});\n"
+ return WalkCmd.KEEP_GOING, pop
+ loopvar = chr(ord("i") + loopdepth - 1)
+ ret += f"{'\t'*len(stack)}for ({c_typename(child.cnt.typ)} {loopvar} = 0; {loopvar} < {cnt_path.c_str('val->')}; {loopvar}++) {{\n"
+ stack.append((path, False))
+ if not isinstance(child.typ, idl.Struct):
+ if child.val:
def lookup_sym(sym: str) -> str:
- match sym:
- case "end":
- return "ctx->net_offset"
- case _:
- assert sym.startswith("&")
- return f"_{sym[1:]}_offset"
-
- if member.static_size == 1:
- ret += f"\t || ({{ ctx->net_bytes[_{member.name}_offset] = {c_expr(member.val, lookup_sym)}; false; }})\n"
- else:
- ret += f"\t || ({{ uint{member.static_size*8}le_encode(&ctx->net_bytes[_{member.name}_offset], {c_expr(member.val, lookup_sym)}); false; }})\n"
+ nonlocal path
+ if sym.startswith("&"):
+ sym = sym[1:]
+ return (
+ "offsetof_"
+ + "".join(m.name + "_" for m in path.elems[:-1])
+ + sym
+ )
+
+ val = c_expr(child.val, lookup_sym)
+ else:
+ val = path.c_str("val->")
+ if isinstance(child.typ, idl.Bitfield):
+ val += f" & {child.typ.name}_masks[ctx->ctx->version]"
+ ret += f"{'\t'*len(stack)}MARSHAL_U{child.typ.static_size*8}LE(ctx, {val});\n"
+ return WalkCmd.KEEP_GOING, pop
- ret += ifdef_pop(1)
- ret += "\t ;\n"
+ walk(typ, handle)
+
+ ret += "\treturn false;\n"
ret += "}\n"
ret += ifdef_pop(0)
# function tables ##########################################################
ret += """
/* function tables ************************************************************/
-
"""
+
+ ret += "\n"
+ ret += f"const uint32_t _{idprefix}table_msg_min_size[{c_ver_enum('NUM')}] = {{\n"
+ rerror = next(typ for typ in typs if typ.name == "Rerror")
+ ret += f"\t[{c_ver_enum('unknown')}] = {rerror.min_size('9P2000')},\n" # SPECIAL (initialization)
+ for ver in sorted(versions):
+ ret += ifdef_push(1, c_ver_ifdef({ver}))
+ ret += f"\t[{c_ver_enum(ver)}] = {rerror.min_size(ver)},\n"
+ ret += ifdef_pop(0)
+ ret += "};\n"
+
+ ret += "\n"
ret += c_macro(
f"#define _MSG_RECV(typ) [{idprefix.upper()}TYP_##typ/2] = {{\n"
f"\t\t.basesize = sizeof(struct {idprefix}msg_##typ),\n"
diff --git a/lib9p/include/lib9p/9p.generated.h b/lib9p/include/lib9p/9p.generated.h
index a5b719e..d34a0f6 100644
--- a/lib9p/include/lib9p/9p.generated.h
+++ b/lib9p/include/lib9p/9p.generated.h
@@ -6,6 +6,8 @@
#include <stdint.h> /* for uint{n}_t types */
+#include <libhw/generic/net.h> /* for struct iovec */
+
/* config *********************************************************************/
#include "config.h"
@@ -20,6 +22,13 @@
#ifndef CONFIG_9P_ENABLE_9P2000_e
#error config.h must define CONFIG_9P_ENABLE_9P2000_e
+#else
+ #if CONFIG_9P_ENABLE_9P2000_e
+ #ifndef(CONFIG_9P_MAX_9P2000_e_WELEM)
+ #error if CONFIG_9P_ENABLE_9P2000_e then config.h must define CONFIG_9P_MAX_9P2000_e_WELEM
+ #endif
+ static_assert(CONFIG_9P_MAX_9P2000_e_WELEM > 0);
+ #endif
#endif
#ifndef CONFIG_9P_ENABLE_9P2000_p9p
@@ -148,15 +157,15 @@ enum lib9p_msg_type { /* uint8_t */
/* payload types **************************************************************/
#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u
-/* size = 2 */
+/* size = 2 ; max_iov = 1 ; max_copy = 2 */
typedef uint16_t lib9p_tag_t;
#define LIB9P_TAG_NOTAG ((lib9p_tag_t)UINT16_C(~0))
-/* size = 4 */
+/* size = 4 ; max_iov = 1 ; max_copy = 4 */
typedef uint32_t lib9p_fid_t;
#define LIB9P_FID_NOFID ((lib9p_fid_t)UINT32_C(~0))
-/* min_size = 2 ; max_size = 65,537 */
+/* min_size = 2 ; exp_size = 29 ; max_size = 65,537 ; max_iov = 2 ; max_copy = 2 */
struct lib9p_s {
uint16_t len;
[[gnu::nonstring]] char *utf8;
@@ -164,7 +173,7 @@ struct lib9p_s {
#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */
#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u
-/* size = 4 */
+/* size = 4 ; max_iov = 1 ; max_copy = 4 */
typedef uint32_t lib9p_dm_t;
#define LIB9P_DM_DIR ((lib9p_dm_t)(1<<31))
@@ -208,7 +217,7 @@ typedef uint32_t lib9p_dm_t;
#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */
#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u
-/* size = 1 */
+/* size = 1 ; max_iov = 1 ; max_copy = 1 */
typedef uint8_t lib9p_qt_t;
#define LIB9P_QT_DIR ((lib9p_qt_t)(1<<7))
@@ -226,13 +235,13 @@ typedef uint8_t lib9p_qt_t;
#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */
#if CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_u
-/* size = 4 */
+/* size = 4 ; max_iov = 1 ; max_copy = 4 */
typedef uint32_t lib9p_nuid_t;
#define LIB9P_NUID_NONUID ((lib9p_nuid_t)UINT32_C(~0))
#endif /* CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_u */
#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u
-/* size = 1 */
+/* size = 1 ; max_iov = 1 ; max_copy = 1 */
typedef uint8_t lib9p_o_t;
/* unused ((lib9p_o_t)(1<<7)) */
@@ -253,7 +262,7 @@ typedef uint8_t lib9p_o_t;
#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */
#if CONFIG_9P_ENABLE_9P2000_L
-/* size = 8 */
+/* size = 8 ; max_iov = 1 ; max_copy = 8 */
typedef uint64_t lib9p_getattr_t;
/* unused ((lib9p_getattr_t)(1<<63)) */
@@ -324,7 +333,7 @@ typedef uint64_t lib9p_getattr_t;
#define LIB9P_GETATTR_BASIC ((lib9p_getattr_t)(0x000007ff))
#define LIB9P_GETATTR_ALL ((lib9p_getattr_t)(0x00003fff))
-/* size = 4 */
+/* size = 4 ; max_iov = 1 ; max_copy = 4 */
typedef uint32_t lib9p_setattr_t;
/* unused ((lib9p_setattr_t)(1<<31)) */
@@ -360,13 +369,13 @@ typedef uint32_t lib9p_setattr_t;
#define LIB9P_SETATTR_UID ((lib9p_setattr_t)(1<<1))
#define LIB9P_SETATTR_MODE ((lib9p_setattr_t)(1<<0))
-/* size = 1 */
+/* size = 1 ; max_iov = 1 ; max_copy = 1 */
typedef uint8_t lib9p_lock_type_t;
#define LIB9P_LOCK_TYPE_RDLCK ((lib9p_lock_type_t)UINT8_C(0))
#define LIB9P_LOCK_TYPE_WRLCK ((lib9p_lock_type_t)UINT8_C(1))
#define LIB9P_LOCK_TYPE_UNLCK ((lib9p_lock_type_t)UINT8_C(2))
-/* size = 4 */
+/* size = 4 ; max_iov = 1 ; max_copy = 4 */
typedef uint32_t lib9p_lock_flags_t;
/* unused ((lib9p_lock_flags_t)(1<<31)) */
@@ -402,7 +411,7 @@ typedef uint32_t lib9p_lock_flags_t;
#define LIB9P_LOCK_FLAGS_RECLAIM ((lib9p_lock_flags_t)(1<<1))
#define LIB9P_LOCK_FLAGS_BLOCK ((lib9p_lock_flags_t)(1<<0))
-/* size = 1 */
+/* size = 1 ; max_iov = 1 ; max_copy = 1 */
typedef uint8_t lib9p_lock_status_t;
#define LIB9P_LOCK_STATUS_SUCCESS ((lib9p_lock_status_t)UINT8_C(0))
#define LIB9P_LOCK_STATUS_BLOCKED ((lib9p_lock_status_t)UINT8_C(1))
@@ -411,56 +420,56 @@ typedef uint8_t lib9p_lock_status_t;
#endif /* CONFIG_9P_ENABLE_9P2000_L */
#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u
-/* size = 9 */
+/* size = 9 ; max_iov = 1 ; max_copy = 9 */
struct lib9p_msg_Tflush {
lib9p_tag_t tag;
uint16_t oldtag;
};
-/* size = 7 */
+/* size = 7 ; max_iov = 1 ; max_copy = 7 */
struct lib9p_msg_Rflush {
lib9p_tag_t tag;
};
-/* min_size = 11 ; max_size = 2,147,483,658 */
+/* min_size = 11 ; exp_size = 8,203 ; max_size = 2,147,483,658 ; max_iov = 2 ; max_copy = 11 */
struct lib9p_msg_Rread {
lib9p_tag_t tag;
uint32_t count;
[[gnu::nonstring]] char *data;
};
-/* size = 11 */
+/* size = 11 ; max_iov = 1 ; max_copy = 11 */
struct lib9p_msg_Rwrite {
lib9p_tag_t tag;
uint32_t count;
};
-/* size = 7 */
+/* size = 7 ; max_iov = 1 ; max_copy = 7 */
struct lib9p_msg_Rclunk {
lib9p_tag_t tag;
};
-/* size = 7 */
+/* size = 7 ; max_iov = 1 ; max_copy = 7 */
struct lib9p_msg_Rremove {
lib9p_tag_t tag;
};
#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */
#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u
-/* size = 7 */
+/* size = 7 ; max_iov = 1 ; max_copy = 7 */
struct lib9p_msg_Rwstat {
lib9p_tag_t tag;
};
#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */
#if CONFIG_9P_ENABLE_9P2000_L
-/* size = 11 */
+/* size = 11 ; max_iov = 1 ; max_copy = 11 */
struct lib9p_msg_Rlerror {
lib9p_tag_t tag;
uint32_t ecode;
};
-/* size = 67 */
+/* size = 67 ; max_iov = 1 ; max_copy = 67 */
struct lib9p_msg_Rstatfs {
lib9p_tag_t tag;
uint32_t type;
@@ -474,75 +483,75 @@ struct lib9p_msg_Rstatfs {
uint32_t namelen;
};
-/* size = 7 */
+/* size = 7 ; max_iov = 1 ; max_copy = 7 */
struct lib9p_msg_Rrename {
lib9p_tag_t tag;
};
-/* size = 7 */
+/* size = 7 ; max_iov = 1 ; max_copy = 7 */
struct lib9p_msg_Rsetattr {
lib9p_tag_t tag;
};
-/* size = 15 */
+/* size = 15 ; max_iov = 1 ; max_copy = 15 */
struct lib9p_msg_Rxattrwalk {
lib9p_tag_t tag;
uint64_t attr_size;
};
-/* size = 7 */
+/* size = 7 ; max_iov = 1 ; max_copy = 7 */
struct lib9p_msg_Rxattrcreate {
lib9p_tag_t tag;
};
-/* min_size = 11 ; max_size = 4,294,967,306 (warning: >UINT32_MAX) */
+/* min_size = 11 ; exp_size = 8,203 ; max_size = 4,294,967,306 (warning: >UINT32_MAX) ; max_iov = 2 ; max_copy = 11 */
struct lib9p_msg_Rreaddir {
lib9p_tag_t tag;
uint32_t count;
[[gnu::nonstring]] char *data;
};
-/* size = 7 */
+/* size = 7 ; max_iov = 1 ; max_copy = 7 */
struct lib9p_msg_Rfsync {
lib9p_tag_t tag;
};
-/* size = 7 */
+/* size = 7 ; max_iov = 1 ; max_copy = 7 */
struct lib9p_msg_Rlink {
lib9p_tag_t tag;
};
-/* size = 7 */
+/* size = 7 ; max_iov = 1 ; max_copy = 7 */
struct lib9p_msg_Rrenameat {
lib9p_tag_t tag;
};
-/* size = 7 */
+/* size = 7 ; max_iov = 1 ; max_copy = 7 */
struct lib9p_msg_Runlinkat {
lib9p_tag_t tag;
};
#endif /* CONFIG_9P_ENABLE_9P2000_L */
#if CONFIG_9P_ENABLE_9P2000_e
-/* size = 15 */
+/* size = 15 ; max_iov = 1 ; max_copy = 15 */
struct lib9p_msg_Tsession {
lib9p_tag_t tag;
uint64_t key;
};
-/* size = 7 */
+/* size = 7 ; max_iov = 1 ; max_copy = 7 */
struct lib9p_msg_Rsession {
lib9p_tag_t tag;
};
-/* min_size = 11 ; max_size = 4,294,967,306 (warning: >UINT32_MAX) */
+/* min_size = 11 ; exp_size = 8,203 ; max_size = 4,294,967,306 (warning: >UINT32_MAX) ; max_iov = 2 ; max_copy = 11 */
struct lib9p_msg_Rsread {
lib9p_tag_t tag;
uint32_t count;
[[gnu::nonstring]] char *data;
};
-/* size = 11 */
+/* size = 11 ; max_iov = 1 ; max_copy = 11 */
struct lib9p_msg_Rswrite {
lib9p_tag_t tag;
uint32_t count;
@@ -550,7 +559,7 @@ struct lib9p_msg_Rswrite {
#endif /* CONFIG_9P_ENABLE_9P2000_e */
#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u
-/* size = 23 */
+/* size = 23 ; max_iov = 1 ; max_copy = 23 */
struct lib9p_msg_Tread {
lib9p_tag_t tag;
lib9p_fid_t fid;
@@ -558,7 +567,7 @@ struct lib9p_msg_Tread {
uint32_t count;
};
-/* min_size = 23 ; max_size = 2,147,483,670 */
+/* min_size = 23 ; exp_size = 8,215 ; max_size = 2,147,483,670 ; max_iov = 2 ; max_copy = 23 */
struct lib9p_msg_Twrite {
lib9p_tag_t tag;
lib9p_fid_t fid;
@@ -567,13 +576,13 @@ struct lib9p_msg_Twrite {
[[gnu::nonstring]] char *data;
};
-/* size = 11 */
+/* size = 11 ; max_iov = 1 ; max_copy = 11 */
struct lib9p_msg_Tclunk {
lib9p_tag_t tag;
lib9p_fid_t fid;
};
-/* size = 11 */
+/* size = 11 ; max_iov = 1 ; max_copy = 11 */
struct lib9p_msg_Tremove {
lib9p_tag_t tag;
lib9p_fid_t fid;
@@ -581,7 +590,7 @@ struct lib9p_msg_Tremove {
#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */
#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u
-/* size = 11 */
+/* size = 11 ; max_iov = 1 ; max_copy = 11 */
struct lib9p_msg_Tstat {
lib9p_tag_t tag;
lib9p_fid_t fid;
@@ -589,26 +598,26 @@ struct lib9p_msg_Tstat {
#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */
#if CONFIG_9P_ENABLE_9P2000_L
-/* size = 11 */
+/* size = 11 ; max_iov = 1 ; max_copy = 11 */
struct lib9p_msg_Tstatfs {
lib9p_tag_t tag;
lib9p_fid_t fid;
};
-/* size = 15 */
+/* size = 15 ; max_iov = 1 ; max_copy = 15 */
struct lib9p_msg_Tlopen {
lib9p_tag_t tag;
lib9p_fid_t fid;
uint32_t flags;
};
-/* size = 11 */
+/* size = 11 ; max_iov = 1 ; max_copy = 11 */
struct lib9p_msg_Treadlink {
lib9p_tag_t tag;
lib9p_fid_t fid;
};
-/* size = 23 */
+/* size = 23 ; max_iov = 1 ; max_copy = 23 */
struct lib9p_msg_Treaddir {
lib9p_tag_t tag;
lib9p_fid_t fid;
@@ -616,7 +625,7 @@ struct lib9p_msg_Treaddir {
uint32_t count;
};
-/* size = 15 */
+/* size = 15 ; max_iov = 1 ; max_copy = 15 */
struct lib9p_msg_Tfsync {
lib9p_tag_t tag;
lib9p_fid_t fid;
@@ -625,25 +634,25 @@ struct lib9p_msg_Tfsync {
#endif /* CONFIG_9P_ENABLE_9P2000_L */
#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u
-/* min_size = 13 ; max_size = 65,548 */
+/* min_size = 13 ; exp_size = 40 ; max_size = 65,548 ; max_iov = 2 ; max_copy = 13 */
struct lib9p_msg_Tversion {
lib9p_tag_t tag;
uint32_t max_msg_size;
struct lib9p_s version;
};
-/* min_size = 13 ; max_size = 65,548 */
+/* min_size = 13 ; exp_size = 40 ; max_size = 65,548 ; max_iov = 2 ; max_copy = 13 */
struct lib9p_msg_Rversion {
lib9p_tag_t tag;
uint32_t max_msg_size;
struct lib9p_s version;
};
-/* LIB9P_VER_9P2000 : min_size = 9 ; max_size = 65,544 */
-/* LIB9P_VER_9P2000_L : min_size = 9 ; max_size = 65,544 */
-/* LIB9P_VER_9P2000_e : min_size = 9 ; max_size = 65,544 */
-/* LIB9P_VER_9P2000_p9p: min_size = 9 ; max_size = 65,544 */
-/* LIB9P_VER_9P2000_u : min_size = 13 ; max_size = 65,548 */
+/* LIB9P_VER_9P2000 : min_size = 9 ; exp_size = 36 ; max_size = 65,544 ; max_iov = 2 ; max_copy = 9 */
+/* LIB9P_VER_9P2000_L : min_size = 9 ; exp_size = 36 ; max_size = 65,544 ; max_iov = 2 ; max_copy = 9 */
+/* LIB9P_VER_9P2000_e : min_size = 9 ; exp_size = 36 ; max_size = 65,544 ; max_iov = 2 ; max_copy = 9 */
+/* LIB9P_VER_9P2000_p9p: min_size = 9 ; exp_size = 36 ; max_size = 65,544 ; max_iov = 2 ; max_copy = 9 */
+/* LIB9P_VER_9P2000_u : min_size = 13 ; exp_size = 40 ; max_size = 65,548 ; max_iov = 3 ; max_copy = 13 */
struct lib9p_msg_Rerror {
lib9p_tag_t tag;
struct lib9p_s ename;
@@ -652,7 +661,7 @@ struct lib9p_msg_Rerror {
#endif /* CONFIG_9P_ENABLE_9P2000_u */
};
-/* min_size = 17 ; max_size = 1,048,609 */
+/* min_size = 17 ; exp_size = 481 ; max_size = 1,048,609 ; max_iov = 32 ; max_copy = 49 */
struct lib9p_msg_Twalk {
lib9p_tag_t tag;
lib9p_fid_t fid;
@@ -663,7 +672,7 @@ struct lib9p_msg_Twalk {
#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */
#if CONFIG_9P_ENABLE_9P2000_L
-/* min_size = 17 ; max_size = 65,552 */
+/* min_size = 17 ; exp_size = 44 ; max_size = 65,552 ; max_iov = 2 ; max_copy = 17 */
struct lib9p_msg_Trename {
lib9p_tag_t tag;
lib9p_fid_t fid;
@@ -671,13 +680,13 @@ struct lib9p_msg_Trename {
struct lib9p_s name;
};
-/* min_size = 9 ; max_size = 65,544 */
+/* min_size = 9 ; exp_size = 36 ; max_size = 65,544 ; max_iov = 2 ; max_copy = 9 */
struct lib9p_msg_Rreadlink {
lib9p_tag_t tag;
struct lib9p_s target;
};
-/* min_size = 17 ; max_size = 65,552 */
+/* min_size = 17 ; exp_size = 44 ; max_size = 65,552 ; max_iov = 2 ; max_copy = 17 */
struct lib9p_msg_Txattrwalk {
lib9p_tag_t tag;
lib9p_fid_t fid;
@@ -685,7 +694,7 @@ struct lib9p_msg_Txattrwalk {
struct lib9p_s name;
};
-/* min_size = 25 ; max_size = 65,560 */
+/* min_size = 25 ; exp_size = 52 ; max_size = 65,560 ; max_iov = 3 ; max_copy = 25 */
struct lib9p_msg_Txattrcreate {
lib9p_tag_t tag;
lib9p_fid_t fid;
@@ -694,7 +703,7 @@ struct lib9p_msg_Txattrcreate {
uint32_t flags;
};
-/* min_size = 34 ; max_size = 65,569 */
+/* min_size = 34 ; exp_size = 61 ; max_size = 65,569 ; max_iov = 2 ; max_copy = 34 */
struct lib9p_msg_Tgetlock {
lib9p_tag_t tag;
lib9p_fid_t fid;
@@ -705,7 +714,7 @@ struct lib9p_msg_Tgetlock {
struct lib9p_s client_id;
};
-/* min_size = 30 ; max_size = 65,565 */
+/* min_size = 30 ; exp_size = 57 ; max_size = 65,565 ; max_iov = 2 ; max_copy = 30 */
struct lib9p_msg_Rgetlock {
lib9p_tag_t tag;
uint8_t type;
@@ -715,7 +724,7 @@ struct lib9p_msg_Rgetlock {
struct lib9p_s client_id;
};
-/* min_size = 17 ; max_size = 65,552 */
+/* min_size = 17 ; exp_size = 44 ; max_size = 65,552 ; max_iov = 2 ; max_copy = 17 */
struct lib9p_msg_Tlink {
lib9p_tag_t tag;
lib9p_fid_t dfid;
@@ -723,7 +732,7 @@ struct lib9p_msg_Tlink {
struct lib9p_s name;
};
-/* min_size = 19 ; max_size = 131,089 */
+/* min_size = 19 ; exp_size = 73 ; max_size = 131,089 ; max_iov = 4 ; max_copy = 19 */
struct lib9p_msg_Trenameat {
lib9p_tag_t tag;
lib9p_fid_t olddirfid;
@@ -732,7 +741,7 @@ struct lib9p_msg_Trenameat {
struct lib9p_s newname;
};
-/* min_size = 17 ; max_size = 65,552 */
+/* min_size = 17 ; exp_size = 44 ; max_size = 65,552 ; max_iov = 3 ; max_copy = 17 */
struct lib9p_msg_Tunlinkat {
lib9p_tag_t tag;
lib9p_fid_t dirfd;
@@ -742,7 +751,7 @@ struct lib9p_msg_Tunlinkat {
#endif /* CONFIG_9P_ENABLE_9P2000_L */
#if CONFIG_9P_ENABLE_9P2000_e
-/* min_size = 13 ; max_size = 4,294,967,308 (warning: >UINT32_MAX) */
+/* min_size = 13 ; exp_size = 477 ; max_size = 4,294,967,308 (warning: >UINT32_MAX) ; max_iov = 0 + (CONFIG_9P_MAX_9P2000_e_WELEM * 2) ; max_copy = 13 + (CONFIG_9P_MAX_9P2000_e_WELEM * 2) */
struct lib9p_msg_Tsread {
lib9p_tag_t tag;
uint32_t fid;
@@ -750,7 +759,7 @@ struct lib9p_msg_Tsread {
struct lib9p_s *wname;
};
-/* min_size = 17 ; max_size = 8,589,934,607 (warning: >UINT32_MAX) */
+/* min_size = 17 ; exp_size = 8,673 ; max_size = 8,589,934,607 (warning: >UINT32_MAX) ; max_iov = 2 + (CONFIG_9P_MAX_9P2000_e_WELEM * 2) ; max_copy = 17 + (CONFIG_9P_MAX_9P2000_e_WELEM * 2) */
struct lib9p_msg_Tswrite {
lib9p_tag_t tag;
uint32_t fid;
@@ -762,18 +771,18 @@ struct lib9p_msg_Tswrite {
#endif /* CONFIG_9P_ENABLE_9P2000_e */
#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u
-/* size = 13 */
+/* size = 13 ; max_iov = 1 ; max_copy = 13 */
struct lib9p_qid {
lib9p_qt_t type;
uint32_t vers;
uint64_t path;
};
-/* LIB9P_VER_9P2000 : min_size = 15 ; max_size = 131,085 */
-/* LIB9P_VER_9P2000_L : min_size = 19 ; max_size = 131,089 */
-/* LIB9P_VER_9P2000_e : min_size = 15 ; max_size = 131,085 */
-/* LIB9P_VER_9P2000_p9p: min_size = 15 ; max_size = 131,085 */
-/* LIB9P_VER_9P2000_u : min_size = 19 ; max_size = 131,089 */
+/* LIB9P_VER_9P2000 : min_size = 15 ; exp_size = 69 ; max_size = 131,085 ; max_iov = 4 ; max_copy = 15 */
+/* LIB9P_VER_9P2000_L : min_size = 19 ; exp_size = 73 ; max_size = 131,089 ; max_iov = 5 ; max_copy = 19 */
+/* LIB9P_VER_9P2000_e : min_size = 15 ; exp_size = 69 ; max_size = 131,085 ; max_iov = 4 ; max_copy = 15 */
+/* LIB9P_VER_9P2000_p9p: min_size = 15 ; exp_size = 69 ; max_size = 131,085 ; max_iov = 4 ; max_copy = 15 */
+/* LIB9P_VER_9P2000_u : min_size = 19 ; exp_size = 73 ; max_size = 131,089 ; max_iov = 5 ; max_copy = 19 */
struct lib9p_msg_Tauth {
lib9p_tag_t tag;
lib9p_fid_t afid;
@@ -784,11 +793,11 @@ struct lib9p_msg_Tauth {
#endif /* CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_u */
};
-/* LIB9P_VER_9P2000 : min_size = 19 ; max_size = 131,089 */
-/* LIB9P_VER_9P2000_L : min_size = 23 ; max_size = 131,093 */
-/* LIB9P_VER_9P2000_e : min_size = 19 ; max_size = 131,089 */
-/* LIB9P_VER_9P2000_p9p: min_size = 19 ; max_size = 131,089 */
-/* LIB9P_VER_9P2000_u : min_size = 23 ; max_size = 131,093 */
+/* LIB9P_VER_9P2000 : min_size = 19 ; exp_size = 73 ; max_size = 131,089 ; max_iov = 4 ; max_copy = 19 */
+/* LIB9P_VER_9P2000_L : min_size = 23 ; exp_size = 77 ; max_size = 131,093 ; max_iov = 5 ; max_copy = 23 */
+/* LIB9P_VER_9P2000_e : min_size = 19 ; exp_size = 73 ; max_size = 131,089 ; max_iov = 4 ; max_copy = 19 */
+/* LIB9P_VER_9P2000_p9p: min_size = 19 ; exp_size = 73 ; max_size = 131,089 ; max_iov = 4 ; max_copy = 19 */
+/* LIB9P_VER_9P2000_u : min_size = 23 ; exp_size = 77 ; max_size = 131,093 ; max_iov = 5 ; max_copy = 23 */
struct lib9p_msg_Tattach {
lib9p_tag_t tag;
lib9p_fid_t fid;
@@ -802,7 +811,7 @@ struct lib9p_msg_Tattach {
#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */
#if CONFIG_9P_ENABLE_9P2000_L
-/* min_size = 25 ; max_size = 65,560 */
+/* min_size = 25 ; exp_size = 52 ; max_size = 65,560 ; max_iov = 3 ; max_copy = 25 */
struct lib9p_msg_Tlcreate {
lib9p_tag_t tag;
lib9p_fid_t fid;
@@ -812,7 +821,7 @@ struct lib9p_msg_Tlcreate {
lib9p_nuid_t gid;
};
-/* min_size = 19 ; max_size = 131,089 */
+/* min_size = 19 ; exp_size = 73 ; max_size = 131,089 ; max_iov = 5 ; max_copy = 19 */
struct lib9p_msg_Tsymlink {
lib9p_tag_t tag;
lib9p_fid_t fid;
@@ -821,7 +830,7 @@ struct lib9p_msg_Tsymlink {
lib9p_nuid_t gid;
};
-/* min_size = 29 ; max_size = 65,564 */
+/* min_size = 29 ; exp_size = 56 ; max_size = 65,564 ; max_iov = 3 ; max_copy = 29 */
struct lib9p_msg_Tmknod {
lib9p_tag_t tag;
lib9p_fid_t dfid;
@@ -832,7 +841,7 @@ struct lib9p_msg_Tmknod {
lib9p_nuid_t gid;
};
-/* min_size = 21 ; max_size = 65,556 */
+/* min_size = 21 ; exp_size = 48 ; max_size = 65,556 ; max_iov = 3 ; max_copy = 21 */
struct lib9p_msg_Tmkdir {
lib9p_tag_t tag;
lib9p_fid_t dfid;
@@ -843,14 +852,14 @@ struct lib9p_msg_Tmkdir {
#endif /* CONFIG_9P_ENABLE_9P2000_L */
#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u
-/* size = 12 */
+/* size = 12 ; max_iov = 1 ; max_copy = 12 */
struct lib9p_msg_Topen {
lib9p_tag_t tag;
lib9p_fid_t fid;
lib9p_o_t mode;
};
-/* min_size = 18 ; max_size = 65,553 */
+/* min_size = 18 ; exp_size = 45 ; max_size = 65,553 ; max_iov = 3 ; max_copy = 18 */
struct lib9p_msg_Tcreate {
lib9p_tag_t tag;
lib9p_fid_t fid;
@@ -861,7 +870,7 @@ struct lib9p_msg_Tcreate {
#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */
#if CONFIG_9P_ENABLE_9P2000_p9p
-/* size = 12 */
+/* size = 12 ; max_iov = 1 ; max_copy = 12 */
struct lib9p_msg_Topenfd {
lib9p_tag_t tag;
lib9p_fid_t fid;
@@ -870,14 +879,14 @@ struct lib9p_msg_Topenfd {
#endif /* CONFIG_9P_ENABLE_9P2000_p9p */
#if CONFIG_9P_ENABLE_9P2000_L
-/* size = 19 */
+/* size = 19 ; max_iov = 1 ; max_copy = 19 */
struct lib9p_msg_Tgetattr {
lib9p_tag_t tag;
lib9p_fid_t fid;
lib9p_getattr_t request_mask;
};
-/* size = 67 */
+/* size = 67 ; max_iov = 1 ; max_copy = 67 */
struct lib9p_msg_Tsetattr {
lib9p_tag_t tag;
lib9p_fid_t fid;
@@ -892,7 +901,7 @@ struct lib9p_msg_Tsetattr {
uint64_t mtime_nsec;
};
-/* min_size = 38 ; max_size = 65,573 */
+/* min_size = 38 ; exp_size = 65 ; max_size = 65,573 ; max_iov = 2 ; max_copy = 38 */
struct lib9p_msg_Tlock {
lib9p_tag_t tag;
lib9p_fid_t fid;
@@ -904,7 +913,7 @@ struct lib9p_msg_Tlock {
struct lib9p_s client_id;
};
-/* size = 8 */
+/* size = 8 ; max_iov = 1 ; max_copy = 8 */
struct lib9p_msg_Rlock {
lib9p_tag_t tag;
lib9p_lock_status_t status;
@@ -912,10 +921,10 @@ struct lib9p_msg_Rlock {
#endif /* CONFIG_9P_ENABLE_9P2000_L */
#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u
-/* LIB9P_VER_9P2000 : min_size = 49 ; max_size = 262,189 */
-/* LIB9P_VER_9P2000_e : min_size = 49 ; max_size = 262,189 */
-/* LIB9P_VER_9P2000_p9p: min_size = 49 ; max_size = 262,189 */
-/* LIB9P_VER_9P2000_u : min_size = 63 ; max_size = 327,738 */
+/* LIB9P_VER_9P2000 : min_size = 49 ; exp_size = 157 ; max_size = 262,189 ; max_iov = 8 ; max_copy = 49 */
+/* LIB9P_VER_9P2000_e : min_size = 49 ; exp_size = 157 ; max_size = 262,189 ; max_iov = 8 ; max_copy = 49 */
+/* LIB9P_VER_9P2000_p9p: min_size = 49 ; exp_size = 157 ; max_size = 262,189 ; max_iov = 8 ; max_copy = 49 */
+/* LIB9P_VER_9P2000_u : min_size = 63 ; exp_size = 198 ; max_size = 327,738 ; max_iov = 11 ; max_copy = 63 */
struct lib9p_stat {
uint16_t kern_type;
uint32_t kern_dev;
@@ -938,19 +947,19 @@ struct lib9p_stat {
#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */
#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u
-/* size = 20 */
+/* size = 20 ; max_iov = 1 ; max_copy = 20 */
struct lib9p_msg_Rauth {
lib9p_tag_t tag;
struct lib9p_qid aqid;
};
-/* size = 20 */
+/* size = 20 ; max_iov = 1 ; max_copy = 20 */
struct lib9p_msg_Rattach {
lib9p_tag_t tag;
struct lib9p_qid qid;
};
-/* min_size = 9 ; max_size = 217 */
+/* min_size = 9 ; exp_size = 217 ; max_size = 217 ; max_iov = 1 ; max_copy = 217 */
struct lib9p_msg_Rwalk {
lib9p_tag_t tag;
uint16_t nwqid;
@@ -959,14 +968,14 @@ struct lib9p_msg_Rwalk {
#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */
#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u
-/* size = 24 */
+/* size = 24 ; max_iov = 1 ; max_copy = 24 */
struct lib9p_msg_Ropen {
lib9p_tag_t tag;
struct lib9p_qid qid;
uint32_t iounit;
};
-/* size = 24 */
+/* size = 24 ; max_iov = 1 ; max_copy = 24 */
struct lib9p_msg_Rcreate {
lib9p_tag_t tag;
struct lib9p_qid qid;
@@ -975,7 +984,7 @@ struct lib9p_msg_Rcreate {
#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */
#if CONFIG_9P_ENABLE_9P2000_p9p
-/* size = 28 */
+/* size = 28 ; max_iov = 1 ; max_copy = 28 */
struct lib9p_msg_Ropenfd {
lib9p_tag_t tag;
struct lib9p_qid qid;
@@ -985,33 +994,33 @@ struct lib9p_msg_Ropenfd {
#endif /* CONFIG_9P_ENABLE_9P2000_p9p */
#if CONFIG_9P_ENABLE_9P2000_L
-/* size = 24 */
+/* size = 24 ; max_iov = 1 ; max_copy = 24 */
struct lib9p_msg_Rlopen {
lib9p_tag_t tag;
struct lib9p_qid qid;
uint32_t iounit;
};
-/* size = 24 */
+/* size = 24 ; max_iov = 1 ; max_copy = 24 */
struct lib9p_msg_Rlcreate {
lib9p_tag_t tag;
struct lib9p_qid qid;
uint32_t iounit;
};
-/* size = 20 */
+/* size = 20 ; max_iov = 1 ; max_copy = 20 */
struct lib9p_msg_Rsymlink {
lib9p_tag_t tag;
struct lib9p_qid qid;
};
-/* size = 20 */
+/* size = 20 ; max_iov = 1 ; max_copy = 20 */
struct lib9p_msg_Rmknod {
lib9p_tag_t tag;
struct lib9p_qid qid;
};
-/* size = 160 */
+/* size = 160 ; max_iov = 1 ; max_copy = 160 */
struct lib9p_msg_Rgetattr {
lib9p_tag_t tag;
uint64_t valid;
@@ -1036,7 +1045,7 @@ struct lib9p_msg_Rgetattr {
uint64_t data_version;
};
-/* size = 20 */
+/* size = 20 ; max_iov = 1 ; max_copy = 20 */
struct lib9p_msg_Rmkdir {
lib9p_tag_t tag;
struct lib9p_qid qid;
@@ -1044,22 +1053,78 @@ struct lib9p_msg_Rmkdir {
#endif /* CONFIG_9P_ENABLE_9P2000_L */
#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u
-/* LIB9P_VER_9P2000 : min_size = 58 ; max_size = 262,198 */
-/* LIB9P_VER_9P2000_e : min_size = 58 ; max_size = 262,198 */
-/* LIB9P_VER_9P2000_p9p: min_size = 58 ; max_size = 262,198 */
-/* LIB9P_VER_9P2000_u : min_size = 72 ; max_size = 327,747 */
+/* LIB9P_VER_9P2000 : min_size = 58 ; exp_size = 166 ; max_size = 262,198 ; max_iov = 8 ; max_copy = 58 */
+/* LIB9P_VER_9P2000_e : min_size = 58 ; exp_size = 166 ; max_size = 262,198 ; max_iov = 8 ; max_copy = 58 */
+/* LIB9P_VER_9P2000_p9p: min_size = 58 ; exp_size = 166 ; max_size = 262,198 ; max_iov = 8 ; max_copy = 58 */
+/* LIB9P_VER_9P2000_u : min_size = 72 ; exp_size = 207 ; max_size = 327,747 ; max_iov = 11 ; max_copy = 72 */
struct lib9p_msg_Rstat {
lib9p_tag_t tag;
struct lib9p_stat stat;
};
-/* LIB9P_VER_9P2000 : min_size = 62 ; max_size = 262,202 */
-/* LIB9P_VER_9P2000_e : min_size = 62 ; max_size = 262,202 */
-/* LIB9P_VER_9P2000_p9p: min_size = 62 ; max_size = 262,202 */
-/* LIB9P_VER_9P2000_u : min_size = 76 ; max_size = 327,751 */
+/* LIB9P_VER_9P2000 : min_size = 62 ; exp_size = 170 ; max_size = 262,202 ; max_iov = 8 ; max_copy = 62 */
+/* LIB9P_VER_9P2000_e : min_size = 62 ; exp_size = 170 ; max_size = 262,202 ; max_iov = 8 ; max_copy = 62 */
+/* LIB9P_VER_9P2000_p9p: min_size = 62 ; exp_size = 170 ; max_size = 262,202 ; max_iov = 8 ; max_copy = 62 */
+/* LIB9P_VER_9P2000_u : min_size = 76 ; exp_size = 211 ; max_size = 327,751 ; max_iov = 11 ; max_copy = 76 */
struct lib9p_msg_Twstat {
lib9p_tag_t tag;
lib9p_fid_t fid;
struct lib9p_stat stat;
};
#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */
+
+/* containers *****************************************************************/
+
+#define _LIB9P_MAX(a, b) ((a) > (b)) ? (a) : (b)
+
+#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u
+ #if CONFIG_9P_ENABLE_9P2000_e
+ #define LIB9P_TMSG_MAX_IOV _LIB9P_MAX(32, 2 + (CONFIG_9P_MAX_9P2000_e_WELEM * 2))
+ #else
+ #define LIB9P_TMSG_MAX_IOV 32
+ #endif
+#endif
+
+#if CONFIG_9P_ENABLE_9P2000_u
+ #if CONFIG_9P_ENABLE_9P2000_e
+ #define LIB9P_TMSG_MAX_COPY _LIB9P_MAX(76, 17 + (CONFIG_9P_MAX_9P2000_e_WELEM * 2))
+ #else
+ #define LIB9P_TMSG_MAX_COPY 76
+ #endif
+#elif CONFIG_9P_ENABLE_9P2000_L
+ #if CONFIG_9P_ENABLE_9P2000_e
+ #define LIB9P_TMSG_MAX_COPY _LIB9P_MAX(67, 17 + (CONFIG_9P_MAX_9P2000_e_WELEM * 2))
+ #else
+ #define LIB9P_TMSG_MAX_COPY 67
+ #endif
+#elif CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p
+ #if CONFIG_9P_ENABLE_9P2000_e
+ #define LIB9P_TMSG_MAX_COPY _LIB9P_MAX(62, 17 + (CONFIG_9P_MAX_9P2000_e_WELEM * 2))
+ #else
+ #define LIB9P_TMSG_MAX_COPY 62
+ #endif
+#endif
+
+#if CONFIG_9P_ENABLE_9P2000_u
+ #define LIB9P_RMSG_MAX_IOV 11
+#elif CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p
+ #define LIB9P_RMSG_MAX_IOV 8
+#elif CONFIG_9P_ENABLE_9P2000_L
+ #define LIB9P_RMSG_MAX_IOV 2
+#endif
+
+#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u
+ #define LIB9P_RMSG_MAX_COPY 217
+#endif
+
+struct lib9p_Tmsg_send_buf {
+ size_t iov_cnt;
+ struct iovec iov[LIB9P_TMSG_MAX_IOV];
+ uint8_t copied[LIB9P_TMSG_MAX_COPY];
+};
+
+struct lib9p_Rmsg_send_buf {
+ size_t iov_cnt;
+ struct iovec iov[LIB9P_RMSG_MAX_IOV];
+ uint8_t copied[LIB9P_RMSG_MAX_COPY];
+};
diff --git a/lib9p/include/lib9p/9p.h b/lib9p/include/lib9p/9p.h
index d4764a2..68e007f 100644
--- a/lib9p/include/lib9p/9p.h
+++ b/lib9p/include/lib9p/9p.h
@@ -118,7 +118,7 @@ void lib9p_Tmsg_unmarshal(struct lib9p_ctx *ctx, uint8_t *net_bytes,
* @errno LINUX_ERANGE: reply does not fit in ctx->max_msg_size
*/
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);
/* main R-message functions ***************************************************/
@@ -128,7 +128,7 @@ ssize_t lib9p_Rmsg_validate(struct lib9p_ctx *ctx, uint8_t *net_bytes);
void lib9p_Rmsg_unmarshal(struct lib9p_ctx *ctx, uint8_t *net_bytes,
enum lib9p_msg_type *ret_typ, void *ret_body);
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);
/* `struct lib9p_stat` helpers ************************************************/
diff --git a/lib9p/internal.h b/lib9p/internal.h
index a648532..d27348e 100644
--- a/lib9p/internal.h
+++ b/lib9p/internal.h
@@ -69,8 +69,10 @@ struct _marshal_ctx {
struct lib9p_ctx *ctx;
/* output */
- uint8_t *net_bytes;
- uint32_t net_offset;
+ size_t net_iov_cnt;
+ struct iovec *net_iov;
+ size_t net_copied_size;
+ uint8_t *net_copied;
};
typedef bool (*_marshal_fn_t)(struct _marshal_ctx *ctx, void *host_val);
@@ -88,6 +90,7 @@ struct _lib9p_send_tentry {
extern const char * _lib9p_table_ver_name[LIB9P_VER_NUM];
extern const char * _lib9p_table_msg_name[LIB9P_VER_NUM][0x100];
+extern const uint32_t _lib9p_table_msg_min_size[LIB9P_VER_NUM];
extern const struct _lib9p_recv_tentry _lib9p_table_Tmsg_recv[LIB9P_VER_NUM][0x80];
extern const struct _lib9p_recv_tentry _lib9p_table_Rmsg_recv[LIB9P_VER_NUM][0x80];
extern const struct _lib9p_send_tentry _lib9p_table_Tmsg_send[LIB9P_VER_NUM][0x80];
diff --git a/lib9p/srv.c b/lib9p/srv.c
index 9837994..c624fa8 100644
--- a/lib9p/srv.c
+++ b/lib9p/srv.c
@@ -131,8 +131,8 @@ struct _lib9p_srv_req {
/* immutable */
struct _srv_sess *parent_sess;
uint16_t tag;
+ uint8_t *net_bytes;
/* mutable */
- uint8_t *net_bytes; /* CONFIG_9P_MAX_MSG_SIZE-sized */
struct lib9p_srv_ctx ctx;
};
@@ -140,31 +140,18 @@ struct _lib9p_srv_req {
#define nonrespond_errorf errorf
-static uint32_t rerror_overhead_for_version(enum lib9p_version version,
- uint8_t *scratch) {
- struct lib9p_ctx empty_ctx = {
- .version = version,
- .max_msg_size = CONFIG_9P_MAX_MSG_SIZE,
- };
- struct lib9p_msg_Rerror empty_error = { 0 };
- bool e;
-
- e = lib9p_Rmsg_marshal(&empty_ctx, LIB9P_TYP_Rerror,
- &empty_error, /* host_body */
- scratch); /* net_bytes */
- assert(!e);
-
- uint32_t min_msg_size = uint32le_decode(scratch);
-
- /* Assert that min_msg_size + biggest_possible_MAX_ERR_SIZE
- * won't overflow uint32... because using
- * __builtin_add_overflow in respond_error() would be a bit
- * much. */
- assert(min_msg_size < (UINT32_MAX - UINT16_MAX));
- /* Assert that min_msg_size doesn't overflow MAX_MSG_SIZE. */
- assert(CONFIG_9P_MAX_MSG_SIZE >= min_msg_size);
-
- return min_msg_size;
+static ssize_t write_Rmsg(struct _lib9p_srv_req *req, struct lib9p_Rmsg_send_buf *resp) {
+ ssize_t r = 0, _r;
+ cr_mutex_lock(&req->parent_sess->parent_conn->writelock);
+ for (size_t i = 0; i < resp->iov_cnt; i++) {
+ _r = LO_CALL(req->parent_sess->parent_conn->fd, write,
+ resp->iov[i].iov_base, resp->iov[i].iov_len);
+ if (_r < 0)
+ return _r;
+ r += _r;
+ }
+ cr_mutex_unlock(&req->parent_sess->parent_conn->writelock);
+ return r;
}
static void respond_error(struct _lib9p_srv_req *req) {
@@ -186,19 +173,17 @@ static void respond_error(struct _lib9p_srv_req *req) {
struct _srv_sess *sess = req->parent_sess;
/* Truncate the error-string if necessary to avoid needing to
- * return LINUX_ERANGE. The assert() in
- * rerror_overhead_for_version() has checked that this
- * addition doesn't overflow. */
+ * return LINUX_ERANGE. */
if (((uint32_t)host.ename.len) + sess->rerror_overhead > sess->max_msg_size)
host.ename.len = sess->max_msg_size - sess->rerror_overhead;
- lib9p_Rmsg_marshal(&req->ctx.basectx, LIB9P_TYP_Rerror,
- &host, req->net_bytes);
+ struct lib9p_Rmsg_send_buf net;
+
+ lib9p_Rmsg_marshal(&req->ctx.basectx,
+ LIB9P_TYP_Rerror, &host,
+ &net);
- cr_mutex_lock(&sess->parent_conn->writelock);
- r = LO_CALL(sess->parent_conn->fd, write,
- req->net_bytes, uint32le_decode(req->net_bytes));
- cr_mutex_unlock(&sess->parent_conn->writelock);
+ r = write_Rmsg(req, &net);
if (r < 0)
nonrespond_errorf("write: %s", net_strerror(-r));
}
@@ -227,15 +212,13 @@ static bool read_exactly(lo_interface net_stream_conn fd, uint8_t *buf, size_t g
static void handle_message(struct _lib9p_srv_req *ctx);
[[noreturn]] void lib9p_srv_read_cr(struct lib9p_srv *srv, lo_interface net_stream_listener listener) {
- uint8_t buf[CONFIG_9P_MAX_MSG_SIZE];
-
assert(srv);
assert(srv->rootdir);
assert(!LO_IS_NULL(listener));
srv->readers++;
- uint32_t initial_rerror_overhead = rerror_overhead_for_version(0, buf);
+ uint32_t initial_rerror_overhead = _lib9p_table_msg_min_size[LIB9P_VER_unknown];
for (;;) {
struct _srv_conn conn = {
@@ -263,6 +246,7 @@ static void handle_message(struct _lib9p_srv_req *ctx);
nextmsg:
/* Read the message. */
size_t done = 0;
+ uint8_t buf[7];
if (read_exactly(conn.fd, buf, 4, &done))
goto close;
size_t goal = uint32le_decode(buf);
@@ -292,11 +276,16 @@ static void handle_message(struct _lib9p_srv_req *ctx);
respond_error(&req);
goto nextmsg;
}
- if (read_exactly(conn.fd, buf, goal, &done))
+ req.net_bytes = malloc(goal);
+ assert(req.net_bytes);
+ memcpy(req.net_bytes, buf, done);
+ if (read_exactly(conn.fd, req.net_bytes, goal, &done)) {
+ free(req.net_bytes);
goto close;
+ }
/* Handle the message... */
- if (buf[4] == LIB9P_TYP_Tversion)
+ if (req.net_bytes[4] == LIB9P_TYP_Tversion)
/* ...in this coroutine for Tversion, */
handle_message(&req);
else
@@ -317,7 +306,6 @@ static void handle_message(struct _lib9p_srv_req *ctx);
/* write coroutine ************************************************************/
COROUTINE lib9p_srv_write_cr(void *_srv) {
- uint8_t net[CONFIG_9P_MAX_MSG_SIZE];
struct _lib9p_srv_req req;
_lib9p_srv_reqch_req_t rpc_handle;
@@ -336,11 +324,9 @@ COROUTINE lib9p_srv_write_cr(void *_srv) {
_lib9p_srv_reqch_send_resp(rpc_handle, 0);
cr_exit();
}
- /* Deep-copy the request from the reader coroutine's
+ /* Copy the request from the reader coroutine's
* stack to our stack. */
req = *rpc_handle.req;
- memcpy(net, req.net_bytes, uint32le_decode(req.net_bytes));
- req.net_bytes = net;
/* Record that we have it. */
reqmap_store(&req.parent_sess->reqs, req.tag, &req);
/* Notify the reader coroutine that we're done with
@@ -408,19 +394,15 @@ static tmessage_handler tmessage_handlers[0x100] = {
};
static void handle_message(struct _lib9p_srv_req *ctx) {
- uint8_t host_req[CONFIG_9P_MAX_HOSTMSG_SIZE];
+ uint8_t *host_req = NULL;
uint8_t host_resp[CONFIG_9P_MAX_HOSTMSG_SIZE];
/* Unmarshal it. */
ssize_t host_size = lib9p_Tmsg_validate(&ctx->ctx.basectx, ctx->net_bytes);
if (host_size < 0)
goto write;
- if ((size_t)host_size > sizeof(host_req)) {
- lib9p_errorf(&ctx->ctx.basectx,
- LINUX_EMSGSIZE, "unmarshalled payload larger than server limit (%zu > %zu)",
- host_size, sizeof(host_req));
- goto write;
- }
+ host_req = malloc(host_size);
+ assert(host_req);
enum lib9p_msg_type typ;
lib9p_Tmsg_unmarshal(&ctx->ctx.basectx, ctx->net_bytes,
&typ, host_req);
@@ -432,15 +414,16 @@ static void handle_message(struct _lib9p_srv_req *ctx) {
if (lib9p_ctx_has_error(&ctx->ctx.basectx))
respond_error(ctx);
else {
- if (lib9p_Rmsg_marshal(&ctx->ctx.basectx, typ+1, host_resp,
- ctx->net_bytes))
+ struct lib9p_Rmsg_send_buf net_resp;
+ if (lib9p_Rmsg_marshal(&ctx->ctx.basectx,
+ typ+1, host_resp,
+ &net_resp))
goto write;
-
- cr_mutex_lock(&ctx->parent_sess->parent_conn->writelock);
- LO_CALL(ctx->parent_sess->parent_conn->fd, write,
- ctx->net_bytes, uint32le_decode(ctx->net_bytes));
- cr_mutex_unlock(&ctx->parent_sess->parent_conn->writelock);
+ write_Rmsg(ctx, &net_resp);
}
+ if (host_req)
+ free(host_req);
+ free(ctx->net_bytes);
}
#define util_handler_common(ctx, req, resp) do { \
@@ -583,7 +566,7 @@ static void handle_Tversion(struct _lib9p_srv_req *ctx,
#endif
}
- uint32_t min_msg_size = rerror_overhead_for_version(version, ctx->net_bytes);
+ uint32_t min_msg_size = _lib9p_table_msg_min_size[version];
if (req->max_msg_size < min_msg_size) {
lib9p_errorf(&ctx->ctx.basectx,
LINUX_EDOM, "requested max_msg_size is less than minimum for %s (%"PRIu32" < %"PRIu32")",