Skip to content

Commit 3e90366

Browse files
authored
Merge pull request #95 from openebs/error-stats
build: update spdk to error stats fix
2 parents 32147a2 + a4e4fa8 commit 3e90366

File tree

5 files changed

+78
-14
lines changed

5 files changed

+78
-14
lines changed

build.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -338,6 +338,7 @@ fn main() {
338338
.rustified_enum("spdk_nvme_path_status_code")
339339
.allowlist_type("spdk_ftl_mode")
340340
.rustified_enum("spdk_ftl_mode")
341+
.blocklist_type("spdk_bdev_io_error_stat")
341342
.allowlist_var("^NVMF.*")
342343
.allowlist_var("^SPDK.*")
343344
.allowlist_var("^spdk.*")

nix/pkgs/libspdk/default.nix

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,8 +92,8 @@ let
9292
# Derivation attributes
9393
#
9494
spdk = rec {
95-
rev = "f61f929aac373ed8af3a27a4bafa4cee046e1922";
96-
sha256 = "sha256-k+jezN1lGteu9AN7qozVyaTmtuYC7dgNRPDpSSYt2l8=";
95+
rev = "b78cde6f5cdd2f0f50810743d2865d7bee825ce4";
96+
sha256 = "sha256-GVWrKeYsKpro1XMYblky7ik6qw07aa/4CZqb9JU5cQU=";
9797
pname = "libspdk${nameSuffix}";
9898
version = "25.05-${lib.substring 0 7 rev}";
9999
name = "${pname}-${version}";

src/bdev_async.rs

Lines changed: 66 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,68 @@
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

44
use futures::channel::{oneshot, oneshot::Canceled};
55

66
use 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
2068
pub 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
);

src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ mod uuid;
5252

5353
pub use crate::{
5454
bdev::Bdev,
55-
bdev_async::{BdevAsyncCallContext, BdevStats},
55+
bdev_async::{BdevAsyncCallContext, BdevErrorStats, BdevStats, BdevStatsResetMode},
5656
bdev_builder::BdevBuilder,
5757
bdev_desc::{BdevDesc, BdevDescError, BdevEvent, LbaRange, LbaRangeLock},
5858
bdev_io::BdevIo,

src/libspdk/mod.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,14 @@ pub use spdk_nvme_media_error_status_code::*;
2020
pub use spdk_nvme_path_status_code::*;
2121
pub use spdk_nvme_status_code_type::*;
2222

23+
/// SPDK Bdev IO Error stats.
24+
#[repr(C)]
25+
#[derive(Debug, Default, Clone, Copy)]
26+
pub struct spdk_bdev_io_error_stat {
27+
/// A count of error status, indexed by the spdk status codes.
28+
pub error_status: [u32; -SPDK_MIN_BDEV_IO_STATUS as usize],
29+
}
30+
2331
/// Initializes a size field of a struct with struct's size_of.
2432
/// Other fields must be initialized explicitly.
2533
///

0 commit comments

Comments
 (0)