Update redox-path
This commit is contained in:
Generated
+3
-2
@@ -555,9 +555,9 @@ checksum = "384c2842d4e069d5ccacf5fe1dca4ef8d07a5444329715f0fc3c61813502d4d1"
|
||||
|
||||
[[package]]
|
||||
name = "redox-path"
|
||||
version = "0.3.1"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "436d45c2b6a5b159d43da708e62b25be3a4a3d5550d654b72216ade4c4bfd717"
|
||||
checksum = "54ec1b67c01c63545205ea6d218b336751399f0d8974c1a635c28604bedb81bc"
|
||||
|
||||
[[package]]
|
||||
name = "redox-scheme"
|
||||
@@ -602,6 +602,7 @@ dependencies = [
|
||||
"redox-scheme",
|
||||
"redox_syscall",
|
||||
"seahash",
|
||||
"smallvec",
|
||||
"termion",
|
||||
"uuid",
|
||||
"xts-mode",
|
||||
|
||||
+3
-1
@@ -58,6 +58,7 @@ parse-size = { version = "1", optional = true }
|
||||
range-tree = { version = "0.1", optional = true }
|
||||
redox_syscall = "0.9.0"
|
||||
seahash = { version = "4.1.0", default-features = false }
|
||||
smallvec = { version = "1.15.2", optional = true }
|
||||
termion = { version = "4", optional = true }
|
||||
uuid = { version = "1.4", default-features = false }
|
||||
xts-mode = { version = "0.5", default-features = false }
|
||||
@@ -79,6 +80,7 @@ std = [
|
||||
"uuid/v4",
|
||||
"redox_syscall/std",
|
||||
"redox-scheme",
|
||||
"smallvec",
|
||||
]
|
||||
|
||||
[target.'cfg(not(target_os = "redox"))'.dependencies]
|
||||
@@ -86,7 +88,7 @@ fuser = { version = "0.16", optional = true }
|
||||
|
||||
[target.'cfg(target_os = "redox")'.dependencies]
|
||||
libredox = { version = "0.1.18", optional = true }
|
||||
redox-path = "0.3.0"
|
||||
redox-path = "0.4.0"
|
||||
redox-scheme = { version = "0.11.2", optional = true }
|
||||
|
||||
[lints.rust]
|
||||
|
||||
+149
-197
@@ -6,7 +6,11 @@ use std::sync::atomic::{AtomicUsize, Ordering};
|
||||
use std::time::{SystemTime, UNIX_EPOCH};
|
||||
|
||||
use libredox::Fd;
|
||||
use redox_path::RedoxReference;
|
||||
use redox_path::RedoxScheme;
|
||||
use redox_path::RedoxStr;
|
||||
use redox_scheme::{scheme::SchemeSync, CallerCtx, OpenResult, SendFdRequest, Socket};
|
||||
use smallvec::SmallVec;
|
||||
use syscall::data::{Stat, StatVfs, StdFsCallMeta, TimeSpec};
|
||||
use syscall::dirent::DirentBuf;
|
||||
use syscall::error::{
|
||||
@@ -22,10 +26,7 @@ use syscall::FobtainFdFlags;
|
||||
use syscall::FsCall;
|
||||
use syscall::MunmapFlags;
|
||||
|
||||
use redox_path::{
|
||||
canonicalize_to_standard, canonicalize_using_cwd, canonicalize_using_scheme, scheme_path,
|
||||
RedoxPath,
|
||||
};
|
||||
use redox_path::RedoxPath;
|
||||
|
||||
use crate::{Disk, FileSystem, Node, Transaction, TreeData, TreePtr, BLOCK_SIZE};
|
||||
|
||||
@@ -64,7 +65,7 @@ impl<D: Disk> Handle<D> {
|
||||
}
|
||||
|
||||
pub struct FileScheme<'sock, D: Disk> {
|
||||
scheme_name: String,
|
||||
scheme_name: RedoxScheme<'sock>,
|
||||
mounted_path: String,
|
||||
pub(crate) fs: FileSystem<D>,
|
||||
socket: &'sock Socket,
|
||||
@@ -86,7 +87,8 @@ impl<'sock, D: Disk> FileScheme<'sock, D> {
|
||||
socket: &'sock Socket,
|
||||
) -> Result<FileScheme<'sock, D>> {
|
||||
Ok(FileScheme {
|
||||
scheme_name,
|
||||
scheme_name: RedoxScheme::new(scheme_name)
|
||||
.expect("scheme name for FileScheme is not valid"),
|
||||
mounted_path,
|
||||
fs,
|
||||
socket,
|
||||
@@ -104,24 +106,23 @@ impl<'sock, D: Disk> FileScheme<'sock, D> {
|
||||
})
|
||||
}
|
||||
|
||||
fn resolve_symlink(
|
||||
scheme_name: &str,
|
||||
/// Resolve a symbolic link of given `node`. `full_path` must be non-canonicalized path from root node.
|
||||
fn resolve_symlink<'a>(
|
||||
scheme_name: &RedoxScheme<'sock>,
|
||||
tx: &mut Transaction<D>,
|
||||
uid: u32,
|
||||
gid: u32,
|
||||
full_path: &str,
|
||||
full_path: RedoxReference<'a>,
|
||||
node: TreeData<Node>,
|
||||
nodes: &mut Vec<(TreeData<Node>, String)>,
|
||||
) -> Result<String> {
|
||||
nodes: &mut SmallVec<[(TreeData<Node>, String); 16]>,
|
||||
) -> Result<RedoxReference<'a>> {
|
||||
let atime = SystemTime::now().duration_since(UNIX_EPOCH).unwrap();
|
||||
|
||||
// symbolic link is relative to this part of the url
|
||||
let mut working_dir =
|
||||
dirname(full_path).unwrap_or(scheme_path(scheme_name).ok_or(Error::new(EINVAL))?);
|
||||
let mut working_dir = full_path.dirname();
|
||||
// node of the link
|
||||
let mut node = node;
|
||||
|
||||
for _ in 0..32 {
|
||||
for _ in 0..64 {
|
||||
// XXX What should the limit be?
|
||||
assert!(node.data().is_symlink());
|
||||
let mut buf = [0; 4096];
|
||||
@@ -133,18 +134,20 @@ impl<'sock, D: Disk> FileScheme<'sock, D> {
|
||||
atime.subsec_nanos(),
|
||||
)?;
|
||||
|
||||
let target = canonicalize_to_standard(
|
||||
Some(&working_dir),
|
||||
str::from_utf8(&buf[..count]).or(Err(Error::new(EINVAL)))?,
|
||||
)
|
||||
.ok_or(Error::new(EINVAL))?;
|
||||
let target_as_path = RedoxPath::from_absolute(&target).ok_or(Error::new(EINVAL))?;
|
||||
|
||||
let (scheme, reference) = target_as_path.as_parts().ok_or(Error::new(EINVAL))?;
|
||||
if scheme.as_ref() != scheme_name {
|
||||
return Err(Error::new(EXDEV));
|
||||
}
|
||||
let target_reference = reference.to_string();
|
||||
let path = str::from_utf8(&buf[..count]).or(Err(Error::new(EINVAL)))?;
|
||||
let path = RedoxStr::new(path).ok_or(Error::new(EINVAL))?;
|
||||
let target_reference = match path {
|
||||
RedoxStr::Absolute(redox_path) => {
|
||||
if redox_path
|
||||
.get_scheme()
|
||||
.is_some_and(|s| s.as_ref() != scheme_name.as_ref())
|
||||
{
|
||||
return Err(Error::new(EXDEV));
|
||||
}
|
||||
redox_path.to_reference()
|
||||
}
|
||||
RedoxStr::Relative(redox_reference) => working_dir.join_checked(redox_reference),
|
||||
};
|
||||
|
||||
nodes.clear();
|
||||
if let Some((next_node, next_node_name)) = Self::path_nodes(
|
||||
@@ -158,10 +161,10 @@ impl<'sock, D: Disk> FileScheme<'sock, D> {
|
||||
)? {
|
||||
if !next_node.data().is_symlink() {
|
||||
nodes.push((next_node, next_node_name));
|
||||
return Ok(target_reference);
|
||||
return Ok(target_reference.into_owned());
|
||||
}
|
||||
node = next_node;
|
||||
working_dir = dirname(&target).ok_or(Error::new(EINVAL))?.to_string();
|
||||
working_dir = target_reference.dirname()
|
||||
} else {
|
||||
return Err(Error::new(ENOENT));
|
||||
}
|
||||
@@ -180,29 +183,32 @@ impl<'sock, D: Disk> FileScheme<'sock, D> {
|
||||
return Ok(len);
|
||||
}
|
||||
|
||||
fn open(&mut self, url: &str, flags: usize, ctx: &CallerCtx) -> Result<OpenResult> {
|
||||
fn open(
|
||||
&mut self,
|
||||
url: RedoxReference<'_>,
|
||||
flags: usize,
|
||||
ctx: &CallerCtx,
|
||||
) -> Result<OpenResult> {
|
||||
self.open_internal(TreePtr::root(), url, flags, ctx)
|
||||
}
|
||||
|
||||
fn open_internal(
|
||||
&mut self,
|
||||
start_ptr: TreePtr<Node>,
|
||||
url: &str,
|
||||
path: RedoxReference<'_>,
|
||||
flags: usize,
|
||||
ctx: &CallerCtx,
|
||||
) -> Result<OpenResult> {
|
||||
let CallerCtx { uid, gid, .. } = *ctx;
|
||||
|
||||
let path = url.trim_matches('/');
|
||||
|
||||
// println!("Open '{}' {:X}", &path, flags);
|
||||
|
||||
//TODO: try to move things into one transaction
|
||||
let scheme_name = &self.scheme_name;
|
||||
let mut nodes = Vec::new();
|
||||
let mut nodes = SmallVec::new();
|
||||
let node_opt = self
|
||||
.fs
|
||||
.tx(|tx| Self::path_nodes(scheme_name, tx, start_ptr, path, uid, gid, &mut nodes))?;
|
||||
.tx(|tx| Self::path_nodes(scheme_name, tx, start_ptr, &path, uid, gid, &mut nodes))?;
|
||||
let parent_ptr_opt = nodes.last().map(|x| x.0.ptr());
|
||||
let handle: Handle<D> = match node_opt {
|
||||
Some((node, _node_name)) => {
|
||||
@@ -257,21 +263,19 @@ impl<'sock, D: Disk> FileScheme<'sock, D> {
|
||||
&& !(flags & O_STAT == O_STAT && flags & O_NOFOLLOW == O_NOFOLLOW)
|
||||
&& flags & O_SYMLINK != O_SYMLINK
|
||||
{
|
||||
let mut resolve_nodes = Vec::new();
|
||||
let full_path =
|
||||
canonicalize_using_scheme(scheme_name, url).ok_or(Error::new(EINVAL))?;
|
||||
let mut resolve_nodes = SmallVec::new();
|
||||
let resolved = self.fs.tx(|tx| {
|
||||
Self::resolve_symlink(
|
||||
scheme_name,
|
||||
tx,
|
||||
uid,
|
||||
gid,
|
||||
&full_path,
|
||||
path,
|
||||
node,
|
||||
&mut resolve_nodes,
|
||||
)
|
||||
})?;
|
||||
return self.open(&resolved, flags, ctx);
|
||||
return self.open(resolved, flags, ctx);
|
||||
} else if !node.data().is_symlink() && flags & O_SYMLINK == O_SYMLINK {
|
||||
return Err(Error::new(EINVAL));
|
||||
} else {
|
||||
@@ -315,79 +319,64 @@ impl<'sock, D: Disk> FileScheme<'sock, D> {
|
||||
}
|
||||
}
|
||||
None => {
|
||||
if flags & O_CREAT == O_CREAT {
|
||||
let mut last_part = String::new();
|
||||
for part in path.split('/') {
|
||||
if !part.is_empty() {
|
||||
last_part = part.to_string();
|
||||
}
|
||||
}
|
||||
if !last_part.is_empty() {
|
||||
if let Some((parent, _parent_name)) = nodes.last() {
|
||||
if !parent.data().permission(uid, gid, Node::MODE_WRITE) {
|
||||
// println!("dir not writable {:o}", parent.1.mode);
|
||||
return Err(Error::new(EACCES));
|
||||
}
|
||||
|
||||
let dir = flags & O_DIRECTORY == O_DIRECTORY;
|
||||
let mode_type = if dir {
|
||||
Node::MODE_DIR
|
||||
} else if flags & O_SYMLINK == O_SYMLINK {
|
||||
Node::MODE_SYMLINK
|
||||
} else {
|
||||
Node::MODE_FILE
|
||||
};
|
||||
|
||||
let node_ptr = self.fs.tx(|tx| {
|
||||
let ctime = SystemTime::now().duration_since(UNIX_EPOCH).unwrap();
|
||||
let mut node = tx.create_node(
|
||||
parent.ptr(),
|
||||
&last_part,
|
||||
mode_type as u16 | (flags as u16 & Node::MODE_PERM),
|
||||
ctime.as_secs(),
|
||||
ctime.subsec_nanos(),
|
||||
)?;
|
||||
let node_ptr = node.ptr();
|
||||
if node.data().uid() != uid || node.data().gid() != gid {
|
||||
node.data_mut().set_uid(uid);
|
||||
node.data_mut().set_gid(gid);
|
||||
tx.sync_tree(node)?;
|
||||
}
|
||||
Ok(node_ptr)
|
||||
})?;
|
||||
|
||||
if dir {
|
||||
Handle::ResourceDir((
|
||||
DirResource::new(
|
||||
path.to_string(),
|
||||
parent_ptr_opt,
|
||||
node_ptr,
|
||||
None,
|
||||
uid,
|
||||
),
|
||||
PhantomData,
|
||||
))
|
||||
} else {
|
||||
Handle::ResourceFile((
|
||||
FileResource::new(
|
||||
path.to_string(),
|
||||
parent_ptr_opt,
|
||||
node_ptr,
|
||||
flags,
|
||||
uid,
|
||||
),
|
||||
PhantomData,
|
||||
))
|
||||
}
|
||||
} else {
|
||||
return Err(Error::new(EPERM));
|
||||
}
|
||||
} else {
|
||||
return Err(Error::new(EPERM));
|
||||
}
|
||||
} else {
|
||||
if flags & O_CREAT != O_CREAT {
|
||||
return Err(Error::new(ENOENT));
|
||||
}
|
||||
let mut last_part = String::new();
|
||||
for part in path.as_ref().split('/') {
|
||||
if !part.is_empty() {
|
||||
last_part = part.to_string();
|
||||
}
|
||||
}
|
||||
if last_part.is_empty() {
|
||||
return Err(Error::new(EPERM));
|
||||
}
|
||||
let Some((parent, _parent_name)) = nodes.last() else {
|
||||
return Err(Error::new(EPERM));
|
||||
};
|
||||
if !parent.data().permission(uid, gid, Node::MODE_WRITE) {
|
||||
// println!("dir not writable {:o}", parent.1.mode);
|
||||
return Err(Error::new(EACCES));
|
||||
}
|
||||
|
||||
let dir = flags & O_DIRECTORY == O_DIRECTORY;
|
||||
let mode_type = if dir {
|
||||
Node::MODE_DIR
|
||||
} else if flags & O_SYMLINK == O_SYMLINK {
|
||||
Node::MODE_SYMLINK
|
||||
} else {
|
||||
Node::MODE_FILE
|
||||
};
|
||||
|
||||
let node_ptr = self.fs.tx(|tx| {
|
||||
let ctime = SystemTime::now().duration_since(UNIX_EPOCH).unwrap();
|
||||
let mut node = tx.create_node(
|
||||
parent.ptr(),
|
||||
&last_part,
|
||||
mode_type as u16 | (flags as u16 & Node::MODE_PERM),
|
||||
ctime.as_secs(),
|
||||
ctime.subsec_nanos(),
|
||||
)?;
|
||||
let node_ptr = node.ptr();
|
||||
if node.data().uid() != uid || node.data().gid() != gid {
|
||||
node.data_mut().set_uid(uid);
|
||||
node.data_mut().set_gid(gid);
|
||||
tx.sync_tree(node)?;
|
||||
}
|
||||
Ok(node_ptr)
|
||||
})?;
|
||||
|
||||
if dir {
|
||||
Handle::ResourceDir((
|
||||
DirResource::new(path.to_string(), parent_ptr_opt, node_ptr, None, uid),
|
||||
PhantomData,
|
||||
))
|
||||
} else {
|
||||
Handle::ResourceFile((
|
||||
FileResource::new(path.to_string(), parent_ptr_opt, node_ptr, flags, uid),
|
||||
PhantomData,
|
||||
))
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -416,7 +405,7 @@ impl<'sock, D: Disk> FileScheme<'sock, D> {
|
||||
fn unlink_internal(
|
||||
&mut self,
|
||||
start_ptr: TreePtr<Node>,
|
||||
path: &str,
|
||||
path: &RedoxReference<'_>,
|
||||
flags: usize,
|
||||
uid: u32,
|
||||
gid: u32,
|
||||
@@ -424,7 +413,7 @@ impl<'sock, D: Disk> FileScheme<'sock, D> {
|
||||
let scheme_name = &self.scheme_name;
|
||||
|
||||
let unlink_result = self.fs.tx(|tx| {
|
||||
let mut nodes = Vec::new();
|
||||
let mut nodes = SmallVec::new();
|
||||
|
||||
let Some((child, child_name)) =
|
||||
Self::path_nodes(scheme_name, tx, start_ptr, path, uid, gid, &mut nodes)?
|
||||
@@ -485,15 +474,16 @@ impl<'sock, D: Disk> FileScheme<'sock, D> {
|
||||
}
|
||||
|
||||
fn path_nodes(
|
||||
scheme_name: &str,
|
||||
scheme_name: &RedoxScheme<'sock>,
|
||||
tx: &mut Transaction<D>,
|
||||
start_ptr: TreePtr<Node>,
|
||||
path: &str,
|
||||
path: &RedoxReference<'_>,
|
||||
uid: u32,
|
||||
gid: u32,
|
||||
nodes: &mut Vec<(TreeData<Node>, String)>,
|
||||
nodes: &mut SmallVec<[(TreeData<Node>, String); 16]>,
|
||||
) -> Result<Option<(TreeData<Node>, String)>> {
|
||||
let mut parts = path
|
||||
.as_ref()
|
||||
.split('/')
|
||||
.filter(|part| !part.is_empty() && *part != ".");
|
||||
let mut part_opt: Option<&str> = None;
|
||||
@@ -516,13 +506,16 @@ impl<'sock, D: Disk> FileScheme<'sock, D> {
|
||||
}
|
||||
if node.data().is_symlink() {
|
||||
let mut url = String::new();
|
||||
url.push_str(scheme_name);
|
||||
url.push(':');
|
||||
// url.push_str(scheme_name.as_ref());
|
||||
// url.push(':');
|
||||
for (_parent, parent_name) in nodes.iter() {
|
||||
url.push('/');
|
||||
if !url.is_empty() {
|
||||
url.push('/');
|
||||
}
|
||||
url.push_str(&parent_name);
|
||||
}
|
||||
Self::resolve_symlink(scheme_name, tx, uid, gid, &url, node, nodes)?;
|
||||
let url = RedoxReference::new(url).ok_or(Error::new(EINVAL))?;
|
||||
Self::resolve_symlink(scheme_name, tx, uid, gid, url, node, nodes)?;
|
||||
node_ptr = nodes.last().unwrap().0.ptr();
|
||||
} else if !node.data().is_dir() {
|
||||
return Err(Error::new(ENOTDIR));
|
||||
@@ -543,61 +536,13 @@ impl<'sock, D: Disk> FileScheme<'sock, D> {
|
||||
}
|
||||
}
|
||||
|
||||
/// given a path with a scheme, return the containing directory (or scheme)
|
||||
fn dirname(path: &str) -> Option<String> {
|
||||
canonicalize_using_cwd(Some(path), "..")
|
||||
}
|
||||
|
||||
// TODO: Reimplement these using the scheme common path related crate
|
||||
pub fn resolve_path<D: Disk>(dir: &dyn Resource<D>, path: String) -> Option<String> {
|
||||
let max_upward_depth = 64; // Same value as MAX_LEVEL of sym loops in relibc
|
||||
let (canon, _depth) =
|
||||
canonicalize_using_cwd_with_max_upward_depth(dir.path(), &path, max_upward_depth)?;
|
||||
|
||||
Some(canon)
|
||||
}
|
||||
pub fn canonicalize_using_cwd_with_max_upward_depth(
|
||||
cwd: &str,
|
||||
path: &str,
|
||||
max_upward_depth: usize,
|
||||
) -> Option<(String, usize)> {
|
||||
let (canonical, upward_depth) =
|
||||
canonicalize_with_max_upward_depth(&format!("{}/{}", cwd, path), max_upward_depth)?;
|
||||
Some((canonical, upward_depth))
|
||||
}
|
||||
pub fn canonicalize_with_max_upward_depth(
|
||||
path: &str,
|
||||
max_upward_depth: usize,
|
||||
) -> Option<(String, usize)> {
|
||||
let mut nskip = 0;
|
||||
let mut parts = Vec::new();
|
||||
let mut upward_depth = 0;
|
||||
|
||||
for part in path.split('/').rev() {
|
||||
if part == "." || part.is_empty() {
|
||||
continue;
|
||||
} else if part == ".." {
|
||||
nskip += 1;
|
||||
upward_depth += 1;
|
||||
if upward_depth > max_upward_depth {
|
||||
return None;
|
||||
}
|
||||
} else if nskip > 0 {
|
||||
nskip -= 1;
|
||||
} else {
|
||||
parts.push(part);
|
||||
}
|
||||
}
|
||||
|
||||
let canonical = parts.iter().rev().fold(String::new(), |mut string, &part| {
|
||||
if !string.is_empty() && !string.ends_with('/') {
|
||||
string.push('/');
|
||||
}
|
||||
string.push_str(part);
|
||||
string
|
||||
});
|
||||
|
||||
Some((canonical, upward_depth))
|
||||
pub fn resolve_path<'a, 'b, D: Disk>(
|
||||
dir: &'a dyn Resource<D>,
|
||||
path: RedoxReference<'b>,
|
||||
) -> Result<RedoxReference<'b>> {
|
||||
let dirpath = RedoxReference::new(dir.path());
|
||||
let dirpath = dirpath.ok_or(Error::new(ENOENT))?;
|
||||
Ok(dirpath.join_checked(path))
|
||||
}
|
||||
|
||||
impl<'sock, D: Disk> SchemeSync for FileScheme<'sock, D> {
|
||||
@@ -615,31 +560,34 @@ impl<'sock, D: Disk> SchemeSync for FileScheme<'sock, D> {
|
||||
_fcntl_flags: u32,
|
||||
ctx: &CallerCtx,
|
||||
) -> Result<OpenResult> {
|
||||
let path = path.to_string();
|
||||
let path = RedoxReference::new(path).ok_or(Error::new(EINVAL))?;
|
||||
let path_to_open = match Handle::get_resource_or(self.handles.get(&dirfd))? {
|
||||
// If pathname is absolute, then dirfd is ignored.
|
||||
Some(res) if !path.starts_with('/') => {
|
||||
resolve_path(res, path).ok_or(Error::new(ENOENT))?
|
||||
}
|
||||
_ => path.to_string(),
|
||||
Some(res) if path.is_relative() => resolve_path(res, path)?,
|
||||
_ => path,
|
||||
};
|
||||
self.open_internal(TreePtr::root(), &path_to_open, flags, ctx)
|
||||
self.open_internal(
|
||||
TreePtr::root(),
|
||||
path_to_open.to_relative().canonical(),
|
||||
flags,
|
||||
ctx,
|
||||
)
|
||||
}
|
||||
|
||||
fn unlinkat(&mut self, dirfd: usize, url: &str, flags: usize, ctx: &CallerCtx) -> Result<()> {
|
||||
fn unlinkat(&mut self, dirfd: usize, path: &str, flags: usize, ctx: &CallerCtx) -> Result<()> {
|
||||
let uid = ctx.uid;
|
||||
let gid = ctx.gid;
|
||||
let url = url.to_string();
|
||||
let path = RedoxReference::new(path).ok_or(Error::new(EINVAL))?;
|
||||
let path = match Handle::get_resource_or(self.handles.get(&dirfd))? {
|
||||
Some(res) => resolve_path(res, url).ok_or(Error::new(ENOENT))?,
|
||||
None => url,
|
||||
// If pathname is absolute, then dirfd is ignored.
|
||||
Some(res) if path.is_relative() => resolve_path(res, path)?,
|
||||
_ => path,
|
||||
};
|
||||
let path = path.trim_matches('/');
|
||||
let start_ptr = TreePtr::root();
|
||||
|
||||
// println!("Unlinkat '{}' flags: {:X}", path, flags);
|
||||
|
||||
self.unlink_internal(start_ptr, path, flags, uid, gid)
|
||||
self.unlink_internal(start_ptr, &path.canonical(), flags, uid, gid)
|
||||
}
|
||||
|
||||
/* Resource operations */
|
||||
@@ -727,7 +675,9 @@ impl<'sock, D: Disk> SchemeSync for FileScheme<'sock, D> {
|
||||
|
||||
//TODO: this function has too much code, try to simplify it
|
||||
fn flink(&mut self, id: usize, url: &str, ctx: &CallerCtx) -> Result<usize> {
|
||||
let new_path = url.trim_matches('/');
|
||||
let new_path = RedoxReference::new(url)
|
||||
.ok_or(Error::new(EINVAL))?
|
||||
.canonical();
|
||||
let uid = ctx.uid;
|
||||
let gid = ctx.gid;
|
||||
|
||||
@@ -749,7 +699,7 @@ impl<'sock, D: Disk> SchemeSync for FileScheme<'sock, D> {
|
||||
}
|
||||
|
||||
let mut new_name = String::new();
|
||||
for part in new_path.split('/') {
|
||||
for part in new_path.as_ref().split('/') {
|
||||
if !part.is_empty() {
|
||||
new_name = part.to_string();
|
||||
}
|
||||
@@ -775,12 +725,12 @@ impl<'sock, D: Disk> SchemeSync for FileScheme<'sock, D> {
|
||||
return Err(Error::new(EACCES));
|
||||
}
|
||||
|
||||
let mut new_nodes = Vec::new();
|
||||
let mut new_nodes = SmallVec::new();
|
||||
let new_node_opt = Self::path_nodes(
|
||||
scheme_name,
|
||||
tx,
|
||||
TreePtr::root(),
|
||||
new_path,
|
||||
&new_path,
|
||||
uid,
|
||||
gid,
|
||||
&mut new_nodes,
|
||||
@@ -821,7 +771,7 @@ impl<'sock, D: Disk> SchemeSync for FileScheme<'sock, D> {
|
||||
|
||||
tx.link_node(new_parent.ptr(), &new_name, orig_node.ptr())?;
|
||||
|
||||
file.set_path(new_path);
|
||||
file.set_path(new_path.as_ref());
|
||||
Ok(0)
|
||||
} else {
|
||||
Err(Error::new(EPERM))
|
||||
@@ -831,7 +781,9 @@ impl<'sock, D: Disk> SchemeSync for FileScheme<'sock, D> {
|
||||
|
||||
//TODO: this function has too much code, try to simplify it
|
||||
fn frename(&mut self, id: usize, url: &str, ctx: &CallerCtx) -> Result<usize> {
|
||||
let new_path = url.trim_matches('/');
|
||||
let new_path = RedoxReference::new(url)
|
||||
.ok_or(Error::new(EINVAL))?
|
||||
.canonical();
|
||||
let uid = ctx.uid;
|
||||
let gid = ctx.gid;
|
||||
|
||||
@@ -853,7 +805,7 @@ impl<'sock, D: Disk> SchemeSync for FileScheme<'sock, D> {
|
||||
}
|
||||
|
||||
let mut new_name = String::new();
|
||||
for part in new_path.split('/') {
|
||||
for part in new_path.as_ref().split('/') {
|
||||
if !part.is_empty() {
|
||||
new_name = part.to_string();
|
||||
}
|
||||
@@ -879,12 +831,12 @@ impl<'sock, D: Disk> SchemeSync for FileScheme<'sock, D> {
|
||||
return Err(Error::new(EACCES));
|
||||
}
|
||||
|
||||
let mut new_nodes = Vec::new();
|
||||
let mut new_nodes = SmallVec::new();
|
||||
let new_node_opt = Self::path_nodes(
|
||||
scheme_name,
|
||||
tx,
|
||||
TreePtr::root(),
|
||||
new_path,
|
||||
&new_path,
|
||||
uid,
|
||||
gid,
|
||||
&mut new_nodes,
|
||||
@@ -925,7 +877,7 @@ impl<'sock, D: Disk> SchemeSync for FileScheme<'sock, D> {
|
||||
|
||||
tx.rename_node(orig_parent_ptr, &old_name, new_parent.ptr(), &new_name)?;
|
||||
|
||||
file.set_path(new_path);
|
||||
file.set_path(new_path.as_ref());
|
||||
Ok(0)
|
||||
} else {
|
||||
Err(Error::new(EPERM))
|
||||
|
||||
Reference in New Issue
Block a user