Implement SMB AFP_AfpInfo read/write via xattr (Phase 2.8 complete)
Some checks failed
Test / test (push) Has been cancelled
Test / build (push) Has been cancelled

This commit is contained in:
Warren
2026-06-22 15:16:59 +08:00
parent 25991c71b2
commit 1c8c47d5fa
6 changed files with 251 additions and 4 deletions

View File

@@ -1,6 +1,7 @@
//! CREATE handler — open or create a file/directory and allocate a FileId.
use std::sync::Arc;
use tokio::sync::RwLock;
use crate::proto::header::Smb2Header;
use crate::proto::messages::{CreateRequest, CreateResponse};
@@ -85,11 +86,58 @@ pub async fn handle(
if stream_path.is_afp_info() {
debug!(base_path = %stream_path.base_path(), stream = %stream_path.stream_name(), "AFP_AfpInfo named stream open");
// For AFP_AfpInfo, we return a virtual handle that reads/writes extended attributes
// TODO: Implement actual AFP_AfpInfo handling via extended attributes
// Create AfpInfoHandle to read/write extended attributes
let base_smb_path = stream_path.base_path().clone();
// Return STATUS_OBJECT_NAME_NOT_FOUND for now (phase 2.6 will implement)
return HandlerResponse::err(ntstatus::STATUS_OBJECT_NAME_NOT_FOUND);
// Check write permission
let want_write = req.desired_access & (FILE_WRITE_DATA | GENERIC_WRITE | GENERIC_ALL) != 0;
if want_write && !granted.allows_write() {
return HandlerResponse::err(ntstatus::STATUS_ACCESS_DENIED);
}
// Allocate file_id
let mut tree = tree_arc.write().await;
let file_id = tree.alloc_file_id();
let read_only = tree.share.backend.capabilities().is_read_only;
let handle = crate::backend::AfpInfoHandle::new(base_smb_path.clone(), backend, want_write && read_only);
let open = Open::new(
file_id,
Box::new(handle),
if want_write { granted } else { Access::Read },
base_smb_path,
false, // is_directory
false, // delete_on_close
0, // oplock_level
0, // share_access
);
let open_arc = Arc::new(RwLock::new(open));
tree.opens.write().await.insert(file_id, open_arc.clone());
drop(tree);
let resp = CreateResponse {
structure_size: 89,
oplock_level: 0,
flags: 0,
create_action: FILE_OPENED,
creation_time: 0,
last_access_time: 0,
last_write_time: 0,
change_time: 0,
allocation_size: 32,
end_of_file: 32,
file_attributes: 0,
reserved2: 0,
file_id,
create_contexts_offset: 0,
create_contexts_length: 0,
create_contexts: vec![],
};
let mut buf = Vec::new();
resp.write_to(&mut buf).expect("encode");
return HandlerResponse::ok(buf);
}
// Handle AFP_Resource named stream