aboutsummaryrefslogtreecommitdiff
path: root/hw/9pfs
diff options
context:
space:
mode:
Diffstat (limited to 'hw/9pfs')
-rw-r--r--hw/9pfs/9p.c21
-rw-r--r--hw/9pfs/9p.h27
2 files changed, 40 insertions, 8 deletions
diff --git a/hw/9pfs/9p.c b/hw/9pfs/9p.c
index cc4094b971..7bb994bbf2 100644
--- a/hw/9pfs/9p.c
+++ b/hw/9pfs/9p.c
@@ -314,8 +314,8 @@ static V9fsFidState *alloc_fid(V9fsState *s, int32_t fid)
f->next = s->fid_list;
s->fid_list = f;
- v9fs_readdir_init(&f->fs.dir);
- v9fs_readdir_init(&f->fs_reclaim.dir);
+ v9fs_readdir_init(s->proto_version, &f->fs.dir);
+ v9fs_readdir_init(s->proto_version, &f->fs_reclaim.dir);
return f;
}
@@ -2228,7 +2228,14 @@ static void coroutine_fn v9fs_read(void *opaque)
goto out_nofid;
}
if (fidp->fid_type == P9_FID_DIR) {
-
+ if (s->proto_version != V9FS_PROTO_2000U) {
+ warn_report_once(
+ "9p: bad client: T_read request on directory only expected "
+ "with 9P2000.u protocol version"
+ );
+ err = -EOPNOTSUPP;
+ goto out;
+ }
if (off == 0) {
v9fs_co_rewinddir(pdu, fidp);
}
@@ -2446,6 +2453,14 @@ static void coroutine_fn v9fs_readdir(void *opaque)
retval = -EINVAL;
goto out;
}
+ if (s->proto_version != V9FS_PROTO_2000L) {
+ warn_report_once(
+ "9p: bad client: T_readdir request only expected with 9P2000.L "
+ "protocol version"
+ );
+ retval = -EOPNOTSUPP;
+ goto out;
+ }
count = v9fs_do_readdir(pdu, fidp, (off_t) initial_offset, max_count);
if (count < 0) {
retval = count;
diff --git a/hw/9pfs/9p.h b/hw/9pfs/9p.h
index 93b7030edf..3dd1b50b1a 100644
--- a/hw/9pfs/9p.h
+++ b/hw/9pfs/9p.h
@@ -197,22 +197,39 @@ typedef struct V9fsXattr
typedef struct V9fsDir {
DIR *stream;
- CoMutex readdir_mutex;
+ P9ProtoVersion proto_version;
+ /* readdir mutex type used for 9P2000.u protocol variant */
+ CoMutex readdir_mutex_u;
+ /* readdir mutex type used for 9P2000.L protocol variant */
+ QemuMutex readdir_mutex_L;
} V9fsDir;
static inline void v9fs_readdir_lock(V9fsDir *dir)
{
- qemu_co_mutex_lock(&dir->readdir_mutex);
+ if (dir->proto_version == V9FS_PROTO_2000U) {
+ qemu_co_mutex_lock(&dir->readdir_mutex_u);
+ } else {
+ qemu_mutex_lock(&dir->readdir_mutex_L);
+ }
}
static inline void v9fs_readdir_unlock(V9fsDir *dir)
{
- qemu_co_mutex_unlock(&dir->readdir_mutex);
+ if (dir->proto_version == V9FS_PROTO_2000U) {
+ qemu_co_mutex_unlock(&dir->readdir_mutex_u);
+ } else {
+ qemu_mutex_unlock(&dir->readdir_mutex_L);
+ }
}
-static inline void v9fs_readdir_init(V9fsDir *dir)
+static inline void v9fs_readdir_init(P9ProtoVersion proto_version, V9fsDir *dir)
{
- qemu_co_mutex_init(&dir->readdir_mutex);
+ dir->proto_version = proto_version;
+ if (proto_version == V9FS_PROTO_2000U) {
+ qemu_co_mutex_init(&dir->readdir_mutex_u);
+ } else {
+ qemu_mutex_init(&dir->readdir_mutex_L);
+ }
}
/**