ReactOS  0.4.12-dev-43-g63b00d8
recovery.h File Reference
#include "nfs41.h"
Include dependency graph for recovery.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

bool_t nfs41_recovery_start_or_wait (IN nfs41_client *client)
 
void nfs41_recovery_finish (IN nfs41_client *client)
 
int nfs41_recover_session (IN nfs41_session *session, IN bool_t client_state_lost)
 
void nfs41_recover_sequence_flags (IN nfs41_session *session, IN uint32_t flags)
 
int nfs41_recover_client_state (IN nfs41_session *session, IN nfs41_client *client)
 
void nfs41_client_state_revoked (IN nfs41_session *session, IN nfs41_client *client, IN uint32_t revoked)
 
bool_t nfs41_recover_stateid (IN nfs41_session *session, IN struct __nfs_argop4 *argop)
 

Function Documentation

◆ nfs41_client_state_revoked()

void nfs41_client_state_revoked ( IN nfs41_session session,
IN nfs41_client client,
IN uint32_t  revoked 
)

Definition at line 633 of file recovery.c.

Referenced by nfs41_recover_sequence_flags().

637 {
640  struct list_entry empty, *opens;
641  struct client_state *clientstate = &session->client->state;
642  stateid_arg *stateids = NULL;
643  uint32_t *statuses = NULL;
644  uint32_t i, count;
645  bool_t grace = TRUE;
646  bool_t want_supported = TRUE;
647 
648  EnterCriticalSection(&clientstate->lock);
649 
650  if (revoked == SEQ4_STATUS_RECALLABLE_STATE_REVOKED) {
651  /* only delegations were revoked. use an empty list for opens */
652  list_init(&empty);
653  opens = ∅
654  } else {
655  opens = &clientstate->opens;
656  }
657 
658  /* get an array of the client's stateids */
659  count = stateid_array(&clientstate->delegations,
660  opens, &stateids, &statuses);
661  if (count == 0)
662  goto out;
663 
664  /* determine which stateids were revoked with TEST_STATEID */
665  if ((revoked & SEQ4_STATUS_EXPIRED_ALL_STATE_REVOKED) == 0)
666  nfs41_test_stateid(session, stateids, count, statuses);
667 
668  /* free all revoked stateids with FREE_STATEID */
669  for (i = 0; i < count; i++)
670  if (statuses[i])
671  nfs41_free_stateid(session, &stateids[i].stateid);
672 
673  /* revoke all of the client's layouts */
675 
676  /* recover the revoked stateids */
677  for (i = 0; i < count; i++) {
678  if (statuses[i]) {
679  if (stateids[i].type == STATEID_DELEG_FILE)
680  stateids[i].delegation->revoked = TRUE;
681  else if (stateids[i].type == STATEID_OPEN)
682  recover_open(session, stateids[i].open, &grace);
683  else if (stateids[i].type == STATEID_LOCK)
684  recover_locks(session, stateids[i].open, &grace);
685  }
686  }
687  for (i = 0; i < count; i++) {
688  /* delegations that weren't recovered by recover_open() */
689  if (statuses[i] && stateids[i].type == STATEID_DELEG_FILE
690  && stateids[i].delegation->revoked)
691  recover_delegation(session, stateids[i].delegation,
692  &grace, &want_supported);
693  }
694 
696 out:
697  LeaveCriticalSection(&clientstate->lock);
698  free(stateids);
699  free(statuses);
700 }
struct cb_recall recall
enum nfsstat4 nfs41_free_stateid(IN nfs41_session *session, IN stateid4 *stateid)
Definition: nfs41_ops.c:1870
#define TRUE
Definition: types.h:120
static int recover_open(IN nfs41_session *session, IN nfs41_open_state *open, IN OUT bool_t *grace)
Definition: recovery.c:202
#define open
Definition: acwin.h:71
int32_t bool_t
Definition: types.h:101
GLuint GLuint GLsizei count
Definition: gl.h:1545
#define free
Definition: debug_ros.c:5
enum nfsstat4 nfs41_test_stateid(IN nfs41_session *session, IN stateid_arg *stateid_array, IN uint32_t count, OUT uint32_t *status_array)
Definition: nfs41_ops.c:1900
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
struct list_entry delegations
Definition: nfs41.h:188
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
static uint32_t stateid_array(IN struct list_entry *delegations, IN struct list_entry *opens, OUT stateid_arg **stateids_out, OUT uint32_t **statuses_out)
Definition: recovery.c:547
static const WCHAR empty[]
Definition: task.c:29
GLenum GLclampf GLint i
Definition: glfuncs.h:14
smooth NULL
Definition: ftsmooth.c:416
int nfs41_client_delegation_recovery(IN nfs41_client *client)
Definition: delegation.c:861
nfs41_delegation_state * delegation
Definition: nfs41_ops.h:287
static FILE * client
Definition: client.c:41
static FILE * out
Definition: regtests2xml.c:44
CRITICAL_SECTION lock
Definition: nfs41.h:189
enum dhcp_state state
Definition: dhcpd.h:214
Definition: list.h:27
UINT32 uint32_t
Definition: types.h:75
struct list_entry opens
Definition: nfs41.h:187
__WINE_SERVER_LIST_INLINE void list_init(struct list *list)
Definition: list.h:149
static int recover_locks(IN nfs41_session *session, IN nfs41_open_state *open, IN OUT bool_t *grace)
Definition: recovery.c:281
static int recover_delegation(IN nfs41_session *session, IN nfs41_delegation_state *deleg, IN OUT bool_t *grace, IN OUT bool_t *want_supported)
Definition: recovery.c:460
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
enum pnfs_status pnfs_file_layout_recall(IN struct __nfs41_client *client, IN const struct cb_layoutrecall_args *recall)

