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.
- Add LockManager to oplock.rs:
- LockRange struct for tracking byte-range locks
- acquire() - check conflicts before granting lock
- release() - remove specific lock by offset/length
- clear() - clear all locks when file closed
- ranges_overlap() - helper for conflict detection
- Add LockManager to ServerState
- Update handlers/lock.rs:
- Parse LockRequest and LockElement
- Process each lock element (acquire/release)
- Support FLAG_EXCLUSIVE_LOCK, FLAG_SHARED_LOCK, FLAG_UNLOCK
- Return STATUS_LOCK_NOT_GRANTED on conflict
- Update handlers/close.rs:
- Clear all locks when file closed
- Add STATUS_LOCK_NOT_GRANTED to ntstatus.rs
All 229 tests pass.
Phase 4: CREATE Handler dynamic oplock granting
- Use OplockManager.can_grant() to determine oplock level
- Register OplockEntry if oplock granted
- Support ShareAccess compatibility checking
- Grant Level II if exclusive/batch oplock exists
Phase 6: CLOSE Handler oplock cleanup
- Unregister from OplockManager when file closed
- Only unregister if oplock_level > 0
All 229 tests pass.