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:
Warren
2026-06-23 09:58:19 +08:00
parent e7863a3034
commit d4f60929fa
6 changed files with 58 additions and 31 deletions

View File

@@ -1,7 +1,7 @@
use std::path::{Path, PathBuf};
use std::sync::Arc;
use std::sync::Mutex;
use std::time::SystemTime;
use tokio::sync::Mutex;
use async_trait::async_trait;
use bytes::Bytes;
@@ -211,11 +211,9 @@ impl Handle for VfsHandle {
async fn read(&self, offset: u64, len: u32) -> Result<Bytes, SmbError> {
match self {
Self::File { file, .. } => {
let mut file = file.lock().unwrap();
file.seek(std::io::SeekFrom::Start(offset))
.map_err(vfs_error_to_io)?;
let mut file = file.lock().await;
let mut buf = vec![0u8; len as usize];
let n = file.read(&mut buf).map_err(map_error)?;
let n = file.read_at(&mut buf, offset).map_err(map_error)?;
buf.truncate(n);
Ok(Bytes::from(buf))
}
@@ -226,10 +224,8 @@ impl Handle for VfsHandle {
async fn write(&self, offset: u64, data: &[u8]) -> Result<u32, SmbError> {
match self {
Self::File { file, .. } => {
let mut file = file.lock().unwrap();
file.seek(std::io::SeekFrom::Start(offset))
.map_err(vfs_error_to_io)?;
let n = file.write(data).map_err(map_error)?;
let mut file = file.lock().await;
let n = file.write_at(data, offset).map_err(map_error)?;
Ok(n as u32)
}
Self::Directory { .. } => Err(SmbError::NotSupported),
@@ -239,7 +235,7 @@ impl Handle for VfsHandle {
async fn flush(&self) -> Result<(), SmbError> {
match self {
Self::File { file, .. } => {
let mut file = file.lock().unwrap();
let mut file = file.lock().await;
file.flush().map_err(map_error)
}
Self::Directory { .. } => Ok(()),
@@ -249,7 +245,7 @@ impl Handle for VfsHandle {
async fn stat(&self) -> Result<FileInfo, SmbError> {
match self {
Self::File { file, path, .. } => {
let mut f = file.lock().unwrap();
let mut f = file.lock().await;
let vfs_stat = f.stat().map_err(map_error)?;
Ok(vfs_stat_to_file_info(&vfs_stat, "", path))
}
@@ -278,7 +274,7 @@ impl Handle for VfsHandle {
async fn truncate(&self, len: u64) -> Result<(), SmbError> {
match self {
Self::File { file, .. } => {
let mut file = file.lock().unwrap();
let mut file = file.lock().await;
file.set_len(len).map_err(map_error)
}
Self::Directory { .. } => Err(SmbError::NotSupported),