◆ nfs41_recover_client_state()

int nfs41_recover_client_state ( IN nfs41_session session,
IN nfs41_client client 
)

Definition at line 487 of file recovery.c.

Referenced by nfs41_recover_sequence_flags(), and nfs41_recover_session().

490 {
493  struct client_state *state = &session->client->state;
494  struct list_entry *entry;
496  nfs41_delegation_state *deleg;
497  bool_t grace = TRUE;
498  bool_t want_supported = TRUE;
499  int status = NFS4_OK;
500 
501  EnterCriticalSection(&state->lock);
502 
503  /* flag all delegations as revoked until successful recovery;
504  * recover_open() and recover_delegation_open() will only ask
505  * for delegations when revoked = TRUE */
506  list_for_each(entry, &state->delegations) {
508  deleg->revoked = TRUE;
509  }
510 
511  /* recover each of the client's opens and associated delegations */
512  list_for_each(entry, &state->opens) {
514  status = recover_open(session, open, &grace);
515  if (status == NFS4_OK)
516  status = recover_locks(session, open, &grace);
517  if (status == NFS4ERR_BADSESSION)
518  goto unlock;
519  }
520 
521  /* recover delegations that weren't associated with any opens */
522  list_for_each(entry, &state->delegations) {
524  if (deleg->revoked) {
525  status = recover_delegation(session,
526  deleg, &grace, &want_supported);
527  if (status == NFS4ERR_BADSESSION)
528  goto unlock;
529  }
530  }
531 
532  /* return any delegations that were reclaimed as 'recalled' */
534 unlock:
535  LeaveCriticalSection(&state->lock);
536 
537  /* revoke all of the client's layouts */
539 
540  if (grace && status != NFS4ERR_BADSESSION) {
541  /* send reclaim_complete, but don't fail on errors */
542  nfs41_reclaim_complete(session);
543  }
544  return status;
545 }
struct cb_recall recall
#define TRUE
Definition: types.h:120
static int recover_open(IN nfs41_session *session, IN nfs41_open_state *open, IN OUT bool_t *grace)
Definition: recovery.c:202
#define open
Definition: acwin.h:71
int32_t bool_t
Definition: types.h:101
uint8_t entry
Definition: isohybrid.c:63
struct list_entry delegations
Definition: nfs41.h:188
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
#define list_for_each(entry, head)
Definition: list.h:36
#define list_container(entry, type, field)
Definition: list.h:33
int nfs41_client_delegation_recovery(IN nfs41_client *client)
Definition: delegation.c:861
#define client_entry(pos)
Definition: namespace.c:33
static FILE * client
Definition: client.c:41
CRITICAL_SECTION lock
Definition: nfs41.h:189
static int state
Definition: maze.c:121
Definition: list.h:27
struct list_entry opens
Definition: nfs41.h:187
static int recover_locks(IN nfs41_session *session, IN nfs41_open_state *open, IN OUT bool_t *grace)
Definition: recovery.c:281
static int recover_delegation(IN nfs41_session *session, IN nfs41_delegation_state *deleg, IN OUT bool_t *grace, IN OUT bool_t *want_supported)
Definition: recovery.c:460
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
static SERVICE_STATUS status
Definition: service.c:31
enum pnfs_status pnfs_file_layout_recall(IN struct __nfs41_client *client, IN const struct cb_layoutrecall_args *recall)
enum nfsstat4 nfs41_reclaim_complete(IN nfs41_session *session)
Definition: nfs41_ops.c:268
Definition: ps.c:97

◆ nfs41_recover_sequence_flags()

void nfs41_recover_sequence_flags ( IN nfs41_session session,
IN uint32_t  flags 
)

Definition at line 98 of file recovery.c.

Referenced by compound_encode_send_decode().

101 {
102  const uint32_t revoked = flags &
107  const uint32_t restarted = flags &
109 
110  /* no state recovery needed */
111  if (revoked == 0 && restarted == 0)
112  return;
113 
114  if (!nfs41_recovery_start_or_wait(session->client))
115  return;
116 
117  if (revoked) {
118  /* free stateids and attempt to recover them */
119  nfs41_client_state_revoked(session, session->client, revoked);
120 
121  /* if RESTART_RECLAIM_NEEDED is also set, just do RECLAIM_COMPLETE */
122  if (restarted) nfs41_reclaim_complete(session);
123 
124  } else if (restarted) {
125  /* do server reboot state recovery */
126  uint32_t status = nfs41_recover_client_state(session, session->client);
127  if (status == NFS4ERR_BADSESSION) {
128  /* recover the session and finish state recovery */
129  nfs41_recover_session(session, TRUE);
130  }
131  }
132 
133  nfs41_recovery_finish(session->client);
134 }
#define TRUE
Definition: types.h:120
bool_t nfs41_recovery_start_or_wait(IN nfs41_client *client)
Definition: recovery.c:34
int nfs41_recover_session(IN nfs41_session *session, IN bool_t client_state_lost)
Definition: recovery.c:69
void nfs41_recovery_finish(IN nfs41_client *client)
Definition: recovery.c:57
GLbitfield flags
Definition: glext.h:7161
int nfs41_recover_client_state(IN nfs41_session *session, IN nfs41_client *client)
Definition: recovery.c:487
void nfs41_client_state_revoked(IN nfs41_session *session, IN nfs41_client *client, IN uint32_t revoked)
Definition: recovery.c:633
UINT32 uint32_t
Definition: types.h:75
enum nfsstat4 nfs41_reclaim_complete(IN nfs41_session *session)
Definition: nfs41_ops.c:268
Definition: ps.c:97

◆ nfs41_recover_session()

int nfs41_recover_session ( IN nfs41_session session,
IN bool_t  client_state_lost 
)

Definition at line 69 of file recovery.c.

Referenced by compound_encode_send_decode(), and nfs41_recover_sequence_flags().

