Fix smb-server xattr: add root_path field for absolute path storage

This commit is contained in:
Warren
2026-06-22 16:25:33 +08:00
parent 9dd2eefeea
commit bb796ec6b9
2 changed files with 12 additions and 12 deletions

Binary file not shown.

View File

@@ -43,6 +43,7 @@ use crate::path::SmbPath;
/// Cheap to clone: internally an `Arc<cap_std::fs::Dir>` plus a flag. /// Cheap to clone: internally an `Arc<cap_std::fs::Dir>` plus a flag.
pub struct LocalFsBackend { pub struct LocalFsBackend {
root: Arc<Dir>, root: Arc<Dir>,
root_path: PathBuf, // Store absolute path for xattr operations
read_only: bool, read_only: bool,
} }
@@ -50,9 +51,11 @@ impl LocalFsBackend {
/// Open `path` as the share root. Errors if the path does not exist or is /// Open `path` as the share root. Errors if the path does not exist or is
/// not a directory. /// not a directory.
pub fn new(path: impl AsRef<Path>) -> io::Result<Self> { pub fn new(path: impl AsRef<Path>) -> io::Result<Self> {
let dir = Dir::open_ambient_dir(path, ambient_authority())?; let p = path.as_ref().canonicalize()?;
let dir = Dir::open_ambient_dir(&p, ambient_authority())?;
Ok(Self { Ok(Self {
root: Arc::new(dir), root: Arc::new(dir),
root_path: p,
read_only: false, read_only: false,
}) })
} }
@@ -431,14 +434,12 @@ impl ShareBackend for LocalFsBackend {
async fn get_xattr(&self, path: &SmbPath, name: &str) -> SmbResult<Vec<u8>> { async fn get_xattr(&self, path: &SmbPath, name: &str) -> SmbResult<Vec<u8>> {
let rel = to_rel_path(path); let rel = to_rel_path(path);
let root = Arc::clone(&self.root); let root_path = self.root_path.clone();
let xattr_name = name.to_string(); let xattr_name = name.to_string();
spawn_blocking(move || { spawn_blocking(move || {
// Get absolute path: dereference Arc first let full_path = root_path.join(&rel);
let full_path = (*root).as_std_path().join(&rel);
// Use xattr::get which returns Option<Vec<u8>>
match xattr::get(&full_path, &xattr_name) { match xattr::get(&full_path, &xattr_name) {
Ok(Some(data)) => Ok(data), Ok(Some(data)) => Ok(data),
Ok(None) => Err(SmbError::NotFound), Ok(None) => Err(SmbError::NotFound),
@@ -455,12 +456,12 @@ impl ShareBackend for LocalFsBackend {
} }
let rel = to_rel_path(path); let rel = to_rel_path(path);
let root = Arc::clone(&self.root); let root_path = self.root_path.clone();
let xattr_name = name.to_string(); let xattr_name = name.to_string();
let value = value.to_vec(); let value = value.to_vec();
spawn_blocking(move || { spawn_blocking(move || {
let full_path = (*root).as_std_path().join(&rel); let full_path = root_path.join(&rel);
xattr::set(&full_path, &xattr_name, &value) xattr::set(&full_path, &xattr_name, &value)
.map_err(|e| SmbError::Io(e.into())) .map_err(|e| SmbError::Io(e.into()))
}) })
@@ -474,11 +475,11 @@ impl ShareBackend for LocalFsBackend {
} }
let rel = to_rel_path(path); let rel = to_rel_path(path);
let root = Arc::clone(&self.root); let root_path = self.root_path.clone();
let xattr_name = name.to_string(); let xattr_name = name.to_string();
spawn_blocking(move || { spawn_blocking(move || {
let full_path = (*root).as_std_path().join(&rel); let full_path = root_path.join(&rel);
xattr::remove(&full_path, &xattr_name) xattr::remove(&full_path, &xattr_name)
.map_err(|e| SmbError::Io(e.into())) .map_err(|e| SmbError::Io(e.into()))
}) })
@@ -488,12 +489,11 @@ impl ShareBackend for LocalFsBackend {
async fn list_xattrs(&self, path: &SmbPath) -> SmbResult<Vec<String>> { async fn list_xattrs(&self, path: &SmbPath) -> SmbResult<Vec<String>> {
let rel = to_rel_path(path); let rel = to_rel_path(path);
let root = Arc::clone(&self.root); let root_path = self.root_path.clone();
spawn_blocking(move || { spawn_blocking(move || {
let full_path = (*root).as_std_path().join(&rel); let full_path = root_path.join(&rel);
// xattr::list returns iterator of OsString
let attrs: Vec<String> = xattr::list(&full_path) let attrs: Vec<String> = xattr::list(&full_path)
.map_err(|e| SmbError::Io(e.into()))? .map_err(|e| SmbError::Io(e.into()))?
.into_iter() .into_iter()