use std::fs::File;
use std::os::fd::{AsFd, AsRawFd};
use std::sync::{Arc, Weak};
#[repr(C)]
struct fuse_backing_map {
fd: u32,
flags: u32,
padding: u64,
}
const FUSE_DEV_IOC_MAGIC: u8 = 229;
const FUSE_DEV_IOC_BACKING_OPEN: u8 = 1;
const FUSE_DEV_IOC_BACKING_CLOSE: u8 = 2;
nix::ioctl_write_ptr!(
fuse_dev_ioc_backing_open,
FUSE_DEV_IOC_MAGIC,
FUSE_DEV_IOC_BACKING_OPEN,
fuse_backing_map
);
nix::ioctl_write_ptr!(
fuse_dev_ioc_backing_close,
FUSE_DEV_IOC_MAGIC,
FUSE_DEV_IOC_BACKING_CLOSE,
u32
);
#[derive(Debug)]
pub struct BackingId {
channel: Weak<File>,
pub(crate) backing_id: u32,
}
impl BackingId {
pub(crate) fn create(channel: &Arc<File>, fd: impl AsFd) -> std::io::Result<Self> {
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() {
let _ = unsafe { fuse_dev_ioc_backing_close(ch.as_raw_fd(), &self.backing_id) };
}
}
}