recovery: client keeps list of associated open state
open state is added to the client's list on a successful call to nfs41_open(), and removed from the list on nfs41_close() regardless of success Signed-off-by: Casey Bodley <cbodley@citi.umich.edu>
This commit is contained in:
parent
3ca917f6b3
commit
7240c69b5d
3 changed files with 44 additions and 0 deletions
|
|
@ -91,6 +91,7 @@ typedef struct __nfs41_open_state {
|
||||||
state_owner4 owner;
|
state_owner4 owner;
|
||||||
nfs41_lock_state last_lock;
|
nfs41_lock_state last_lock;
|
||||||
struct __pnfs_file_layout *layout;
|
struct __pnfs_file_layout *layout;
|
||||||
|
struct list_entry client_entry; /* entry in nfs41_client.opens */
|
||||||
SRWLOCK lock;
|
SRWLOCK lock;
|
||||||
LONG ref_count;
|
LONG ref_count;
|
||||||
} nfs41_open_state;
|
} nfs41_open_state;
|
||||||
|
|
@ -109,6 +110,11 @@ typedef struct __nfs41_rpc_clnt {
|
||||||
bool_t in_recovery;
|
bool_t in_recovery;
|
||||||
} nfs41_rpc_clnt;
|
} nfs41_rpc_clnt;
|
||||||
|
|
||||||
|
struct client_state {
|
||||||
|
struct list_entry opens; /* list of associated nfs41_open_state */
|
||||||
|
CRITICAL_SECTION lock;
|
||||||
|
};
|
||||||
|
|
||||||
typedef struct __nfs41_client {
|
typedef struct __nfs41_client {
|
||||||
nfs41_server *server;
|
nfs41_server *server;
|
||||||
client_owner4 owner;
|
client_owner4 owner;
|
||||||
|
|
@ -126,6 +132,9 @@ typedef struct __nfs41_client {
|
||||||
HANDLE cond;
|
HANDLE cond;
|
||||||
struct __nfs41_root *root;
|
struct __nfs41_root *root;
|
||||||
bool_t in_recovery;
|
bool_t in_recovery;
|
||||||
|
|
||||||
|
/* for state recovery on server reboot */
|
||||||
|
struct client_state state;
|
||||||
} nfs41_client;
|
} nfs41_client;
|
||||||
|
|
||||||
#define NFS41_MAX_NUM_SLOTS NFS41_MAX_RPC_REQS
|
#define NFS41_MAX_NUM_SLOTS NFS41_MAX_RPC_REQS
|
||||||
|
|
|
||||||
|
|
@ -131,6 +131,9 @@ int nfs41_client_create(
|
||||||
client->is_data = is_data;
|
client->is_data = is_data;
|
||||||
update_exchangeid_res(client, exchangeid);
|
update_exchangeid_res(client, exchangeid);
|
||||||
|
|
||||||
|
list_init(&client->state.opens);
|
||||||
|
InitializeCriticalSection(&client->state.lock);
|
||||||
|
|
||||||
//initialize a lock used to protect access to client id and client id seq#
|
//initialize a lock used to protect access to client id and client id seq#
|
||||||
InitializeSRWLock(&client->exid_lock);
|
InitializeSRWLock(&client->exid_lock);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -73,6 +73,7 @@ out_free:
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* open state reference counting */
|
||||||
void nfs41_open_state_ref(
|
void nfs41_open_state_ref(
|
||||||
IN nfs41_open_state *state)
|
IN nfs41_open_state *state)
|
||||||
{
|
{
|
||||||
|
|
@ -94,6 +95,28 @@ void nfs41_open_state_deref(
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* client list of associated open state */
|
||||||
|
static void client_state_add(
|
||||||
|
IN nfs41_open_state *state)
|
||||||
|
{
|
||||||
|
nfs41_client *client = state->session->client;
|
||||||
|
|
||||||
|
EnterCriticalSection(&client->state.lock);
|
||||||
|
list_add_tail(&client->state.opens, &state->client_entry);
|
||||||
|
LeaveCriticalSection(&client->state.lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void client_state_remove(
|
||||||
|
IN nfs41_open_state *state)
|
||||||
|
{
|
||||||
|
nfs41_client *client = state->session->client;
|
||||||
|
|
||||||
|
EnterCriticalSection(&client->state.lock);
|
||||||
|
list_remove(&state->client_entry);
|
||||||
|
LeaveCriticalSection(&client->state.lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* NFS41_OPEN */
|
/* NFS41_OPEN */
|
||||||
static int parse_open(unsigned char *buffer, uint32_t length, nfs41_upcall *upcall)
|
static int parse_open(unsigned char *buffer, uint32_t length, nfs41_upcall *upcall)
|
||||||
{
|
{
|
||||||
|
|
@ -395,6 +418,9 @@ static int handle_open(nfs41_upcall *upcall)
|
||||||
args->mode, state, &info);
|
args->mode, state, &info);
|
||||||
|
|
||||||
if (status == NFS4_OK) {
|
if (status == NFS4_OK) {
|
||||||
|
/* add to the client's list of state for recovery */
|
||||||
|
client_state_add(state);
|
||||||
|
|
||||||
nfs_to_basic_info(&info, &args->basic_info);
|
nfs_to_basic_info(&info, &args->basic_info);
|
||||||
nfs_to_standard_info(&info, &args->std_info);
|
nfs_to_standard_info(&info, &args->std_info);
|
||||||
state->do_close = 1;
|
state->do_close = 1;
|
||||||
|
|
@ -468,6 +494,9 @@ static void cancel_open(IN nfs41_upcall *upcall)
|
||||||
if (status)
|
if (status)
|
||||||
dprintf(1, "cancel_open: nfs41_close() failed with %s\n",
|
dprintf(1, "cancel_open: nfs41_close() failed with %s\n",
|
||||||
nfs_error_string(status));
|
nfs_error_string(status));
|
||||||
|
|
||||||
|
/* remove from the client's list of state for recovery */
|
||||||
|
client_state_remove(state);
|
||||||
} else if (args->created) {
|
} else if (args->created) {
|
||||||
const nfs41_component *name = &state->file.name;
|
const nfs41_component *name = &state->file.name;
|
||||||
status = nfs41_remove(state->session, &state->parent, name);
|
status = nfs41_remove(state->session, &state->parent, name);
|
||||||
|
|
@ -545,6 +574,9 @@ static int handle_close(nfs41_upcall *upcall)
|
||||||
nfs_error_string(status));
|
nfs_error_string(status));
|
||||||
status = nfs_to_windows_error(status, ERROR_INTERNAL_ERROR);
|
status = nfs_to_windows_error(status, ERROR_INTERNAL_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* remove from the client's list of state for recovery */
|
||||||
|
client_state_remove(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (status || !rm_status)
|
if (status || !rm_status)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue