lock: address differences in lock semantics

zero-length ranges: valid on windows, but nfs servers MUST return NFS4ERR_INVAL for LOCK with length=0. use MRxIsLockRealizable() to return STATUS_NOT_SUPPORTED for zero-length ranges (avoiding the lock upcall and rpc)

ranges that extend past UINT64_MAX: not valid on windows. NFS expects length=UINT64_MAX for locking to end-of-file. use length=UINT64_MAX if length >= UINT64_MAX-offset (making lock ranges consistent with linux client)

Signed-off-by: Casey Bodley <cbodley@citi.umich.edu>
This commit is contained in:
Casey Bodley 2011-06-13 12:02:59 -04:00
parent 2d252266c2
commit d98da23d49
3 changed files with 18 additions and 2 deletions

View file

@ -155,6 +155,13 @@ static int handle_lock(nfs41_upcall *upcall)
nfs41_lock_stateid_arg(state, &stateid);
/* 18.10.3. Operation 12: LOCK - Create Lock
* "To lock the file from a specific offset through the end-of-file
* (no matter how long the file actually is) use a length field equal
* to NFS4_UINT64_MAX." */
if (args->length >= NFS4_UINT64_MAX - args->offset)
args->length = NFS4_UINT64_MAX;
status = nfs41_lock(state->session, &state->file, &state->owner,
type, args->offset, args->length, FALSE, TRUE, &stateid);
if (status) {
@ -240,6 +247,10 @@ static int handle_unlock(nfs41_upcall *upcall)
if (safe_read(&buf, &buf_len, &offset, sizeof(LONGLONG))) break;
if (safe_read(&buf, &buf_len, &length, sizeof(LONGLONG))) break;
/* do the same translation as LOCK, or the ranges won't match */
if (length >= NFS4_UINT64_MAX - offset)
length = NFS4_UINT64_MAX;
status = nfs41_unlock(state->session,
&state->file, offset, length, &stateid);
if (status == NFS4_OK) {

View file

@ -67,8 +67,8 @@ typedef struct __readwrite_upcall_args {
} readwrite_upcall_args;
typedef struct __lock_upcall_args {
LONGLONG offset;
LONGLONG length;
uint64_t offset;
uint64_t length;
BOOLEAN exclusive;
BOOLEAN blocking;
} lock_upcall_args;