1use crate::error::GlueError;
2use crate::BtrfsUtilError;
3use crate::Result;
4
5#[cfg(feature = "enable-glue-errors")]
6use std::convert::Into;
7use std::convert::TryFrom;
8use std::ffi::CStr;
9use std::os::raw::c_char;
10
11use thiserror::Error;
12
13pub(crate) type LibErrorCode = u32;
17
18#[derive(Clone, Debug, Eq, Error, PartialEq)]
22pub enum LibError {
23 #[error("Success")]
25 Ok = btrfsutil_sys::btrfs_util_error_BTRFS_UTIL_OK as isize,
26 #[error("Stop iteration")]
28 StopIteration = btrfsutil_sys::btrfs_util_error_BTRFS_UTIL_ERROR_STOP_ITERATION as isize,
29 #[error("Cannot allocate memory")]
31 NoMemory = btrfsutil_sys::btrfs_util_error_BTRFS_UTIL_ERROR_NO_MEMORY as isize,
32 #[error("Invalid argument")]
34 InvalidArgument = btrfsutil_sys::btrfs_util_error_BTRFS_UTIL_ERROR_INVALID_ARGUMENT as isize,
35 #[error("Not a Btrfs filesystem")]
37 NotBtrfs = btrfsutil_sys::btrfs_util_error_BTRFS_UTIL_ERROR_NOT_BTRFS as isize,
38 #[error("Not a Btrfs subvolume")]
40 NotSubvolume = btrfsutil_sys::btrfs_util_error_BTRFS_UTIL_ERROR_NOT_SUBVOLUME as isize,
41 #[error("Subvolume not found")]
43 SubvolumeNotFound =
44 btrfsutil_sys::btrfs_util_error_BTRFS_UTIL_ERROR_SUBVOLUME_NOT_FOUND as isize,
45 #[error("Could not open")]
47 OpenFailed = btrfsutil_sys::btrfs_util_error_BTRFS_UTIL_ERROR_OPEN_FAILED as isize,
48 #[error("Could not rmdir")]
50 RmdirFailed = btrfsutil_sys::btrfs_util_error_BTRFS_UTIL_ERROR_RMDIR_FAILED as isize,
51 #[error("Could not unlink")]
53 UnlinkFailed = btrfsutil_sys::btrfs_util_error_BTRFS_UTIL_ERROR_UNLINK_FAILED as isize,
54 #[error("Could not stat")]
56 StatFailed = btrfsutil_sys::btrfs_util_error_BTRFS_UTIL_ERROR_STAT_FAILED as isize,
57 #[error("Could not statfs")]
59 StatfsFailed = btrfsutil_sys::btrfs_util_error_BTRFS_UTIL_ERROR_STATFS_FAILED as isize,
60 #[error("Could not search B-tree")]
62 SearchFailed = btrfsutil_sys::btrfs_util_error_BTRFS_UTIL_ERROR_SEARCH_FAILED as isize,
63 #[error("Could not lookup inode")]
65 InoLookupFailed = btrfsutil_sys::btrfs_util_error_BTRFS_UTIL_ERROR_INO_LOOKUP_FAILED as isize,
66 #[error("Could not get subvolume flags")]
68 SubvolGetflagsFailed =
69 btrfsutil_sys::btrfs_util_error_BTRFS_UTIL_ERROR_SUBVOL_GETFLAGS_FAILED as isize,
70 #[error("Could not set subvolume flags")]
72 SubvolSetflagsFailed =
73 btrfsutil_sys::btrfs_util_error_BTRFS_UTIL_ERROR_SUBVOL_SETFLAGS_FAILED as isize,
74 #[error("Could not create subvolume")]
76 SubvolCreateFailed =
77 btrfsutil_sys::btrfs_util_error_BTRFS_UTIL_ERROR_SUBVOL_CREATE_FAILED as isize,
78 #[error("Could not create snapshot")]
80 SnapCreateFailed = btrfsutil_sys::btrfs_util_error_BTRFS_UTIL_ERROR_SNAP_CREATE_FAILED as isize,
81 #[error("Could not destroy subvolume/snapshot")]
83 SnapDestroyFailed =
84 btrfsutil_sys::btrfs_util_error_BTRFS_UTIL_ERROR_SNAP_DESTROY_FAILED as isize,
85 #[error("Could not set default subvolume")]
87 DefaultSubvolFailed =
88 btrfsutil_sys::btrfs_util_error_BTRFS_UTIL_ERROR_DEFAULT_SUBVOL_FAILED as isize,
89 #[error("Could not sync filesystem")]
91 SyncFailed = btrfsutil_sys::btrfs_util_error_BTRFS_UTIL_ERROR_SYNC_FAILED as isize,
92 #[error("Could not start filesystem sync")]
94 StartSyncFailed = btrfsutil_sys::btrfs_util_error_BTRFS_UTIL_ERROR_START_SYNC_FAILED as isize,
95 #[error("Could not wait for filesystem sync")]
97 WaitSyncFailed = btrfsutil_sys::btrfs_util_error_BTRFS_UTIL_ERROR_WAIT_SYNC_FAILED as isize,
98 #[error("Could not get subvolume information with BTRFS_IOC_GET_SUBVOL_INFO")]
100 GetSubvolInfoFailed =
101 btrfsutil_sys::btrfs_util_error_BTRFS_UTIL_ERROR_GET_SUBVOL_INFO_FAILED as isize,
102 #[error("Could not get rootref information with BTRFS_IOC_GET_SUBVOL_ROOTREF")]
104 GetSubvolRootrefFailed =
105 btrfsutil_sys::btrfs_util_error_BTRFS_UTIL_ERROR_GET_SUBVOL_ROOTREF_FAILED as isize,
106 #[error("Could not resolve subvolume path with BTRFS_IOC_INO_LOOKUP_USER")]
108 InoLookupUserFailed =
109 btrfsutil_sys::btrfs_util_error_BTRFS_UTIL_ERROR_INO_LOOKUP_USER_FAILED as isize,
110 #[error("Could not get filesystem information")]
112 FsInfoFailed = btrfsutil_sys::btrfs_util_error_BTRFS_UTIL_ERROR_FS_INFO_FAILED as isize,
113}
114
115impl LibError {
116 pub fn strerror(&self) -> Result<&'static str> {
128 let err_str_ptr: *const c_char;
129
130 let errno = self.clone() as LibErrorCode;
131 unsafe {
132 err_str_ptr = btrfsutil_sys::btrfs_util_strerror(errno);
133 }
134
135 glue_error!(err_str_ptr.is_null(), GlueError::NullPointerReceived);
136
137 let cstr: &CStr = unsafe { CStr::from_ptr(err_str_ptr) };
138 match cstr.to_str() {
139 Ok(val) => Ok(val),
140 Err(e) => glue_error!(GlueError::Utf8Error(e)),
141 }
142 }
143}
144
145impl TryFrom<LibErrorCode> for LibError {
146 type Error = BtrfsUtilError;
147 fn try_from(errno: LibErrorCode) -> Result<Self> {
148 glue_error!(errno > 26, GlueError::UnknownErrno(errno));
149 match errno {
150 btrfsutil_sys::btrfs_util_error_BTRFS_UTIL_OK => Ok(LibError::Ok),
151 btrfsutil_sys::btrfs_util_error_BTRFS_UTIL_ERROR_STOP_ITERATION => {
152 Ok(LibError::StopIteration)
153 }
154 btrfsutil_sys::btrfs_util_error_BTRFS_UTIL_ERROR_NO_MEMORY => Ok(LibError::NoMemory),
155 btrfsutil_sys::btrfs_util_error_BTRFS_UTIL_ERROR_INVALID_ARGUMENT => {
156 Ok(LibError::InvalidArgument)
157 }
158 btrfsutil_sys::btrfs_util_error_BTRFS_UTIL_ERROR_NOT_BTRFS => Ok(LibError::NotBtrfs),
159 btrfsutil_sys::btrfs_util_error_BTRFS_UTIL_ERROR_NOT_SUBVOLUME => {
160 Ok(LibError::NotSubvolume)
161 }
162 btrfsutil_sys::btrfs_util_error_BTRFS_UTIL_ERROR_SUBVOLUME_NOT_FOUND => {
163 Ok(LibError::SubvolumeNotFound)
164 }
165 btrfsutil_sys::btrfs_util_error_BTRFS_UTIL_ERROR_OPEN_FAILED => {
166 Ok(LibError::OpenFailed)
167 }
168 btrfsutil_sys::btrfs_util_error_BTRFS_UTIL_ERROR_RMDIR_FAILED => {
169 Ok(LibError::RmdirFailed)
170 }
171 btrfsutil_sys::btrfs_util_error_BTRFS_UTIL_ERROR_UNLINK_FAILED => {
172 Ok(LibError::UnlinkFailed)
173 }
174 btrfsutil_sys::btrfs_util_error_BTRFS_UTIL_ERROR_STAT_FAILED => {
175 Ok(LibError::StatFailed)
176 }
177 btrfsutil_sys::btrfs_util_error_BTRFS_UTIL_ERROR_STATFS_FAILED => {
178 Ok(LibError::StatfsFailed)
179 }
180 btrfsutil_sys::btrfs_util_error_BTRFS_UTIL_ERROR_SEARCH_FAILED => {
181 Ok(LibError::SearchFailed)
182 }
183 btrfsutil_sys::btrfs_util_error_BTRFS_UTIL_ERROR_INO_LOOKUP_FAILED => {
184 Ok(LibError::InoLookupFailed)
185 }
186 btrfsutil_sys::btrfs_util_error_BTRFS_UTIL_ERROR_SUBVOL_GETFLAGS_FAILED => {
187 Ok(LibError::SubvolGetflagsFailed)
188 }
189 btrfsutil_sys::btrfs_util_error_BTRFS_UTIL_ERROR_SUBVOL_SETFLAGS_FAILED => {
190 Ok(LibError::SubvolSetflagsFailed)
191 }
192 btrfsutil_sys::btrfs_util_error_BTRFS_UTIL_ERROR_SUBVOL_CREATE_FAILED => {
193 Ok(LibError::SubvolCreateFailed)
194 }
195 btrfsutil_sys::btrfs_util_error_BTRFS_UTIL_ERROR_SNAP_CREATE_FAILED => {
196 Ok(LibError::SnapCreateFailed)
197 }
198 btrfsutil_sys::btrfs_util_error_BTRFS_UTIL_ERROR_SNAP_DESTROY_FAILED => {
199 Ok(LibError::SnapDestroyFailed)
200 }
201 btrfsutil_sys::btrfs_util_error_BTRFS_UTIL_ERROR_DEFAULT_SUBVOL_FAILED => {
202 Ok(LibError::DefaultSubvolFailed)
203 }
204 btrfsutil_sys::btrfs_util_error_BTRFS_UTIL_ERROR_SYNC_FAILED => {
205 Ok(LibError::SyncFailed)
206 }
207 btrfsutil_sys::btrfs_util_error_BTRFS_UTIL_ERROR_START_SYNC_FAILED => {
208 Ok(LibError::StartSyncFailed)
209 }
210 btrfsutil_sys::btrfs_util_error_BTRFS_UTIL_ERROR_WAIT_SYNC_FAILED => {
211 Ok(LibError::WaitSyncFailed)
212 }
213 btrfsutil_sys::btrfs_util_error_BTRFS_UTIL_ERROR_GET_SUBVOL_INFO_FAILED => {
214 Ok(LibError::GetSubvolInfoFailed)
215 }
216 btrfsutil_sys::btrfs_util_error_BTRFS_UTIL_ERROR_GET_SUBVOL_ROOTREF_FAILED => {
217 Ok(LibError::GetSubvolRootrefFailed)
218 }
219 btrfsutil_sys::btrfs_util_error_BTRFS_UTIL_ERROR_INO_LOOKUP_USER_FAILED => {
220 Ok(LibError::InoLookupUserFailed)
221 }
222 btrfsutil_sys::btrfs_util_error_BTRFS_UTIL_ERROR_FS_INFO_FAILED => {
223 Ok(LibError::FsInfoFailed)
224 }
225 _ => glue_error!(GlueError::UnknownErrno(errno)),
226 }
227 }
228}
229
230#[cfg(feature = "enable-glue-errors")]
231impl Into<BtrfsUtilError> for LibError {
232 fn into(self) -> BtrfsUtilError {
233 BtrfsUtilError::Lib(self)
234 }
235}