SMB performance optimization: pread/pwrite, tokio::sync::Mutex, direct response, fast-path
- VfsFile trait: add read_at()/write_at() with seek+read default impl - LocalFs: override with real pread/pwrite (FileExt::read_at/write_at) — 1 syscall vs 2 - smb_server_backend: use read_at/write_at + tokio::sync::Mutex (non-blocking async) - read handler: build response directly, avoid Bytes→Vec<u8> copy + intermediate struct - oplock break: fast-path skip when ≤1 open entry (single-user scenario)
This commit is contained in:
20
vendor/smb-server/src/oplock.rs
vendored
20
vendor/smb-server/src/oplock.rs
vendored
@@ -112,17 +112,23 @@ impl OplockManager {
|
||||
new_share_access: u32,
|
||||
new_granted_access: Access,
|
||||
) -> Vec<OplockBreakNotification> {
|
||||
// Fast-path: no entries or single entry can't conflict with itself
|
||||
let entry_count = {
|
||||
let file_opens = self.file_opens.read().await;
|
||||
file_opens.get(path).map_or(0, |e| e.len())
|
||||
};
|
||||
if entry_count <= 1 {
|
||||
return Vec::new();
|
||||
}
|
||||
|
||||
let mut notifications = Vec::new();
|
||||
let mut file_opens = self.file_opens.write().await;
|
||||
|
||||
if let Some(entries) = file_opens.get_mut(path) {
|
||||
for entry in entries.iter_mut() {
|
||||
// Check if new open conflicts with existing oplock
|
||||
if !share_access_compatible(entry.share_access, new_share_access) {
|
||||
// Need to break the oplock
|
||||
let new_level = OplockLevel::Ii as u8; // Downgrade to Level II
|
||||
let new_level = OplockLevel::Ii as u8;
|
||||
|
||||
// Build notification (MS-SMB2 §2.2.23.1)
|
||||
notifications.push(OplockBreakNotification {
|
||||
structure_size: 24,
|
||||
oplock_level: new_level,
|
||||
@@ -131,7 +137,6 @@ impl OplockManager {
|
||||
file_id: entry.file_id,
|
||||
});
|
||||
|
||||
// Update entry's oplock level
|
||||
entry.oplock_level = new_level;
|
||||
}
|
||||
}
|
||||
@@ -266,6 +271,11 @@ impl LeaseManager {
|
||||
|
||||
/// Break lease when conflicting access occurs (MS-SMB2 §3.3.5.10).
|
||||
pub async fn break_lease(&self, requested_state: u32) -> Vec<LeaseBreakNotification> {
|
||||
// Fast-path: no leases to break
|
||||
if self.leases.read().await.is_empty() {
|
||||
return Vec::new();
|
||||
}
|
||||
|
||||
let mut leases = self.leases.write().await;
|
||||
let mut notifications = Vec::new();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user