Hi, Steven,
For the error returned when a byte range lock conflicts with an
existing lock in SMB, the logic is as follows: If a lock request is above a
configured offset, or if a lock request matches a previously failed lock
offset, it will change it from "fail immediately" with timeout of 0 to timeout
of 250 ms on operation issue. The result is that the lock will be pending for
250ms waiting for lock availability, and if it does not retrieve it, it returns
a different error (STATUS_FILE_LOCK_CONFLICT).
Pseudo code of above logic should be something as below:
If (FailImmediately) // Timeout = 0
If Offset == Open.LastFailedLockOffset OR Offset >=
LockViolationDelayOffset
Set Timeout = LockViolationDelay // within 250
milliseconds
End If
End If
If Timeout = 0 and Lock Not Acquired
Set LockViolationDelayOffset = (Offset of lock attempt)
return STATUS_LOCK_NOT_GRANTED
Else If Timeout > 0 and Lock Not Acquired after Timeout
return STATUS_FILE_LOCK_CONFLICT
Else
return STATUS_SUCCESS
End If.
With the logic above, you can easily explain what shows in your network
trace. We will add the logic to the SMB protocol document. Please let us
know if you have further questions regarding this behavior.
Thanks!
--------------------------------------------------------------------
Hongwei Sun - Sr. Support Escalation Engineer
DSC Protocol Team, Microsoft
[email protected]<mailto:[email protected]>
Tel: 469-7757027 x 57027
---------------------------------------------------------------------
From: Steven Danneman [mailto:[email protected]]
Sent: Wednesday, November 25, 2009 5:54 PM
To: Interoperability Documentation Help; [email protected];
[email protected]
Subject: SMBv1 LockAndX return status on lock conflict
Hello,
When requesting a byte-range lock over SMBv1 on a range of a file which is
already locked and thus will contend, the error code returned is inconsistent.
The first attempt to acquire a held lock will return STATUS_LOCK_NOT_GRANTED.
Subsequent requests will return STATUS_FILE_LOCK_CONFLICT.
This seems as though it may be an error in the implementation of the SMBv1
protocol as the explanation of the two errors in MS-ERREF implies that
STATUS_LOCK_NOT_GRANTED should always be returned in this circumstance:
STATUS_LOCK_NOT_GRANTED A requested file lock cannot be granted
due to other existing locks.
STATUS_FILE_LOCK_CONFLICT A requested read/write cannot be
granted due to a conflicting file lock.
And in this same scenario the SMBv2 protocol always returns
STATUS_LOCK_NOT_GRANTED.
I aware this is a well known issue, as the Samba torture test demonstrating
this behavior have existed for a number of years, but I haven't found any
Microsoft documentation describing the semantics of this behavior. I've looked
in MS-CIFS, MS-SMB, MS-SMB2, and MS-FSA.
Furthermore, which error code is returned becomes even more complicated when
additional lock requests are interspersed. For example the attached pcap
against a W2K8R2 server shows:
1) Two file handles opened to the same file 0x400b, 0x400c
2) Packet 27,28: Handle 0x400b successfully acquiring an exclusive lock on
range 100 - 110
3) Packet 29-32: Handles 0x400b and 0x400c requesting the same held range and
receiving STATUS_LOCK_NOT_GRANTED
4) Packet 33-44: Again requesting the same held range and receiving
STATUS_FILE_LOCK_CONFLICT
5) Packet 45-54: Requesting a lock on an overlapping range, 105-115, and
receiving the same pattern of errors
6) Packet 55-64: Requesting a lock on the previous range, 100-110, and now
having the response be "reset" back to STATUS_LOCK_NOT_GRANTED
I'd like to have some documentation of the algorithm for determining which
error to return based on the state of existing locks, or history of previously
requested locks.
Thanks,
Steven Danneman | Software Development Engineer
Isilon Systems P +1-206-315-7500 F +1-206-315-7501
www.isilon.com<http://www.isilon.com>
[cid:[email protected]] How breakthroughs begin. (tm)
<<inline: image001.gif>>
_______________________________________________ cifs-protocol mailing list [email protected] https://lists.samba.org/mailman/listinfo/cifs-protocol
