From 9c7f19c46d8fb58b6bcfe0d1d026c05657ffba96 Mon Sep 17 00:00:00 2001 From: "Luke T. Shumaker" Date: Mon, 7 Oct 2024 18:04:03 -0600 Subject: wip --- lib9p/include/lib9p/srv.h | 62 +++++++++-------- lib9p/srv.c | 165 +++++++++++++++++++++++++++++++++------------- 2 files changed, 155 insertions(+), 72 deletions(-) (limited to 'lib9p') diff --git a/lib9p/include/lib9p/srv.h b/lib9p/include/lib9p/srv.h index c56ee3f..11c1fac 100644 --- a/lib9p/include/lib9p/srv.h +++ b/lib9p/include/lib9p/srv.h @@ -34,59 +34,67 @@ static inline int lib9p_srv_acknowledge_flush(struct lib9p_srv_ctx *ctx) { /* vtables you must implement *************************************************/ +struct lib9p_srv_file; +struct lib9p_srv_io; + struct lib9p_srv_file_vtable { /* all */ - struct lib9p_srv_io (*io )(struct lib9p_srv_ctx *ctx, void *impl, - lib9p_o_t flags); - struct lib9p_stat (*stat )(struct lib9p_srv_ctx *ctx, void *impl); - void (*wstat )(struct lib9p_srv_ctx *ctx, void *impl, - struct lib9p_stat new); - void (*remove )(struct lib9p_srv_ctx *ctx, void *impl); - void (*free )(struct lib9p_srv_ctx *ctx, void *impl); + struct lib9p_srv_io *(*io )(struct lib9p_srv_ctx *, struct lib9p_srv_file *, + lib9p_o_t flags); + struct lib9p_stat (*stat )(struct lib9p_srv_ctx *, struct lib9p_srv_file *); + void (*wstat )(struct lib9p_srv_ctx *, struct lib9p_srv_file *, + struct lib9p_stat new); + void (*remove )(struct lib9p_srv_ctx *, struct lib9p_srv_file *); + void (*free )(struct lib9p_srv_ctx *, struct lib9p_srv_file *); /* optional */ /* dir */ - struct lib9p_srv_file (*dopen )(struct lib9p_srv_ctx *ctx, void *impl, + struct lib9p_srv_file *(*dopen )(struct lib9p_srv_ctx *, struct lib9p_srv_file *, char *childname); - struct lib9p_srv_file (*dcreate)(struct lib9p_srv_ctx *ctx, void *impl, + struct lib9p_srv_file *(*dcreate)(struct lib9p_srv_ctx *, struct lib9p_srv_file *, char *childname, lib9p_dm_t perm, lib9p_o_t flags); }; struct lib9p_srv_io_dir_vtable { - size_t (*readdir)(struct lib9p_srv_ctx *ctx, void *impl, - struct lib9p_stat *buf, size_t count, - size_t offset); + size_t (*readdir)(struct lib9p_srv_ctx *, struct lib9p_srv_io_dir *, + struct lib9p_stat *buf, size_t count, + size_t offset); }; struct lib9p_srv_io_file_vtable { - uint32_t (*pread )(struct lib9p_srv_ctx *ctx, void *impl, - void *buf, uint32_t count, - uint64_t offset); - uint32_t (*pwrite )(struct lib9p_srv_ctx *ctx, void *impl, - void *buf, uint32_t count, - uint64_t offset); + uint32_t (*pread )(struct lib9p_srv_ctx *, struct lib9p_srv_io_file *, + void *buf, uint32_t count, + uint64_t offset); + uint32_t (*pwrite )(struct lib9p_srv_ctx *, struct lib9p_srv_io_file *, + void *buf, uint32_t count, + uint64_t offset); }; /* objects you'll deal with ***************************************************/ struct lib9p_srv_file { - struct lib9p_srv_file_vtable vtable; + struct lib9p_srv_file_vtable *vtable; + + /* Managed by srv.c */ + struct lib9p_srv_file *_parent_dir; + struct lib9p_srv_file *_refcount; - struct lib9p_srv_file *parent_dir; - void *impldata; + /* This is where your implementation data goes. */ + char data[0]; }; struct lib9p_srv_io { union { - struct lib9p_srv_io_dir_vtable dir; - struct lib9p_srv_io_file_vtable file; + struct lib9p_srv_io_dir_vtable *dir; + struct lib9p_srv_io_file_vtable *file; } vtable; struct lib9p_srv_file *file; struct lib9p_qid qid; uint32_t iounit; - void *impldata; + /* This is where your implementation data goes. */ + char data[0]; }; /* main server entrypoints ****************************************************/ @@ -95,9 +103,9 @@ CR_RPC_DECLARE(_lib9p_srv_reqch, struct _lib9p_srv_req *, bool) struct lib9p_srv { /* Things you provide */ - int sockfd; - void /*TODO*/ (*auth )(struct lib9p_srv_ctx *ctx, char *treename); - struct lib9p_srv_file (*rootdir)(struct lib9p_srv_ctx *ctx, char *treename); + int sockfd; + void /*TODO*/ (*auth )(struct lib9p_srv_ctx *, char *treename); /* optional */ + struct lib9p_srv_file *(*rootdir)(struct lib9p_srv_ctx *, char *treename); /* For internal use */ _lib9p_srv_reqch_t _reqch; diff --git a/lib9p/srv.c b/lib9p/srv.c index 7dca9ec..84b3ae8 100644 --- a/lib9p/srv.c +++ b/lib9p/srv.c @@ -17,7 +17,7 @@ #define NAME fidmap #define KEY_T uint32_t -#define VAL_T struct lib9p_srv_file +#define VAL_T struct lib9p_srv_file * #define CAP CONFIG_9P_MAX_FIDS #include "map.h" @@ -368,6 +368,10 @@ static void handle_message(struct _lib9p_srv_req *ctx) { static void handle_Tversion(struct _lib9p_srv_req *ctx, struct lib9p_msg_Tversion *req, struct lib9p_msg_Rversion *resp) { + assert(ctx); + assert(req); + assert(resp); + enum lib9p_version version = LIB9P_VER_unknown; if (req->version.len >= 6 && @@ -422,10 +426,11 @@ static void handle_Tversion(struct _lib9p_srv_req *ctx, if (ctx->parent_sess->fids.len) { /* Close all FIDs. */ uint32_t fid; - struct lib9p_srv_file *fptr; - MAP_FOREACH(&ctx->parent_sess->fids, fid, fptr) { - fptr->vtable.free(&ctx->ctx, fptr->impldata); - fidmap_del(&ctx->parent_sess->fids, fid); + struct lib9p_srv_file **filepp __attribute__((unused)); + MAP_FOREACH(&ctx->parent_sess->fids, fid, filepp) { + handle_Tclunk(ctx, + &(struct lib9p_msg_Tclunk){.fid = fid}, + &(struct lib9p_msg_Rclunk){}); } } @@ -437,7 +442,11 @@ static void handle_Tversion(struct _lib9p_srv_req *ctx, static void handle_Tauth(struct _lib9p_srv_req *ctx, struct lib9p_msg_Tauth *req, - struct lib9p_msg_Rauth *UNUSED(resp)) { + struct lib9p_msg_Rauth *resp) { + assert(ctx); + assert(req); + assert(resp); + ctx->ctx.uid = req->n_uname; ctx->ctx.uname = req->uname.utf8; struct lib9p_srv *srv = ctx->parent_sess->parent_conn->parent_srv; @@ -456,6 +465,10 @@ static void handle_Tauth(struct _lib9p_srv_req *ctx, static void handle_Tattach(struct _lib9p_srv_req *ctx, struct lib9p_msg_Tattach *req, struct lib9p_msg_Rattach *resp) { + assert(ctx); + assert(req); + assert(resp); + ctx->ctx.uid = req->n_uname; ctx->ctx.uname = req->uname.utf8; struct lib9p_srv *srv = ctx->parent_sess->parent_conn->parent_srv; @@ -501,117 +514,179 @@ static void handle_Tattach(struct _lib9p_srv_req *ctx, return; } - struct lib9p_srv_file rootdir = srv->rootdir(&ctx->ctx, req->aname.utf8); + struct lib9p_srv_file *rootdir = srv->rootdir(&ctx->ctx, req->aname.utf8); if (lib9p_ctx_has_error(&ctx->ctx.basectx)) return; + rootdir->_parent_dir = rootdir; - struct lib9p_stat stat = rootdir.vtable.stat(&ctx->ctx, rootdir.impldata); - if (lib9p_ctx_has_error(&ctx->ctx.basectx)) { - if (rootdir.vtable.free) - rootdir.vtable.free(&ctx->ctx, rootdir.impldata); + if (!fidmap_store(&ctx->parent_sess->fids, req->fid, rootdir)) { + lib9p_error(&ctx->ctx.basectx, + LINUX_EMFILE, "too many open files"); + if (rootdir->vtable->free) + rootdir->vtable->free(&ctx->ctx, rootdir); return; } - struct lib9p_srv_file *rootdir_ptr = fidmap_store(&ctx->parent_sess->fids, req->fid, rootdir); - if (!rootdir_ptr) { - lib9p_error(&ctx->ctx.basectx, - LINUX_EMFILE, "too many open files"); - if (rootdir.vtable.free) - rootdir.vtable.free(&ctx->ctx, rootdir.impldata); + struct lib9p_stat stat = rootdir->vtable->stat(&ctx->ctx, rootdir); + if (lib9p_ctx_has_error(&ctx->ctx.basectx)) { + handle_Tclunk(ctx, + &(struct lib9p_msg_Tclunk){.fid = req->fid}, + &(struct lib9p_msg_Rclunk){}); return; } + resp->qid = stat.file_qid; return; } static void handle_Tflush(struct _lib9p_srv_req *ctx, - struct lib9p_msg_Tflush *UNUSED(req), - struct lib9p_msg_Rflush *UNUSED(resp)) { + struct lib9p_msg_Tflush *req, + struct lib9p_msg_Rflush *resp) { + assert(ctx); + assert(req); + assert(resp); + lib9p_error(&ctx->ctx.basectx, LINUX_EOPNOTSUPP, "flush not yet implemented"); } static void handle_Twalk(struct _lib9p_srv_req *ctx, - struct lib9p_msg_Twalk *UNUSED(req), - struct lib9p_msg_Rwalk *UNUSED(resp)) { + struct lib9p_msg_Twalk *req, + struct lib9p_msg_Rwalk *resp) { + assert(ctx); + assert(req); + assert(resp); + lib9p_error(&ctx->ctx.basectx, LINUX_EOPNOTSUPP, "walk not yet implemented"); } static void handle_Topen(struct _lib9p_srv_req *ctx, - struct lib9p_msg_Topen *UNUSED(req), - struct lib9p_msg_Ropen *UNUSED(resp)) { + struct lib9p_msg_Topen *req, + struct lib9p_msg_Ropen *resp) { + assert(ctx); + assert(req); + assert(resp); + lib9p_error(&ctx->ctx.basectx, LINUX_EOPNOTSUPP, "open not yet implemented"); } static void handle_Tcreate(struct _lib9p_srv_req *ctx, - struct lib9p_msg_Tcreate *UNUSED(req), - struct lib9p_msg_Rcreate *UNUSED(resp)) { + struct lib9p_msg_Tcreate *req, + struct lib9p_msg_Rcreate *resp) { + assert(ctx); + assert(req); + assert(resp); + lib9p_error(&ctx->ctx.basectx, LINUX_EOPNOTSUPP, "create not yet implemented"); } static void handle_Tread(struct _lib9p_srv_req *ctx, - struct lib9p_msg_Tread *UNUSED(req), - struct lib9p_msg_Rread *UNUSED(resp)) { + struct lib9p_msg_Tread *req, + struct lib9p_msg_Rread *resp) { + assert(ctx); + assert(req); + assert(resp); + lib9p_error(&ctx->ctx.basectx, LINUX_EOPNOTSUPP, "read not yet implemented"); } static void handle_Twrite(struct _lib9p_srv_req *ctx, - struct lib9p_msg_Twrite *UNUSED(req), - struct lib9p_msg_Rwrite *UNUSED(resp)) { + struct lib9p_msg_Twrite *req, + struct lib9p_msg_Rwrite *resp) { + assert(ctx); + assert(req); + assert(resp); + lib9p_error(&ctx->ctx.basectx, LINUX_EOPNOTSUPP, "write not yet implemented"); } static void handle_Tclunk(struct _lib9p_srv_req *ctx, - struct lib9p_msg_Tclunk *UNUSED(req), - struct lib9p_msg_Rclunk *UNUSED(resp)) { - lib9p_error(&ctx->ctx.basectx, - LINUX_EOPNOTSUPP, "clunk not yet implemented"); + struct lib9p_msg_Tclunk *req, + struct lib9p_msg_Rclunk *resp) { + assert(ctx); + assert(req); + assert(resp); + + struct lib9p_srv_file **filepp = fidmap_load(&ctx->parent_sess->fids, req->fid); + if (!filepp) { + lib9p_errorf(&ctx->ctx.basectx, + LINUX_EBADF, "bad file number %"PRIu32, req->fid); + return; + } + + if ((*filepp)->vtable->free) + (*filepp)->vtable->free(&ctx->ctx, *filepp); + fidmap_del(&ctx->parent_sess->fids, req->fid); } static void handle_Tremove(struct _lib9p_srv_req *ctx, - struct lib9p_msg_Tremove *UNUSED(req), - struct lib9p_msg_Rremove *UNUSED(resp)) { + struct lib9p_msg_Tremove *req, + struct lib9p_msg_Rremove *resp) { + assert(ctx); + assert(req); + assert(resp); + lib9p_error(&ctx->ctx.basectx, LINUX_EOPNOTSUPP, "remove not yet implemented"); } static void handle_Tstat(struct _lib9p_srv_req *ctx, - struct lib9p_msg_Tstat *UNUSED(req), - struct lib9p_msg_Rstat *UNUSED(resp)) { + struct lib9p_msg_Tstat *req, + struct lib9p_msg_Rstat *resp) { + assert(ctx); + assert(req); + assert(resp); + lib9p_error(&ctx->ctx.basectx, LINUX_EOPNOTSUPP, "stat not yet implemented"); } static void handle_Twstat(struct _lib9p_srv_req *ctx, - struct lib9p_msg_Twstat *UNUSED(req), - struct lib9p_msg_Rwstat *UNUSED(resp)) { + struct lib9p_msg_Twstat *req, + struct lib9p_msg_Rwstat *resp) { + assert(ctx); + assert(req); + assert(resp); + lib9p_error(&ctx->ctx.basectx, LINUX_EOPNOTSUPP, "wstat not yet implemented"); } static void handle_Tsession(struct _lib9p_srv_req *ctx, - struct lib9p_msg_Tsession *UNUSED(req), - struct lib9p_msg_Rsession *UNUSED(resp)) { + struct lib9p_msg_Tsession *req, + struct lib9p_msg_Rsession *resp) { + assert(ctx); + assert(req); + assert(resp); + lib9p_error(&ctx->ctx.basectx, LINUX_EOPNOTSUPP, "session not yet implemented"); } static void handle_Tsread(struct _lib9p_srv_req *ctx, - struct lib9p_msg_Tsread *UNUSED(req), - struct lib9p_msg_Rsread *UNUSED(resp)) { + struct lib9p_msg_Tsread *req, + struct lib9p_msg_Rsread *resp) { + assert(ctx); + assert(req); + assert(resp); + lib9p_error(&ctx->ctx.basectx, LINUX_EOPNOTSUPP, "sread not yet implemented"); } static void handle_Tswrite(struct _lib9p_srv_req *ctx, - struct lib9p_msg_Tswrite *UNUSED(req), - struct lib9p_msg_Rswrite *UNUSED(resp)) { + struct lib9p_msg_Tswrite *req, + struct lib9p_msg_Rswrite *resp) { + assert(ctx); + assert(req); + assert(resp); + lib9p_error(&ctx->ctx.basectx, LINUX_EOPNOTSUPP, "swrite not yet implemented"); } -- cgit v1.2.3-2-g168b