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 <cbodley@citi.umich.edu>
This commit is contained in:
parent
b9775a69e9
commit
49693532a2
3 changed files with 15 additions and 2 deletions
|
|
@ -236,6 +236,8 @@ static int handle_lock(nfs41_upcall *upcall)
|
||||||
goto out_free;
|
goto out_free;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EnterCriticalSection(&state->locks.lock);
|
||||||
|
|
||||||
lock_stateid_arg(state, &stateid);
|
lock_stateid_arg(state, &stateid);
|
||||||
|
|
||||||
status = nfs41_lock(state->session, &state->file, &state->owner,
|
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",
|
dprintf(LKLVL, "nfs41_lock failed with %s\n",
|
||||||
nfs_error_string(status));
|
nfs_error_string(status));
|
||||||
status = nfs_to_windows_error(status, ERROR_BAD_NET_RESP);
|
status = nfs_to_windows_error(status, ERROR_BAD_NET_RESP);
|
||||||
|
LeaveCriticalSection(&state->locks.lock);
|
||||||
goto out_free;
|
goto out_free;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* save lock state with the open */
|
/* save lock state with the open */
|
||||||
open_lock_add(state, &stateid, lock);
|
open_lock_add(state, &stateid, lock);
|
||||||
|
LeaveCriticalSection(&state->locks.lock);
|
||||||
|
|
||||||
args->acquired = TRUE; /* for cancel_lock() */
|
args->acquired = TRUE; /* for cancel_lock() */
|
||||||
out:
|
out:
|
||||||
return status;
|
return status;
|
||||||
|
|
@ -281,12 +286,15 @@ static void cancel_lock(IN nfs41_upcall *upcall)
|
||||||
if (status != ERROR_LOCKED)
|
if (status != ERROR_LOCKED)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
|
EnterCriticalSection(&state->locks.lock);
|
||||||
lock_stateid_arg(state, &stateid);
|
lock_stateid_arg(state, &stateid);
|
||||||
|
|
||||||
status = nfs41_unlock(state->session, &state->file,
|
status = nfs41_unlock(state->session, &state->file,
|
||||||
args->offset, args->length, &stateid);
|
args->offset, args->length, &stateid);
|
||||||
|
|
||||||
open_unlock_remove(state, &stateid, &input);
|
open_unlock_remove(state, &stateid, &input);
|
||||||
|
LeaveCriticalSection(&state->locks.lock);
|
||||||
|
|
||||||
status = nfs_to_windows_error(status, ERROR_BAD_NET_RESP);
|
status = nfs_to_windows_error(status, ERROR_BAD_NET_RESP);
|
||||||
out:
|
out:
|
||||||
dprintf(1, "<-- cancel_lock() returning %d\n", status);
|
dprintf(1, "<-- cancel_lock() returning %d\n", status);
|
||||||
|
|
@ -321,8 +329,6 @@ static int handle_unlock(nfs41_upcall *upcall)
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
int status = NO_ERROR;
|
int status = NO_ERROR;
|
||||||
|
|
||||||
lock_stateid_arg(state, &stateid);
|
|
||||||
|
|
||||||
for (i = 0; i < args->count; i++) {
|
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.offset, sizeof(LONGLONG))) break;
|
||||||
if (safe_read(&buf, &buf_len, &input.length, 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)
|
if (status != ERROR_LOCKED)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
EnterCriticalSection(&state->locks.lock);
|
||||||
|
lock_stateid_arg(state, &stateid);
|
||||||
|
|
||||||
status = nfs41_unlock(state->session, &state->file,
|
status = nfs41_unlock(state->session, &state->file,
|
||||||
input.offset, input.length, &stateid);
|
input.offset, input.length, &stateid);
|
||||||
|
|
||||||
open_unlock_remove(state, &stateid, &input);
|
open_unlock_remove(state, &stateid, &input);
|
||||||
|
LeaveCriticalSection(&state->locks.lock);
|
||||||
|
|
||||||
status = nfs_to_windows_error(status, ERROR_BAD_NET_RESP);
|
status = nfs_to_windows_error(status, ERROR_BAD_NET_RESP);
|
||||||
}
|
}
|
||||||
return status;
|
return status;
|
||||||
|
|
|
||||||
|
|
@ -149,6 +149,7 @@ typedef struct __nfs41_open_state {
|
||||||
stateid4 stateid;
|
stateid4 stateid;
|
||||||
struct list_entry list;
|
struct list_entry list;
|
||||||
uint32_t counter;
|
uint32_t counter;
|
||||||
|
CRITICAL_SECTION lock;
|
||||||
} locks;
|
} locks;
|
||||||
|
|
||||||
HANDLE srv_open; /* for data cache invalidation */
|
HANDLE srv_open; /* for data cache invalidation */
|
||||||
|
|
|
||||||
|
|
@ -61,6 +61,7 @@ static int create_open_state(
|
||||||
state->ref_count = 1;
|
state->ref_count = 1;
|
||||||
list_init(&state->locks.list);
|
list_init(&state->locks.list);
|
||||||
list_init(&state->client_entry);
|
list_init(&state->client_entry);
|
||||||
|
InitializeCriticalSection(&state->locks.lock);
|
||||||
|
|
||||||
*state_out = state;
|
*state_out = state;
|
||||||
status = NO_ERROR;
|
status = NO_ERROR;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue