use crate::{
bindings::{btrfs_ioctl_ino_lookup_args, btrfs_ioctl_ino_lookup_user_args},
util::btrfs_ioctl,
};
use std::{ffi::CStr, fs::File, io, os::unix::io::AsRawFd, path::Path};
pub fn treeid<P: AsRef<Path>>(pathname: P) -> io::Result<u64> {
let fd = File::open(pathname)?;
fd::treeid(fd.as_raw_fd())
}
pub fn path_as_str<'a, P: AsRef<Path>>(fs: P, objectid: u64, treeid: u64) -> io::Result<&'a str> {
let fd = File::open(fs)?;
fd::path_as_str(fd.as_raw_fd(), objectid, treeid)
}
pub fn path_as_bytes<'a, P: AsRef<Path>>(
fs: P,
objectid: u64,
treeid: u64,
) -> io::Result<&'a [u8]> {
let fd = File::open(fs)?;
fd::path_as_bytes(fd.as_raw_fd(), objectid, treeid)
}
pub fn user_path_as_str<'a, P: AsRef<Path>>(
pathname: P,
dirid: u64,
treeid: u64,
) -> io::Result<(&'a str, &'a str)> {
let fd = File::open(pathname)?;
fd::user_path_as_str(fd.as_raw_fd(), dirid, treeid)
}
pub fn user_path_as_bytes<'a, P: AsRef<Path>>(
pathname: P,
dirid: u64,
treeid: u64,
) -> io::Result<(&'a [u8], &'a [u8])> {
let fd = File::open(pathname)?;
fd::user_path_as_bytes(fd.as_raw_fd(), dirid, treeid)
}
pub mod fd {
use super::*;
use crate::bindings::{
BTRFS_FIRST_FREE_OBJECTID, BTRFS_IOC_INO_LOOKUP, BTRFS_IOC_INO_LOOKUP_USER,
};
use std::{
io::{Error, ErrorKind},
os::unix::io::RawFd,
};
pub fn treeid(fd: RawFd) -> io::Result<u64> {
let mut args = btrfs_ioctl_ino_lookup_args {
objectid: BTRFS_FIRST_FREE_OBJECTID,
..Default::default()
};
btrfs_ioctl(fd, BTRFS_IOC_INO_LOOKUP, &mut args)?;
Ok(args.treeid)
}
pub fn user_path_as_str<'a>(
fd: RawFd,
dirid: u64,
treeid: u64,
) -> io::Result<(&'a str, &'a str)> {
let mut args = btrfs_ioctl_ino_lookup_user_args {
dirid,
treeid,
..Default::default()
};
btrfs_ioctl(fd, BTRFS_IOC_INO_LOOKUP_USER, &mut args)?;
unsafe {
Ok((
match CStr::from_ptr(args.path.as_ptr().cast()).to_str() {
Ok(s) => s,
Err(_) => error!(InvalidData;),
},
match CStr::from_ptr(args.name.as_ptr().cast()).to_str() {
Ok(s) => s,
Err(_) => error!(InvalidData;),
},
))
}
}
pub fn user_path_as_bytes<'a>(
fd: RawFd,
dirid: u64,
treeid: u64,
) -> io::Result<(&'a [u8], &'a [u8])> {
let mut args = btrfs_ioctl_ino_lookup_user_args {
dirid,
treeid,
..Default::default()
};
btrfs_ioctl(fd, BTRFS_IOC_INO_LOOKUP_USER, &mut args)?;
unsafe {
Ok((
CStr::from_ptr(args.path.as_ptr().cast()).to_bytes(),
CStr::from_ptr(args.name.as_ptr().cast()).to_bytes(),
))
}
}
pub fn path_as_str<'a>(fd: RawFd, objectid: u64, treeid: u64) -> io::Result<&'a str> {
let mut args = btrfs_ioctl_ino_lookup_args {
treeid,
objectid,
..Default::default()
};
btrfs_ioctl(fd, BTRFS_IOC_INO_LOOKUP, &mut args)?;
unsafe {
CStr::from_ptr(args.name.as_ptr().cast())
.to_str()
.or(Err(Error::from(ErrorKind::InvalidData)))
}
}
pub fn path_as_bytes<'a>(fd: RawFd, objectid: u64, treeid: u64) -> io::Result<&'a [u8]> {
let mut args = btrfs_ioctl_ino_lookup_args {
treeid,
objectid,
..Default::default()
};
btrfs_ioctl(fd, BTRFS_IOC_INO_LOOKUP, &mut args)?;
unsafe { Ok(CStr::from_ptr(args.name.as_ptr().cast()).to_bytes()) }
}
}