summaryrefslogtreecommitdiff
path: root/lib9p/srv.c
diff options
context:
space:
mode:
authorLuke T. Shumaker <lukeshu@lukeshu.com>2025-06-07 15:23:29 -0600
committerLuke T. Shumaker <lukeshu@lukeshu.com>2025-06-12 02:28:40 -0600
commit2d7f2350559dde046e95bcc28c1f89f41f5a6d75 (patch)
tree374571661ef53086e6a9e025b9b344bf80451cb4 /lib9p/srv.c
parent4109b15224b08fe49297097d9891e4c584712400 (diff)
lib9p_srv: Adopt a pread_to-like interface
Diffstat (limited to 'lib9p/srv.c')
-rw-r--r--lib9p/srv.c53
1 files changed, 41 insertions, 12 deletions
diff --git a/lib9p/srv.c b/lib9p/srv.c
index ecdf169..03d7b93 100644
--- a/lib9p/srv.c
+++ b/lib9p/srv.c
@@ -1185,6 +1185,11 @@ static void handle_Tread(struct srv_req *ctx,
/* TODO: serialize simultaneous reads to the same FID */
+ /* req->count <= CONFIG_9P_SRV_MAX_MSG_SIZE <= CONFIG_9P_SRV_MAX_HOSTMSG_SIZE <= SIZE_MAX */
+ assert(req->count <= SIZE_MAX);
+ /* req->offset is u64, uoff is u64 */
+ static_assert(req->offset <= UOFF_MAX);
+
if (req->count > ctx->basectx.max_msg_size - lib9p_version_min_Rread_size(ctx->basectx.version))
req->count = ctx->basectx.max_msg_size - lib9p_version_min_Rread_size(ctx->basectx.version);
@@ -1219,20 +1224,44 @@ static void handle_Tread(struct srv_req *ctx,
ctx->user = srv_userid_decref(ctx->user);
}
-static void handle_read_file(struct srv_req *ctx, struct srv_fidinfo *fidinfo, uint64_t offset, uint32_t count) {
- iovec_or_error r = LO_CALL(fidinfo->file.io, pread, ctx, count, offset);
- if (r.is_err) {
- srv_respond(ctx, read, NULL, r.err);
- return;
- }
+struct rread_writer {
+ struct srv_req *ctx;
+ size_t count;
+ bool written;
+
+};
+LO_IMPLEMENTATION_STATIC(io_writer, struct rread_writer, rread);
+
+static size_t_and_error rread_writev(struct rread_writer *self, const struct iovec *iov, int iovcnt) {
+ assert(self);
+ assert(!self->written);
+ assert(iovcnt == 1);
+ assert(iov);
+ assert(iov->iov_len <= self->count);
+
struct lib9p_msg_Rread resp = {
- .tag = ctx->tag,
- .count = r.iovec.iov_len,
- .data = r.iovec.iov_base,
+ .tag = self->ctx->tag,
+ .count = iov->iov_len,
+ .data = iov->iov_base,
};
- if (resp.count > count)
- resp.count = count;
- srv_respond(ctx, read, &resp, ERROR_NULL);
+
+ srv_respond(self->ctx, read, &resp, ERROR_NULL);
+
+ self->written = true;
+ return ERROR_AND(size_t, iov->iov_len, ERROR_NULL);
+}
+
+static void handle_read_file(struct srv_req *ctx, struct srv_fidinfo *fidinfo, uint64_t offset, uint32_t count) {
+ struct rread_writer _writer = {
+ .ctx = ctx,
+ .count = (size_t) count,
+ .written = false,
+ };
+ lo_interface io_writer writer = LO_BOX(io_writer, &_writer);
+ error err = LO_CALL(fidinfo->file.io, pread, ctx, writer, offset, count);
+ assert(ERROR_IS_NULL(err) == _writer.written);
+ if (!ERROR_IS_NULL(err))
+ srv_respond(ctx, read, NULL, err);
}
#if _LIB9P_ENABLE_stat