tests/9p: add 'Tsetattr' request to test client

Add and implement functions to 9pfs test client for sending a 9p2000.L
'Tsetattr' request and receiving its 'Rsetattr' response counterpart.

Signed-off-by: Christian Schoenebeck <qemu_oss@crudebyte.com>
Signed-off-by: Greg Kurz <groug@kaod.org>
Message-Id: <20250312152933.383967-6-groug@kaod.org>
This commit is contained in:
Christian Schoenebeck 2025-03-12 16:29:31 +01:00
parent 371a269ff8
commit 4719a2d591
3 changed files with 84 additions and 0 deletions

View file

@ -557,6 +557,55 @@ void v9fs_rgetattr(P9Req *req, v9fs_attr *attr)
v9fs_req_free(req);
}
/*
* size[4] Tsetattr tag[2] fid[4] valid[4] mode[4] uid[4] gid[4] size[8]
* atime_sec[8] atime_nsec[8] mtime_sec[8] mtime_nsec[8]
*/
TSetAttrRes v9fs_tsetattr(TSetAttrOpt opt)
{
P9Req *req;
uint32_t err;
g_assert(opt.client);
req = v9fs_req_init(
opt.client, 4/*fid*/ + 4/*valid*/ + 4/*mode*/ + 4/*uid*/ + 4/*gid*/ +
8/*size*/ + 8/*atime_sec*/ + 8/*atime_nsec*/ + 8/*mtime_sec*/ +
8/*mtime_nsec*/, P9_TSETATTR, opt.tag
);
v9fs_uint32_write(req, opt.fid);
v9fs_uint32_write(req, (uint32_t) opt.attr.valid);
v9fs_uint32_write(req, opt.attr.mode);
v9fs_uint32_write(req, opt.attr.uid);
v9fs_uint32_write(req, opt.attr.gid);
v9fs_uint64_write(req, opt.attr.size);
v9fs_uint64_write(req, opt.attr.atime_sec);
v9fs_uint64_write(req, opt.attr.atime_nsec);
v9fs_uint64_write(req, opt.attr.mtime_sec);
v9fs_uint64_write(req, opt.attr.mtime_nsec);
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_rsetattr(req);
}
req = NULL; /* request was freed */
}
return (TSetAttrRes) { .req = req };
}
/* size[4] Rsetattr tag[2] */
void v9fs_rsetattr(P9Req *req)
{
v9fs_req_recv(req, P9_RSETATTR);
v9fs_req_free(req);
}
/* size[4] Treaddir tag[2] fid[4] offset[8] count[4] */
TReadDirRes v9fs_treaddir(TReadDirOpt opt)
{

View file

@ -65,6 +65,16 @@ typedef struct v9fs_attr {
#define P9_GETATTR_BASIC 0x000007ffULL /* Mask for fields up to BLOCKS */
#define P9_GETATTR_ALL 0x00003fffULL /* Mask for ALL fields */
#define P9_SETATTR_MODE 0x00000001UL
#define P9_SETATTR_UID 0x00000002UL
#define P9_SETATTR_GID 0x00000004UL
#define P9_SETATTR_SIZE 0x00000008UL
#define P9_SETATTR_ATIME 0x00000010UL
#define P9_SETATTR_MTIME 0x00000020UL
#define P9_SETATTR_CTIME 0x00000040UL
#define P9_SETATTR_ATIME_SET 0x00000080UL
#define P9_SETATTR_MTIME_SET 0x00000100UL
struct V9fsDirent {
v9fs_qid qid;
uint64_t offset;
@ -182,6 +192,28 @@ typedef struct TGetAttrRes {
P9Req *req;
} TGetAttrRes;
/* options for 'Tsetattr' 9p request */
typedef struct TSetAttrOpt {
/* 9P client being used (mandatory) */
QVirtio9P *client;
/* user supplied tag number being returned with response (optional) */
uint16_t tag;
/* file ID of file/dir whose attributes shall be modified (required) */
uint32_t fid;
/* new attribute values to be set by 9p server */
v9fs_attr attr;
/* only send Tsetattr 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;
} TSetAttrOpt;
/* result of 'Tsetattr' 9p request */
typedef struct TSetAttrRes {
/* if requestOnly was set: request object for further processing */
P9Req *req;
} TSetAttrRes;
/* options for 'Treaddir' 9p request */
typedef struct TReadDirOpt {
/* 9P client being used (mandatory) */
@ -470,6 +502,8 @@ TWalkRes v9fs_twalk(TWalkOpt opt);
void v9fs_rwalk(P9Req *req, uint16_t *nwqid, v9fs_qid **wqid);
TGetAttrRes v9fs_tgetattr(TGetAttrOpt);
void v9fs_rgetattr(P9Req *req, v9fs_attr *attr);
TSetAttrRes v9fs_tsetattr(TSetAttrOpt opt);
void v9fs_rsetattr(P9Req *req);
TReadDirRes v9fs_treaddir(TReadDirOpt);
void v9fs_rreaddir(P9Req *req, uint32_t *count, uint32_t *nentries,
struct V9fsDirent **entries);

View file

@ -20,6 +20,7 @@
#define tversion(...) v9fs_tversion((TVersionOpt) __VA_ARGS__)
#define tattach(...) v9fs_tattach((TAttachOpt) __VA_ARGS__)
#define tgetattr(...) v9fs_tgetattr((TGetAttrOpt) __VA_ARGS__)
#define tsetattr(...) v9fs_tsetattr((TSetAttrOpt) __VA_ARGS__)
#define treaddir(...) v9fs_treaddir((TReadDirOpt) __VA_ARGS__)
#define tlopen(...) v9fs_tlopen((TLOpenOpt) __VA_ARGS__)
#define twrite(...) v9fs_twrite((TWriteOpt) __VA_ARGS__)