vfs: improve _find() path handling
This commit is contained in:
parent
a126118589
commit
3aec9ce556
@ -540,49 +540,44 @@ impl IoContext {
|
||||
Ok((buffer, node.flatten_hardlink()?))
|
||||
}
|
||||
|
||||
fn _find(&self, mut at: NodeRef, path: &Path, follow_links: bool) -> Result<NodeRef, Error> {
|
||||
log::debug!("_find({path:?})");
|
||||
let mut element;
|
||||
let mut rest = path;
|
||||
fn _find(&self, mut at: NodeRef, mut path: &Path, follow_link: bool) -> Result<NodeRef, Error> {
|
||||
while !path.is_empty() {
|
||||
let (name, tail) = path.split_left();
|
||||
|
||||
loop {
|
||||
(element, rest) = rest.split_left();
|
||||
let name = match name {
|
||||
Path::SELF_NAME => {
|
||||
path = tail;
|
||||
continue;
|
||||
}
|
||||
Path::PARENT_NAME => {
|
||||
at = at.parent();
|
||||
if at.mountpoint_target().is_some() {
|
||||
// Just exited root -> mountpoint, go up to mountpoint's parent
|
||||
at = at.parent();
|
||||
}
|
||||
path = tail;
|
||||
continue;
|
||||
}
|
||||
name => name,
|
||||
};
|
||||
|
||||
if !at.is_directory() {
|
||||
log::info!("at is not a dir");
|
||||
return Err(Error::NotADirectory);
|
||||
}
|
||||
|
||||
match element {
|
||||
Path::PARENT_NAME => {
|
||||
at = at.parent();
|
||||
}
|
||||
Path::SELF_NAME => {}
|
||||
_ => break,
|
||||
}
|
||||
let access = self.check_access(&at, AccessMode::EXEC)?;
|
||||
let filename = Filename::new(name)?;
|
||||
let child = at.lookup_or_load(filename, access)?.flatten_hardlink()?;
|
||||
let follow_links = follow_link || !tail.is_empty();
|
||||
|
||||
let child = self._resolve(child, follow_links)?;
|
||||
|
||||
at = child;
|
||||
path = tail;
|
||||
}
|
||||
|
||||
let is_end = element.is_empty() && rest.is_empty();
|
||||
|
||||
at = self._resolve(at, follow_links || !is_end)?;
|
||||
|
||||
if !at.is_directory() {
|
||||
return Err(Error::NotADirectory);
|
||||
}
|
||||
|
||||
if element.is_empty() && rest.is_empty() {
|
||||
return Ok(at);
|
||||
}
|
||||
|
||||
let access = self.check_access(&at, AccessMode::EXEC)?;
|
||||
let filename = Filename::new(element)?;
|
||||
let node = at.lookup_or_load(filename, access)?.flatten_hardlink()?;
|
||||
let node = self._resolve(node, follow_links)?;
|
||||
|
||||
if rest.is_empty() {
|
||||
Ok(node.flatten_hardlink()?)
|
||||
} else {
|
||||
self._find(node, rest, follow_links)
|
||||
}
|
||||
at.flatten_hardlink()
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user