Add v9fs_txattrwalk() and v9fs_rxattrwalk() functions to the 9p test client. This can be used to retrieve a list of xattrs or to acquire a FID that can subsequently be used to retrieve the value of an xattr.
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 | 48 +++++++++++++++++++++++++++ tests/qtest/libqos/virtio-9p-client.h | 28 ++++++++++++++++ 2 files changed, 76 insertions(+) diff --git a/tests/qtest/libqos/virtio-9p-client.c b/tests/qtest/libqos/virtio-9p-client.c index 305b0dac63..b2f0037b7b 100644 --- a/tests/qtest/libqos/virtio-9p-client.c +++ b/tests/qtest/libqos/virtio-9p-client.c @@ -1227,3 +1227,51 @@ void v9fs_rxattrcreate(P9Req *req) v9fs_req_recv(req, P9_RXATTRCREATE); v9fs_req_free(req); } + +/* size[4] Txattrwalk tag[2] fid[4] newfid[4] name[s] */ +TXattrWalkRes v9fs_txattrwalk(TXattrWalkOpt opt) +{ + P9Req *req; + uint32_t err; + uint32_t body_size = 4 + 4; + uint16_t string_size; + uint64_t xattr_size = 0; + + g_assert(opt.client); + g_assert(opt.name); + + string_size = v9fs_string_size(opt.name); + g_assert_cmpint(body_size, <=, UINT32_MAX - string_size); + body_size += string_size; + + req = v9fs_req_init(opt.client, body_size, P9_TXATTRWALK, opt.tag); + v9fs_uint32_write(req, opt.fid); + v9fs_uint32_write(req, opt.newfid); + v9fs_string_write(req, opt.name); + v9fs_req_send(req); + + if (!opt.requestOnly) { + v9fs_req_wait_for_reply(req, NULL); + if (opt.expectErr) { + v9fs_rlerror(req, &err); + g_assert_cmpint(err, ==, opt.expectErr); + } else { + v9fs_rxattrwalk(req, &xattr_size); + } + req = NULL; /* request was freed */ + } + + return (TXattrWalkRes) { .req = req, xattr_size }; +} + +/* size[4] Rxattrwalk tag[2] size[8] */ +void v9fs_rxattrwalk(P9Req *req, uint64_t *size) +{ + v9fs_req_recv(req, P9_RXATTRWALK); + if (size) { + v9fs_uint64_read(req, size); + } else { + v9fs_memskip(req, 8); + } + v9fs_req_free(req); +} diff --git a/tests/qtest/libqos/virtio-9p-client.h b/tests/qtest/libqos/virtio-9p-client.h index 4b04324503..c910407f70 100644 --- a/tests/qtest/libqos/virtio-9p-client.h +++ b/tests/qtest/libqos/virtio-9p-client.h @@ -553,6 +553,32 @@ typedef struct TXattrCreateRes { uint32_t err; } TXattrCreateRes; +/* options for 'Txattrwalk' 9p request */ +typedef struct TXattrWalkOpt { + /* 9P client being used (mandatory) */ + QVirtio9P *client; + /* user supplied tag number being returned with response (optional) */ + uint16_t tag; + /* file ID of file/dir from which to walk (required) */ + uint32_t fid; + /* file ID that will refer to the walked-to xattr (required) */ + uint32_t newfid; + /* xattr name, or empty for a list of all xattrs (required) */ + const char *name; + /* only send Txattrwalk request but not wait for a reply? (optional) */ + bool requestOnly; + /* do we expect an Rlerror response, if yes which error code? (optional) */ + uint32_t expectErr; +} TXattrWalkOpt; + +/* result of 'Txattrwalk' 9p request */ +typedef struct TXattrWalkRes { + /* if requestOnly was set: request object for further processing */ + P9Req *req; + /* size of xattr */ + uint64_t size; +} TXattrWalkRes; + void v9fs_set_allocator(QGuestAllocator *t_alloc); void v9fs_memwrite(P9Req *req, const void *addr, size_t len); void v9fs_memskip(P9Req *req, size_t len); @@ -610,5 +636,7 @@ TClunkRes v9fs_tclunk(TClunkOpt opt); void v9fs_rclunk(P9Req *req); TXattrCreateRes v9fs_txattrcreate(TXattrCreateOpt opt); void v9fs_rxattrcreate(P9Req *req); +TXattrWalkRes v9fs_txattrwalk(TXattrWalkOpt opt); +void v9fs_rxattrwalk(P9Req *req, uint64_t *size); #endif -- 2.47.3
