mod ioctl; use clap::Parser; use std::fs::File; use std::os::fd::AsRawFd; use std::path::{Path, PathBuf}; use std::sync::Arc; use log::LevelFilter; use users::{get_current_gid, get_current_uid}; use aya::AyaFS; use aya::block_device::BLOCK_SIZE; use aya::block_device::disk::Disk; use crate::ioctl::ioctl_blkgetsize64; #[derive(Parser, Debug)] #[command(author, version, about)] struct Args { block_device: Option, #[arg(short, long)] user_id: Option, #[arg(short, long)] group_id: Option, #[arg(short, action = clap::ArgAction::Count)] verbosity: u8, } fn get_device_size>(path: T) -> u64 { let device = File::options() .write(true) .open(path.as_ref()) .expect("Failed to open device."); let device_raw_fd = device.as_raw_fd(); let mut device_size = 0u64; let device_size_ptr = &mut device_size as *mut u64; unsafe { ioctl_blkgetsize64(device_raw_fd, device_size_ptr) .expect("ioctl exceptions occur."); } device_size } fn main() { let args = Args::parse(); let device_path = args.block_device .expect("Not device path specified."); let verbosity = args.verbosity; let uid = args.user_id.unwrap_or_else(get_current_uid); let gid = args.group_id.unwrap_or_else(get_current_gid); let log_level = match verbosity { 0 => LevelFilter::Error, 1 => LevelFilter::Warn, 2 => LevelFilter::Info, 3 => LevelFilter::Debug, _ => LevelFilter::Trace, }; env_logger::builder().filter_level(log_level).init(); let device_size = get_device_size(device_path.as_path()); let disk = Arc::new(Disk::new(device_path)); let mut fs = AyaFS::new( disk, device_size as usize / BLOCK_SIZE, uid, gid, ); fs.write_back(); }