[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_msize
uk_9pdev_req_create
  uk_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

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.