Coverage Report

Created: 2026-05-16 06:08

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/p9-0.3.2/src/protocol/messages.rs
Line
Count
Source
1
// Copyright 2018 The ChromiumOS Authors
2
// Use of this source code is governed by a BSD-style license that can be
3
// found in the LICENSE file.
4
5
use std::io;
6
use std::io::ErrorKind;
7
use std::io::Read;
8
use std::io::Write;
9
use std::mem;
10
use std::vec::Vec;
11
12
use p9_wire_format_derive::P9WireFormat;
13
14
use crate::protocol::wire_format::Data;
15
use crate::protocol::wire_format::P9String;
16
use crate::protocol::wire_format::WireFormat;
17
18
// Message type constants.  Taken from "include/net/9p/9p.h" in the linux kernel
19
// tree.  The protocol specifies each R* message to be the corresponding T*
20
// message plus one.
21
const TLERROR: u8 = 6;
22
const RLERROR: u8 = TLERROR + 1;
23
const TSTATFS: u8 = 8;
24
const RSTATFS: u8 = TSTATFS + 1;
25
const TLOPEN: u8 = 12;
26
const RLOPEN: u8 = TLOPEN + 1;
27
const TLCREATE: u8 = 14;
28
const RLCREATE: u8 = TLCREATE + 1;
29
const TSYMLINK: u8 = 16;
30
const RSYMLINK: u8 = TSYMLINK + 1;
31
const TMKNOD: u8 = 18;
32
const RMKNOD: u8 = TMKNOD + 1;
33
const TRENAME: u8 = 20;
34
const RRENAME: u8 = TRENAME + 1;
35
const TREADLINK: u8 = 22;
36
const RREADLINK: u8 = TREADLINK + 1;
37
const TGETATTR: u8 = 24;
38
const RGETATTR: u8 = TGETATTR + 1;
39
const TSETATTR: u8 = 26;
40
const RSETATTR: u8 = TSETATTR + 1;
41
const TXATTRWALK: u8 = 30;
42
const RXATTRWALK: u8 = TXATTRWALK + 1;
43
const TXATTRCREATE: u8 = 32;
44
const RXATTRCREATE: u8 = TXATTRCREATE + 1;
45
const TREADDIR: u8 = 40;
46
const RREADDIR: u8 = TREADDIR + 1;
47
const TFSYNC: u8 = 50;
48
const RFSYNC: u8 = TFSYNC + 1;
49
const TLOCK: u8 = 52;
50
const RLOCK: u8 = TLOCK + 1;
51
const TGETLOCK: u8 = 54;
52
const RGETLOCK: u8 = TGETLOCK + 1;
53
const TLINK: u8 = 70;
54
const RLINK: u8 = TLINK + 1;
55
const TMKDIR: u8 = 72;
56
const RMKDIR: u8 = TMKDIR + 1;
57
const TRENAMEAT: u8 = 74;
58
const RRENAMEAT: u8 = TRENAMEAT + 1;
59
const TUNLINKAT: u8 = 76;
60
const RUNLINKAT: u8 = TUNLINKAT + 1;
61
const TVERSION: u8 = 100;
62
const RVERSION: u8 = TVERSION + 1;
63
const TAUTH: u8 = 102;
64
const RAUTH: u8 = TAUTH + 1;
65
const TATTACH: u8 = 104;
66
const RATTACH: u8 = TATTACH + 1;
67
const _TERROR: u8 = 106;
68
const _RERROR: u8 = _TERROR + 1;
69
const TFLUSH: u8 = 108;
70
const RFLUSH: u8 = TFLUSH + 1;
71
const TWALK: u8 = 110;
72
const RWALK: u8 = TWALK + 1;
73
const _TOPEN: u8 = 112;
74
const _ROPEN: u8 = _TOPEN + 1;
75
const _TCREATE: u8 = 114;
76
const _RCREATE: u8 = _TCREATE + 1;
77
const TREAD: u8 = 116;
78
const RREAD: u8 = TREAD + 1;
79
const TWRITE: u8 = 118;
80
const RWRITE: u8 = TWRITE + 1;
81
const TCLUNK: u8 = 120;
82
const RCLUNK: u8 = TCLUNK + 1;
83
const TREMOVE: u8 = 122;
84
const RREMOVE: u8 = TREMOVE + 1;
85
const _TSTAT: u8 = 124;
86
const _RSTAT: u8 = _TSTAT + 1;
87
const _TWSTAT: u8 = 126;
88
const _RWSTAT: u8 = _TWSTAT + 1;
89
90
/// A message sent from a 9P client to a 9P server.
91
#[derive(Debug)]
92
pub enum Tmessage {
93
    Version(Tversion),
94
    Flush(Tflush),
95
    Walk(Twalk),
96
    Read(Tread),
97
    Write(Twrite),
98
    Clunk(Tclunk),
99
    Remove(Tremove),
100
    Attach(Tattach),
101
    Auth(Tauth),
102
    Statfs(Tstatfs),
103
    Lopen(Tlopen),
104
    Lcreate(Tlcreate),
105
    Symlink(Tsymlink),
106
    Mknod(Tmknod),
107
    Rename(Trename),
108
    Readlink(Treadlink),
109
    GetAttr(Tgetattr),
110
    SetAttr(Tsetattr),
111
    XattrWalk(Txattrwalk),
112
    XattrCreate(Txattrcreate),
113
    Readdir(Treaddir),
114
    Fsync(Tfsync),
115
    Lock(Tlock),
116
    GetLock(Tgetlock),
117
    Link(Tlink),
118
    Mkdir(Tmkdir),
119
    RenameAt(Trenameat),
120
    UnlinkAt(Tunlinkat),
121
}
122
123
#[derive(Debug)]
124
pub struct Tframe {
125
    pub tag: u16,
126
    pub msg: io::Result<Tmessage>,
127
}
128
129
impl WireFormat for Tframe {
130
0
    fn byte_size(&self) -> u32 {
131
0
        let msg = self
132
0
            .msg
133
0
            .as_ref()
134
0
            .expect("tried to encode Tframe with invalid msg");
135
0
        let msg_size = match msg {
136
0
            Tmessage::Version(ref version) => version.byte_size(),
137
0
            Tmessage::Flush(ref flush) => flush.byte_size(),
138
0
            Tmessage::Walk(ref walk) => walk.byte_size(),
139
0
            Tmessage::Read(ref read) => read.byte_size(),
140
0
            Tmessage::Write(ref write) => write.byte_size(),
141
0
            Tmessage::Clunk(ref clunk) => clunk.byte_size(),
142
0
            Tmessage::Remove(ref remove) => remove.byte_size(),
143
0
            Tmessage::Attach(ref attach) => attach.byte_size(),
144
0
            Tmessage::Auth(ref auth) => auth.byte_size(),
145
0
            Tmessage::Statfs(ref statfs) => statfs.byte_size(),
146
0
            Tmessage::Lopen(ref lopen) => lopen.byte_size(),
147
0
            Tmessage::Lcreate(ref lcreate) => lcreate.byte_size(),
148
0
            Tmessage::Symlink(ref symlink) => symlink.byte_size(),
149
0
            Tmessage::Mknod(ref mknod) => mknod.byte_size(),
150
0
            Tmessage::Rename(ref rename) => rename.byte_size(),
151
0
            Tmessage::Readlink(ref readlink) => readlink.byte_size(),
152
0
            Tmessage::GetAttr(ref getattr) => getattr.byte_size(),
153
0
            Tmessage::SetAttr(ref setattr) => setattr.byte_size(),
154
0
            Tmessage::XattrWalk(ref xattrwalk) => xattrwalk.byte_size(),
155
0
            Tmessage::XattrCreate(ref xattrcreate) => xattrcreate.byte_size(),
156
0
            Tmessage::Readdir(ref readdir) => readdir.byte_size(),
157
0
            Tmessage::Fsync(ref fsync) => fsync.byte_size(),
158
0
            Tmessage::Lock(ref lock) => lock.byte_size(),
159
0
            Tmessage::GetLock(ref getlock) => getlock.byte_size(),
160
0
            Tmessage::Link(ref link) => link.byte_size(),
161
0
            Tmessage::Mkdir(ref mkdir) => mkdir.byte_size(),
162
0
            Tmessage::RenameAt(ref renameat) => renameat.byte_size(),
163
0
            Tmessage::UnlinkAt(ref unlinkat) => unlinkat.byte_size(),
164
        };
165
166
        // size + type + tag + message size
167
0
        (mem::size_of::<u32>() + mem::size_of::<u8>() + mem::size_of::<u16>()) as u32 + msg_size
168
0
    }
169
170
0
    fn encode<W: Write>(&self, writer: &mut W) -> io::Result<()> {
171
0
        let msg = match self.msg.as_ref() {
172
0
            Ok(msg) => msg,
173
            Err(_) => {
174
0
                return Err(io::Error::new(
175
0
                    io::ErrorKind::InvalidData,
176
0
                    "tried to encode Tframe with invalid msg",
177
0
                ))
178
            }
179
        };
180
181
0
        self.byte_size().encode(writer)?;
182
183
0
        let ty = match msg {
184
0
            Tmessage::Version(_) => TVERSION,
185
0
            Tmessage::Flush(_) => TFLUSH,
186
0
            Tmessage::Walk(_) => TWALK,
187
0
            Tmessage::Read(_) => TREAD,
188
0
            Tmessage::Write(_) => TWRITE,
189
0
            Tmessage::Clunk(_) => TCLUNK,
190
0
            Tmessage::Remove(_) => TREMOVE,
191
0
            Tmessage::Attach(_) => TATTACH,
192
0
            Tmessage::Auth(_) => TAUTH,
193
0
            Tmessage::Statfs(_) => TSTATFS,
194
0
            Tmessage::Lopen(_) => TLOPEN,
195
0
            Tmessage::Lcreate(_) => TLCREATE,
196
0
            Tmessage::Symlink(_) => TSYMLINK,
197
0
            Tmessage::Mknod(_) => TMKNOD,
198
0
            Tmessage::Rename(_) => TRENAME,
199
0
            Tmessage::Readlink(_) => TREADLINK,
200
0
            Tmessage::GetAttr(_) => TGETATTR,
201
0
            Tmessage::SetAttr(_) => TSETATTR,
202
0
            Tmessage::XattrWalk(_) => TXATTRWALK,
203
0
            Tmessage::XattrCreate(_) => TXATTRCREATE,
204
0
            Tmessage::Readdir(_) => TREADDIR,
205
0
            Tmessage::Fsync(_) => TFSYNC,
206
0
            Tmessage::Lock(_) => TLOCK,
207
0
            Tmessage::GetLock(_) => TGETLOCK,
208
0
            Tmessage::Link(_) => TLINK,
209
0
            Tmessage::Mkdir(_) => TMKDIR,
210
0
            Tmessage::RenameAt(_) => TRENAMEAT,
211
0
            Tmessage::UnlinkAt(_) => TUNLINKAT,
212
        };
213
214
0
        ty.encode(writer)?;
215
0
        self.tag.encode(writer)?;
216
217
0
        match msg {
218
0
            Tmessage::Version(ref version) => version.encode(writer),
219
0
            Tmessage::Flush(ref flush) => flush.encode(writer),
220
0
            Tmessage::Walk(ref walk) => walk.encode(writer),
221
0
            Tmessage::Read(ref read) => read.encode(writer),
222
0
            Tmessage::Write(ref write) => write.encode(writer),
223
0
            Tmessage::Clunk(ref clunk) => clunk.encode(writer),
224
0
            Tmessage::Remove(ref remove) => remove.encode(writer),
225
0
            Tmessage::Attach(ref attach) => attach.encode(writer),
226
0
            Tmessage::Auth(ref auth) => auth.encode(writer),
227
0
            Tmessage::Statfs(ref statfs) => statfs.encode(writer),
228
0
            Tmessage::Lopen(ref lopen) => lopen.encode(writer),
229
0
            Tmessage::Lcreate(ref lcreate) => lcreate.encode(writer),
230
0
            Tmessage::Symlink(ref symlink) => symlink.encode(writer),
231
0
            Tmessage::Mknod(ref mknod) => mknod.encode(writer),
232
0
            Tmessage::Rename(ref rename) => rename.encode(writer),
233
0
            Tmessage::Readlink(ref readlink) => readlink.encode(writer),
234
0
            Tmessage::GetAttr(ref getattr) => getattr.encode(writer),
235
0
            Tmessage::SetAttr(ref setattr) => setattr.encode(writer),
236
0
            Tmessage::XattrWalk(ref xattrwalk) => xattrwalk.encode(writer),
237
0
            Tmessage::XattrCreate(ref xattrcreate) => xattrcreate.encode(writer),
238
0
            Tmessage::Readdir(ref readdir) => readdir.encode(writer),
239
0
            Tmessage::Fsync(ref fsync) => fsync.encode(writer),
240
0
            Tmessage::Lock(ref lock) => lock.encode(writer),
241
0
            Tmessage::GetLock(ref getlock) => getlock.encode(writer),
242
0
            Tmessage::Link(ref link) => link.encode(writer),
243
0
            Tmessage::Mkdir(ref mkdir) => mkdir.encode(writer),
244
0
            Tmessage::RenameAt(ref renameat) => renameat.encode(writer),
245
0
            Tmessage::UnlinkAt(ref unlinkat) => unlinkat.encode(writer),
246
        }
247
0
    }
248
249
4.20M
    fn decode<R: Read>(reader: &mut R) -> io::Result<Self> {
250
4.20M
        let byte_size: u32 = WireFormat::decode(reader)?;
251
252
        // byte_size includes the size of byte_size so remove that from the
253
        // expected length of the message.  Also make sure that byte_size is at least
254
        // that long to begin with.
255
4.19M
        if byte_size < mem::size_of::<u32>() as u32 {
256
287
            return Err(io::Error::new(
257
287
                ErrorKind::InvalidData,
258
287
                format!("byte_size(= {}) is less than 4 bytes", byte_size),
259
287
            ));
260
4.19M
        }
261
262
4.19M
        let reader = &mut reader.take((byte_size - mem::size_of::<u32>() as u32) as u64);
263
264
4.19M
        let mut ty = [0u8];
265
4.19M
        reader.read_exact(&mut ty)?;
266
267
4.19M
        let tag: u16 = WireFormat::decode(reader)?;
268
4.19M
        let msg = Self::decode_message(reader, ty[0]);
269
270
4.19M
        Ok(Tframe { tag, msg })
271
4.20M
    }
Unexecuted instantiation: <p9::protocol::messages::Tframe as p9::protocol::wire_format::WireFormat>::decode::<std::io::Take<&mut devices::virtio::descriptor_utils::Reader>>
<p9::protocol::messages::Tframe as p9::protocol::wire_format::WireFormat>::decode::<std::io::cursor::Cursor<&[u8]>>
Line
Count
Source
249
4.20M
    fn decode<R: Read>(reader: &mut R) -> io::Result<Self> {
250
4.20M
        let byte_size: u32 = WireFormat::decode(reader)?;
251
252
        // byte_size includes the size of byte_size so remove that from the
253
        // expected length of the message.  Also make sure that byte_size is at least
254
        // that long to begin with.
255
4.19M
        if byte_size < mem::size_of::<u32>() as u32 {
256
287
            return Err(io::Error::new(
257
287
                ErrorKind::InvalidData,
258
287
                format!("byte_size(= {}) is less than 4 bytes", byte_size),
259
287
            ));
260
4.19M
        }
261
262
4.19M
        let reader = &mut reader.take((byte_size - mem::size_of::<u32>() as u32) as u64);
263
264
4.19M
        let mut ty = [0u8];
265
4.19M
        reader.read_exact(&mut ty)?;
266
267
4.19M
        let tag: u16 = WireFormat::decode(reader)?;
268
4.19M
        let msg = Self::decode_message(reader, ty[0]);
269
270
4.19M
        Ok(Tframe { tag, msg })
271
4.20M
    }
272
}
273
274
impl Tframe {
275
4.19M
    fn decode_message<R: Read>(reader: &mut R, ty: u8) -> io::Result<Tmessage> {
276
4.19M
        match ty {
277
5.62k
            TVERSION => Ok(Tmessage::Version(WireFormat::decode(reader)?)),
278
9.90k
            TFLUSH => Ok(Tmessage::Flush(WireFormat::decode(reader)?)),
279
14.2k
            TWALK => Ok(Tmessage::Walk(WireFormat::decode(reader)?)),
280
173k
            TREAD => Ok(Tmessage::Read(WireFormat::decode(reader)?)),
281
60.5k
            TWRITE => Ok(Tmessage::Write(WireFormat::decode(reader)?)),
282
106k
            TCLUNK => Ok(Tmessage::Clunk(WireFormat::decode(reader)?)),
283
13.2k
            TREMOVE => Ok(Tmessage::Remove(WireFormat::decode(reader)?)),
284
15.6k
            TATTACH => Ok(Tmessage::Attach(WireFormat::decode(reader)?)),
285
24.1k
            TAUTH => Ok(Tmessage::Auth(WireFormat::decode(reader)?)),
286
32.7k
            TSTATFS => Ok(Tmessage::Statfs(WireFormat::decode(reader)?)),
287
111k
            TLOPEN => Ok(Tmessage::Lopen(WireFormat::decode(reader)?)),
288
25.2k
            TLCREATE => Ok(Tmessage::Lcreate(WireFormat::decode(reader)?)),
289
19.6k
            TSYMLINK => Ok(Tmessage::Symlink(WireFormat::decode(reader)?)),
290
62.8k
            TMKNOD => Ok(Tmessage::Mknod(WireFormat::decode(reader)?)),
291
11.3k
            TRENAME => Ok(Tmessage::Rename(WireFormat::decode(reader)?)),
292
12.4k
            TREADLINK => Ok(Tmessage::Readlink(WireFormat::decode(reader)?)),
293
26.4k
            TGETATTR => Ok(Tmessage::GetAttr(WireFormat::decode(reader)?)),
294
407k
            TSETATTR => Ok(Tmessage::SetAttr(WireFormat::decode(reader)?)),
295
17.7k
            TXATTRWALK => Ok(Tmessage::XattrWalk(WireFormat::decode(reader)?)),
296
45.1k
            TXATTRCREATE => Ok(Tmessage::XattrCreate(WireFormat::decode(reader)?)),
297
15.9k
            TREADDIR => Ok(Tmessage::Readdir(WireFormat::decode(reader)?)),
298
163k
            TFSYNC => Ok(Tmessage::Fsync(WireFormat::decode(reader)?)),
299
24.2k
            TLOCK => Ok(Tmessage::Lock(WireFormat::decode(reader)?)),
300
47.6k
            TGETLOCK => Ok(Tmessage::GetLock(WireFormat::decode(reader)?)),
301
5.81k
            TLINK => Ok(Tmessage::Link(WireFormat::decode(reader)?)),
302
17.0k
            TMKDIR => Ok(Tmessage::Mkdir(WireFormat::decode(reader)?)),
303
12.0k
            TRENAMEAT => Ok(Tmessage::RenameAt(WireFormat::decode(reader)?)),
304
13.3k
            TUNLINKAT => Ok(Tmessage::UnlinkAt(WireFormat::decode(reader)?)),
305
2.70M
            err => Err(io::Error::new(
306
2.70M
                ErrorKind::InvalidData,
307
2.70M
                format!("unknown message type {}", err),
308
2.70M
            )),
309
        }
310
4.19M
    }
Unexecuted instantiation: <p9::protocol::messages::Tframe>::decode_message::<std::io::Take<&mut std::io::Take<&mut devices::virtio::descriptor_utils::Reader>>>
<p9::protocol::messages::Tframe>::decode_message::<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>
Line
Count
Source
275
4.19M
    fn decode_message<R: Read>(reader: &mut R, ty: u8) -> io::Result<Tmessage> {
276
4.19M
        match ty {
277
5.62k
            TVERSION => Ok(Tmessage::Version(WireFormat::decode(reader)?)),
278
9.90k
            TFLUSH => Ok(Tmessage::Flush(WireFormat::decode(reader)?)),
279
14.2k
            TWALK => Ok(Tmessage::Walk(WireFormat::decode(reader)?)),
280
173k
            TREAD => Ok(Tmessage::Read(WireFormat::decode(reader)?)),
281
60.5k
            TWRITE => Ok(Tmessage::Write(WireFormat::decode(reader)?)),
282
106k
            TCLUNK => Ok(Tmessage::Clunk(WireFormat::decode(reader)?)),
283
13.2k
            TREMOVE => Ok(Tmessage::Remove(WireFormat::decode(reader)?)),
284
15.6k
            TATTACH => Ok(Tmessage::Attach(WireFormat::decode(reader)?)),
285
24.1k
            TAUTH => Ok(Tmessage::Auth(WireFormat::decode(reader)?)),
286
32.7k
            TSTATFS => Ok(Tmessage::Statfs(WireFormat::decode(reader)?)),
287
111k
            TLOPEN => Ok(Tmessage::Lopen(WireFormat::decode(reader)?)),
288
25.2k
            TLCREATE => Ok(Tmessage::Lcreate(WireFormat::decode(reader)?)),
289
19.6k
            TSYMLINK => Ok(Tmessage::Symlink(WireFormat::decode(reader)?)),
290
62.8k
            TMKNOD => Ok(Tmessage::Mknod(WireFormat::decode(reader)?)),
291
11.3k
            TRENAME => Ok(Tmessage::Rename(WireFormat::decode(reader)?)),
292
12.4k
            TREADLINK => Ok(Tmessage::Readlink(WireFormat::decode(reader)?)),
293
26.4k
            TGETATTR => Ok(Tmessage::GetAttr(WireFormat::decode(reader)?)),
294
407k
            TSETATTR => Ok(Tmessage::SetAttr(WireFormat::decode(reader)?)),
295
17.7k
            TXATTRWALK => Ok(Tmessage::XattrWalk(WireFormat::decode(reader)?)),
296
45.1k
            TXATTRCREATE => Ok(Tmessage::XattrCreate(WireFormat::decode(reader)?)),
297
15.9k
            TREADDIR => Ok(Tmessage::Readdir(WireFormat::decode(reader)?)),
298
163k
            TFSYNC => Ok(Tmessage::Fsync(WireFormat::decode(reader)?)),
299
24.2k
            TLOCK => Ok(Tmessage::Lock(WireFormat::decode(reader)?)),
300
47.6k
            TGETLOCK => Ok(Tmessage::GetLock(WireFormat::decode(reader)?)),
301
5.81k
            TLINK => Ok(Tmessage::Link(WireFormat::decode(reader)?)),
302
17.0k
            TMKDIR => Ok(Tmessage::Mkdir(WireFormat::decode(reader)?)),
303
12.0k
            TRENAMEAT => Ok(Tmessage::RenameAt(WireFormat::decode(reader)?)),
304
13.3k
            TUNLINKAT => Ok(Tmessage::UnlinkAt(WireFormat::decode(reader)?)),
305
2.70M
            err => Err(io::Error::new(
306
2.70M
                ErrorKind::InvalidData,
307
2.70M
                format!("unknown message type {}", err),
308
2.70M
            )),
309
        }
310
4.19M
    }
311
}
312
313
#[derive(Debug, P9WireFormat)]
314
pub struct Tversion {
315
    pub msize: u32,
316
    pub version: P9String,
317
}
318
319
#[derive(Debug, P9WireFormat)]
320
pub struct Tflush {
321
    pub oldtag: u16,
322
}
323
324
#[derive(Debug, P9WireFormat)]
325
pub struct Twalk {
326
    pub fid: u32,
327
    pub newfid: u32,
328
    pub wnames: Vec<P9String>,
329
}
330
331
#[derive(Debug, P9WireFormat)]
332
pub struct Tread {
333
    pub fid: u32,
334
    pub offset: u64,
335
    pub count: u32,
336
}
337
338
#[derive(Debug, P9WireFormat)]
339
pub struct Twrite {
340
    pub fid: u32,
341
    pub offset: u64,
342
    pub data: Data,
343
}
344
345
#[derive(Debug, P9WireFormat)]
346
pub struct Tclunk {
347
    pub fid: u32,
348
}
349
350
#[derive(Debug, P9WireFormat)]
351
pub struct Tremove {
352
    pub fid: u32,
353
}
354
355
#[derive(Debug, P9WireFormat)]
356
pub struct Tauth {
357
    pub afid: u32,
358
    pub uname: P9String,
359
    pub aname: P9String,
360
    pub n_uname: u32,
361
}
362
363
#[derive(Debug, P9WireFormat)]
364
pub struct Tattach {
365
    pub fid: u32,
366
    pub afid: u32,
367
    pub uname: P9String,
368
    pub aname: P9String,
369
    pub n_uname: u32,
370
}
371
372
#[derive(Debug, P9WireFormat)]
373
pub struct Tstatfs {
374
    pub fid: u32,
375
}
376
377
#[derive(Debug, P9WireFormat)]
378
pub struct Tlopen {
379
    pub fid: u32,
380
    pub flags: u32,
381
}
382
383
#[derive(Debug, P9WireFormat)]
384
pub struct Tlcreate {
385
    pub fid: u32,
386
    pub name: P9String,
387
    pub flags: u32,
388
    pub mode: u32,
389
    pub gid: u32,
390
}
391
392
#[derive(Debug, P9WireFormat)]
393
pub struct Tsymlink {
394
    pub fid: u32,
395
    pub name: P9String,
396
    pub symtgt: P9String,
397
    pub gid: u32,
398
}
399
400
#[derive(Debug, P9WireFormat)]
401
pub struct Tmknod {
402
    pub dfid: u32,
403
    pub name: P9String,
404
    pub mode: u32,
405
    pub major: u32,
406
    pub minor: u32,
407
    pub gid: u32,
408
}
409
410
#[derive(Debug, P9WireFormat)]
411
pub struct Trename {
412
    pub fid: u32,
413
    pub dfid: u32,
414
    pub name: P9String,
415
}
416
417
#[derive(Debug, P9WireFormat)]
418
pub struct Treadlink {
419
    pub fid: u32,
420
}
421
422
#[derive(Debug, P9WireFormat)]
423
pub struct Tgetattr {
424
    pub fid: u32,
425
    pub request_mask: u64,
426
}
427
428
#[derive(Debug, P9WireFormat)]
429
pub struct Tsetattr {
430
    pub fid: u32,
431
    pub valid: u32,
432
    pub mode: u32,
433
    pub uid: u32,
434
    pub gid: u32,
435
    pub size: u64,
436
    pub atime_sec: u64,
437
    pub atime_nsec: u64,
438
    pub mtime_sec: u64,
439
    pub mtime_nsec: u64,
440
}
441
442
#[derive(Debug, P9WireFormat)]
443
pub struct Txattrwalk {
444
    pub fid: u32,
445
    pub newfid: u32,
446
    pub name: P9String,
447
}
448
449
#[derive(Debug, P9WireFormat)]
450
pub struct Txattrcreate {
451
    pub fid: u32,
452
    pub name: P9String,
453
    pub attr_size: u64,
454
    pub flags: u32,
455
}
456
457
#[derive(Debug, P9WireFormat)]
458
pub struct Treaddir {
459
    pub fid: u32,
460
    pub offset: u64,
461
    pub count: u32,
462
}
463
464
#[derive(Debug, P9WireFormat)]
465
pub struct Tfsync {
466
    pub fid: u32,
467
    pub datasync: u32,
468
}
469
470
#[derive(Debug, P9WireFormat)]
471
pub struct Tlock {
472
    pub fid: u32,
473
    pub type_: u8,
474
    pub flags: u32,
475
    pub start: u64,
476
    pub length: u64,
477
    pub proc_id: u32,
478
    pub client_id: P9String,
479
}
480
481
#[derive(Debug, P9WireFormat)]
482
pub struct Tgetlock {
483
    pub fid: u32,
484
    pub type_: u8,
485
    pub start: u64,
486
    pub length: u64,
487
    pub proc_id: u32,
488
    pub client_id: P9String,
489
}
490
491
#[derive(Debug, P9WireFormat)]
492
pub struct Tlink {
493
    pub dfid: u32,
494
    pub fid: u32,
495
    pub name: P9String,
496
}
497
498
#[derive(Debug, P9WireFormat)]
499
pub struct Tmkdir {
500
    pub dfid: u32,
501
    pub name: P9String,
502
    pub mode: u32,
503
    pub gid: u32,
504
}
505
506
#[derive(Debug, P9WireFormat)]
507
pub struct Trenameat {
508
    pub olddirfid: u32,
509
    pub oldname: P9String,
510
    pub newdirfid: u32,
511
    pub newname: P9String,
512
}
513
514
#[derive(Debug, P9WireFormat)]
515
pub struct Tunlinkat {
516
    pub dirfd: u32,
517
    pub name: P9String,
518
    pub flags: u32,
519
}
520
521
/// A message sent from a 9P server to a 9P client in response to a request from
522
/// that client.  Encapsulates a full frame.
523
#[derive(Debug)]
524
pub enum Rmessage {
525
    Version(Rversion),
526
    Flush,
527
    Walk(Rwalk),
528
    Read(Rread),
529
    Write(Rwrite),
530
    Clunk,
531
    Remove,
532
    Attach(Rattach),
533
    Auth(Rauth),
534
    Statfs(Rstatfs),
535
    Lopen(Rlopen),
536
    Lcreate(Rlcreate),
537
    Symlink(Rsymlink),
538
    Mknod(Rmknod),
539
    Rename,
540
    Readlink(Rreadlink),
541
    GetAttr(Rgetattr),
542
    SetAttr,
543
    XattrWalk(Rxattrwalk),
544
    XattrCreate,
545
    Readdir(Rreaddir),
546
    Fsync,
547
    Lock(Rlock),
548
    GetLock(Rgetlock),
549
    Link,
550
    Mkdir(Rmkdir),
551
    RenameAt,
552
    UnlinkAt,
553
    Lerror(Rlerror),
554
}
555
556
#[derive(Debug)]
557
pub struct Rframe {
558
    pub tag: u16,
559
    pub msg: Rmessage,
560
}
561
562
impl WireFormat for Rframe {
563
0
    fn byte_size(&self) -> u32 {
564
0
        let msg_size = match self.msg {
565
0
            Rmessage::Version(ref version) => version.byte_size(),
566
0
            Rmessage::Flush => 0,
567
0
            Rmessage::Walk(ref walk) => walk.byte_size(),
568
0
            Rmessage::Read(ref read) => read.byte_size(),
569
0
            Rmessage::Write(ref write) => write.byte_size(),
570
0
            Rmessage::Clunk => 0,
571
0
            Rmessage::Remove => 0,
572
0
            Rmessage::Attach(ref attach) => attach.byte_size(),
573
0
            Rmessage::Auth(ref auth) => auth.byte_size(),
574
0
            Rmessage::Statfs(ref statfs) => statfs.byte_size(),
575
0
            Rmessage::Lopen(ref lopen) => lopen.byte_size(),
576
0
            Rmessage::Lcreate(ref lcreate) => lcreate.byte_size(),
577
0
            Rmessage::Symlink(ref symlink) => symlink.byte_size(),
578
0
            Rmessage::Mknod(ref mknod) => mknod.byte_size(),
579
0
            Rmessage::Rename => 0,
580
0
            Rmessage::Readlink(ref readlink) => readlink.byte_size(),
581
0
            Rmessage::GetAttr(ref getattr) => getattr.byte_size(),
582
0
            Rmessage::SetAttr => 0,
583
0
            Rmessage::XattrWalk(ref xattrwalk) => xattrwalk.byte_size(),
584
0
            Rmessage::XattrCreate => 0,
585
0
            Rmessage::Readdir(ref readdir) => readdir.byte_size(),
586
0
            Rmessage::Fsync => 0,
587
0
            Rmessage::Lock(ref lock) => lock.byte_size(),
588
0
            Rmessage::GetLock(ref getlock) => getlock.byte_size(),
589
0
            Rmessage::Link => 0,
590
0
            Rmessage::Mkdir(ref mkdir) => mkdir.byte_size(),
591
0
            Rmessage::RenameAt => 0,
592
0
            Rmessage::UnlinkAt => 0,
593
0
            Rmessage::Lerror(ref lerror) => lerror.byte_size(),
594
        };
595
596
        // size + type + tag + message size
597
0
        (mem::size_of::<u32>() + mem::size_of::<u8>() + mem::size_of::<u16>()) as u32 + msg_size
598
0
    }
599
600
0
    fn encode<W: Write>(&self, writer: &mut W) -> io::Result<()> {
601
0
        self.byte_size().encode(writer)?;
602
603
0
        let ty = match self.msg {
604
0
            Rmessage::Version(_) => RVERSION,
605
0
            Rmessage::Flush => RFLUSH,
606
0
            Rmessage::Walk(_) => RWALK,
607
0
            Rmessage::Read(_) => RREAD,
608
0
            Rmessage::Write(_) => RWRITE,
609
0
            Rmessage::Clunk => RCLUNK,
610
0
            Rmessage::Remove => RREMOVE,
611
0
            Rmessage::Attach(_) => RATTACH,
612
0
            Rmessage::Auth(_) => RAUTH,
613
0
            Rmessage::Statfs(_) => RSTATFS,
614
0
            Rmessage::Lopen(_) => RLOPEN,
615
0
            Rmessage::Lcreate(_) => RLCREATE,
616
0
            Rmessage::Symlink(_) => RSYMLINK,
617
0
            Rmessage::Mknod(_) => RMKNOD,
618
0
            Rmessage::Rename => RRENAME,
619
0
            Rmessage::Readlink(_) => RREADLINK,
620
0
            Rmessage::GetAttr(_) => RGETATTR,
621
0
            Rmessage::SetAttr => RSETATTR,
622
0
            Rmessage::XattrWalk(_) => RXATTRWALK,
623
0
            Rmessage::XattrCreate => RXATTRCREATE,
624
0
            Rmessage::Readdir(_) => RREADDIR,
625
0
            Rmessage::Fsync => RFSYNC,
626
0
            Rmessage::Lock(_) => RLOCK,
627
0
            Rmessage::GetLock(_) => RGETLOCK,
628
0
            Rmessage::Link => RLINK,
629
0
            Rmessage::Mkdir(_) => RMKDIR,
630
0
            Rmessage::RenameAt => RRENAMEAT,
631
0
            Rmessage::UnlinkAt => RUNLINKAT,
632
0
            Rmessage::Lerror(_) => RLERROR,
633
        };
634
635
0
        ty.encode(writer)?;
636
0
        self.tag.encode(writer)?;
637
638
0
        match self.msg {
639
0
            Rmessage::Version(ref version) => version.encode(writer),
640
0
            Rmessage::Flush => Ok(()),
641
0
            Rmessage::Walk(ref walk) => walk.encode(writer),
642
0
            Rmessage::Read(ref read) => read.encode(writer),
643
0
            Rmessage::Write(ref write) => write.encode(writer),
644
0
            Rmessage::Clunk => Ok(()),
645
0
            Rmessage::Remove => Ok(()),
646
0
            Rmessage::Attach(ref attach) => attach.encode(writer),
647
0
            Rmessage::Auth(ref auth) => auth.encode(writer),
648
0
            Rmessage::Statfs(ref statfs) => statfs.encode(writer),
649
0
            Rmessage::Lopen(ref lopen) => lopen.encode(writer),
650
0
            Rmessage::Lcreate(ref lcreate) => lcreate.encode(writer),
651
0
            Rmessage::Symlink(ref symlink) => symlink.encode(writer),
652
0
            Rmessage::Mknod(ref mknod) => mknod.encode(writer),
653
0
            Rmessage::Rename => Ok(()),
654
0
            Rmessage::Readlink(ref readlink) => readlink.encode(writer),
655
0
            Rmessage::GetAttr(ref getattr) => getattr.encode(writer),
656
0
            Rmessage::SetAttr => Ok(()),
657
0
            Rmessage::XattrWalk(ref xattrwalk) => xattrwalk.encode(writer),
658
0
            Rmessage::XattrCreate => Ok(()),
659
0
            Rmessage::Readdir(ref readdir) => readdir.encode(writer),
660
0
            Rmessage::Fsync => Ok(()),
661
0
            Rmessage::Lock(ref lock) => lock.encode(writer),
662
0
            Rmessage::GetLock(ref getlock) => getlock.encode(writer),
663
0
            Rmessage::Link => Ok(()),
664
0
            Rmessage::Mkdir(ref mkdir) => mkdir.encode(writer),
665
0
            Rmessage::RenameAt => Ok(()),
666
0
            Rmessage::UnlinkAt => Ok(()),
667
0
            Rmessage::Lerror(ref lerror) => lerror.encode(writer),
668
        }
669
0
    }
Unexecuted instantiation: <p9::protocol::messages::Rframe as p9::protocol::wire_format::WireFormat>::encode::<devices::virtio::descriptor_utils::Writer>
Unexecuted instantiation: <p9::protocol::messages::Rframe as p9::protocol::wire_format::WireFormat>::encode::<_>
670
671
0
    fn decode<R: Read>(reader: &mut R) -> io::Result<Self> {
672
0
        let byte_size: u32 = WireFormat::decode(reader)?;
673
674
        // byte_size includes the size of byte_size so remove that from the
675
        // expected length of the message.
676
0
        let reader = &mut reader.take((byte_size - mem::size_of::<u32>() as u32) as u64);
677
678
0
        let mut ty = [0u8];
679
0
        reader.read_exact(&mut ty)?;
680
681
0
        let tag: u16 = WireFormat::decode(reader)?;
682
683
0
        let msg = match ty[0] {
684
0
            RVERSION => Ok(Rmessage::Version(WireFormat::decode(reader)?)),
685
0
            RFLUSH => Ok(Rmessage::Flush),
686
0
            RWALK => Ok(Rmessage::Walk(WireFormat::decode(reader)?)),
687
0
            RREAD => Ok(Rmessage::Read(WireFormat::decode(reader)?)),
688
0
            RWRITE => Ok(Rmessage::Write(WireFormat::decode(reader)?)),
689
0
            RCLUNK => Ok(Rmessage::Clunk),
690
0
            RREMOVE => Ok(Rmessage::Remove),
691
0
            RATTACH => Ok(Rmessage::Attach(WireFormat::decode(reader)?)),
692
0
            RAUTH => Ok(Rmessage::Auth(WireFormat::decode(reader)?)),
693
0
            RSTATFS => Ok(Rmessage::Statfs(WireFormat::decode(reader)?)),
694
0
            RLOPEN => Ok(Rmessage::Lopen(WireFormat::decode(reader)?)),
695
0
            RLCREATE => Ok(Rmessage::Lcreate(WireFormat::decode(reader)?)),
696
0
            RSYMLINK => Ok(Rmessage::Symlink(WireFormat::decode(reader)?)),
697
0
            RMKNOD => Ok(Rmessage::Mknod(WireFormat::decode(reader)?)),
698
0
            RRENAME => Ok(Rmessage::Rename),
699
0
            RREADLINK => Ok(Rmessage::Readlink(WireFormat::decode(reader)?)),
700
0
            RGETATTR => Ok(Rmessage::GetAttr(WireFormat::decode(reader)?)),
701
0
            RSETATTR => Ok(Rmessage::SetAttr),
702
0
            RXATTRWALK => Ok(Rmessage::XattrWalk(WireFormat::decode(reader)?)),
703
0
            RXATTRCREATE => Ok(Rmessage::XattrCreate),
704
0
            RREADDIR => Ok(Rmessage::Readdir(WireFormat::decode(reader)?)),
705
0
            RFSYNC => Ok(Rmessage::Fsync),
706
0
            RLOCK => Ok(Rmessage::Lock(WireFormat::decode(reader)?)),
707
0
            RGETLOCK => Ok(Rmessage::GetLock(WireFormat::decode(reader)?)),
708
0
            RLINK => Ok(Rmessage::Link),
709
0
            RMKDIR => Ok(Rmessage::Mkdir(WireFormat::decode(reader)?)),
710
0
            RRENAMEAT => Ok(Rmessage::RenameAt),
711
0
            RUNLINKAT => Ok(Rmessage::UnlinkAt),
712
0
            RLERROR => Ok(Rmessage::Lerror(WireFormat::decode(reader)?)),
713
0
            err => Err(io::Error::new(
714
0
                ErrorKind::InvalidData,
715
0
                format!("unknown message type {}", err),
716
0
            )),
717
0
        }?;
718
719
0
        Ok(Rframe { tag, msg })
720
0
    }
721
}
722
723
#[derive(Debug, Copy, Clone, P9WireFormat)]
724
pub struct Qid {
725
    pub ty: u8,
726
    pub version: u32,
727
    pub path: u64,
728
}
729
730
#[derive(Debug, P9WireFormat)]
731
pub struct Dirent {
732
    pub qid: Qid,
733
    pub offset: u64,
734
    pub ty: u8,
735
    pub name: P9String,
736
}
737
738
#[derive(Debug, P9WireFormat)]
739
pub struct Rversion {
740
    pub msize: u32,
741
    pub version: P9String,
742
}
743
744
#[derive(Debug, P9WireFormat)]
745
pub struct Rwalk {
746
    pub wqids: Vec<Qid>,
747
}
748
749
#[derive(Debug, P9WireFormat)]
750
pub struct Rread {
751
    pub data: Data,
752
}
753
754
#[derive(Debug, P9WireFormat)]
755
pub struct Rwrite {
756
    pub count: u32,
757
}
758
759
#[derive(Debug, P9WireFormat)]
760
pub struct Rauth {
761
    pub aqid: Qid,
762
}
763
764
#[derive(Debug, P9WireFormat)]
765
pub struct Rattach {
766
    pub qid: Qid,
767
}
768
769
#[derive(Debug, P9WireFormat)]
770
pub struct Rlerror {
771
    pub ecode: u32,
772
}
773
774
#[derive(Debug, P9WireFormat)]
775
pub struct Rstatfs {
776
    pub ty: u32,
777
    pub bsize: u32,
778
    pub blocks: u64,
779
    pub bfree: u64,
780
    pub bavail: u64,
781
    pub files: u64,
782
    pub ffree: u64,
783
    pub fsid: u64,
784
    pub namelen: u32,
785
}
786
787
#[derive(Debug, P9WireFormat)]
788
pub struct Rlopen {
789
    pub qid: Qid,
790
    pub iounit: u32,
791
}
792
793
#[derive(Debug, P9WireFormat)]
794
pub struct Rlcreate {
795
    pub qid: Qid,
796
    pub iounit: u32,
797
}
798
799
#[derive(Debug, P9WireFormat)]
800
pub struct Rsymlink {
801
    pub qid: Qid,
802
}
803
804
#[derive(Debug, P9WireFormat)]
805
pub struct Rmknod {
806
    pub qid: Qid,
807
}
808
809
#[derive(Debug, P9WireFormat)]
810
pub struct Rreadlink {
811
    pub target: P9String,
812
}
813
814
#[derive(Debug, P9WireFormat)]
815
pub struct Rgetattr {
816
    pub valid: u64,
817
    pub qid: Qid,
818
    pub mode: u32,
819
    pub uid: u32,
820
    pub gid: u32,
821
    pub nlink: u64,
822
    pub rdev: u64,
823
    pub size: u64,
824
    pub blksize: u64,
825
    pub blocks: u64,
826
    pub atime_sec: u64,
827
    pub atime_nsec: u64,
828
    pub mtime_sec: u64,
829
    pub mtime_nsec: u64,
830
    pub ctime_sec: u64,
831
    pub ctime_nsec: u64,
832
    pub btime_sec: u64,
833
    pub btime_nsec: u64,
834
    pub gen: u64,
835
    pub data_version: u64,
836
}
837
838
#[derive(Debug, P9WireFormat)]
839
pub struct Rxattrwalk {
840
    pub size: u64,
841
}
842
843
#[derive(Debug, P9WireFormat)]
844
pub struct Rreaddir {
845
    pub data: Data,
846
}
847
848
#[derive(Debug, P9WireFormat)]
849
pub struct Rlock {
850
    pub status: u8,
851
}
852
853
#[derive(Debug, P9WireFormat)]
854
pub struct Rgetlock {
855
    pub type_: u8,
856
    pub start: u64,
857
    pub length: u64,
858
    pub proc_id: u32,
859
    pub client_id: P9String,
860
}
861
862
#[derive(Debug, P9WireFormat)]
863
pub struct Rmkdir {
864
    pub qid: Qid,
865
}