Add v9fs_tcreate() and v9fs_rcreate() functions to the 9p test client for the legacy 9p2000(.u) Tcreate request type.
This is a preparatory patch, these functions will be used by the subsequently added 9p race test. Signed-off-by: Christian Schoenebeck <[email protected]> --- tests/qtest/libqos/virtio-9p-client.c | 60 +++++++++++++++++++++++++++ tests/qtest/libqos/virtio-9p-client.h | 50 ++++++++++++++++++++++ 2 files changed, 110 insertions(+) diff --git a/tests/qtest/libqos/virtio-9p-client.c b/tests/qtest/libqos/virtio-9p-client.c index 4a3fc1511b..ce67a4b8c5 100644 --- a/tests/qtest/libqos/virtio-9p-client.c +++ b/tests/qtest/libqos/virtio-9p-client.c @@ -1365,3 +1365,63 @@ void v9fs_rstat(P9Req *req, v9fs_stat *stat) v9fs_req_free(req); } + +/* size[4] Tcreate tag[2] fid[4] name[s] perm[4] mode[1] extension[s] */ +TCreateRes v9fs_tcreate(TCreateOpt opt) +{ + P9Req *req; + uint8_t mode = opt.mode; + uint32_t body_size = 4 + 4 + 1; + uint16_t string_size; + + g_assert(opt.client); + /* expecting either Rcreate or an error response, but obviously not both */ + g_assert(!opt.expectErr || !(opt.rcreate.qid || opt.rcreate.iounit)); + + if (!opt.perm) { + opt.perm = 0644; + } + if (!opt.extension) { + opt.extension = ""; + } + + string_size = v9fs_string_size(opt.name) + + v9fs_string_size(opt.extension); + g_assert_cmpint(body_size, <=, UINT32_MAX - string_size); + body_size += string_size; + + req = v9fs_req_init(opt.client, body_size, P9_TCREATE, opt.tag); + v9fs_uint32_write(req, opt.fid); + v9fs_string_write(req, opt.name); + v9fs_uint32_write(req, opt.perm); + v9fs_memwrite(req, &mode, 1); + v9fs_string_write(req, opt.extension); + v9fs_req_send(req); + + if (!opt.requestOnly) { + v9fs_req_wait_for_reply(req, NULL); + if (opt.expectErr) { + v9fs_req_check_err(req, opt.expectErr); + } else { + v9fs_rcreate(req, opt.rcreate.qid, opt.rcreate.iounit); + } + req = NULL; /* request was freed */ + } + + return (TCreateRes) { .req = req }; +} + +/* size[4] Rcreate tag[2] qid[13] iounit[4] */ +void v9fs_rcreate(P9Req *req, v9fs_qid *qid, uint32_t *iounit) +{ + v9fs_req_recv(req, P9_RCREATE); + if (qid) { + v9fs_memread(req, qid, 13); + } else { + v9fs_memskip(req, 13); + } + if (iounit) { + v9fs_uint32_read(req, iounit); + } + v9fs_req_free(req); +} diff --git a/tests/qtest/libqos/virtio-9p-client.h b/tests/qtest/libqos/virtio-9p-client.h index f604cc0ee5..88e0f41ff0 100644 --- a/tests/qtest/libqos/virtio-9p-client.h +++ b/tests/qtest/libqos/virtio-9p-client.h @@ -372,6 +372,54 @@ typedef struct TMkdirRes { P9Req *req; } TMkdirRes; +/* create directory */ +#define P9_CREATE_PERM_DMDIR 0x80000000 + +/* options for 'Tcreate' 9p request (legacy 9p2000.u) */ +typedef struct TCreateOpt { + /* 9P client being used (mandatory) */ + QVirtio9P *client; + /* user supplied tag number being returned with response (optional) */ + uint16_t tag; + /* file ID of the directory the new file shall be created in (required) */ + uint32_t fid; + /* name of the new file (required) */ + const char *name; + /* + * Create mode bits (including file type bits): + * e.g. 0644 for a regular file, + * or P9_CREATE_PERM_DMDIR | 0755 for a directory + * (optional) + */ + uint32_t perm; + /* + * Open mode byte: + * OREAD (0), OWRITE (1), ORDWR (2), OEXEC(3), OTRUNC(0x10), ORCLOSE(0x40) + * (optional) + */ + uint8_t mode; + /* + * Extension data for special files (e.g. symlink target), empty for + * regular files. (optional) + */ + const char *extension; + /* data being received from 9p server as 'Rcreate' response (optional) */ + struct { + v9fs_qid *qid; + uint32_t *iounit; + } rcreate; + /* only send Tcreate request but not wait for a reply? (optional) */ + bool requestOnly; + /* do we expect an error response, if yes which error code? (optional) */ + uint32_t expectErr; +} TCreateOpt; + +/* result of 'Tcreate' 9p request */ +typedef struct TCreateRes { + /* if requestOnly was set: request object for further processing */ + P9Req *req; +} TCreateRes; + /* options for 'Tlcreate' 9p request */ typedef struct TlcreateOpt { /* 9P client being used (mandatory) */ @@ -666,6 +714,8 @@ TFlushRes v9fs_tflush(TFlushOpt); void v9fs_rflush(P9Req *req); TMkdirRes v9fs_tmkdir(TMkdirOpt); void v9fs_rmkdir(P9Req *req, v9fs_qid *qid); +TCreateRes v9fs_tcreate(TCreateOpt opt); +void v9fs_rcreate(P9Req *req, v9fs_qid *qid, uint32_t *iounit); TlcreateRes v9fs_tlcreate(TlcreateOpt); void v9fs_rlcreate(P9Req *req, v9fs_qid *qid, uint32_t *iounit); TsymlinkRes v9fs_tsymlink(TsymlinkOpt); -- 2.47.3
