Implement SMB Oplocks Phase 3+5
Phase 3: NotificationQueue - Add notification_tx to Connection struct - Modify writer.rs to use tokio::select! for response + notification - Add write_to_bytes() to OplockBreakNotification - Support server→client async messages Phase 5: WRITE Handler oplock break - Get path/share_access before write - Trigger OplockManager.break_oplock() - Send OPLOCK_BREAK_NOTIFICATION to affected clients - Encode and send via notification channel All 229 tests pass.
This commit is contained in:
30
vendor/smb-server/src/handlers/write.rs
vendored
30
vendor/smb-server/src/handlers/write.rs
vendored
@@ -13,7 +13,7 @@ use crate::ntstatus;
|
||||
use crate::server::ServerState;
|
||||
|
||||
pub async fn handle(
|
||||
_server: &Arc<ServerState>,
|
||||
server: &Arc<ServerState>,
|
||||
conn: &Arc<Connection>,
|
||||
hdr: &Smb2Header,
|
||||
body: &[u8],
|
||||
@@ -41,6 +41,34 @@ pub async fn handle(
|
||||
Some(o) => o,
|
||||
None => return HandlerResponse::err(ntstatus::STATUS_FILE_CLOSED),
|
||||
};
|
||||
|
||||
// Phase 5: Get path and trigger oplock break before write
|
||||
let (path, share_access) = {
|
||||
let open = open_arc.read().await;
|
||||
(open.last_path.clone(), open.share_access)
|
||||
};
|
||||
|
||||
// Trigger oplock break for conflicting clients
|
||||
let notifications = server.oplock_manager.break_oplock(
|
||||
&path,
|
||||
share_access,
|
||||
granted,
|
||||
).await;
|
||||
|
||||
// Send notifications to affected clients
|
||||
for notification in notifications {
|
||||
// Build SMB2 frame for notification
|
||||
use crate::proto::framing::encode_frame;
|
||||
let notification_bytes = notification.write_to_bytes();
|
||||
let mut frame = Vec::with_capacity(notification_bytes.len() + 4);
|
||||
encode_frame(¬ification_bytes, &mut frame);
|
||||
|
||||
// Send via notification channel (if available)
|
||||
if let Some(tx) = conn.notification_tx.read().await.as_ref() {
|
||||
let _ = tx.send(frame).await;
|
||||
}
|
||||
}
|
||||
|
||||
let result = {
|
||||
let open = open_arc.read().await;
|
||||
match open.handle.as_ref() {
|
||||
|
||||
Reference in New Issue
Block a user