use crate::bindings::{
btrfs_ioctl_get_subvol_info_args, btrfs_root_item, BTRFS_PATH_NAME_MAX, BTRFS_SUBVOL_NAME_MAX,
};
use std::{
io,
path::{Component, MAIN_SEPARATOR},
ptr::addr_of_mut,
};
macro_rules! copy_bytes_to_c_char_array {
($b:expr, $len:expr) => {{
let mut uninit = ::std::mem::MaybeUninit::<[::libc::c_char; $len]>::uninit();
let p = uninit.as_mut_ptr().cast::<::libc::c_char>();
unsafe {
$b.as_ptr().copy_to_nonoverlapping(p.cast(), $b.len());
p.add($b.len()).write(0);
uninit.assume_init()
}
}};
}
pub(crate) fn vol_args_name_from_bytes(bytes: &[u8]) -> [libc::c_char; BTRFS_PATH_NAME_MAX + 1] {
copy_bytes_to_c_char_array!(bytes, BTRFS_PATH_NAME_MAX + 1)
}
pub(crate) fn vol_args_v2_name_from_bytes(
bytes: &[u8],
) -> [libc::c_char; BTRFS_SUBVOL_NAME_MAX as usize + 1] {
copy_bytes_to_c_char_array!(bytes, BTRFS_SUBVOL_NAME_MAX as usize + 1)
}
pub(crate) fn vol_args_v2_name_from_str_checked(
name: &str,
) -> io::Result<[libc::c_char; BTRFS_SUBVOL_NAME_MAX as usize + 1]> {
if name == Component::CurDir.as_os_str() || name == Component::ParentDir.as_os_str() {
error!(AlreadyExists)
} else if name.is_empty() || name.contains(MAIN_SEPARATOR) {
error!(InvalidInput)
}
Ok(vol_args_v2_name_from_bytes(name.as_bytes()))
}
pub(crate) fn root_item_to_subvol_info_args(
dest: *mut btrfs_ioctl_get_subvol_info_args,
src: &btrfs_root_item,
) {
unsafe {
addr_of_mut!((*dest).generation).write(u64::from_le(src.generation));
addr_of_mut!((*dest).flags).write(u64::from_le(src.flags));
addr_of_mut!((*dest).uuid).write(src.uuid);
addr_of_mut!((*dest).parent_uuid).write(src.parent_uuid);
addr_of_mut!((*dest).received_uuid).write(src.received_uuid);
addr_of_mut!((*dest).ctransid).write(u64::from_le(src.ctransid));
addr_of_mut!((*dest).otransid).write(u64::from_le(src.otransid));
addr_of_mut!((*dest).stransid).write(u64::from_le(src.stransid));
addr_of_mut!((*dest).rtransid).write(u64::from_le(src.rtransid));
addr_of_mut!((*dest).ctime.sec).write(u64::from_le(src.ctime.sec));
addr_of_mut!((*dest).ctime.nsec).write(u32::from_le(src.ctime.nsec));
addr_of_mut!((*dest).otime.sec).write(u64::from_le(src.otime.sec));
addr_of_mut!((*dest).otime.nsec).write(u32::from_le(src.otime.nsec));
addr_of_mut!((*dest).stime.sec).write(u64::from_le(src.stime.sec));
addr_of_mut!((*dest).stime.nsec).write(u32::from_le(src.stime.nsec));
addr_of_mut!((*dest).rtime.sec).write(u64::from_le(src.rtime.sec));
addr_of_mut!((*dest).rtime.nsec).write(u32::from_le(src.rtime.nsec));
}
}