pub struct DsmRange { /* private fields */ }Expand description
One DSM range entry. NVMe spec: each entry covers up to 4 GiB of LBAs.
Fields are private — construct via DsmRange::new (which takes a
1-based block count, matching the rest of this module’s I/O API)
and refine with DsmRange::with_context. This makes it impossible
to confuse the public 1-based count with the spec’s 0-based wire
encoding (which execute applies internally).
Implementations§
Source§impl DsmRange
impl DsmRange
Sourcepub fn new(slba: u64, nlb: u32) -> Self
pub fn new(slba: u64, nlb: u32) -> Self
Construct a range starting at slba covering nlb logical blocks.
nlb is 1-based (1 = a single LBA), consistent with the rest of
this module; it is decremented to the spec’s 0-based encoding when
the command is submitted. nlb of 0 is treated as 1.
Examples found in repository?
examples/io_smoke.rs (line 73)
19fn main() -> Result<(), Box<dyn std::error::Error>> {
20 let root = Root::scan()?;
21 let mut exercised = 0;
22
23 for host in root.hosts() {
24 for subsys in host.subsystems() {
25 for ctrl in subsys.controllers() {
26 let model = ctrl.model().unwrap_or("?").trim();
27 if model != QEMU_MODEL {
28 println!(
29 "skipping {}: model {model:?} != {QEMU_MODEL:?} (refusing on real hardware)",
30 ctrl.name()?
31 );
32 continue;
33 }
34
35 for ns in ctrl.namespaces() {
36 let lba_size = ns.lba_size();
37 println!(
38 "exercising {} (NSID {}, {} B LBAs)",
39 ns.name()?,
40 ns.nsid(),
41 lba_size
42 );
43
44 // ---- Write one LBA with a recognizable pattern -----
45 let mut pattern = vec![0u8; lba_size as usize];
46 for (i, b) in pattern.iter_mut().enumerate() {
47 *b = (i & 0xFF) as u8;
48 }
49 ns.write(0, 1, &pattern).fua().execute()?;
50 println!(" write ok");
51
52 // ---- Read it back ---------------------------------
53 let got = ns.read_to_vec(0, 1)?;
54 assert_eq!(got, pattern, "read did not return the bytes we wrote");
55 println!(" read ok (round-trip matches)");
56
57 // ---- Compare (should succeed) ---------------------
58 ns.compare(0, 1, &pattern).execute()?;
59 println!(" compare ok");
60
61 // ---- Verify (controller-side integrity check) -----
62 ns.verify(0, 1).execute()?;
63 println!(" verify ok");
64
65 // ---- Write zeroes over the LBA --------------------
66 ns.write_zeroes(0, 1).execute()?;
67 let zeroed = ns.read_to_vec(0, 1)?;
68 assert!(zeroed.iter().all(|&b| b == 0), "expected all-zero LBA");
69 println!(" write_zeroes ok");
70
71 // ---- DSM deallocate (TRIM) ------------------------
72 ns.dsm(DsmAttr::DEALLOCATE)
73 .ranges(&[DsmRange::new(0, 1)])
74 .execute()?;
75 println!(" dsm(deallocate) ok");
76
77 // ---- Flush ----------------------------------------
78 ns.flush()?;
79 println!(" flush ok");
80
81 exercised += 1;
82 }
83 }
84 }
85 }
86
87 if exercised == 0 {
88 println!("(no QEMU virtual NVMe controllers found)");
89 } else {
90 println!("\nall I/O commands exercised on {exercised} namespace(s)");
91 }
92 Ok(())
93}Sourcepub fn with_context(self, context: u32) -> Self
pub fn with_context(self, context: u32) -> Self
Attach DSM context-attribute bits (frequency / latency / access-pattern hints — see the NVMe spec figure on DSM context attributes).
Trait Implementations§
Auto Trait Implementations§
impl Freeze for DsmRange
impl RefUnwindSafe for DsmRange
impl Send for DsmRange
impl Sync for DsmRange
impl Unpin for DsmRange
impl UnsafeUnpin for DsmRange
impl UnwindSafe for DsmRange
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more