72 {
73  enum nfsstat4 status = NFS4_OK;
74 
75 restart_recovery:
76  /* recover the session */
77  status = nfs41_session_renew(session);
78 
79  if (status == NFS4ERR_STALE_CLIENTID) {
80  /* recover the client */
81  client_state_lost = TRUE;
82  status = nfs41_client_renew(session->client);
83  if (status == NFS4_OK)
84  goto restart_recovery; /* resume session recovery */
85 
86  eprintf("nfs41_client_renew() failed with %d\n", status);
87  } else if (status) {
88  eprintf("nfs41_session_renew() failed with %d\n", status);
89  } else if (client_state_lost) {
90  /* recover the client's state */
91  status = nfs41_recover_client_state(session, session->client);
92  if (status == NFS4ERR_BADSESSION)
93  goto restart_recovery;
94  }
95  return status;
96 }
#define TRUE
Definition: types.h:120
void eprintf(LPCSTR format,...)
Definition: daemon_debug.c:86
int nfs41_recover_client_state(IN nfs41_session *session, IN nfs41_client *client)
Definition: recovery.c:487
int nfs41_client_renew(IN nfs41_client *client)
Definition: nfs41_client.c:168
nfsstat4
Definition: nfs41_const.h:86
int nfs41_session_renew(IN nfs41_session *session)
static SERVICE_STATUS status
Definition: service.c:31
Definition: ps.c:97

◆ nfs41_recover_stateid()

bool_t nfs41_recover_stateid ( IN nfs41_session session,
IN struct __nfs_argop4 argop 
)

◆ nfs41_recovery_finish()

void nfs41_recovery_finish ( IN nfs41_client client)

Definition at line 57 of file recovery.c.

Referenced by compound_encode_send_decode(), and nfs41_recover_sequence_flags().

59 {
60  EnterCriticalSection(&client->recovery.lock);
61  dprintf(1, "Finished recovery for client %llu\n", client->clnt_id);
62  client->recovery.in_recovery = FALSE;
63  WakeAllConditionVariable(&client->recovery.cond);
64  LeaveCriticalSection(&client->recovery.lock);
65 }
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
VOID WINAPI WakeAllConditionVariable(PCONDITION_VARIABLE ConditionVariable)
Definition: sync.c:137
#define dprintf
Definition: regdump.c:33
static FILE * client
Definition: client.c:41
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)

◆ nfs41_recovery_start_or_wait()

bool_t nfs41_recovery_start_or_wait ( IN nfs41_client client)

Definition at line 34 of file recovery.c.

Referenced by compound_encode_send_decode(), and nfs41_recover_sequence_flags().

36 {
37  bool_t status = TRUE;
38 
39  EnterCriticalSection(&client->recovery.lock);
40 
41  if (!client->recovery.in_recovery) {
42  dprintf(1, "Entering recovery mode for client %llu\n", client->clnt_id);
43  client->recovery.in_recovery = TRUE;
44  } else {
45  status = FALSE;
46  dprintf(1, "Waiting for recovery of client %llu\n", client->clnt_id);
47  while (client->recovery.in_recovery)
48  SleepConditionVariableCS(&client->recovery.cond,
49  &client->recovery.lock, INFINITE);
50  dprintf(1, "Woke up after recovery of client %llu\n", client->clnt_id);
51  }
52 
53  LeaveCriticalSection(&client->recovery.lock);
54  return status;
55 }
#define TRUE
Definition: types.h:120
int32_t bool_t
Definition: types.h:101
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
#define dprintf
Definition: regdump.c:33
static FILE * client
Definition: client.c:41
BOOL WINAPI SleepConditionVariableCS(PCONDITION_VARIABLE ConditionVariable, PCRITICAL_SECTION CriticalSection, DWORD Timeout)
Definition: sync.c:105
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
#define INFINITE
Definition: serial.h:102
static SERVICE_STATUS status
Definition: service.c:31
Definition: ps.c:97