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:
@@ -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),
|
||||
|
||||
Reference in New Issue
Block a user