diff options
author | Luke T. Shumaker <lukeshu@lukeshu.com> | 2025-04-12 21:30:52 -0600 |
---|---|---|
committer | Luke T. Shumaker <lukeshu@lukeshu.com> | 2025-04-13 02:29:43 -0600 |
commit | 06cc1184f375ce5929010254781483277d9447d2 (patch) | |
tree | 122ee1bd59890429202d6d0951591d3540fa431a /lib9p/srv.c | |
parent | d2afc58a861ba9d5a1add97d42a3b5aaa0536450 (diff) |
lib9p: srv: Less nesting in the context structs
Diffstat (limited to 'lib9p/srv.c')
-rw-r--r-- | lib9p/srv.c | 327 |
1 files changed, 160 insertions, 167 deletions
diff --git a/lib9p/srv.c b/lib9p/srv.c index 836890c..b8b6683 100644 --- a/lib9p/srv.c +++ b/lib9p/srv.c @@ -55,14 +55,14 @@ static_assert(CONFIG_9P_SRV_MAX_HOSTMSG_SIZE <= SSIZE_MAX); bool lib9p_srv_flush_requested(struct lib9p_srv_ctx *ctx) { assert(ctx); - return _lib9p_srv_flushch_can_send(&ctx->_flushch); + return _lib9p_srv_flushch_can_send(&ctx->flushch); } void lib9p_srv_acknowledge_flush(struct lib9p_srv_ctx *ctx) { assert(ctx); - assert(_lib9p_srv_flushch_can_send(&ctx->_flushch)); + assert(_lib9p_srv_flushch_can_send(&ctx->flushch)); lib9p_error(&ctx->basectx, LINUX_ECANCELED, "request canceled by flush"); - _lib9p_srv_flushch_send(&ctx->_flushch, true); + _lib9p_srv_flushch_send(&ctx->flushch, true); } /* structs ********************************************************************/ @@ -87,7 +87,7 @@ MAP_DECLARE(pathmap, srv_path_t, struct srv_pathinfo); #define FIDFLAG_RCLOSE (1<<2) #define FIDFLAG_OPEN (FIDFLAG_OPEN_R|FIDFLAG_OPEN_W) -struct _srv_fidinfo { +struct srv_fidinfo { srv_path_t path; uint8_t flags; union { @@ -102,8 +102,8 @@ struct _srv_fidinfo { }; }; -MAP_DECLARE(fidmap, lib9p_fid_t, struct _srv_fidinfo); -MAP_DECLARE(reqmap, lib9p_tag_t, struct _lib9p_srv_req *); +MAP_DECLARE(fidmap, lib9p_fid_t, struct srv_fidinfo); +MAP_DECLARE(reqmap, lib9p_tag_t, struct lib9p_srv_ctx *); /* The hierarchy of concepts is: * @@ -111,9 +111,9 @@ MAP_DECLARE(reqmap, lib9p_tag_t, struct _lib9p_srv_req *); * */ -/* struct _srv_srv {} is defined in <lib9p/srv.h> */ +/* struct lib9p_srv {} is defined in <lib9p/srv.h> */ -struct _srv_conn { +struct srv_conn { /* immutable */ struct lib9p_srv *parent_srv; lo_interface net_stream_conn fd; @@ -122,34 +122,28 @@ struct _srv_conn { cr_mutex_t writelock; }; -struct _srv_sess { +#define srv_sess _lib9p_srv_sess +struct srv_sess { /* immutable */ - struct _srv_conn *parent_conn; + struct srv_conn *parent_conn; enum lib9p_version version; uint32_t max_msg_size; /* mutable */ bool initialized; bool closing; - struct pathmap paths; /* srv_path_t => lib9p_srv_file + metadata */ - struct fidmap fids; /* lib9p_fid_t => lib9p_srv_{fio,dio} + metadata */ - struct reqmap reqs; /* lib9p_tag_t => *_lib9p_srv_req */ + struct pathmap paths; /* srv_path_t => `lib9p_srv_file` + metadata */ + struct fidmap fids; /* lib9p_fid_t => `lib9p_srv_{fio,dio}` + metadata */ + struct reqmap reqs; /* lib9p_tag_t => `struct srv_req *` */ }; -struct _lib9p_srv_req { - /* immutable */ - struct _srv_sess *parent_sess; - uint16_t tag; - uint8_t *net_bytes; - /* mutable */ - struct lib9p_srv_ctx ctx; -}; +#define srv_req lib9p_srv_ctx /* struct lib9p_srv_ctx {} is defined in <lib9p/srv.h> */ /* base utilities *************************************************************/ -static void msglog(struct _lib9p_srv_req *req, enum lib9p_msg_type typ, void *hostmsg) { +static void msglog(struct srv_req *req, enum lib9p_msg_type typ, void *hostmsg) { struct lib9p_srv *srv = req->parent_sess->parent_conn->parent_srv; if (srv->msglog) { - srv->msglog(&req->ctx, typ, hostmsg); + srv->msglog(req, typ, hostmsg); return; } /* It sucks that %v trips -Wformat and -Wformat-extra-args @@ -157,13 +151,13 @@ static void msglog(struct _lib9p_srv_req *req, enum lib9p_msg_type typ, void *ho #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wformat" #pragma GCC diagnostic ignored "-Wformat-extra-args" - infof("%c %v", typ % 2 ? '<' : '>', lo_box_lib9p_msg_as_fmt_formatter(&req->ctx.basectx, typ, hostmsg)); + infof("%c %v", typ % 2 ? '<' : '>', lo_box_lib9p_msg_as_fmt_formatter(&req->basectx, typ, hostmsg)); #pragma GCC diagnostic pop } #define nonrespond_errorf errorf -static ssize_t write_Rmsg(struct _lib9p_srv_req *req, struct lib9p_Rmsg_send_buf *resp) { +static ssize_t write_Rmsg(struct srv_req *req, struct lib9p_Rmsg_send_buf *resp) { ssize_t r; cr_mutex_lock(&req->parent_sess->parent_conn->writelock); r = io_writev(req->parent_sess->parent_conn->fd, resp->iov, resp->iov_cnt); @@ -171,23 +165,23 @@ static ssize_t write_Rmsg(struct _lib9p_srv_req *req, struct lib9p_Rmsg_send_buf return r; } -static void respond_error(struct _lib9p_srv_req *req) { +static void respond_error(struct srv_req *req) { #if CONFIG_9P_ENABLE_9P2000_u - assert(req->ctx.basectx.err_num); + assert(req->basectx.err_num); #endif - assert(req->ctx.basectx.err_msg[0]); + assert(req->basectx.err_msg[0]); ssize_t r; struct lib9p_msg_Rerror host = { .tag = req->tag, - .errstr = lib9p_strn(req->ctx.basectx.err_msg, + .errstr = lib9p_strn(req->basectx.err_msg, CONFIG_9P_MAX_ERR_SIZE), #if CONFIG_9P_ENABLE_9P2000_u - .errnum = req->ctx.basectx.err_num, + .errnum = req->basectx.err_num, #endif }; - struct _srv_sess *sess = req->parent_sess; + struct srv_sess *sess = req->parent_sess; /* XXX: This assumes that a version's min_msg_size is the * Rerror overhead. That's true for the current @@ -201,7 +195,7 @@ static void respond_error(struct _lib9p_srv_req *req) { struct lib9p_Rmsg_send_buf net; - lib9p_Rmsg_marshal(&req->ctx.basectx, + lib9p_Rmsg_marshal(&req->basectx, LIB9P_TYP_Rerror, &host, &net); @@ -232,7 +226,7 @@ static bool read_exactly(lo_interface net_stream_conn fd, uint8_t *buf, size_t g return false; } -static void handle_message(struct _lib9p_srv_req *ctx); +static void handle_message(struct srv_req *ctx); void lib9p_srv_accept_and_read_loop(struct lib9p_srv *srv, lo_interface net_stream_listener listener) { assert(srv); @@ -255,19 +249,19 @@ void lib9p_srv_accept_and_read_loop(struct lib9p_srv *srv, lo_interface net_stre } } -static void clunkremove(struct _lib9p_srv_req *ctx, lib9p_fid_t fid, bool remove); +static void clunkremove(struct srv_req *ctx, lib9p_fid_t fid, bool remove); void lib9p_srv_read(struct lib9p_srv *srv, lo_interface net_stream_conn _conn) { assert(srv); assert(srv->rootdir); assert(!LO_IS_NULL(_conn)); - struct _srv_conn conn = { + struct srv_conn conn = { .parent_srv = srv, .fd = _conn, .reader = cr_getcid(), }; - struct _srv_sess sess = { + struct srv_sess sess = { .parent_conn = &conn, .version = LIB9P_VER_unknown, .max_msg_size = CONFIG_9P_SRV_MAX_MSG_SIZE, @@ -286,19 +280,20 @@ void lib9p_srv_read(struct lib9p_srv *srv, lo_interface net_stream_conn _conn) { } if (read_exactly(conn.fd, buf, 7, &done)) break; - struct _lib9p_srv_req req = { + struct lib9p_srv_authinfo authinfo = {}; + struct srv_req req = { + .basectx = { + .version = sess.version, + .max_msg_size = sess.max_msg_size, + }, + .authinfo = &authinfo, + .parent_sess = &sess, .tag = uint16le_decode(&buf[5]), .net_bytes = buf, - .ctx = { - .basectx = { - .version = sess.version, - .max_msg_size = sess.max_msg_size, - }, - }, }; if (goal > sess.max_msg_size) { - lib9p_errorf(&req.ctx.basectx, + lib9p_errorf(&req.basectx, LINUX_EMSGSIZE, "T-message larger than %s limit (%zu > %"PRIu32")", sess.initialized ? "negotiated" : "server", goal, @@ -336,18 +331,16 @@ void lib9p_srv_read(struct lib9p_srv *srv, lo_interface net_stream_conn _conn) { map_free(&sess.reqs); MAP_FOREACH(&sess.fids, fid, fidinfo) { - struct _lib9p_srv_req req = { - .parent_sess = &sess, - .ctx = { - .basectx = { - .version = sess.version, - .max_msg_size = sess.max_msg_size, - }, + struct srv_req req = { + .basectx = { + .version = sess.version, + .max_msg_size = sess.max_msg_size, }, + .parent_sess = &sess, }; clunkremove(&req, fid, false); - if (lib9p_ctx_has_error(&req.ctx.basectx)) - errorf("clunk: %.*s", CONFIG_9P_MAX_ERR_SIZE, req.ctx.basectx.err_msg); + if (lib9p_ctx_has_error(&req.basectx)) + errorf("clunk: %.*s", CONFIG_9P_MAX_ERR_SIZE, req.basectx.err_msg); } map_free(&sess.fids); @@ -358,7 +351,7 @@ void lib9p_srv_read(struct lib9p_srv *srv, lo_interface net_stream_conn _conn) { /* write coroutine ************************************************************/ void lib9p_srv_worker_loop(struct lib9p_srv *srv) { - struct _lib9p_srv_req req; + struct srv_req req; _lib9p_srv_reqch_req_t rpc_handle; assert(srv); @@ -378,7 +371,7 @@ void lib9p_srv_worker_loop(struct lib9p_srv *srv) { * stack to our stack. */ req = *rpc_handle.req; /* Record that we have it. */ - struct _lib9p_srv_req **reqpp = map_store(&req.parent_sess->reqs, req.tag, &req); + struct srv_req **reqpp = map_store(&req.parent_sess->reqs, req.tag, &req); assert(reqpp && *reqpp == &req); /* Notify the reader coroutine that we're done with * its data. */ @@ -388,8 +381,8 @@ void lib9p_srv_worker_loop(struct lib9p_srv *srv) { handle_message(&req); /* Release resources. ****************************************/ - while (_lib9p_srv_flushch_can_send(&req.ctx._flushch)) - _lib9p_srv_flushch_send(&req.ctx._flushch, false); + while (_lib9p_srv_flushch_can_send(&req.flushch)) + _lib9p_srv_flushch_send(&req.flushch, false); map_del(&req.parent_sess->reqs, req.tag); if (req.parent_sess->closing && !map_len(&req.parent_sess->reqs)) cr_unpause(req.parent_sess->parent_conn->reader); @@ -397,7 +390,7 @@ void lib9p_srv_worker_loop(struct lib9p_srv *srv) { } #define _HANDLER_PROTO(typ) \ - static void handle_T##typ(struct _lib9p_srv_req *, \ + static void handle_T##typ(struct srv_req *, \ struct lib9p_msg_T##typ *, \ struct lib9p_msg_R##typ *) _HANDLER_PROTO(version); @@ -419,7 +412,7 @@ _HANDLER_PROTO(sread); _HANDLER_PROTO(swrite); #endif -typedef void (*tmessage_handler)(struct _lib9p_srv_req *, void *, void *); +typedef void (*tmessage_handler)(struct srv_req *, void *, void *); static tmessage_handler tmessage_handlers[0x100] = { [LIB9P_TYP_Tversion] = (tmessage_handler)handle_Tversion, @@ -442,18 +435,18 @@ static tmessage_handler tmessage_handlers[0x100] = { #endif }; -static void handle_message(struct _lib9p_srv_req *ctx) { +static void handle_message(struct srv_req *ctx) { uint8_t *host_req = NULL; uint8_t host_resp[CONFIG_9P_SRV_MAX_HOSTMSG_SIZE]; /* Unmarshal it. */ - ssize_t host_size = lib9p_Tmsg_validate(&ctx->ctx.basectx, ctx->net_bytes); + ssize_t host_size = lib9p_Tmsg_validate(&ctx->basectx, ctx->net_bytes); if (host_size < 0) goto write; host_req = calloc(1, host_size); assert(host_req); enum lib9p_msg_type typ; - lib9p_Tmsg_unmarshal(&ctx->ctx.basectx, ctx->net_bytes, + lib9p_Tmsg_unmarshal(&ctx->basectx, ctx->net_bytes, &typ, host_req); msglog(ctx, typ, host_req); @@ -461,11 +454,11 @@ static void handle_message(struct _lib9p_srv_req *ctx) { tmessage_handlers[typ](ctx, (void *)host_req, (void *)host_resp); write: - if (lib9p_ctx_has_error(&ctx->ctx.basectx)) + if (lib9p_ctx_has_error(&ctx->basectx)) respond_error(ctx); else { struct lib9p_Rmsg_send_buf net_resp; - if (lib9p_Rmsg_marshal(&ctx->ctx.basectx, + if (lib9p_Rmsg_marshal(&ctx->basectx, typ+1, host_resp, &net_resp)) goto write; @@ -484,7 +477,7 @@ static void handle_message(struct _lib9p_srv_req *ctx) { resp->tag = req->tag; \ } while (0) -static inline bool srv_util_check_perm(struct _lib9p_srv_req *ctx, struct lib9p_stat *stat, uint8_t action) { +static inline bool srv_util_check_perm(struct srv_req *ctx, struct lib9p_stat *stat, uint8_t action) { assert(ctx); assert(stat); assert(action); @@ -502,7 +495,7 @@ static inline bool srv_util_check_perm(struct _lib9p_srv_req *ctx, struct lib9p_ * * Returns a pointer to the stored pathinfo. */ -static inline struct srv_pathinfo *srv_util_pathsave(struct _lib9p_srv_req *ctx, +static inline struct srv_pathinfo *srv_util_pathsave(struct srv_req *ctx, lo_interface lib9p_srv_file file, srv_path_t parent_path) { assert(ctx); @@ -535,7 +528,7 @@ static inline struct srv_pathinfo *srv_util_pathsave(struct _lib9p_srv_req *ctx, * Decrement the path's gc_refcount, and trigger garbage collection as * appropriate. */ -static inline void srv_util_pathfree(struct _lib9p_srv_req *ctx, srv_path_t path) { +static inline void srv_util_pathfree(struct srv_req *ctx, srv_path_t path) { assert(ctx); struct srv_pathinfo *pathinfo = map_load(&ctx->parent_sess->paths, path); @@ -559,7 +552,7 @@ static inline bool srv_util_pathisdir(struct srv_pathinfo *pathinfo) { * pathinfo->gc_refcount has already been incremented; does *not* * decrement it on failure. */ -static inline struct _srv_fidinfo *srv_util_fidsave(struct _lib9p_srv_req *ctx, lib9p_fid_t fid, struct srv_pathinfo *pathinfo, bool overwrite) { +static inline struct srv_fidinfo *srv_util_fidsave(struct srv_req *ctx, lib9p_fid_t fid, struct srv_pathinfo *pathinfo, bool overwrite) { assert(ctx); assert(fid != LIB9P_FID_NOFID); assert(pathinfo); @@ -567,7 +560,7 @@ static inline struct _srv_fidinfo *srv_util_fidsave(struct _lib9p_srv_req *ctx, struct lib9p_qid qid = LO_CALL(pathinfo->file, qid); - struct _srv_fidinfo *fidinfo = map_load(&ctx->parent_sess->fids, fid); + struct srv_fidinfo *fidinfo = map_load(&ctx->parent_sess->fids, fid); if (fidinfo) { if (overwrite) { struct srv_pathinfo *old_pathinfo = map_load(&ctx->parent_sess->paths, fidinfo->path); @@ -581,22 +574,22 @@ static inline struct _srv_fidinfo *srv_util_fidsave(struct _lib9p_srv_req *ctx, } srv_util_pathfree(ctx, fidinfo->path); } else { - lib9p_error(&ctx->ctx.basectx, + lib9p_error(&ctx->basectx, LINUX_EBADF, "FID already in use"); return NULL; } } else { - fidinfo = map_store(&ctx->parent_sess->fids, fid, (struct _srv_fidinfo){}); + fidinfo = map_store(&ctx->parent_sess->fids, fid, (struct srv_fidinfo){}); assert(fidinfo); } - *fidinfo = (struct _srv_fidinfo){ + *fidinfo = (struct srv_fidinfo){ .path = qid.path, }; return fidinfo; } -static void handle_Tversion(struct _lib9p_srv_req *ctx, +static void handle_Tversion(struct srv_req *ctx, struct lib9p_msg_Tversion *req, struct lib9p_msg_Rversion *resp) { util_handler_common(ctx, req, resp); @@ -624,7 +617,7 @@ static void handle_Tversion(struct _lib9p_srv_req *ctx, uint32_t min_msg_size = lib9p_version_min_msg_size(version); if (req->max_msg_size < min_msg_size) { - lib9p_errorf(&ctx->ctx.basectx, + lib9p_errorf(&ctx->basectx, LINUX_EDOM, "requested max_msg_size is less than minimum for %s (%"PRIu32" < %"PRIu32")", lib9p_version_str(version), req->max_msg_size, min_msg_size); return; @@ -644,7 +637,7 @@ static void handle_Tversion(struct _lib9p_srv_req *ctx, size_t i = 0; bool flushed; MAP_FOREACH(&ctx->parent_sess->reqs, tag, reqpp) { - list[i] = CR_SELECT_RECV(&((*reqpp)->ctx._flushch), &flushed); + list[i] = CR_SELECT_RECV(&((*reqpp)->flushch), &flushed); } assert(i == map_len(&ctx->parent_sess->reqs)); cr_select_v(i, list); @@ -664,82 +657,82 @@ static void handle_Tversion(struct _lib9p_srv_req *ctx, ctx->parent_sess->max_msg_size = resp->max_msg_size; } -static void handle_Tauth(struct _lib9p_srv_req *ctx, +static void handle_Tauth(struct srv_req *ctx, struct lib9p_msg_Tauth *req, struct lib9p_msg_Rauth *resp) { util_handler_common(ctx, req, resp); - ctx->ctx.uid = req->n_uid; - ctx->ctx.uname = req->uname; + ctx->authinfo->uid = req->n_uid; + ctx->authinfo->uname = req->uname; struct lib9p_srv *srv = ctx->parent_sess->parent_conn->parent_srv; if (!srv->auth) { - lib9p_error(&ctx->ctx.basectx, + lib9p_error(&ctx->basectx, LINUX_EOPNOTSUPP, "authentication not required"); return; } - srv->auth(&ctx->ctx, req->aname); - lib9p_error(&ctx->ctx.basectx, + srv->auth(ctx, req->aname); + lib9p_error(&ctx->basectx, LINUX_EOPNOTSUPP, "TODO: auth not implemented"); } -static void handle_Tattach(struct _lib9p_srv_req *ctx, +static void handle_Tattach(struct srv_req *ctx, struct lib9p_msg_Tattach *req, struct lib9p_msg_Rattach *resp) { util_handler_common(ctx, req, resp); - ctx->ctx.uid = req->n_uid; - ctx->ctx.uname = req->uname; + ctx->authinfo->uid = req->n_uid; + ctx->authinfo->uname = req->uname; struct lib9p_srv *srv = ctx->parent_sess->parent_conn->parent_srv; if (srv->auth) { /* struct lib9p_srv_filehandle *fh = map_get(req->afid); if (!fh) - lib9p_error(&ctx->ctx.basectx, + lib9p_error(&ctx->basectx, LINUX_EACCES, "FID provided as auth-file is not a valid FID"); else if (fh->type != FH_AUTH) - lib9p_error(&ctx->ctx.basectx, + lib9p_error(&ctx->basectx, LINUX_EACCES, "FID provided as auth-file is not an auth-file"); else if (!lib9p_str_eq(fh->data.auth.uname, req->uname)) - lib9p_errorf(&ctx->ctx.basectx, + lib9p_errorf(&ctx->basectx, LINUX_EACCES, "FID provided as auth-file is for user=\"%.*s\" and cannot be used for user=\"%.*s\"", fh->data.auth.uname.len, fh->data.auth.uname.utf8, req->uname.len, req->uname.utf8); else if (!lib9p_str_eq(fh->data.auth.aname, req->aname)) - lib9p_errorf(&ctx->ctx.basectx, + lib9p_errorf(&ctx->basectx, LINUX_EACCES, "FID provided as auth-file is for tree=\"%.*s\" and cannot be used for tree=\"%.*s\"", fh->data.auth.aname.len, fh->data.auth.aname.utf8, req->aname.len, req->aname.utf8); else if (!fh->data.auth.authenticated) - lib9p_error(&ctx->ctx.basectx, + lib9p_error(&ctx->basectx, LINUX_EACCES, "FID provided as auth-file has not completed authentication"); fh->refcount--; if (lib9p_ctx_has_error(&ctx->ctx)) return; */ - lib9p_error(&ctx->ctx.basectx, + lib9p_error(&ctx->basectx, LINUX_EOPNOTSUPP, "TODO: auth not (yet?) implemented"); return; } else { if (req->afid != LIB9P_FID_NOFID) { - lib9p_error(&ctx->ctx.basectx, + lib9p_error(&ctx->basectx, LINUX_EACCES, "FID provided as auth-file, but no auth-file is required"); return; } } if (req->fid == LIB9P_FID_NOFID) { - lib9p_error(&ctx->ctx.basectx, + lib9p_error(&ctx->basectx, LINUX_EBADF, "cannot assign to NOFID"); return; } /* 1. File object */ - lo_interface lib9p_srv_file root_file = srv->rootdir(&ctx->ctx, req->aname); - assert(LO_IS_NULL(root_file) == lib9p_ctx_has_error(&ctx->ctx.basectx)); - if (lib9p_ctx_has_error(&ctx->ctx.basectx)) + lo_interface lib9p_srv_file root_file = srv->rootdir(ctx, req->aname); + assert(LO_IS_NULL(root_file) == lib9p_ctx_has_error(&ctx->basectx)); + if (lib9p_ctx_has_error(&ctx->basectx)) return; struct lib9p_qid root_qid = LO_CALL(root_file, qid); @@ -758,30 +751,30 @@ static void handle_Tattach(struct _lib9p_srv_req *ctx, return; } -static void handle_Tflush(struct _lib9p_srv_req *ctx, +static void handle_Tflush(struct srv_req *ctx, struct lib9p_msg_Tflush *req, struct lib9p_msg_Rflush *resp) { util_handler_common(ctx, req, resp); - struct _lib9p_srv_req **oldreqp = map_load(&ctx->parent_sess->reqs, req->oldtag); + struct srv_req **oldreqp = map_load(&ctx->parent_sess->reqs, req->oldtag); if (oldreqp) - _lib9p_srv_flushch_recv(&((*oldreqp)->ctx._flushch)); + _lib9p_srv_flushch_recv(&((*oldreqp)->flushch)); } -static void handle_Twalk(struct _lib9p_srv_req *ctx, +static void handle_Twalk(struct srv_req *ctx, struct lib9p_msg_Twalk *req, struct lib9p_msg_Rwalk *resp) { util_handler_common(ctx, req, resp); if (req->newfid == LIB9P_FID_NOFID) { - lib9p_error(&ctx->ctx.basectx, + lib9p_error(&ctx->basectx, LINUX_EBADF, "cannot assign to NOFID"); return; } - struct _srv_fidinfo *fidinfo = map_load(&ctx->parent_sess->fids, req->fid); + struct srv_fidinfo *fidinfo = map_load(&ctx->parent_sess->fids, req->fid); if (!fidinfo) { - lib9p_errorf(&ctx->ctx.basectx, + lib9p_errorf(&ctx->basectx, LINUX_EBADF, "bad file number %"PRIu32, req->fid); return; } @@ -799,25 +792,25 @@ static void handle_Twalk(struct _lib9p_srv_req *ctx, new_pathinfo->gc_refcount++; } else { if (!srv_util_pathisdir(pathinfo)) { - lib9p_error(&ctx->ctx.basectx, + lib9p_error(&ctx->basectx, LINUX_ENOTDIR, "not a directory"); break; } - lo_interface lib9p_srv_file member_file = LO_CALL(pathinfo->file, dwalk, &ctx->ctx, req->wname[resp->nwqid]); - assert(LO_IS_NULL(member_file) == lib9p_ctx_has_error(&ctx->ctx.basectx)); - if (lib9p_ctx_has_error(&ctx->ctx.basectx)) + lo_interface lib9p_srv_file member_file = LO_CALL(pathinfo->file, dwalk, ctx, req->wname[resp->nwqid]); + assert(LO_IS_NULL(member_file) == lib9p_ctx_has_error(&ctx->basectx)); + if (lib9p_ctx_has_error(&ctx->basectx)) break; new_pathinfo = srv_util_pathsave(ctx, member_file, LO_CALL(pathinfo->file, qid).path); } if (srv_util_pathisdir(new_pathinfo)) { - struct lib9p_stat stat = LO_CALL(new_pathinfo->file, stat, &ctx->ctx); - if (lib9p_ctx_has_error(&ctx->ctx.basectx)) + struct lib9p_stat stat = LO_CALL(new_pathinfo->file, stat, ctx); + if (lib9p_ctx_has_error(&ctx->basectx)) break; lib9p_stat_assert(stat); if (!srv_util_check_perm(ctx, &stat, 0b001)) { - lib9p_error(&ctx->ctx.basectx, + lib9p_error(&ctx->basectx, LINUX_EACCES, "you do not have execute permission on that directory"); srv_util_pathfree(ctx, LO_CALL(new_pathinfo->file, qid).path); break; @@ -833,27 +826,27 @@ static void handle_Twalk(struct _lib9p_srv_req *ctx, if (!srv_util_fidsave(ctx, req->newfid, pathinfo, req->newfid == req->fid)) srv_util_pathfree(ctx, LO_CALL(pathinfo->file, qid).path); } else { - assert(lib9p_ctx_has_error(&ctx->ctx.basectx)); + assert(lib9p_ctx_has_error(&ctx->basectx)); srv_util_pathfree(ctx, LO_CALL(pathinfo->file, qid).path); if (resp->nwqid > 0) - lib9p_ctx_clear_error(&ctx->ctx.basectx); + lib9p_ctx_clear_error(&ctx->basectx); } } -static void handle_Topen(struct _lib9p_srv_req *ctx, +static void handle_Topen(struct srv_req *ctx, struct lib9p_msg_Topen *req, struct lib9p_msg_Ropen *resp) { util_handler_common(ctx, req, resp); /* Check that the FID is valid for this. */ - struct _srv_fidinfo *fidinfo = map_load(&ctx->parent_sess->fids, req->fid); + struct srv_fidinfo *fidinfo = map_load(&ctx->parent_sess->fids, req->fid); if (!fidinfo) { - lib9p_errorf(&ctx->ctx.basectx, + lib9p_errorf(&ctx->basectx, LINUX_EBADF, "bad file number %"PRIu32, req->fid); return; } if (fidinfo->flags & FIDFLAG_OPEN) { - lib9p_error(&ctx->ctx.basectx, + lib9p_error(&ctx->basectx, LINUX_EALREADY, "FID is already open"); return; } @@ -863,7 +856,7 @@ static void handle_Topen(struct _lib9p_srv_req *ctx, if ( ((req->mode & LIB9P_O_MODE_MASK) != LIB9P_O_MODE_READ) || (req->mode & LIB9P_O_TRUNC) || (req->mode & LIB9P_O_RCLOSE) ) { - lib9p_error(&ctx->ctx.basectx, + lib9p_error(&ctx->basectx, LINUX_EISDIR, "directories cannot be written, executed, truncated, or removed-on-close"); return; } @@ -877,23 +870,23 @@ static void handle_Topen(struct _lib9p_srv_req *ctx, if (reqmode & LIB9P_O_RCLOSE) { struct srv_pathinfo *parent = map_load(&ctx->parent_sess->paths, pathinfo->parent_dir); assert(parent); - struct lib9p_stat parent_stat = LO_CALL(parent->file, stat, &ctx->ctx); - if (lib9p_ctx_has_error(&ctx->ctx.basectx)) + struct lib9p_stat parent_stat = LO_CALL(parent->file, stat, ctx); + if (lib9p_ctx_has_error(&ctx->basectx)) return; lib9p_stat_assert(parent_stat); if (!srv_util_check_perm(ctx, &parent_stat, 0b010)) { - lib9p_error(&ctx->ctx.basectx, + lib9p_error(&ctx->basectx, LINUX_EACCES, "permission denied to remove-on-close"); return; } fidflags |= FIDFLAG_RCLOSE; } - struct lib9p_stat stat = LO_CALL(pathinfo->file, stat, &ctx->ctx); - if (lib9p_ctx_has_error(&ctx->ctx.basectx)) + struct lib9p_stat stat = LO_CALL(pathinfo->file, stat, ctx); + if (lib9p_ctx_has_error(&ctx->basectx)) return; lib9p_stat_assert(stat); if ((stat.file_mode & LIB9P_DM_EXCL) && pathinfo->io_refcount) { - lib9p_error(&ctx->ctx.basectx, + lib9p_error(&ctx->basectx, LINUX_EEXIST, "exclusive file is already opened"); return; } @@ -920,7 +913,7 @@ static void handle_Topen(struct _lib9p_srv_req *ctx, break; } if (!srv_util_check_perm(ctx, &stat, perm_bits)) { - lib9p_error(&ctx->ctx.basectx, + lib9p_error(&ctx->basectx, LINUX_EACCES, "permission denied"); return; } @@ -929,20 +922,20 @@ static void handle_Topen(struct _lib9p_srv_req *ctx, uint32_t iounit; struct lib9p_qid qid; if (srv_util_pathisdir(pathinfo)) { - fidinfo->dir.io = LO_CALL(pathinfo->file, dopen, &ctx->ctx); - assert(LO_IS_NULL(fidinfo->dir.io) == lib9p_ctx_has_error(&ctx->ctx.basectx)); - if (lib9p_ctx_has_error(&ctx->ctx.basectx)) + fidinfo->dir.io = LO_CALL(pathinfo->file, dopen, ctx); + assert(LO_IS_NULL(fidinfo->dir.io) == lib9p_ctx_has_error(&ctx->basectx)); + if (lib9p_ctx_has_error(&ctx->basectx)) return; fidinfo->dir.idx = 0; fidinfo->dir.off = 0; qid = LO_CALL(fidinfo->dir.io, qid); iounit = 0; } else { - fidinfo->file.io = LO_CALL(pathinfo->file, fopen, &ctx->ctx, + fidinfo->file.io = LO_CALL(pathinfo->file, fopen, ctx, rd, wr, reqmode & LIB9P_O_TRUNC); - assert(LO_IS_NULL(fidinfo->file.io) == lib9p_ctx_has_error(&ctx->ctx.basectx)); - if (lib9p_ctx_has_error(&ctx->ctx.basectx)) + assert(LO_IS_NULL(fidinfo->file.io) == lib9p_ctx_has_error(&ctx->basectx)); + if (lib9p_ctx_has_error(&ctx->basectx)) return; qid = LO_CALL(fidinfo->file.io, qid); iounit = LO_CALL(fidinfo->file.io, iounit); @@ -959,16 +952,16 @@ static void handle_Topen(struct _lib9p_srv_req *ctx, resp->iounit = iounit; } -static void handle_Tcreate(struct _lib9p_srv_req *ctx, +static void handle_Tcreate(struct srv_req *ctx, struct lib9p_msg_Tcreate *req, struct lib9p_msg_Rcreate *resp) { util_handler_common(ctx, req, resp); - lib9p_error(&ctx->ctx.basectx, + lib9p_error(&ctx->basectx, LINUX_EOPNOTSUPP, "create not (yet?) implemented"); } -static void handle_Tread(struct _lib9p_srv_req *ctx, +static void handle_Tread(struct srv_req *ctx, struct lib9p_msg_Tread *req, struct lib9p_msg_Rread *resp) { util_handler_common(ctx, req, resp); @@ -976,14 +969,14 @@ static void handle_Tread(struct _lib9p_srv_req *ctx, /* TODO: serialize simultaneous reads to the same FID */ /* Check that the FID is valid for this. */ - struct _srv_fidinfo *fidinfo = map_load(&ctx->parent_sess->fids, req->fid); + struct srv_fidinfo *fidinfo = map_load(&ctx->parent_sess->fids, req->fid); if (!fidinfo) { - lib9p_errorf(&ctx->ctx.basectx, + lib9p_errorf(&ctx->basectx, LINUX_EBADF, "bad file number %"PRIu32, req->fid); return; } if (!(fidinfo->flags & FIDFLAG_OPEN_R)) { - lib9p_error(&ctx->ctx.basectx, + lib9p_error(&ctx->basectx, LINUX_EINVAL, "FID not open for reading"); return; } @@ -1001,19 +994,19 @@ static void handle_Tread(struct _lib9p_srv_req *ctx, else if (req->offset == fidinfo->dir.off) idx = fidinfo->dir.idx; else { - lib9p_errorf(&ctx->ctx.basectx, + lib9p_errorf(&ctx->basectx, LINUX_EINVAL, "invalid offset (must be 0 or %"PRIu64"): %"PRIu64, fidinfo->dir.off, req->offset); return; } /* Do it. */ resp->data = (char *)(&resp[1]); - size_t num = LO_CALL(fidinfo->dir.io, dread, &ctx->ctx, (uint8_t *)resp->data, req->count, idx); + size_t num = LO_CALL(fidinfo->dir.io, dread, ctx, (uint8_t *)resp->data, req->count, idx); /* Translate object-count back to byte-count. */ uint32_t len = 0; for (size_t i = 0; i < num; i++) { uint32_t i_len; - lib9p_stat_validate(&ctx->ctx.basectx, req->count, &((uint8_t *)resp->data)[len], &i_len, NULL); + lib9p_stat_validate(&ctx->basectx, req->count, &((uint8_t *)resp->data)[len], &i_len, NULL); len += i_len; } resp->count = len; @@ -1022,8 +1015,8 @@ static void handle_Tread(struct _lib9p_srv_req *ctx, fidinfo->dir.off = req->offset + len; } else { struct iovec iov; - LO_CALL(fidinfo->file.io, pread, &ctx->ctx, req->count, req->offset, &iov); - if (!lib9p_ctx_has_error(&ctx->ctx.basectx)) { + LO_CALL(fidinfo->file.io, pread, ctx, req->count, req->offset, &iov); + if (!lib9p_ctx_has_error(&ctx->basectx)) { resp->count = iov.iov_len; resp->data = iov.iov_base; if (resp->count > req->count) @@ -1032,7 +1025,7 @@ static void handle_Tread(struct _lib9p_srv_req *ctx, } } -static void handle_Twrite(struct _lib9p_srv_req *ctx, +static void handle_Twrite(struct srv_req *ctx, struct lib9p_msg_Twrite *req, struct lib9p_msg_Rwrite *resp) { util_handler_common(ctx, req, resp); @@ -1040,14 +1033,14 @@ static void handle_Twrite(struct _lib9p_srv_req *ctx, /* TODO: serialize simultaneous writes to the same FID */ /* Check that the FID is valid for this. */ - struct _srv_fidinfo *fidinfo = map_load(&ctx->parent_sess->fids, req->fid); + struct srv_fidinfo *fidinfo = map_load(&ctx->parent_sess->fids, req->fid); if (!fidinfo) { - lib9p_errorf(&ctx->ctx.basectx, + lib9p_errorf(&ctx->basectx, LINUX_EBADF, "bad file number %"PRIu32, req->fid); return; } if (!(fidinfo->flags & FIDFLAG_OPEN_W)) { - lib9p_error(&ctx->ctx.basectx, + lib9p_error(&ctx->basectx, LINUX_EINVAL, "FID not open for writing"); return; } @@ -1057,13 +1050,13 @@ static void handle_Twrite(struct _lib9p_srv_req *ctx, assert(pathinfo); /* Do it. */ - resp->count = LO_CALL(fidinfo->file.io, pwrite, &ctx->ctx, req->data, req->count, req->offset); + resp->count = LO_CALL(fidinfo->file.io, pwrite, ctx, req->data, req->count, req->offset); } -static void clunkremove(struct _lib9p_srv_req *ctx, lib9p_fid_t fid, bool remove) { - struct _srv_fidinfo *fidinfo = map_load(&ctx->parent_sess->fids, fid); +static void clunkremove(struct srv_req *ctx, lib9p_fid_t fid, bool remove) { + struct srv_fidinfo *fidinfo = map_load(&ctx->parent_sess->fids, fid); if (!fidinfo) { - lib9p_errorf(&ctx->ctx.basectx, + lib9p_errorf(&ctx->basectx, LINUX_EBADF, "bad file number %"PRIu32, fid); return; } @@ -1074,19 +1067,19 @@ static void clunkremove(struct _lib9p_srv_req *ctx, lib9p_fid_t fid, bool remove if (remove) { if (pathinfo->parent_dir == fidinfo->path) { - lib9p_errorf(&ctx->ctx.basectx, + lib9p_errorf(&ctx->basectx, LINUX_EBUSY, "cannot remove root"); goto clunk; } struct srv_pathinfo *parent = map_load(&ctx->parent_sess->paths, pathinfo->parent_dir); assert(parent); - struct lib9p_stat parent_stat = LO_CALL(parent->file, stat, &ctx->ctx); + struct lib9p_stat parent_stat = LO_CALL(parent->file, stat, ctx); if (!srv_util_check_perm(ctx, &parent_stat, 0b010)) { - lib9p_error(&ctx->ctx.basectx, + lib9p_error(&ctx->basectx, LINUX_EACCES, "you do not have write permission on the parent directory"); goto clunk; } - LO_CALL(pathinfo->file, remove, &ctx->ctx); + LO_CALL(pathinfo->file, remove, ctx); } clunk: @@ -1101,7 +1094,7 @@ static void clunkremove(struct _lib9p_srv_req *ctx, lib9p_fid_t fid, bool remove map_del(&ctx->parent_sess->fids, fid); } -static void handle_Tclunk(struct _lib9p_srv_req *ctx, +static void handle_Tclunk(struct srv_req *ctx, struct lib9p_msg_Tclunk *req, struct lib9p_msg_Rclunk *resp) { util_handler_common(ctx, req, resp); @@ -1110,7 +1103,7 @@ static void handle_Tclunk(struct _lib9p_srv_req *ctx, } -static void handle_Tremove(struct _lib9p_srv_req *ctx, +static void handle_Tremove(struct srv_req *ctx, struct lib9p_msg_Tremove *req, struct lib9p_msg_Rremove *resp) { util_handler_common(ctx, req, resp); @@ -1118,59 +1111,59 @@ static void handle_Tremove(struct _lib9p_srv_req *ctx, clunkremove(ctx, req->fid, true); } -static void handle_Tstat(struct _lib9p_srv_req *ctx, +static void handle_Tstat(struct srv_req *ctx, struct lib9p_msg_Tstat *req, struct lib9p_msg_Rstat *resp) { util_handler_common(ctx, req, resp); - struct _srv_fidinfo *fidinfo = map_load(&ctx->parent_sess->fids, req->fid); + struct srv_fidinfo *fidinfo = map_load(&ctx->parent_sess->fids, req->fid); if (!fidinfo) { - lib9p_errorf(&ctx->ctx.basectx, + lib9p_errorf(&ctx->basectx, LINUX_EBADF, "bad file number %"PRIu32, req->fid); return; } struct srv_pathinfo *pathinfo = map_load(&ctx->parent_sess->paths, fidinfo->path); assert(pathinfo); - resp->stat = LO_CALL(pathinfo->file, stat, &ctx->ctx); - if (!lib9p_ctx_has_error(&ctx->ctx.basectx)) + resp->stat = LO_CALL(pathinfo->file, stat, ctx); + if (!lib9p_ctx_has_error(&ctx->basectx)) lib9p_stat_assert(resp->stat); } -static void handle_Twstat(struct _lib9p_srv_req *ctx, +static void handle_Twstat(struct srv_req *ctx, struct lib9p_msg_Twstat *req, struct lib9p_msg_Rwstat *resp) { util_handler_common(ctx, req, resp); - lib9p_error(&ctx->ctx.basectx, + lib9p_error(&ctx->basectx, LINUX_EOPNOTSUPP, "wstat not (yet?) implemented"); } #if CONFIG_9P_ENABLE_9P2000_e -static void handle_Tsession(struct _lib9p_srv_req *ctx, +static void handle_Tsession(struct srv_req *ctx, struct lib9p_msg_Tsession *req, struct lib9p_msg_Rsession *resp) { util_handler_common(ctx, req, resp); - lib9p_error(&ctx->ctx.basectx, + lib9p_error(&ctx->basectx, LINUX_EOPNOTSUPP, "session not (yet?) implemented"); } -static void handle_Tsread(struct _lib9p_srv_req *ctx, +static void handle_Tsread(struct srv_req *ctx, struct lib9p_msg_Tsread *req, struct lib9p_msg_Rsread *resp) { util_handler_common(ctx, req, resp); - lib9p_error(&ctx->ctx.basectx, + lib9p_error(&ctx->basectx, LINUX_EOPNOTSUPP, "sread not (yet?) implemented"); } -static void handle_Tswrite(struct _lib9p_srv_req *ctx, +static void handle_Tswrite(struct srv_req *ctx, struct lib9p_msg_Tswrite *req, struct lib9p_msg_Rswrite *resp) { util_handler_common(ctx, req, resp); - lib9p_error(&ctx->ctx.basectx, + lib9p_error(&ctx->basectx, LINUX_EOPNOTSUPP, "swrite not (yet?) implemented"); } #endif |