From 2d7f2350559dde046e95bcc28c1f89f41f5a6d75 Mon Sep 17 00:00:00 2001 From: "Luke T. Shumaker" Date: Sat, 7 Jun 2025 15:23:29 -0600 Subject: lib9p_srv: Adopt a pread_to-like interface --- lib9p/srv.c | 53 +++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 41 insertions(+), 12 deletions(-) (limited to 'lib9p/srv.c') 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 -- cgit v1.2.3-2-g168b