Files
markbase/markbase-fuse/src/main.rs
Warren c2e3984ac8
Some checks failed
Test / test (push) Has been cancelled
Test / build (push) Has been cancelled
Phase 3完成:FUSE完整重构以支持fuse-t
核心成果:
- fuse-t库成功纳入项目(build.rs + Cargo.toml)
- fuse-backend-rs API完整实现(270行代码)
- FileSystem trait完整重写(lookup/getattr/read/readdir/open/release/opendir/releasedir/statfs)
- ZeroCopyWriter API正确集成(write_from方法)
- 服务循环正确实现(get_request + handle_message)

技术实现:
- 依赖:fuse-backend-rs(fusedev + fuse-t features)
- 链接:fuse-t库(pkg-config + DiskArbitration framework)
- 数据库:find_node_id_by_parent方法新增
- API:DirEntry/Entry/stat64正确使用
- 服务:FuseSession/FuseChannel正确集成

编译状态:
- 8警告,0错误
- 成功编译markbase-fuse库和main程序

状态:Phase 3完整实施完成
2026-06-13 16:33:13 +08:00

115 lines
3.0 KiB
Rust

use anyhow::Result;
use clap::{Parser, Subcommand};
use std::path::PathBuf;
use std::sync::Arc;
#[derive(Parser)]
#[command(name = "markbase-fuse", about = "MarkBase FUSE Mount Tool")]
struct Cli {
#[command(subcommand)]
command: Commands,
}
#[derive(Subcommand)]
enum Commands {
Mount {
#[arg(short, long)]
user: String,
#[arg(short, long)]
dir: PathBuf,
#[arg(short, long, default_value = "untitled folder")]
tree_type: String,
},
Unmount {
#[arg(short, long)]
dir: PathBuf,
},
}
fn main() -> Result<()> {
let cli = Cli::parse();
match cli.command {
Commands::Mount { user, dir, tree_type } => {
mount_user(user, tree_type, dir)?;
}
Commands::Unmount { dir } => {
unmount_user(dir)?;
}
}
Ok(())
}
fn mount_user(user: String, tree_type: String, dir: PathBuf) -> Result<()> {
use fuse_backend_rs::api::server::Server;
use fuse_backend_rs::transport::FuseSession;
use markbase_fuse::MarkBaseFs;
use std::env::current_dir;
let mut db_path = current_dir()?;
db_path.push(format!("data/users/{}.sqlite", user));
if !db_path.exists() {
return Err(anyhow::anyhow!(
"User database not found: {}",
db_path.display()
));
}
if !dir.exists() {
std::fs::create_dir_all(&dir)?;
}
println!("=== MarkBase FUSE (fuse-backend-rs + fuse-t) ===");
println!("User: {}", user);
println!("Tree Type: {}", tree_type);
println!("Database: {}", db_path.display());
println!("Mount point: {}", dir.display());
println!("");
let fs = MarkBaseFs::new(&db_path.to_string_lossy(), &tree_type)?;
let server = Arc::new(Server::new(fs));
let mut session = FuseSession::new(&dir, "markbase", "markbase-fuse", false)?;
session.mount()?;
println!("Mounted successfully!");
println!("Press Ctrl+C to unmount...");
let mut channel = session.new_channel()?;
let ebadf = std::io::Error::from_raw_os_error(libc::EBADF);
loop {
if let Some((reader, writer)) = channel.get_request()? {
if let Err(e) = server.handle_message(reader, writer.into(), None, None) {
match e {
fuse_backend_rs::Error::EncodeMessage(e) if e.kind() == std::io::ErrorKind::Other => {
break;
}
_ => {
eprintln!("Handling fuse message failed: {:?}", e);
continue;
}
}
}
} else {
println!("fuse server exits");
break;
}
}
session.umount()?;
println!("Unmounted successfully");
Ok(())
}
fn unmount_user(dir: PathBuf) -> Result<()> {
println!("Unmounting: {}", dir.display());
std::process::Command::new("umount").arg(&dir).status()?;
println!("Unmounted successfully");
Ok(())
}