diff options
author | Luke T. Shumaker <lukeshu@lukeshu.com> | 2025-03-26 22:18:47 -0600 |
---|---|---|
committer | Luke T. Shumaker <lukeshu@lukeshu.com> | 2025-03-26 22:18:47 -0600 |
commit | 6ab74d74ee6dc1663b66d0a9a0471f63ade5659a (patch) | |
tree | b579303cc5df38191ee9e8ad63793fbe4c867c02 /lib9p/include | |
parent | 9f2e2e96321f14da97adda618a7e4721cbb9791c (diff) | |
parent | 865bb702f828784a0225b5eae9ed8803094140d5 (diff) |
Merge branch 'lukeshu/9p-read-iovec'
Diffstat (limited to 'lib9p/include')
-rw-r--r-- | lib9p/include/lib9p/srv.h | 145 |
1 files changed, 103 insertions, 42 deletions
diff --git a/lib9p/include/lib9p/srv.h b/lib9p/include/lib9p/srv.h index 83aabc0..ff5ebdc 100644 --- a/lib9p/include/lib9p/srv.h +++ b/lib9p/include/lib9p/srv.h @@ -37,53 +37,98 @@ int lib9p_srv_acknowledge_flush(struct lib9p_srv_ctx *ctx); /* interface definitions ******************************************************/ -#define lib9p_srv_file_LO_IFACE \ - /* all - resource management */ \ - LO_FUNC(void , free ) /* must not error */ \ - LO_FUNC(struct lib9p_qid , qid ) /* must not error */ \ - LO_FUNC(uint32_t , chio , struct lib9p_srv_ctx *, \ - bool rd, bool wr, \ - bool trunc) \ - \ - /* all - syscalls */ \ - LO_FUNC(struct lib9p_stat , stat , struct lib9p_srv_ctx *) \ - LO_FUNC(void , wstat , struct lib9p_srv_ctx *, \ - struct lib9p_stat new) \ - LO_FUNC(void , remove , struct lib9p_srv_ctx *) \ - \ - /* directories - base */ \ - LO_FUNC(lo_interface lib9p_srv_file, dopen , struct lib9p_srv_ctx *, \ - struct lib9p_s childname) \ - LO_FUNC(lo_interface lib9p_srv_file, dcreate, struct lib9p_srv_ctx *, \ - struct lib9p_s childname, \ - lib9p_dm_t perm, \ - lib9p_o_t flags) \ - \ - /* directories - once opened */ \ - LO_FUNC(size_t /* <- obj cnt */ , dread , struct lib9p_srv_ctx *, \ - uint8_t *buf, \ - /* num bytes -> */ uint32_t byte_count, \ - /* starting at this object -> */ size_t obj_offset) \ - \ - /* non-directories - once opened */ \ - LO_FUNC(uint32_t , pread , struct lib9p_srv_ctx *, \ - void *buf, \ - uint32_t byte_count, \ - uint64_t byte_offset) \ - LO_FUNC(uint32_t , pwrite , struct lib9p_srv_ctx *, \ - void *buf, \ - uint32_t byte_count, \ +lo_interface lib9p_srv_fio; +lo_interface lib9p_srv_dio; + +/* FIXME: I don't like that the pointers returned by stat() and + * pread() have to remain live after they return. Perhaps a + * `respond()`-callback? But that just reads as gross in C. + * + * FIXME: It would be nice if pread() could return more than 1 iovec. + */ +#define lib9p_srv_file_LO_IFACE \ + /* resource management **********************************************/ \ + \ + /** \ + * free() is be called when all FIDs associated with the file are \ + * clunked. \ + * \ + * free() MUST NOT error. \ + */ \ + LO_FUNC(void , free ) \ + \ + /** \ + * qid() is called frequently and returns the current QID of the file. \ + * The .path field MUST never change, the .type field may change in \ + * response to wstat() calls (but the QT_DIR bit MUST NOT change), and \ + * the .vers field may change frequently in response to any number of \ + * things (wstat(), write(), or non-9P events). \ + * \ + * qid() MUST NOT error. \ + */ \ + LO_FUNC(struct lib9p_qid , qid ) \ + \ + /* non-"opened" generic I/O *****************************************/ \ + \ + LO_FUNC(struct lib9p_stat , stat , struct lib9p_srv_ctx *) \ + LO_FUNC(void , wstat , struct lib9p_srv_ctx *, \ + struct lib9p_stat new) \ + LO_FUNC(void , remove , struct lib9p_srv_ctx *) \ + \ + /* non-"opened" directory I/O ***************************************/ \ + \ + LO_FUNC(lo_interface lib9p_srv_file, dwalk , struct lib9p_srv_ctx *, \ + struct lib9p_s childname) \ + LO_FUNC(lo_interface lib9p_srv_file, dcreate, struct lib9p_srv_ctx *, \ + struct lib9p_s childname, \ + lib9p_dm_t perm, \ + lib9p_o_t flags) \ + \ + /* open() for I/O ***************************************************/ \ + \ + LO_FUNC(lo_interface lib9p_srv_fio , fopen , struct lib9p_srv_ctx *, \ + bool rd, bool wr, \ + bool trunc) \ + LO_FUNC(lo_interface lib9p_srv_dio , dopen , struct lib9p_srv_ctx *) +LO_INTERFACE(lib9p_srv_file); + +#define lib9p_srv_fio_LO_IFACE \ + LO_FUNC(struct lib9p_qid , qid ) \ + LO_FUNC(void , iofree ) \ + LO_FUNC(uint32_t , iounit ) \ + LO_FUNC(void , pread , struct lib9p_srv_ctx *, \ + uint32_t byte_count, \ + uint64_t byte_offset, \ + struct iovec *ret) \ + LO_FUNC(uint32_t , pwrite , struct lib9p_srv_ctx *, \ + void *buf, \ + uint32_t byte_count, \ uint64_t byte_offset) -LO_INTERFACE(lib9p_srv_file) +LO_INTERFACE(lib9p_srv_fio); + +/* FIXME: The dio interface just feels clunky. I'm not in a rush to + * change it because util9p_static_dir is already implemented and I + * don't anticipate the sbc-harness needing another dio + * implementation. But if I wanted lib9p to be used outside of + * sbc-harness, this is one of the first things that I'd want to + * change. + */ +#define lib9p_srv_dio_LO_IFACE \ + LO_FUNC(struct lib9p_qid , qid ) \ + LO_FUNC(void , iofree ) \ + LO_FUNC(size_t /* <- obj cnt */ , dread , struct lib9p_srv_ctx *, \ + uint8_t *buf, \ + /* num bytes -> */ uint32_t byte_count, \ + /* starting at this object -> */ size_t obj_offset) +LO_INTERFACE(lib9p_srv_dio); #define LIB9P_SRV_NOTDIR(TYP, NAM) \ - static lo_interface lib9p_srv_file NAM##_dopen (TYP *, struct lib9p_srv_ctx *, struct lib9p_s) { assert_notreached("not a directory"); } \ + static lo_interface lib9p_srv_file NAM##_dwalk (TYP *, struct lib9p_srv_ctx *, struct lib9p_s) { assert_notreached("not a directory"); } \ static lo_interface lib9p_srv_file NAM##_dcreate(TYP *, struct lib9p_srv_ctx *, struct lib9p_s, lib9p_dm_t, lib9p_o_t) { assert_notreached("not a directory"); } \ - static size_t NAM##_dread (TYP *, struct lib9p_srv_ctx *, uint8_t *, uint32_t, size_t) { assert_notreached("not a directory"); } + static lo_interface lib9p_srv_dio NAM##_dopen (TYP *, struct lib9p_srv_ctx *) { assert_notreached("not a directory"); } #define LIB9P_SRV_NOTFILE(TYP, NAM) \ - static uint32_t NAM##_pread (TYP *, struct lib9p_srv_ctx *, void *, uint32_t, uint64_t) { assert_notreached("not a file"); } \ - static uint32_t NAM##_pwrite(TYP *, struct lib9p_srv_ctx *, void *, uint32_t, uint64_t) { assert_notreached("not a file"); } + static lo_interface lib9p_srv_fio NAM##_fopen (TYP *, struct lib9p_srv_ctx *, bool, bool, bool) { assert_notreached("not a file"); } /* main server entrypoints ****************************************************/ @@ -103,16 +148,32 @@ struct lib9p_srv { }; /** + * In an infinite loop, accept a connection and read messages from it until + * close; dispatching requests to a pool of lib9p_srv_write_cr() coroutines + * with the same `srv`. + * * Will just close the connection if a T-message has a size[4] <7. * + * @param srv: The server configuration and state; has an associated pool of + * lib9p_srv_write_cr() coroutines. + * @param listener: The listener object to accept connections from. + * * @errno LINUX_EMSGSIZE T-message has size[4] bigger than max_msg_size * @errno LINUX_EDOM Tversion specified an impossibly small max_msg_size * @errno LINUX_EOPNOTSUPP T-message has an R-message type, or an unrecognized T-message type * @errno LINUX_EBADMSG T-message has wrong size[4] for its content, or has invalid UTF-8 * @errno LINUX_ERANGE R-message does not fit into max_msg_size */ - [[noreturn]] void lib9p_srv_read_cr(struct lib9p_srv *srv, lo_interface net_stream_listener listener); + +/** + * Service requests to the `struct lib9p_srv *srv` argument that have been + * read by lib9p_srv_read_cr(). + * + * @param struct lib9p_srv *srv: The server configuration and state; has an + * associated pool of lib9p_srv_read_cr() + * coroutines. + */ COROUTINE lib9p_srv_write_cr(void *_srv); #endif /* _LIB9P_SRV_H_ */ |