1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
use std::ffi::CString;
use crate::{
IoCtx, RadosCompletion, Result,
error::{maybe_err, maybe_err_or_val},
librados::{rados_aio_getxattr, rados_getxattr},
};
impl IoCtx<'_> {
/// Blockingly get the value of extended attribute
/// `name` for object `object`, using a buffer of `buf_size`
/// bytes to store the result.
///
/// # Panics
/// This function panics of `object` or `name` have internal `0` bytes.
///
// TODO: what does this return if `buf_size` is too small?
pub fn get_xattr_blocking(&self, object: &str, name: &str, buf_size: usize) -> Result<Vec<u8>> {
let object = CString::new(object).expect("Object ID contained internal NUL");
let name = CString::new(name).expect("Name contained internal NUL");
let mut data_buf = vec![0u8; buf_size];
let len = maybe_err_or_val(unsafe {
rados_getxattr(
self.inner(),
object.as_ptr(),
name.as_ptr(),
data_buf.as_mut_ptr() as _,
data_buf.len(),
)
})?;
data_buf.truncate(len as _);
Ok(data_buf)
}
/// Get the value of extended attribute `name`
/// for object `object`, using a buffer of `buf_size`
/// bytes to store the result.
///
/// # Panics
/// This function panics of `object` or `name` have internal `0` bytes.
///
// TODO: what does this return if `buf_size` is too small?
pub async fn get_xattr(&self, object: &str, name: &str, buf_size: usize) -> Result<Vec<u8>> {
let object = CString::new(object).expect("Object ID contained internal NUL");
let name = CString::new(name).expect("Name contained internal NUL");
let data_buf = vec![0u8; buf_size];
// SAFETY: the passed-in closure returns `true` if and only
// if creation of the async operation succeeds.
let completion = unsafe {
RadosCompletion::new_with(false, data_buf, |completion, mut data_buf| {
// SAFETY: the values passed to this function are
// all pointers to pinned values that are available
// for the lifetime of `self`, which is also
maybe_err(rados_aio_getxattr(
self.inner(),
object.as_ptr(),
completion,
name.as_ptr(),
data_buf.as_mut_ptr() as _,
data_buf.len(),
))
})?
};
let (len, mut buf) = completion.wait_for().await?;
buf.truncate(len);
Ok(buf)
}
}