|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [UNIKRAFT PATCH v2 2/9] lib/uk9p: Switch to using the new serialization
This patch migrates 9p.c and 9pfs to use the new serialization
implementation.
Signed-off-by: Cristian Banu <cristb@xxxxxxxxx>
---
lib/9pfs/9pfs_vnops.c | 2 +-
lib/uk9p/9p.c | 302 +++++++++++++++++++++++++-----------------
lib/uk9p/9preq.c | 27 ++--
3 files changed, 192 insertions(+), 139 deletions(-)
diff --git a/lib/9pfs/9pfs_vnops.c b/lib/9pfs/9pfs_vnops.c
index 5e6a7bb..6d3ece3 100644
--- a/lib/9pfs/9pfs_vnops.c
+++ b/lib/9pfs/9pfs_vnops.c
@@ -409,7 +409,7 @@ again:
fake_request.recv.size = fd->readdir_sz;
fake_request.recv.offset = fd->readdir_off;
fake_request.state = UK_9PREQ_RECEIVED;
- rc = uk_9preq_deserialize(&fake_request, "S", &stat);
+ rc = uk_9preq_readstat(&fake_request, &stat);
if (rc == -ENOBUFS) {
/*
diff --git a/lib/uk9p/9p.c b/lib/uk9p/9p.c
index eb4c2dc..638555b 100644
--- a/lib/uk9p/9p.c
+++ b/lib/uk9p/9p.c
@@ -40,28 +40,49 @@
#include <uk/9preq.h>
#include <uk/9pfid.h>
+static inline int send_and_wait_zc(struct uk_9pdev *dev, struct uk_9preq *req,
+ enum uk_9preq_zcdir zc_dir, void *zc_buf, uint32_t zc_size,
+ uint32_t zc_offset)
+{
+ int rc;
+
+ if ((rc = uk_9preq_ready(req, zc_dir, zc_buf, zc_size, zc_offset)) ||
+ (rc = uk_9pdev_request(dev, req)) ||
+ (rc = uk_9preq_waitreply(req)))
+ return rc;
+
+ return 0;
+}
+
+static inline int send_and_wait_no_zc(struct uk_9pdev *dev,
+ struct uk_9preq *req)
+{
+ return send_and_wait_zc(dev, req, UK_9PREQ_ZCDIR_NONE, NULL, 0, 0);
+}
+
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;
+ int rc = 0;
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);
+ req = uk_9pdev_req_create(dev, UK_9P_TVERSION, __PAGE_SIZE);
if (PTRISERR(req))
return req;
- rc = uk_9preq_deserialize(req, "ds", &new_msize, received);
+ uk_pr_debug("TVERSION msize %u version %s\n",
+ dev->msize, requested);
- if (rc)
- return ERR2PTR(rc);
+ if ((rc = uk_9preq_write32(req, dev->msize)) ||
+ (rc = uk_9preq_writestr(req, &requested_str)) ||
+ (rc = send_and_wait_no_zc(dev, req)) ||
+ (rc = uk_9preq_read32(req, &new_msize)) ||
+ (rc = uk_9preq_readstr(req, received)))
+ goto free;
uk_pr_debug("RVERSION msize %u version %.*s\n", new_msize,
received->size, received->data);
@@ -76,6 +97,10 @@ struct uk_9preq *uk_9p_version(struct uk_9pdev *dev,
uk_pr_debug("Invalid new message size.\n");
return req;
+
+free:
+ uk_9pdev_req_remove(dev, req);
+ return ERR2PTR(rc);
}
struct uk_9pfid *uk_9p_attach(struct uk_9pdev *dev, uint32_t afid,
@@ -94,43 +119,56 @@ struct uk_9pfid *uk_9p_attach(struct uk_9pdev *dev,
uint32_t afid,
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);
+ req = uk_9pdev_req_create(dev, UK_9P_TATTACH, __PAGE_SIZE);
if (PTRISERR(req)) {
uk_9pdev_fid_release(fid);
return (void *)req;
}
- rc = uk_9preq_deserialize(req, "Q", &fid->qid);
+ uk_pr_debug("TATTACH fid %u afid %u uname %s aname %s n_uname %u\n",
+ fid->fid, afid, uname, aname, n_uname);
+
+ rc = 0;
+ if ((rc = uk_9preq_write32(req, fid->fid)) ||
+ (rc = uk_9preq_write32(req, afid)) ||
+ (rc = uk_9preq_writestr(req, &uname_str)) ||
+ (rc = uk_9preq_writestr(req, &aname_str)) ||
+ (rc = uk_9preq_write32(req, n_uname)) ||
+ (rc = send_and_wait_no_zc(dev, req)) ||
+ (rc = uk_9preq_readqid(req, &fid->qid)))
+ goto free;
+
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;
+
+free:
+ uk_9pdev_fid_release(fid);
+ uk_9pdev_req_remove(dev, req);
+ return ERR2PTR(rc);
}
int uk_9p_flush(struct uk_9pdev *dev, uint16_t oldtag)
{
struct uk_9preq *req;
+ int rc = 0;
- uk_pr_debug("TFLUSH oldtag %u\n", oldtag);
- req = uk_9pdev_call(dev, UK_9P_TFLUSH, __PAGE_SIZE, "w", oldtag);
+ req = uk_9pdev_req_create(dev, UK_9P_TFLUSH, __PAGE_SIZE);
if (PTRISERR(req))
return PTR2ERR(req);
+ uk_pr_debug("TFLUSH oldtag %u\n", oldtag);
+ if ((rc = uk_9preq_write16(req, oldtag)) ||
+ (rc = send_and_wait_no_zc(dev, req)))
+ goto out;
uk_pr_debug("RFLUSH\n");
- uk_9pdev_req_remove(dev, req);
- return 0;
+out:
+ uk_9pdev_req_remove(dev, req);
+ return rc;
}
struct uk_9pfid *uk_9p_walk(struct uk_9pdev *dev, struct uk_9pfid *fid,
@@ -141,7 +179,7 @@ struct uk_9pfid *uk_9p_walk(struct uk_9pdev *dev, struct
uk_9pfid *fid,
struct uk_9p_str name_str;
uint16_t nwqid;
uint16_t nwname;
- int rc;
+ int rc = 0;
uk_9p_str_init(&name_str, name);
@@ -151,51 +189,56 @@ struct uk_9pfid *uk_9p_walk(struct uk_9pdev *dev, struct
uk_9pfid *fid,
nwname = name ? 1 : 0;
+ req = uk_9pdev_req_create(dev, UK_9P_TWALK, __PAGE_SIZE);
+ if (PTRISERR(req)) {
+ rc = PTR2ERR(req);
+ goto out;
+ }
+
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);
+ if ((rc = uk_9preq_write32(req, fid->fid)) ||
+ (rc = uk_9preq_write32(req, newfid->fid)) ||
+ (rc = uk_9preq_write16(req, nwname)) ||
+ (rc = uk_9preq_writestr(req, &name_str)))
+ goto out;
} 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 ((rc = uk_9preq_write32(req, fid->fid)) ||
+ (rc = uk_9preq_write32(req, newfid->fid)) ||
+ (rc = uk_9preq_write16(req, nwname)))
+ goto out;
}
- if (PTRISERR(req)) {
+ if ((rc = send_and_wait_no_zc(dev, 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;
+ if ((rc = uk_9preq_read16(req, &nwqid)))
+ goto out;
uk_pr_debug("RWALK nwqid %u\n", nwqid);
if (nwqid != nwname) {
rc = -ENOENT;
- goto out_req;
+ goto out;
}
-
if (nwname) {
- rc = uk_9preq_deserialize(req, "Q", &newfid->qid);
- if (rc < 0)
- goto out_req;
+ if ((rc = uk_9preq_readqid(req, &newfid->qid)))
+ goto out;
} else
newfid->qid = fid->qid;
- rc = 0;
-out_req:
- uk_9pdev_req_remove(dev, req);
out:
+ uk_9pdev_req_remove(dev, req);
if (rc) {
uk_9pdev_fid_release(newfid);
return ERR2PTR(rc);
@@ -207,22 +250,27 @@ out:
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);
+ int rc = 0;
- req = uk_9pdev_call(dev, UK_9P_TOPEN, __PAGE_SIZE, "db",
- fid->fid, mode);
+ req = uk_9pdev_req_create(dev, UK_9P_TOPEN, __PAGE_SIZE);
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("TOPEN fid %u mode %u\n", fid->fid, mode);
+
+ if ((rc = uk_9preq_write32(req, fid->fid)) ||
+ (rc = uk_9preq_write8(req, mode)) ||
+ (rc = send_and_wait_no_zc(dev, req)) ||
+ (rc = uk_9preq_readqid(req, &fid->qid)) ||
+ (rc = uk_9preq_read32(req, &fid->iounit)))
+ goto out;
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);
+out:
+ uk_9pdev_req_remove(dev, req);
return rc;
}
@@ -233,63 +281,80 @@ int uk_9p_create(struct uk_9pdev *dev, struct uk_9pfid
*fid,
struct uk_9preq *req;
struct uk_9p_str name_str;
struct uk_9p_str extension_str;
- int rc;
+ int rc = 0;
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);
+ req = uk_9pdev_req_create(dev, UK_9P_TCREATE, __PAGE_SIZE);
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("TOPEN fid %u mode %u\n", fid->fid, mode);
+
+ if ((rc = uk_9preq_write32(req, fid->fid)) ||
+ (rc = uk_9preq_writestr(req, &name_str)) ||
+ (rc = uk_9preq_write32(req, perm)) ||
+ (rc = uk_9preq_write8(req, mode)) ||
+ (rc = uk_9preq_writestr(req, &extension_str)) ||
+ (rc = send_and_wait_no_zc(dev, req)) ||
+ (rc = uk_9preq_readqid(req, &fid->qid)) ||
+ (rc = uk_9preq_read32(req, &fid->iounit)))
+ goto out;
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);
+out:
+ uk_9pdev_req_remove(dev, req);
return rc;
}
int uk_9p_remove(struct uk_9pdev *dev, struct uk_9pfid *fid)
{
struct uk_9preq *req;
+ int rc = 0;
/* 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);
+ req = uk_9pdev_req_create(dev, UK_9P_TREMOVE, __PAGE_SIZE);
if (PTRISERR(req))
return PTR2ERR(req);
- uk_9pdev_req_remove(dev, req);
+ uk_pr_debug("TREMOVE fid %u\n", fid->fid);
+ if ((rc = uk_9preq_write32(req, fid->fid)) ||
+ (rc = send_and_wait_no_zc(dev, req)))
+ goto out;
uk_pr_debug("RREMOVE\n");
- return 0;
+out:
+ uk_9pdev_req_remove(dev, req);
+ return rc;
}
int uk_9p_clunk(struct uk_9pdev *dev, struct uk_9pfid *fid)
{
struct uk_9preq *req;
+ int rc = 0;
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);
+ req = uk_9pdev_req_create(dev, UK_9P_TCLUNK, __PAGE_SIZE);
if (PTRISERR(req))
return PTR2ERR(req);
- uk_9pdev_req_remove(dev, req);
+ uk_pr_debug("TCLUNK fid %u\n", fid->fid);
+ if ((rc = uk_9preq_write32(req, fid->fid)) ||
+ (rc = send_and_wait_no_zc(dev, req)))
+ goto out;
uk_pr_debug("RCLUNK\n");
- return 0;
+out:
+ uk_9pdev_req_remove(dev, req);
+ return rc;
}
int64_t uk_9p_read(struct uk_9pdev *dev, struct uk_9pfid *fid,
@@ -309,24 +374,12 @@ int64_t uk_9p_read(struct uk_9pdev *dev, struct uk_9pfid
*fid,
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)
+ if ((rc = uk_9preq_write32(req, fid->fid)) ||
+ (rc = uk_9preq_write64(req, offset)) ||
+ (rc = uk_9preq_write32(req, count)) ||
+ (rc = send_and_wait_zc(dev, req, UK_9PREQ_ZCDIR_READ, buf,
+ count, 11)) ||
+ (rc = uk_9preq_read32(req, &count)))
goto out;
uk_pr_debug("RREAD count %u\n", count);
@@ -353,24 +406,12 @@ int64_t uk_9p_write(struct uk_9pdev *dev, struct uk_9pfid
*fid,
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)
+ if ((rc = uk_9preq_write32(req, fid->fid)) ||
+ (rc = uk_9preq_write64(req, offset)) ||
+ (rc = uk_9preq_write32(req, count)) ||
+ (rc = send_and_wait_zc(dev, req, UK_9PREQ_ZCDIR_WRITE,
+ (void *)buf, count, 23)) ||
+ (rc = uk_9preq_read32(req, &count)))
goto out;
uk_pr_debug("RWRITE count %u\n", count);
@@ -386,45 +427,58 @@ 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;
+ int rc = 0;
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);
+ req = uk_9pdev_req_create(dev, UK_9P_TSTAT, __PAGE_SIZE);
if (PTRISERR(req))
return req;
- rc = uk_9preq_deserialize(req, "wS", &dummy, stat);
- if (rc)
- return ERR2PTR(rc);
+ uk_pr_debug("TSTAT fid %u\n", fid->fid);
+
+ if ((rc = uk_9preq_write32(req, fid->fid)) ||
+ (rc = send_and_wait_no_zc(dev, req)) ||
+ (rc = uk_9preq_read16(req, &dummy)) ||
+ (rc = uk_9preq_readstat(req, stat)))
+ goto out;
+
uk_pr_debug("RSTAT\n");
return req;
+
+out:
+ uk_9pdev_req_remove(dev, req);
+ return ERR2PTR(rc);
}
int uk_9p_wstat(struct uk_9pdev *dev, struct uk_9pfid *fid,
struct uk_9p_stat *stat)
{
struct uk_9preq *req;
+ int rc = 0;
+ uint16_t *dummy;
- /*
- * 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);
+ req = uk_9pdev_req_create(dev, UK_9P_TWSTAT, __PAGE_SIZE);
if (PTRISERR(req))
return PTR2ERR(req);
- uk_9pdev_req_remove(dev, req);
- uk_pr_debug("RWSTAT");
- return 0;
+ uk_pr_debug("TWSTAT fid %u\n", fid->fid);
+
+ if ((rc = uk_9preq_write32(req, fid->fid)))
+ goto out;
+
+ dummy = (uint16_t *)(req->xmit.buf + req->xmit.offset);
+ if ((rc = uk_9preq_write16(req, 0)) ||
+ (rc = uk_9preq_writestat(req, stat)))
+ goto out;
+ *dummy = stat->size + 2;
+
+ if ((rc = send_and_wait_no_zc(dev, req)))
+ goto out;
+
+ uk_pr_debug("RWSTAT\n");
+
+out:
+ uk_9pdev_req_remove(dev, req);
+ return rc;
}
diff --git a/lib/uk9p/9preq.c b/lib/uk9p/9preq.c
index 0fc4b1e..8d787e7 100644
--- a/lib/uk9p/9preq.c
+++ b/lib/uk9p/9preq.c
@@ -434,10 +434,8 @@ int uk_9preq_ready(struct uk_9preq *req, enum
uk_9preq_zcdir zc_dir,
UK_ASSERT(req);
- if (UK_READ_ONCE(req->state) != UK_9PREQ_INITIALIZED) {
- rc = -EIO;
- goto out;
- }
+ if (UK_READ_ONCE(req->state) != UK_9PREQ_INITIALIZED)
+ return -EIO;
/* Save current offset as the size of the message. */
total_size = req->xmit.offset;
@@ -448,10 +446,10 @@ int uk_9preq_ready(struct uk_9preq *req, enum
uk_9preq_zcdir zc_dir,
/* Serialize the header. */
req->xmit.offset = 0;
- rc = uk_9preq_serialize(req, "dbw", total_size_with_zc, req->xmit.type,
- req->tag);
- if (rc < 0)
- goto out;
+ if ((rc = uk_9preq_write32(req, total_size_with_zc)) < 0 ||
+ (rc = uk_9preq_write8(req, req->xmit.type)) < 0 ||
+ (rc = uk_9preq_write16(req, req->tag)) < 0)
+ return rc;
/* Reset offset and size to sane values. */
req->xmit.offset = 0;
@@ -474,8 +472,7 @@ int uk_9preq_ready(struct uk_9preq *req, enum
uk_9preq_zcdir zc_dir,
/* Update the state. */
UK_WRITE_ONCE(req->state, UK_9PREQ_READY);
-out:
- return rc;
+ return 0;
}
int uk_9preq_receive_cb(struct uk_9preq *req, uint32_t recv_size)
@@ -495,8 +492,10 @@ int uk_9preq_receive_cb(struct uk_9preq *req, uint32_t
recv_size)
/* Deserialize the header into request fields. */
req->recv.offset = 0;
req->recv.size = recv_size;
- rc = _fcall_deserialize(&req->recv, "dbw", &size,
- &req->recv.type, &tag);
+ if ((rc = uk_9preq_read32(req, &size)) < 0 ||
+ (rc = uk_9preq_read8(req, &req->recv.type)) < 0 ||
+ (rc = uk_9preq_read16(req, &tag)) < 0)
+ return rc;
/* Check sanity of deserialized values. */
if (rc < 0)
@@ -557,8 +556,8 @@ int uk_9preq_error(struct uk_9preq *req)
*/
UK_BUGON(req->recv.offset != UK_9P_HEADER_SIZE);
- rc = uk_9preq_deserialize(req, "sd", &error, &errcode);
- if (rc < 0)
+ if ((rc = uk_9preq_readstr(req, &error)) < 0 ||
+ (rc = uk_9preq_read32(req, &errcode)) < 0)
return rc;
uk_pr_debug("RERROR %.*s %d\n", error.size, error.data, errcode);
--
2.26.2
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |