use std::os::fd::AsFd;
use std::os::unix::io::AsRawFd;
use std::sync::Arc;
use std::sync::Weak;
use log::error;
use crate::dev_fuse::DevFuse;
use crate::ll::ioctl::fuse_backing_map;
use crate::ll::ioctl::fuse_dev_ioc_backing_close;
use crate::ll::ioctl::fuse_dev_ioc_backing_open;
#[derive(Debug)]
pub struct BackingId {
pub(crate) channel: Weak<DevFuse>,
pub(crate) backing_id: u32,
}
impl BackingId {
pub(crate) fn create(channel: &Arc<DevFuse>, fd: impl AsFd) -> std::io::Result<Self> {
if !cfg!(target_os = "linux") {
return Err(std::io::Error::new(
std::io::ErrorKind::Other,
"backing IDs are only supported on Linux",
));
}
let map = fuse_backing_map {
fd: fd.as_fd().as_raw_fd() as u32,
flags: 0,
padding: 0,
};
let id = unsafe { fuse_dev_ioc_backing_open(channel.as_raw_fd(), &map) }?;
Ok(Self {
channel: Arc::downgrade(channel),
backing_id: id as u32,
})
}
}
impl Drop for BackingId {
fn drop(&mut self) {
if let Some(ch) = self.channel.upgrade() {
if let Err(e) = unsafe { fuse_dev_ioc_backing_close(ch.as_raw_fd(), &self.backing_id) }
{
error!("Failed to close backing fd: {e}");
}
}
}
}