From 49693532a2980f81b9e06ccb3374bccb3e39c3ea Mon Sep 17 00:00:00 2001 From: Casey Bodley Date: Tue, 1 May 2012 15:08:42 -0400 Subject: [PATCH] locks: serialize lock requests adds a critical section to nfs41_open_state. this lock is taken before generating the stateid/seqid, and released after updated stateid is saved to nfs41_open_state Signed-off-by: Casey Bodley --- daemon/lock.c | 15 +++++++++++++-- daemon/nfs41.h | 1 + daemon/open.c | 1 + 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/daemon/lock.c b/daemon/lock.c index 9cf4d4e..c1ac146 100644 --- a/daemon/lock.c +++ b/daemon/lock.c @@ -236,6 +236,8 @@ static int handle_lock(nfs41_upcall *upcall) goto out_free; } + EnterCriticalSection(&state->locks.lock); + lock_stateid_arg(state, &stateid); status = nfs41_lock(state->session, &state->file, &state->owner, @@ -244,11 +246,14 @@ static int handle_lock(nfs41_upcall *upcall) dprintf(LKLVL, "nfs41_lock failed with %s\n", nfs_error_string(status)); status = nfs_to_windows_error(status, ERROR_BAD_NET_RESP); + LeaveCriticalSection(&state->locks.lock); goto out_free; } /* save lock state with the open */ open_lock_add(state, &stateid, lock); + LeaveCriticalSection(&state->locks.lock); + args->acquired = TRUE; /* for cancel_lock() */ out: return status; @@ -281,12 +286,15 @@ static void cancel_lock(IN nfs41_upcall *upcall) if (status != ERROR_LOCKED) goto out; + EnterCriticalSection(&state->locks.lock); lock_stateid_arg(state, &stateid); status = nfs41_unlock(state->session, &state->file, args->offset, args->length, &stateid); open_unlock_remove(state, &stateid, &input); + LeaveCriticalSection(&state->locks.lock); + status = nfs_to_windows_error(status, ERROR_BAD_NET_RESP); out: dprintf(1, "<-- cancel_lock() returning %d\n", status); @@ -321,8 +329,6 @@ static int handle_unlock(nfs41_upcall *upcall) uint32_t i; int status = NO_ERROR; - lock_stateid_arg(state, &stateid); - for (i = 0; i < args->count; i++) { if (safe_read(&buf, &buf_len, &input.offset, sizeof(LONGLONG))) break; if (safe_read(&buf, &buf_len, &input.length, sizeof(LONGLONG))) break; @@ -336,10 +342,15 @@ static int handle_unlock(nfs41_upcall *upcall) if (status != ERROR_LOCKED) continue; + EnterCriticalSection(&state->locks.lock); + lock_stateid_arg(state, &stateid); + status = nfs41_unlock(state->session, &state->file, input.offset, input.length, &stateid); open_unlock_remove(state, &stateid, &input); + LeaveCriticalSection(&state->locks.lock); + status = nfs_to_windows_error(status, ERROR_BAD_NET_RESP); } return status; diff --git a/daemon/nfs41.h b/daemon/nfs41.h index 84558ad..7aa6c18 100644 --- a/daemon/nfs41.h +++ b/daemon/nfs41.h @@ -149,6 +149,7 @@ typedef struct __nfs41_open_state { stateid4 stateid; struct list_entry list; uint32_t counter; + CRITICAL_SECTION lock; } locks; HANDLE srv_open; /* for data cache invalidation */ diff --git a/daemon/open.c b/daemon/open.c index cf66668..8097829 100644 --- a/daemon/open.c +++ b/daemon/open.c @@ -61,6 +61,7 @@ static int create_open_state( state->ref_count = 1; list_init(&state->locks.list); list_init(&state->client_entry); + InitializeCriticalSection(&state->locks.lock); *state_out = state; status = NO_ERROR;