implemented rmdir
This commit is contained in:
parent
2ed107478e
commit
c9e8833ac6
4 changed files with 131 additions and 99 deletions
|
|
@ -1,6 +1,5 @@
|
|||
use std::ffi::c_int;
|
||||
use std::io::{Read, Write};
|
||||
use std::rc::Rc;
|
||||
use std::time::Duration;
|
||||
|
||||
use fat_bits::dir::DirEntry;
|
||||
|
|
@ -44,7 +43,8 @@ impl Filesystem for FatFuse {
|
|||
let Some(name) = name.to_str() else {
|
||||
// TODO: add proper handling of non-utf8 strings
|
||||
debug!("cannot convert OsStr {:?} to str", name);
|
||||
reply.error(ENOSYS);
|
||||
|
||||
reply.error(EINVAL);
|
||||
return;
|
||||
};
|
||||
|
||||
|
|
@ -62,28 +62,17 @@ impl Filesystem for FatFuse {
|
|||
|
||||
let parent_inode = parent_inode.borrow();
|
||||
|
||||
let dir_entry: DirEntry =
|
||||
match parent_inode
|
||||
.dir_iter(&self.fat_fs)
|
||||
.and_then(|mut dir_iter| {
|
||||
dir_iter
|
||||
.find(|dir_entry| &dir_entry.name_string() == name)
|
||||
.ok_or(ENOENT)
|
||||
}) {
|
||||
Ok(dir_entry) => dir_entry,
|
||||
Err(err) => {
|
||||
debug!("error: {}", err);
|
||||
reply.error(err);
|
||||
let dir_entry: DirEntry = match parent_inode.find_child_by_name(&self.fat_fs, name) {
|
||||
Ok(dir_entry) => dir_entry,
|
||||
Err(err) => {
|
||||
debug!("error: {}", err);
|
||||
reply.error(err);
|
||||
|
||||
return;
|
||||
}
|
||||
};
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
let inode = self.get_or_make_inode_by_dir_entry(
|
||||
&dir_entry,
|
||||
parent_inode.ino(),
|
||||
parent_inode.path(),
|
||||
);
|
||||
let inode = self.get_or_make_inode(&dir_entry, &parent_inode);
|
||||
|
||||
let mut inode = inode.borrow_mut();
|
||||
|
||||
|
|
@ -239,8 +228,39 @@ impl Filesystem for FatFuse {
|
|||
name: &std::ffi::OsStr,
|
||||
reply: fuser::ReplyEmpty,
|
||||
) {
|
||||
debug!("[Not Implemented] rmdir(parent: {:#x?}, name: {:?})", parent, name,);
|
||||
reply.error(ENOSYS);
|
||||
let Some(name) = name.to_str() else {
|
||||
// TODO: add proper handling of non-utf8 strings
|
||||
debug!("cannot convert OsStr {:?} to str", name);
|
||||
|
||||
reply.error(EINVAL);
|
||||
return;
|
||||
};
|
||||
|
||||
let Some(parent_inode) = self.get_inode(parent) else {
|
||||
debug!("parent inode {parent} does not exist");
|
||||
|
||||
reply.error(ENOENT);
|
||||
return;
|
||||
};
|
||||
|
||||
let dir_entry = match parent_inode.borrow().find_child_by_name(&self.fat_fs, name) {
|
||||
Ok(dir_entry) => dir_entry,
|
||||
Err(err) => {
|
||||
debug!("parent inode {parent} has no child {name}");
|
||||
|
||||
reply.error(err);
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
if let Err(err) = dir_entry.erase(&self.fat_fs) {
|
||||
debug!("error while erasing DirEntry: {err}");
|
||||
|
||||
reply.error(EIO);
|
||||
return;
|
||||
}
|
||||
|
||||
reply.ok();
|
||||
}
|
||||
|
||||
fn rename(
|
||||
|
|
@ -651,14 +671,10 @@ impl Filesystem for FatFuse {
|
|||
// also skip over `offset` entries
|
||||
let dirs: Vec<DirEntry> = dir_iter.skip(offset).collect();
|
||||
|
||||
let dir_ino = dir_inode.ino();
|
||||
let dir_path = dir_inode.path();
|
||||
|
||||
for dir_entry in dirs {
|
||||
let name = dir_entry.name_string();
|
||||
|
||||
let inode =
|
||||
self.get_or_make_inode_by_dir_entry(&dir_entry, dir_ino, Rc::clone(&dir_path));
|
||||
let inode = self.get_or_make_inode(&dir_entry, &dir_inode);
|
||||
|
||||
let inode = inode.borrow();
|
||||
|
||||
|
|
|
|||
|
|
@ -4,10 +4,10 @@ use std::time::SystemTime;
|
|||
|
||||
use chrono::{NaiveDateTime, NaiveTime};
|
||||
use fat_bits::FatFs;
|
||||
use fat_bits::dir::DirEntry;
|
||||
use fat_bits::dir::{DirEntry, DirIter};
|
||||
use fat_bits::iter::{ClusterChainReader, ClusterChainWriter};
|
||||
use fuser::FileAttr;
|
||||
use libc::{EISDIR, ENOTDIR};
|
||||
use libc::{EISDIR, ENOENT, ENOTDIR};
|
||||
use log::debug;
|
||||
use rand::{Rng, SeedableRng as _};
|
||||
|
||||
|
|
@ -311,7 +311,7 @@ impl Inode {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn dir_iter(&self, fat_fs: &FatFs) -> Result<impl Iterator<Item = DirEntry>, i32> {
|
||||
pub fn dir_iter<'a>(&'a self, fat_fs: &'a FatFs) -> Result<DirIter<'a>, i32> {
|
||||
if self.kind != Kind::Dir {
|
||||
return Err(ENOTDIR);
|
||||
}
|
||||
|
|
@ -325,6 +325,11 @@ impl Inode {
|
|||
Ok(fat_fs.dir_iter(self.first_cluster))
|
||||
}
|
||||
|
||||
pub fn find_child_by_name(&self, fat_fs: &FatFs, name: &str) -> Result<DirEntry, i32> {
|
||||
self.dir_iter(fat_fs)
|
||||
.and_then(|mut dir_iter| dir_iter.find_by_name(name).ok_or(ENOENT))
|
||||
}
|
||||
|
||||
pub fn file_reader<'a>(&'a self, fat_fs: &'a FatFs) -> Result<ClusterChainReader<'a>, i32> {
|
||||
if self.is_dir() {
|
||||
return Err(EISDIR);
|
||||
|
|
|
|||
|
|
@ -206,12 +206,9 @@ impl FatFuse {
|
|||
self.inode_table.get(&ino)
|
||||
}
|
||||
|
||||
fn get_or_make_inode_by_dir_entry(
|
||||
&mut self,
|
||||
dir_entry: &DirEntry,
|
||||
parent_ino: u64,
|
||||
parent_path: Rc<str>,
|
||||
) -> InodeRef {
|
||||
fn get_or_make_inode(&mut self, dir_entry: &DirEntry, parent: &Inode) -> InodeRef {
|
||||
// let parent = parent.borrow();
|
||||
|
||||
// try to find inode by first cluster first
|
||||
if dir_entry.first_cluster() != 0
|
||||
&& let Some(inode) = self.get_inode_by_first_cluster(dir_entry.first_cluster())
|
||||
|
|
@ -223,9 +220,9 @@ impl FatFuse {
|
|||
// mostly for empty files/directories which have a first cluster of 0
|
||||
|
||||
let path = {
|
||||
let mut path = parent_path.as_ref().to_owned();
|
||||
let mut path = parent.path().as_ref().to_owned();
|
||||
|
||||
if parent_ino != inode::ROOT_INO {
|
||||
if parent.ino() != inode::ROOT_INO {
|
||||
// root inode already has trailing slash
|
||||
path.push('/');
|
||||
}
|
||||
|
|
@ -242,9 +239,9 @@ impl FatFuse {
|
|||
// no inode found, make a new one
|
||||
let ino = self.next_ino();
|
||||
|
||||
let Some(parent_inode) = self.get_inode(parent_ino).cloned() else {
|
||||
let Some(parent_inode) = self.get_inode(parent.ino()).cloned() else {
|
||||
// TODO: what do we do here? should not happen
|
||||
panic!("parent_ino {} does not lead to inode", parent_ino);
|
||||
panic!("parent_ino {} does not lead to inode", parent.ino());
|
||||
};
|
||||
|
||||
let inode =
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue