[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Minios-devel] [UNIKRAFT PATCH v3 7/8] lib/uk9p: Add 9P helper API
Thanks a lot for all the changes. I agree with your suggestion regarding the function names. I think the API looks pretty clean now. Reviewed-by: Simon Kuenzer <simon.kuenzer@xxxxxxxxx> On 05.09.19 14:14, Cristian Banu wrote: This patch implements an API for the operations supported by the 9P protocol. Each supported message type has an associated function with which to make requests. Signed-off-by: Cristian Banu <cristb@xxxxxxxxx> --- lib/uk9p/9p.c | 430 +++++++++++++++++++++++++++++++++++++++++++++++ lib/uk9p/Makefile.uk | 1 + lib/uk9p/exportsyms.uk | 15 ++ lib/uk9p/include/uk/9p.h | 265 +++++++++++++++++++++++++++++ 4 files changed, 711 insertions(+) create mode 100644 lib/uk9p/9p.c create mode 100644 lib/uk9p/include/uk/9p.h diff --git a/lib/uk9p/9p.c b/lib/uk9p/9p.c new file mode 100644 index 000000000000..eb4c2dc86cf6 --- /dev/null +++ b/lib/uk9p/9p.c @@ -0,0 +1,430 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* + * Authors: Cristian Banu <cristb@xxxxxxxxx> + * + * Copyright (c) 2019, University Politehnica of Bucharest. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * THIS HEADER MAY NOT BE EXTRACTED OR MODIFIED IN ANY WAY. + */ + +#include <uk/config.h> +#include <uk/assert.h> +#include <uk/errptr.h> +#include <uk/9p.h> +#include <uk/9pdev.h> +#include <uk/9preq.h> +#include <uk/9pfid.h> + +struct uk_9preq *uk_9p_version(struct uk_9pdev *dev, + const char *requested, struct uk_9p_str *received) +{ + struct uk_9p_str requested_str; + struct uk_9preq *req; + int rc; + uint32_t new_msize; + + uk_9p_str_init(&requested_str, requested); + + uk_pr_debug("TVERSION msize %u version %s\n", + dev->msize, requested); + + req = uk_9pdev_call(dev, UK_9P_TVERSION, __PAGE_SIZE, "ds", + dev->msize, &requested_str); + if (PTRISERR(req)) + return req; + + rc = uk_9preq_deserialize(req, "ds", &new_msize, received); + + if (rc) + return ERR2PTR(rc); + + uk_pr_debug("RVERSION msize %u version %.*s\n", new_msize, + received->size, received->data); + + /* + * Note: the 9P specification mentions that new_msize <= dev->msize. + * Howevver, execution can continue even if the invariant is violated + * and set_msize() fails, as the old message size is always within the + * accepted limit. + */ + if (!uk_9pdev_set_msize(dev, new_msize)) + uk_pr_debug("Invalid new message size.\n"); + + return req; +} + +struct uk_9pfid *uk_9p_attach(struct uk_9pdev *dev, uint32_t afid, + const char *uname, const char *aname, uint32_t n_uname) +{ + struct uk_9preq *req; + struct uk_9pfid *fid; + struct uk_9p_str uname_str; + struct uk_9p_str aname_str; + int rc; + + uk_9p_str_init(&uname_str, uname); + uk_9p_str_init(&aname_str, aname); + + fid = uk_9pdev_fid_create(dev); + if (PTRISERR(fid)) + return fid; + + uk_pr_debug("TATTACH fid %u afid %u uname %s aname %s n_uname %u\n", + fid->fid, afid, uname, aname, n_uname); + + req = uk_9pdev_call(dev, UK_9P_TATTACH, __PAGE_SIZE, "ddssd", + fid->fid, afid, &uname_str, &aname_str, n_uname); + if (PTRISERR(req)) { + uk_9pdev_fid_release(fid); + return (void *)req; + } + + rc = uk_9preq_deserialize(req, "Q", &fid->qid); + uk_9pdev_req_remove(dev, req); + + uk_pr_debug("RATTACH qid type %u version %u path %lu\n", + fid->qid.type, fid->qid.version, fid->qid.path); + + if (rc < 0) { + uk_9pdev_fid_release(fid); + return ERR2PTR(rc); + } + + return fid; +} + +int uk_9p_flush(struct uk_9pdev *dev, uint16_t oldtag) +{ + struct uk_9preq *req; + + uk_pr_debug("TFLUSH oldtag %u\n", oldtag); + req = uk_9pdev_call(dev, UK_9P_TFLUSH, __PAGE_SIZE, "w", oldtag); + if (PTRISERR(req)) + return PTR2ERR(req); + + uk_pr_debug("RFLUSH\n"); + uk_9pdev_req_remove(dev, req); + + return 0; +} + +struct uk_9pfid *uk_9p_walk(struct uk_9pdev *dev, struct uk_9pfid *fid, + const char *name) +{ + struct uk_9preq *req; + struct uk_9pfid *newfid; + struct uk_9p_str name_str; + uint16_t nwqid; + uint16_t nwname; + int rc; + + uk_9p_str_init(&name_str, name); + + newfid = uk_9pdev_fid_create(dev); + if (PTRISERR(newfid)) + return newfid; + + nwname = name ? 1 : 0; + + if (name) { + uk_pr_debug("TWALK fid %u newfid %u nwname %d name %s\n", + fid->fid, newfid->fid, nwname, name); + req = uk_9pdev_call(dev, UK_9P_TWALK, __PAGE_SIZE, "ddws", + fid->fid, newfid->fid, nwname, &name_str); + } else { + uk_pr_debug("TWALK fid %u newfid %u nwname %d\n", + fid->fid, newfid->fid, nwname); + req = uk_9pdev_call(dev, UK_9P_TWALK, __PAGE_SIZE, "ddw", + fid->fid, newfid->fid, nwname); + } + + if (PTRISERR(req)) { + /* + * Don't clunk if request has finished with error, as the fid + * is invalid. + */ + newfid->was_removed = 1; + rc = PTR2ERR(req); + goto out; + } + + rc = uk_9preq_deserialize(req, "w", &nwqid); + if (rc < 0) + goto out_req; + + uk_pr_debug("RWALK nwqid %u\n", nwqid); + + if (nwqid != nwname) { + rc = -ENOENT; + goto out_req; + } + + + if (nwname) { + rc = uk_9preq_deserialize(req, "Q", &newfid->qid); + if (rc < 0) + goto out_req; + } else + newfid->qid = fid->qid; + + rc = 0; +out_req: + uk_9pdev_req_remove(dev, req); +out: + if (rc) { + uk_9pdev_fid_release(newfid); + return ERR2PTR(rc); + } + + return newfid; +} + +int uk_9p_open(struct uk_9pdev *dev, struct uk_9pfid *fid, uint8_t mode) +{ + struct uk_9preq *req; + int rc; + + uk_pr_debug("TOPEN fid %u mode %u\n", fid->fid, mode); + + req = uk_9pdev_call(dev, UK_9P_TOPEN, __PAGE_SIZE, "db", + fid->fid, mode); + if (PTRISERR(req)) + return PTR2ERR(req); + + rc = uk_9preq_deserialize(req, "Qd", &fid->qid, &fid->iounit); + uk_9pdev_req_remove(dev, req); + + uk_pr_debug("ROPEN qid type %u version %u path %lu iounit %u\n", + fid->qid.type, fid->qid.version, fid->qid.path, + fid->iounit); + + return rc; +} + +int uk_9p_create(struct uk_9pdev *dev, struct uk_9pfid *fid, + const char *name, uint32_t perm, uint8_t mode, + const char *extension) +{ + struct uk_9preq *req; + struct uk_9p_str name_str; + struct uk_9p_str extension_str; + int rc; + + uk_9p_str_init(&name_str, name); + uk_9p_str_init(&extension_str, extension); + + uk_pr_debug("TCREATE fid %u name %s perm %u mode %u ext %s\n", + fid->fid, name, perm, mode, extension); + + req = uk_9pdev_call(dev, UK_9P_TCREATE, __PAGE_SIZE, "dsdbs", + fid->fid, &name_str, perm, mode, &extension_str); + if (PTRISERR(req)) + return PTR2ERR(req); + + rc = uk_9preq_deserialize(req, "Qd", &fid->qid, &fid->iounit); + uk_9pdev_req_remove(dev, req); + + uk_pr_debug("RCREATE qid type %u version %u path %lu iounit %u\n", + fid->qid.type, fid->qid.version, fid->qid.path, + fid->iounit); + + return rc; +} + +int uk_9p_remove(struct uk_9pdev *dev, struct uk_9pfid *fid) +{ + struct uk_9preq *req; + + /* The fid is considered invalid even if the remove fails. */ + fid->was_removed = 1; + + uk_pr_debug("TREMOVE fid %u\n", fid->fid); + req = uk_9pdev_call(dev, UK_9P_TREMOVE, __PAGE_SIZE, "d", fid->fid); + if (PTRISERR(req)) + return PTR2ERR(req); + + uk_9pdev_req_remove(dev, req); + uk_pr_debug("RREMOVE\n"); + + return 0; +} + +int uk_9p_clunk(struct uk_9pdev *dev, struct uk_9pfid *fid) +{ + struct uk_9preq *req; + + if (fid->was_removed) + return 0; + + uk_pr_debug("TCLUNK fid %u\n", fid->fid); + req = uk_9pdev_call(dev, UK_9P_TCLUNK, __PAGE_SIZE, "d", fid->fid); + if (PTRISERR(req)) + return PTR2ERR(req); + + uk_9pdev_req_remove(dev, req); + uk_pr_debug("RCLUNK\n"); + + return 0; +} + +int64_t uk_9p_read(struct uk_9pdev *dev, struct uk_9pfid *fid, + uint64_t offset, uint32_t count, char *buf) +{ + struct uk_9preq *req; + int64_t rc; + + if (fid->iounit != 0) + count = MIN(count, fid->iounit); + count = MIN(count, dev->msize - 11); + + uk_pr_debug("TREAD fid %u offset %lu count %u\n", fid->fid, + offset, count); + + req = uk_9pdev_req_create(dev, UK_9P_TREAD, __PAGE_SIZE); + if (PTRISERR(req)) + return PTR2ERR(req); + + rc = uk_9preq_serialize(req, "dqd", fid->fid, offset, count); + if (rc < 0) + goto out; + + rc = uk_9preq_ready(req, UK_9PREQ_ZCDIR_READ, buf, count, 11); + if (rc < 0) + goto out; + + rc = uk_9pdev_request(dev, req); + if (rc < 0) + goto out; + + rc = uk_9preq_waitreply(req); + if (rc < 0) + goto out; + + rc = uk_9preq_deserialize(req, "d", &count); + if (rc < 0) + goto out; + + uk_pr_debug("RREAD count %u\n", count); + + rc = count; + +out: + uk_9pdev_req_remove(dev, req); + return rc; +} + +int64_t uk_9p_write(struct uk_9pdev *dev, struct uk_9pfid *fid, + uint64_t offset, uint32_t count, const char *buf) +{ + struct uk_9preq *req; + int64_t rc; + + count = MIN(count, fid->iounit); + count = MIN(count, dev->msize - 23); + + uk_pr_debug("TWRITE fid %u offset %lu count %u\n", fid->fid, + offset, count); + req = uk_9pdev_req_create(dev, UK_9P_TWRITE, __PAGE_SIZE); + if (PTRISERR(req)) + return PTR2ERR(req); + + rc = uk_9preq_serialize(req, "dqd", fid->fid, offset, count); + if (rc < 0) + goto out; + + rc = uk_9preq_ready(req, UK_9PREQ_ZCDIR_WRITE, (void *)buf, count, 23); + if (rc < 0) + goto out; + + rc = uk_9pdev_request(dev, req); + if (rc < 0) + goto out; + + rc = uk_9preq_waitreply(req); + if (rc < 0) + goto out; + + rc = uk_9preq_deserialize(req, "d", &count); + if (rc < 0) + goto out; + + uk_pr_debug("RWRITE count %u\n", count); + + rc = count; + +out: + uk_9pdev_req_remove(dev, req); + return rc; +} + +struct uk_9preq *uk_9p_stat(struct uk_9pdev *dev, struct uk_9pfid *fid, + struct uk_9p_stat *stat) +{ + struct uk_9preq *req; + int rc; + uint16_t dummy; + + uk_pr_debug("TSTAT fid %u\n", fid->fid); + req = uk_9pdev_call(dev, UK_9P_TSTAT, __PAGE_SIZE, "d", fid->fid); + if (PTRISERR(req)) + return req; + + rc = uk_9preq_deserialize(req, "wS", &dummy, stat); + if (rc) + return ERR2PTR(rc); + uk_pr_debug("RSTAT\n"); + + return req; +} + +int uk_9p_wstat(struct uk_9pdev *dev, struct uk_9pfid *fid, + struct uk_9p_stat *stat) +{ + struct uk_9preq *req; + + /* + * The packed size of stat is 61 bytes + the size occupied by the + * strings. + */ + stat->size = 61; + stat->size += stat->name.size; + stat->size += stat->uid.size; + stat->size += stat->gid.size; + stat->size += stat->muid.size; + stat->size += stat->extension.size; + + uk_pr_debug("TWSTAT fid %u\n", fid->fid); + req = uk_9pdev_call(dev, UK_9P_TWSTAT, __PAGE_SIZE, "dwS", fid->fid, + stat->size + 2, stat); + if (PTRISERR(req)) + return PTR2ERR(req); + uk_9pdev_req_remove(dev, req); + uk_pr_debug("RWSTAT"); + + return 0; +} diff --git a/lib/uk9p/Makefile.uk b/lib/uk9p/Makefile.uk index cd4bf4b8a033..efc0ee748ad4 100644 --- a/lib/uk9p/Makefile.uk +++ b/lib/uk9p/Makefile.uk @@ -7,3 +7,4 @@ LIBUK9P_SRCS-y += $(LIBUK9P_BASE)/9pdev_trans.c LIBUK9P_SRCS-y += $(LIBUK9P_BASE)/9preq.c LIBUK9P_SRCS-y += $(LIBUK9P_BASE)/9pdev.c LIBUK9P_SRCS-y += $(LIBUK9P_BASE)/9pfid.c +LIBUK9P_SRCS-y += $(LIBUK9P_BASE)/9p.c diff --git a/lib/uk9p/exportsyms.uk b/lib/uk9p/exportsyms.uk index ec469a2bff03..aae9e8a127b5 100644 --- a/lib/uk9p/exportsyms.uk +++ b/lib/uk9p/exportsyms.uk @@ -20,6 +20,8 @@ uk_9pdev_disconnect uk_9pdev_request uk_9pdev_xmit_notify uk_9pdev_call +uk_9pdev_set_msize +uk_9pdev_get_msizeuk_9pdev_req_createuk_9pdev_req_lookup @@ -31,3 +33,16 @@ uk_9pdev_get_msize uk_9pdev_fid_create uk_9pfid_get uk_9pfid_put + +uk_9p_version +uk_9p_attach +uk_9p_flush +uk_9p_walk +uk_9p_open +uk_9p_create +uk_9p_remove +uk_9p_clunk +uk_9p_read +uk_9p_write +uk_9p_stat +uk_9p_wstat diff --git a/lib/uk9p/include/uk/9p.h b/lib/uk9p/include/uk/9p.h new file mode 100644 index 000000000000..59d18d9d03c9 --- /dev/null +++ b/lib/uk9p/include/uk/9p.h @@ -0,0 +1,265 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* + * Authors: Cristian Banu <cristb@xxxxxxxxx> + * + * Copyright (c) 2019, University Politehnica of Bucharest. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * THIS HEADER MAY NOT BE EXTRACTED OR MODIFIED IN ANY WAY. + */ +#ifndef __UK_9P__ +#define __UK_9P__ + +#include <stdarg.h> +#include <stdint.h> +#include <string.h> +#include <uk/config.h> +#include <uk/9p_core.h> +#include <uk/9pdev.h> +#include <uk/9preq.h> +#include <uk/9pfid.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Negotiates the version and is the first message in a 9P session. + * + * @param dev + * The Unikraft 9P Device. + * @param requested + * Requested version string. + * @param received + * Received version string. + * @return + * - (!ERRPTR): The request. It must be removed only after all accesses to + * the received version string are done. + * - ERRPTR: The error returned either by the API or by the remote server. + */ +struct uk_9preq *uk_9p_version(struct uk_9pdev *dev, + const char *requested, struct uk_9p_str *received); + +/** + * Attaches to a filesystem tree exported by the 9P server, returning the + * fid of the root directory. + * + * @param dev + * The Unikraft 9P Device. + * @param afid + * Authentication fid, usually UK_9P_NOFID. + * @param uname + * User name, can be empty string for virtio/xen. + * @param aname + * The file tree to access, can be left empty for virtio/xen. + * @param n_uname + * Numeric uname, part of the 9P2000.u unix extension to the protocol. + * @return + * - (!ERRPTR): The fid of the root directory in the accessed file tree. + * - ERRPTR: The error returned either by the API or by the remote server. + */ +struct uk_9pfid *uk_9p_attach(struct uk_9pdev *dev, uint32_t afid, + const char *uname, const char *aname, uint32_t n_uname); + +/** + * Flushes the given request tag, canceling the corresponding request if + * the server has not yet replied to it. + * + * @param dev + * The Unikraft 9P Device. + * @param oldtag + * Request tag. + * @return + * - 0: Successful. + * - (< 0): An error occurred. + */ +int uk_9p_flush(struct uk_9pdev *dev, uint16_t oldtag); + +/** + * Walks the filesystem tree from the given directory fid, attempting to obtain + * the fid for the child with the given name. + * + * @param dev + * The Unikraft 9P Device. + * @param fid + * Directory fid. + * @param name + * File name. + * @return + * - (!ERRPTR): The fid of the child entry. + * - ERRPTR: The error returned either by the API or by the remote server. + */ +struct uk_9pfid *uk_9p_walk(struct uk_9pdev *dev, struct uk_9pfid *fid, + const char *name); + +/** + * Opens the fid with the given mode. + * + * @param dev + * The Unikraft 9P Device. + * @param fid + * 9P fid. + * @param mode + * 9P open mode. + * @return + * - 0: Successful. + * - (< 0): An error occurred. + */ +int uk_9p_open(struct uk_9pdev *dev, struct uk_9pfid *fid, uint8_t mode); + +/** + * Creates a new file with the given name in the directory associated with fid, + * and associates fid with the newly created file, opening it with the given + * mode. + * + * @param dev + * The Unikraft 9P Device. + * @param fid + * 9P directory fid. + * @param name + * Name of the created file. + * @param perm + * 9P permission bits. + * @param mode + * 9P open mode. + * @param extension + * String describing special files, depending on the mode bit. + * @return + * - 0: Successful. + * - (< 0): An error occurred. + */ +int uk_9p_create(struct uk_9pdev *dev, struct uk_9pfid *fid, + const char *name, uint32_t perm, uint8_t mode, + const char *extension); + +/** + * Removes the file associated with fid. + * + * @param dev + * The Unikraft 9P Device. + * @param fid + * 9P fid to remove. + * @return + * - 0: Successful. + * - (< 0): An error occurred. + */ +int uk_9p_remove(struct uk_9pdev *dev, struct uk_9pfid *fid); + +/** + * Clunks the fid, telling the server to forget its previous association. + * + * @param dev + * The Unikraft 9P Device. + * @param fid + * 9P fid to clunk. + * @return + * - 0: Successful. + * - (< 0): An error occurred. + */ +int uk_9p_clunk(struct uk_9pdev *dev, struct uk_9pfid *fid); + +/** + * Reads count bytes from the fid, starting from the given offset, placing + * them into the buffer. As in the case of POSIX read(), the number of + * bytes read may be less than count, which is not an error, but rather + * signals that the offset is close to EOF or count is too big for the + * transport of this 9P device. A return value of 0 indicates end of + * file. + * + * @param dev + * The Unikraft 9P Device. + * @param fid + * 9P fid to read from. + * @param offset + * Offset at which to start reading. + * @param count + * Maximum number of bytes to read. + * @param buf + * Buffer to read into. + * @return + * - (>= 0): Amount of bytes read. + * - (< 0): An error occurred. + */ +int64_t uk_9p_read(struct uk_9pdev *dev, struct uk_9pfid *fid, + uint64_t offset, uint32_t count, char *buf); + +/** + * Writes count bytes from buf to the fid, starting from the given offset. + * + * @param dev + * The Unikraft 9P Device. + * @param fid + * 9P fid to write to. + * @param offset + * Offset at which to start writing. + * @param count + * Maximum number of bytes to write. + * @param buf + * Data to be written. + * @return + * - (>= 0): Amount of bytes written. + * - (< 0): An error occurred. + */ +int64_t uk_9p_write(struct uk_9pdev *dev, struct uk_9pfid *fid, + uint64_t offset, uint32_t count, const char *buf); + +/** + * Stats the given fid and places the data into the given stat structure. + * + * @param dev + * The Unikraft 9P Device. + * @param fid + * 9P fid to stat. + * @param stat + * Where to store the stat results. + * @return + * - (!ERRPTR): The request. It must be removed only after all accesses to + * the strings in the stat structure are over. + * - ERRPTR: The error returned either by the API or by the remote server. + */ +struct uk_9preq *uk_9p_stat(struct uk_9pdev *dev, struct uk_9pfid *fid, + struct uk_9p_stat *stat); + +/** + * Changes the file attributes of a given fid. + * + * @param dev + * The Unikraft 9P Device. + * @param fid + * 9P fid to clunk. + * @return + * - 0: Successful. + * - (< 0): An error occurred. + */ +int uk_9p_wstat(struct uk_9pdev *dev, struct uk_9pfid *fid, + struct uk_9p_stat *stat); + +#ifdef __cplusplus +} +#endif + +#endif /* __UK_9P__ */ _______________________________________________ Minios-devel mailing list Minios-devel@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/mailman/listinfo/minios-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |