1- /// ! Asynchronous methods of `Bdev<>` wrapper.
2- use std:: os:: raw:: c_void;
1+ //! Asynchronous methods of `Bdev<>` wrapper.
2+ use std:: { ops :: Deref , os:: raw:: c_void} ;
33
44use futures:: channel:: { oneshot, oneshot:: Canceled } ;
55
66use crate :: {
77 error:: { SpdkError :: BdevUnregisterFailed , SpdkResult } ,
88 ffihelper:: { cb_arg, done_errno_cb, errno_error, errno_result_from_i32, ErrnoResult } ,
99 libspdk:: {
10- bdev_reset_device_stat, spdk_bdev, spdk_bdev_get_device_stat, spdk_bdev_io_stat ,
11- spdk_bdev_unregister , SPDK_BDEV_RESET_STAT_ALL , SPDK_BDEV_RESET_STAT_NONE ,
10+ bdev_reset_device_stat, spdk_bdev, spdk_bdev_get_device_stat, spdk_bdev_io_error_stat ,
11+ spdk_bdev_io_stat , spdk_bdev_unregister ,
1212 } ,
1313 Bdev , BdevOps ,
1414} ;
1515
16- /// TODO
17- pub type BdevStats = spdk_bdev_io_stat ;
16+ /// Wrapper for [`spdk_bdev_io_error_stat`].
17+ pub type BdevErrorStats = Box < spdk_bdev_io_error_stat > ;
18+
19+ /// Wrapper for [`spdk_bdev_io_stat`].
20+ /// # Safety
21+ /// Don't attempt to copy and rebox the error stats point without ensuring it's erased first.
22+ /// This can be done via [`Self::take_error_stats`].
23+ pub struct BdevStats ( spdk_bdev_io_stat ) ;
24+ impl Deref for BdevStats {
25+ type Target = spdk_bdev_io_stat ;
26+ fn deref ( & self ) -> & Self :: Target {
27+ & self . 0
28+ }
29+ }
30+ impl Drop for BdevStats {
31+ fn drop ( & mut self ) {
32+ if !self . 0 . io_error . is_null ( ) {
33+ unsafe {
34+ drop ( Box :: from_raw ( self . 0 . io_error ) ) ;
35+ }
36+ }
37+ }
38+ }
39+ impl BdevStats {
40+ /// Take the errors stats [`spdk_bdev_io_error_stat`] from the total stats.
41+ pub fn take_error_stats ( & mut self ) -> Option < BdevErrorStats > {
42+ if self . 0 . io_error . is_null ( ) {
43+ return None ;
44+ }
45+ let errors = self . io_error ;
46+ self . 0 . io_error = std:: ptr:: null_mut ( ) ;
47+ Some ( unsafe { Box :: from_raw ( errors) } )
48+ }
49+ }
50+
51+ /// Bdev Stat reset mode.
52+ pub enum BdevStatsResetMode {
53+ All ,
54+ MaxMin ,
55+ Errors ,
56+ }
57+ impl From < BdevStatsResetMode > for crate :: libspdk:: spdk_bdev_reset_stat_mode {
58+ fn from ( value : BdevStatsResetMode ) -> Self {
59+ match value {
60+ BdevStatsResetMode :: All => crate :: libspdk:: SPDK_BDEV_RESET_STAT_ALL ,
61+ BdevStatsResetMode :: MaxMin => crate :: libspdk:: SPDK_BDEV_RESET_STAT_MAXMIN ,
62+ BdevStatsResetMode :: Errors => crate :: libspdk:: SPDK_BDEV_RESET_STAT_ERROR ,
63+ }
64+ }
65+ }
1866
1967/// TODO
2068pub struct BdevAsyncCallContext {
@@ -76,8 +124,15 @@ where
76124 }
77125
78126 /// Get bdev IOStats or errno value in case of an error.
79- pub async fn stats_async ( & self ) -> ErrnoResult < BdevStats > {
127+ pub async fn stats_async ( & self , errors : bool ) -> ErrnoResult < BdevStats > {
80128 let mut stat: spdk_bdev_io_stat = unsafe { std:: mem:: zeroed ( ) } ;
129+ if errors {
130+ let io_err = Box :: new ( spdk_bdev_io_error_stat:: default ( ) ) ;
131+ unsafe {
132+ stat. io_error = Box :: into_raw ( io_err) ;
133+ }
134+ }
135+
81136 let ( s, r) = oneshot:: channel :: < i32 > ( ) ;
82137
83138 // This will iterate over I/O channels and call async callback when
@@ -86,26 +141,26 @@ where
86141 spdk_bdev_get_device_stat (
87142 self . as_inner_ptr ( ) ,
88143 & mut stat as * mut _ ,
89- SPDK_BDEV_RESET_STAT_NONE ,
144+ crate :: libspdk :: SPDK_BDEV_RESET_STAT_NONE ,
90145 Some ( inner_stats_callback) ,
91146 cb_arg ( s) ,
92147 ) ;
93148 }
94149
95150 let errno = r. await . expect ( "Cancellation is not supported" ) ;
96- errno_result_from_i32 ( stat, errno)
151+ errno_result_from_i32 ( BdevStats ( stat) , errno)
97152 }
98153
99154 /// This function resets all stat counters for a given Bdev.
100155 /// Returns Errno in case of an error.
101- pub async fn stats_reset_async ( & self ) -> ErrnoResult < ( ) > {
156+ pub async fn stats_reset_async ( & self , reset_mode : BdevStatsResetMode ) -> ErrnoResult < ( ) > {
102157 let ( s, r) = oneshot:: channel :: < i32 > ( ) ;
103158 // This will iterate over I/O channels to reset IOStats and call async
104159 // callback when done.
105160 unsafe {
106161 bdev_reset_device_stat (
107162 self . as_inner_ptr ( ) ,
108- SPDK_BDEV_RESET_STAT_ALL ,
163+ reset_mode . into ( ) ,
109164 Some ( inner_stats_reset_callback) ,
110165 cb_arg ( s) ,
111166 ) ;
0 commit comments