ReactOS  0.4.14-dev-115-g4576127
recovery.c File Reference
#include <time.h>
#include "recovery.h"
#include "delegation.h"
#include "nfs41_callback.h"
#include "nfs41_compound.h"
#include "nfs41_ops.h"
#include "daemon_debug.h"
Include dependency graph for recovery.c:

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)
 
static int recover_open_grace (IN nfs41_session *session, IN nfs41_path_fh *parent, IN nfs41_path_fh *file, IN state_owner4 *owner, IN uint32_t access, IN uint32_t deny, OUT stateid4 *stateid, OUT open_delegation4 *delegation)
 
static int recover_open_no_grace (IN nfs41_session *session, IN nfs41_path_fh *parent, IN nfs41_path_fh *file, IN state_owner4 *owner, IN uint32_t access, IN uint32_t deny, OUT stateid4 *stateid, OUT open_delegation4 *delegation)
 
static int recover_open (IN nfs41_session *session, IN nfs41_open_state *open, IN OUT bool_t *grace)
 
static int recover_locks (IN nfs41_session *session, IN nfs41_open_state *open, IN OUT bool_t *grace)
 
static int recover_delegation_want (IN nfs41_session *session, IN nfs41_delegation_state *deleg, IN OUT bool_t *grace)
 
static int recover_delegation_open (IN nfs41_session *session, IN nfs41_delegation_state *deleg, IN OUT bool_t *grace)
 
static int recover_delegation (IN nfs41_session *session, IN nfs41_delegation_state *deleg, IN OUT bool_t *grace, IN OUT bool_t *want_supported)
 
int nfs41_recover_client_state (IN nfs41_session *session, IN nfs41_client *client)
 
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)
 
void nfs41_client_state_revoked (IN nfs41_session *session, IN nfs41_client *client, IN uint32_t revoked)
 
static bool_t recover_stateid_open (IN nfs_argop4 *argop, IN stateid_arg *stateid)
 
static bool_t recover_stateid_lock (IN nfs_argop4 *argop, IN stateid_arg *stateid)
 
static bool_t recover_stateid_delegation (IN nfs_argop4 *argop, IN stateid_arg *stateid)
 
bool_t nfs41_recover_stateid (IN nfs41_session *session, IN 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.

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 = &empty;
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:95
int32_t bool_t
Definition: types.h:101
static const WCHAR empty[]
Definition: main.c:49
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
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
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)

Referenced by nfs41_recover_sequence_flags().

◆ 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.

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:95
int32_t bool_t
Definition: types.h:101
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
static int state
Definition: maze.c:121
uint32_t entry
Definition: isohybrid.c:63
Definition: list.h:27
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

Referenced by nfs41_recover_sequence_flags(), and nfs41_recover_session().

◆ 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.

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

Referenced by compound_encode_send_decode().

◆ 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.

72 {
73  enum nfsstat4 status = NFS4_OK;
74 
75 restart_recovery:
76  /* recover the session */
77  status = nfs41_session_renew(session);
78 
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);
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

Referenced by compound_encode_send_decode(), and nfs41_recover_sequence_flags().

◆ nfs41_recover_stateid()

bool_t nfs41_recover_stateid ( IN nfs41_session session,
IN nfs_argop4 argop 
)

Definition at line 788 of file recovery.c.

791 {
792  stateid_arg *stateid = NULL;
793 
794  /* get the stateid_arg from the operation's arguments */
795  if (argop->op == OP_OPEN) {
797  if (open->claim->claim == CLAIM_DELEGATE_CUR)
798  stateid = open->claim->u.deleg_cur.delegate_stateid;
799  else if (open->claim->claim == CLAIM_DELEG_CUR_FH)
800  stateid = open->claim->u.deleg_cur_fh.delegate_stateid;
801  } else if (argop->op == OP_CLOSE) {
803  stateid = close->stateid;
804  } else if (argop->op == OP_READ) {
805  nfs41_read_args *read = (nfs41_read_args*)argop->arg;
806  stateid = read->stateid;
807  } else if (argop->op == OP_WRITE) {
808  nfs41_write_args *write = (nfs41_write_args*)argop->arg;
809  stateid = write->stateid;
810  } else if (argop->op == OP_LOCK) {
811  nfs41_lock_args *lock = (nfs41_lock_args*)argop->arg;
812  if (lock->locker.new_lock_owner)
813  stateid = lock->locker.u.open_owner.open_stateid;
814  else
815  stateid = lock->locker.u.lock_owner.lock_stateid;
816  } else if (argop->op == OP_LOCKU) {
817  nfs41_locku_args *locku = (nfs41_locku_args*)argop->arg;
818  stateid = locku->lock_stateid;
819  } else if (argop->op == OP_SETATTR) {
820  nfs41_setattr_args *setattr = (nfs41_setattr_args*)argop->arg;
821  stateid = setattr->stateid;
822  } else if (argop->op == OP_LAYOUTGET) {
823  pnfs_layoutget_args *lget = (pnfs_layoutget_args*)argop->arg;
824  stateid = lget->stateid;
825  } else if (argop->op == OP_DELEGRETURN) {
827  stateid = dr->stateid;
828  }
829  if (stateid == NULL)
830  return FALSE;
831 
832  /* if there's recovery in progress, wait for it to finish */
833  EnterCriticalSection(&session->client->recovery.lock);
834  while (session->client->recovery.in_recovery)
835  SleepConditionVariableCS(&session->client->recovery.cond,
836  &session->client->recovery.lock, INFINITE);
837  LeaveCriticalSection(&session->client->recovery.lock);
838 
839  switch (stateid->type) {
840  case STATEID_OPEN:
841  return recover_stateid_open(argop, stateid);
842 
843  case STATEID_LOCK:
844  return recover_stateid_lock(argop, stateid);
845 
846  case STATEID_DELEG_FILE:
847  return recover_stateid_delegation(argop, stateid);
848 
849  default:
850  eprintf("%s can't recover stateid type %u\n",
851  nfs_opnum_to_string(argop->op), stateid->type);
852  break;
853  }
854  return FALSE;
855 }
static bool_t recover_stateid_open(IN nfs_argop4 *argop, IN stateid_arg *stateid)
Definition: recovery.c:703
rwlock_t lock
Definition: tcpcore.h:1163
#define open
Definition: acwin.h:95
stateid_arg * stateid
Definition: nfs41_ops.h:782
void eprintf(LPCSTR format,...)
Definition: daemon_debug.c:86
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
static bool_t recover_stateid_lock(IN nfs_argop4 *argop, IN stateid_arg *stateid)
Definition: recovery.c:723
#define write
Definition: acwin.h:97
smooth NULL
Definition: ftsmooth.c:416
stateid_arg * stateid
Definition: nfs41_ops.h:377
if(!(yy_init))
Definition: macro.lex.yy.c:714
enum stateid_type type
Definition: nfs41_ops.h:285
stateid_arg * stateid
Definition: nfs41_ops.h:912
static bool_t recover_stateid_delegation(IN nfs_argop4 *argop, IN stateid_arg *stateid)
Definition: recovery.c:752
#define close
Definition: acwin.h:98
stateid_arg * lock_stateid
Definition: nfs41_ops.h:478
BOOL WINAPI SleepConditionVariableCS(PCONDITION_VARIABLE ConditionVariable, PCRITICAL_SECTION CriticalSection, DWORD Timeout)
Definition: sync.c:105
const char * nfs_opnum_to_string(int opnum)
Definition: daemon_debug.c:305
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
#define INFINITE
Definition: serial.h:102
_CRTIMP int __cdecl read(_In_ int _FileHandle, _Out_writes_bytes_(_MaxCharCount) void *_DstBuf, _In_ unsigned int _MaxCharCount)

Referenced by compound_encode_send_decode().

◆ nfs41_recovery_finish()

void nfs41_recovery_finish ( IN nfs41_client client)

Definition at line 57 of file recovery.c.

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)

Referenced by compound_encode_send_decode(), and nfs41_recover_sequence_flags().

◆ nfs41_recovery_start_or_wait()

bool_t nfs41_recovery_start_or_wait ( IN nfs41_client client)

Definition at line 34 of file recovery.c.

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

Referenced by compound_encode_send_decode(), and nfs41_recover_sequence_flags().

◆ recover_delegation()

static int recover_delegation ( IN nfs41_session session,
IN nfs41_delegation_state deleg,
IN OUT bool_t grace,
IN OUT bool_t want_supported 
)
static

Definition at line 460 of file recovery.c.

465 {
466  int status;
467 
468  /* 10.2.1. Delegation Recovery
469  * When a client needs to reclaim a delegation and there is no
470  * associated open, the client may use the CLAIM_PREVIOUS variant
471  * of the WANT_DELEGATION operation. However, since the server is
472  * not required to support this operation, an alternative is to
473  * reclaim via a dummy OPEN together with the delegation using an
474  * OPEN of type CLAIM_PREVIOUS. */
475  if (*want_supported)
476  status = recover_delegation_want(session, deleg, grace);
477  else
479 
480  if (status == NFS4ERR_NOTSUPP) {
481  *want_supported = FALSE;
482  status = recover_delegation_open(session, deleg, grace);
483  }
484  return status;
485 }
static int recover_delegation_open(IN nfs41_session *session, IN nfs41_delegation_state *deleg, IN OUT bool_t *grace)
Definition: recovery.c:396
static int recover_delegation_want(IN nfs41_session *session, IN nfs41_delegation_state *deleg, IN OUT bool_t *grace)
Definition: recovery.c:338
static SERVICE_STATUS status
Definition: service.c:31
Definition: ps.c:97

Referenced by nfs41_client_state_revoked(), and nfs41_recover_client_state().

◆ recover_delegation_open()

static int recover_delegation_open ( IN nfs41_session session,
IN nfs41_delegation_state deleg,
IN OUT bool_t grace 
)
static

Definition at line 396 of file recovery.c.

400 {
401  state_owner4 owner;
402  open_delegation4 delegation = { 0 };
403  stateid_arg stateid;
406  int status = NFS4_OK;
407 
408  /* choose the desired access mode based on delegation type */
409  AcquireSRWLockShared(&deleg->lock);
410  delegation.type = deleg->state.type;
411  if (delegation.type == OPEN_DELEGATE_WRITE)
413  else
415  ReleaseSRWLockShared(&deleg->lock);
416 
417  /* construct a temporary open owner by concatenating the time
418  * in seconds with the delegation pointer */
419  time((time_t*)owner.owner);
420  memcpy(owner.owner + sizeof(time_t), deleg, sizeof(deleg));
421  owner.owner_len = sizeof(time_t) + sizeof(deleg);
422 
423  if (*grace) {
424  status = recover_open_grace(session, &deleg->parent, &deleg->file,
425  &owner, access, deny, &stateid.stateid, &delegation);
426  if (status == NFS4ERR_NO_GRACE) {
427  *grace = FALSE;
428  /* send RECLAIM_COMPLETE before any out-of-grace recovery */
429  nfs41_reclaim_complete(session);
430  }
431  }
432  if (!*grace) {
433  status = recover_open_no_grace(session, &deleg->parent, &deleg->file,
434  &owner, access, deny, &stateid.stateid, &delegation);
435  }
436  if (status)
437  goto out;
438 
439  /* update delegation state */
440  AcquireSRWLockExclusive(&deleg->lock);
441  if (delegation.type != OPEN_DELEGATE_READ &&
442  delegation.type != OPEN_DELEGATE_WRITE) {
443  eprintf("recover_delegation_open() got delegation type %u, "
444  "expected %u\n", delegation.type, deleg->state.type);
445  } else {
446  memcpy(&deleg->state, &delegation, sizeof(open_delegation4));
447  deleg->revoked = FALSE;
448  }
449  ReleaseSRWLockExclusive(&deleg->lock);
450 
451  /* send CLOSE to free the open stateid */
452  stateid.open = NULL;
453  stateid.delegation = NULL;
454  stateid.type = STATEID_OPEN;
455  nfs41_close(session, &deleg->file, &stateid);
456 out:
457  return status;
458 }
VOID WINAPI AcquireSRWLockExclusive(PSRWLOCK Lock)
Definition: sync.c:54
void eprintf(LPCSTR format,...)
Definition: daemon_debug.c:86
__u16 time
Definition: mkdosfs.c:366
unsigned char owner[NFS4_OPAQUE_LIMIT]
Definition: nfs41_types.h:119
static int recover_open_no_grace(IN nfs41_session *session, IN nfs41_path_fh *parent, IN nfs41_path_fh *file, IN state_owner4 *owner, IN uint32_t access, IN uint32_t deny, OUT stateid4 *stateid, OUT open_delegation4 *delegation)
Definition: recovery.c:157
smooth NULL
Definition: ftsmooth.c:416
static int recover_open_grace(IN nfs41_session *session, IN nfs41_path_fh *parent, IN nfs41_path_fh *file, IN state_owner4 *owner, IN uint32_t access, IN uint32_t deny, OUT stateid4 *stateid, OUT open_delegation4 *delegation)
Definition: recovery.c:138
uint32_t owner_len
Definition: nfs41_types.h:118
enum stateid_type type
Definition: nfs41_ops.h:285
nfs41_delegation_state * delegation
Definition: nfs41_ops.h:287
enum open_delegation_type4 type
Definition: nfs41_types.h:154
static FILE * out
Definition: regtests2xml.c:44
nfs41_open_state * open
Definition: nfs41_ops.h:286
VOID WINAPI ReleaseSRWLockExclusive(PSRWLOCK Lock)
Definition: sync.c:82
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
__kernel_time_t time_t
Definition: linux.h:252
GLuint GLint GLboolean GLint GLenum access
Definition: glext.h:7866
stateid4 stateid
Definition: nfs41_ops.h:284
int nfs41_close(IN nfs41_session *session, IN nfs41_path_fh *file, IN stateid_arg *stateid)
Definition: nfs41_ops.c:627
UINT32 uint32_t
Definition: types.h:75
static SERVICE_STATUS status
Definition: service.c:31
VOID WINAPI AcquireSRWLockShared(PSRWLOCK Lock)
Definition: sync.c:61
VOID WINAPI ReleaseSRWLockShared(PSRWLOCK Lock)
Definition: sync.c:89
enum nfsstat4 nfs41_reclaim_complete(IN nfs41_session *session)
Definition: nfs41_ops.c:268
Definition: ps.c:97

Referenced by recover_delegation().

◆ recover_delegation_want()

static int recover_delegation_want ( IN nfs41_session session,
IN nfs41_delegation_state deleg,
IN OUT bool_t grace 
)
static

Definition at line 338 of file recovery.c.

342 {
343  deleg_claim4 claim;
344  open_delegation4 delegation = { 0 };
345  uint32_t want_flags = 0;
346  int status = NFS4_OK;
347 
348  AcquireSRWLockShared(&deleg->lock);
349  delegation.type = deleg->state.type;
350  ReleaseSRWLockShared(&deleg->lock);
351 
352  if (delegation.type == OPEN_DELEGATE_READ)
354  else
356 
357  if (*grace) {
358  /* recover the delegation with WANT_DELEGATION/CLAIM_PREVIOUS */
359  claim.claim = CLAIM_PREVIOUS;
360  claim.prev_delegate_type = delegation.type;
361 
362  status = nfs41_want_delegation(session, &deleg->file, &claim,
363  want_flags, FALSE, &delegation);
364  if (status == NFS4ERR_NO_GRACE) {
365  *grace = FALSE;
366  /* send RECLAIM_COMPLETE before any out-of-grace recovery */
367  nfs41_reclaim_complete(session);
368  }
369  }
370  if (!*grace) {
371  /* attempt out-of-grace recovery with with CLAIM_DELEG_PREV_FH */
372  claim.claim = CLAIM_DELEG_PREV_FH;
373 
374  status = nfs41_want_delegation(session, &deleg->file, &claim,
375  want_flags, FALSE, &delegation);
376  }
377  if (status)
378  goto out;
379 
380  /* update delegation state */
381  AcquireSRWLockExclusive(&deleg->lock);
382  if (delegation.type != OPEN_DELEGATE_READ &&
383  delegation.type != OPEN_DELEGATE_WRITE) {
384  eprintf("recover_delegation_want() got delegation type %u, "
385  "expected %u\n", delegation.type, deleg->state.type);
386  } else {
387  memcpy(&deleg->state, &delegation, sizeof(open_delegation4));
388  deleg->revoked = FALSE;
389  }
390  ReleaseSRWLockExclusive(&deleg->lock);
391 out:
392  return status;
393 }
VOID WINAPI AcquireSRWLockExclusive(PSRWLOCK Lock)
Definition: sync.c:54
enum nfsstat4 nfs41_want_delegation(IN nfs41_session *session, IN nfs41_path_fh *file, IN deleg_claim4 *claim, IN uint32_t want, IN bool_t try_recovery, OUT open_delegation4 *delegation)
Definition: nfs41_ops.c:1624
void eprintf(LPCSTR format,...)
Definition: daemon_debug.c:86
uint32_t prev_delegate_type
Definition: nfs41_ops.h:796
enum open_delegation_type4 type
Definition: nfs41_types.h:154
static FILE * out
Definition: regtests2xml.c:44
VOID WINAPI ReleaseSRWLockExclusive(PSRWLOCK Lock)
Definition: sync.c:82
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
UINT32 uint32_t
Definition: types.h:75
uint32_t claim
Definition: nfs41_ops.h:794
static SERVICE_STATUS status
Definition: service.c:31
VOID WINAPI AcquireSRWLockShared(PSRWLOCK Lock)
Definition: sync.c:61
VOID WINAPI ReleaseSRWLockShared(PSRWLOCK Lock)
Definition: sync.c:89
enum nfsstat4 nfs41_reclaim_complete(IN nfs41_session *session)
Definition: nfs41_ops.c:268
Definition: ps.c:97

Referenced by recover_delegation().

◆ recover_locks()

static int recover_locks ( IN nfs41_session session,
IN nfs41_open_state open,
IN OUT bool_t grace 
)
static

Definition at line 281 of file recovery.c.

285 {
286  stateid_arg stateid;
287  struct list_entry *entry;
289  int status = NFS4_OK;
290 
292 
293  /* initialize the open stateid for the first lock request */
294  memcpy(&stateid.stateid, &open->stateid, sizeof(stateid4));
295  stateid.type = STATEID_OPEN;
296  stateid.open = open;
297  stateid.delegation = NULL;
298 
299  /* recover any locks for this open */
300  list_for_each(entry, &open->locks.list) {
302  if (lock->delegated)
303  continue;
304 
305  if (*grace) {
306  status = nfs41_lock(session, &open->file, &open->owner,
307  lock->exclusive ? WRITE_LT : READ_LT, lock->offset,
308  lock->length, TRUE, FALSE, &stateid);
309  if (status == NFS4ERR_NO_GRACE) {
310  *grace = FALSE;
311  /* send RECLAIM_COMPLETE before any out-of-grace recovery */
312  nfs41_reclaim_complete(session);
313  }
314  }
315  if (!*grace) {
316  /* attempt out-of-grace recovery with a normal LOCK */
317  status = nfs41_lock(session, &open->file, &open->owner,
318  lock->exclusive ? WRITE_LT : READ_LT, lock->offset,
319  lock->length, FALSE, FALSE, &stateid);
320  }
321  if (status == NFS4ERR_BADSESSION)
322  break;
323  }
324 
325  if (status != NFS4ERR_BADSESSION) {
326  /* if we got a lock stateid back, save the lock with the open */
327  if (stateid.type == STATEID_LOCK)
328  memcpy(&open->locks.stateid, &stateid.stateid, sizeof(stateid4));
329  else
330  open->locks.stateid.seqid = 0;
331  }
332 
334  return status;
335 }
VOID WINAPI AcquireSRWLockExclusive(PSRWLOCK Lock)
Definition: sync.c:54
#define TRUE
Definition: types.h:120
rwlock_t lock
Definition: tcpcore.h:1163
#define open
Definition: acwin.h:95
#define list_for_each(entry, head)
Definition: list.h:36
smooth NULL
Definition: ftsmooth.c:416
#define list_container(entry, type, field)
Definition: list.h:33
enum stateid_type type
Definition: nfs41_ops.h:285
nfs41_delegation_state * delegation
Definition: nfs41_ops.h:287
nfs41_open_state * open
Definition: nfs41_ops.h:286
VOID WINAPI ReleaseSRWLockExclusive(PSRWLOCK Lock)
Definition: sync.c:82
uint32_t entry
Definition: isohybrid.c:63
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
int nfs41_lock(IN nfs41_session *session, IN nfs41_path_fh *file, IN state_owner4 *owner, IN uint32_t type, IN uint64_t offset, IN uint64_t length, IN bool_t reclaim, IN bool_t try_recovery, IN OUT stateid_arg *stateid)
Definition: nfs41_ops.c:904
stateid4 stateid
Definition: nfs41_ops.h:284
Definition: list.h:27
#define open_entry(pos)
Definition: delegation.c:89
static SERVICE_STATUS status
Definition: service.c:31
enum nfsstat4 nfs41_reclaim_complete(IN nfs41_session *session)
Definition: nfs41_ops.c:268
Definition: ps.c:97

Referenced by nfs41_client_state_revoked(), and nfs41_recover_client_state().

◆ recover_open()

static int recover_open ( IN nfs41_session session,
IN nfs41_open_state open,
IN OUT bool_t grace 
)
static

Definition at line 202 of file recovery.c.

206 {
207  open_delegation4 delegation = { 0 };
208  stateid4 stateid = { 0 };
210 
211  /* check for an associated delegation */
213  if (open->delegation.state) {
214  nfs41_delegation_state *deleg = open->delegation.state;
215  if (deleg->revoked) {
216  /* reclaim the delegation along with the open */
217  AcquireSRWLockShared(&deleg->lock);
218  delegation.type = deleg->state.type;
219  ReleaseSRWLockShared(&deleg->lock);
220  } else if (deleg->state.recalled) {
221  /* we'll need an open stateid regardless */
222  } else if (list_empty(&open->locks.list)) {
223  /* if there are locks, we need an open stateid to
224  * reclaim them; otherwise, the open can be delegated */
225  open->do_close = FALSE;
226  status = NFS4_OK;
227  }
228  }
230 
231  if (status == NFS4_OK) /* use existing delegation */
232  goto out;
233 
234  if (*grace) {
235  status = recover_open_grace(session, &open->parent, &open->file,
236  &open->owner, open->share_access, open->share_deny,
237  &stateid, &delegation);
238  if (status == NFS4ERR_NO_GRACE) {
239  *grace = FALSE;
240  /* send RECLAIM_COMPLETE before any out-of-grace recovery */
241  nfs41_reclaim_complete(session);
242  }
243  }
244  if (!*grace) {
245  status = recover_open_no_grace(session, &open->parent, &open->file,
246  &open->owner, open->share_access, open->share_deny,
247  &stateid, &delegation);
248  }
249 
250  if (status)
251  goto out;
252 
254  /* update the open stateid */
255  memcpy(&open->stateid, &stateid, sizeof(stateid4));
256  open->do_close = TRUE;
257 
258  if (open->delegation.state) {
259  nfs41_delegation_state *deleg = open->delegation.state;
260  if (deleg->revoked) {
261  /* update delegation state */
262  AcquireSRWLockExclusive(&deleg->lock);
263  if (delegation.type != OPEN_DELEGATE_READ &&
264  delegation.type != OPEN_DELEGATE_WRITE) {
265  eprintf("recover_open() got delegation type %u, "
266  "expected %u\n", delegation.type, deleg->state.type);
267  } else {
268  memcpy(&deleg->state, &delegation, sizeof(open_delegation4));
269  deleg->revoked = FALSE;
270  }
271  ReleaseSRWLockExclusive(&deleg->lock);
272  }
273  } else /* granted a new delegation? */
274  nfs41_delegation_granted(session, &open->parent, &open->file,
275  &delegation, FALSE, &open->delegation.state);
277 out:
278  return status;
279 }
VOID WINAPI AcquireSRWLockExclusive(PSRWLOCK Lock)
Definition: sync.c:54
#define TRUE
Definition: types.h:120
#define open
Definition: acwin.h:95
void eprintf(LPCSTR format,...)
Definition: daemon_debug.c:86
static int recover_open_no_grace(IN nfs41_session *session, IN nfs41_path_fh *parent, IN nfs41_path_fh *file, IN state_owner4 *owner, IN uint32_t access, IN uint32_t deny, OUT stateid4 *stateid, OUT open_delegation4 *delegation)
Definition: recovery.c:157
static int recover_open_grace(IN nfs41_session *session, IN nfs41_path_fh *parent, IN nfs41_path_fh *file, IN state_owner4 *owner, IN uint32_t access, IN uint32_t deny, OUT stateid4 *stateid, OUT open_delegation4 *delegation)
Definition: recovery.c:138
open_delegation4 state
Definition: nfs41.h:96
enum open_delegation_type4 type
Definition: nfs41_types.h:154
static FILE * out
Definition: regtests2xml.c:44
VOID WINAPI ReleaseSRWLockExclusive(PSRWLOCK Lock)
Definition: sync.c:82
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
__WINE_SERVER_LIST_INLINE int list_empty(const struct list *list)
Definition: list.h:143
int nfs41_delegation_granted(IN nfs41_session *session, IN nfs41_path_fh *parent, IN nfs41_path_fh *file, IN open_delegation4 *delegation, IN bool_t try_recovery, OUT nfs41_delegation_state **deleg_out)
Definition: delegation.c:330
static SERVICE_STATUS status
Definition: service.c:31
VOID WINAPI AcquireSRWLockShared(PSRWLOCK Lock)
Definition: sync.c:61
VOID WINAPI ReleaseSRWLockShared(PSRWLOCK Lock)
Definition: sync.c:89
enum nfsstat4 nfs41_reclaim_complete(IN nfs41_session *session)
Definition: nfs41_ops.c:268
Definition: ps.c:97

Referenced by nfs41_client_state_revoked(), and nfs41_recover_client_state().

◆ recover_open_grace()

static int recover_open_grace ( IN nfs41_session session,
IN nfs41_path_fh parent,
IN nfs41_path_fh file,
IN state_owner4 owner,
IN uint32_t  access,
IN uint32_t  deny,
OUT stateid4 stateid,
OUT open_delegation4 delegation 
)
static

Definition at line 138 of file recovery.c.

147 {
148  /* reclaim the open stateid with CLAIM_PREVIOUS */
149  open_claim4 claim;
150  claim.claim = CLAIM_PREVIOUS;
151  claim.u.prev.delegate_type = delegation->type;
152 
153  return nfs41_open(session, parent, file, owner, &claim, access, deny,
154  OPEN4_NOCREATE, 0, NULL, FALSE, stateid, delegation, NULL);
155 }
smooth NULL
Definition: ftsmooth.c:416
r parent
Definition: btrfs.c:2897
union __open_claim4::@40 u
int nfs41_open(IN nfs41_session *session, IN nfs41_path_fh *parent, IN nfs41_path_fh *file, IN state_owner4 *owner, IN open_claim4 *claim, IN uint32_t allow, IN uint32_t deny, IN uint32_t create, IN uint32_t how_mode, IN OPTIONAL nfs41_file_info *createattrs, IN bool_t try_recovery, OUT stateid4 *stateid, OUT open_delegation4 *delegation, OUT OPTIONAL nfs41_file_info *info)
Definition: nfs41_ops.c:366
GLuint GLint GLboolean GLint GLenum access
Definition: glext.h:7866
uint32_t claim
Definition: nfs41_ops.h:615
struct __open_claim4::@40::__open_claim_prev prev
Definition: fci.c:126

Referenced by recover_delegation_open(), and recover_open().

◆ recover_open_no_grace()

static int recover_open_no_grace ( IN nfs41_session session,
IN nfs41_path_fh parent,
IN nfs41_path_fh file,
IN state_owner4 owner,
IN uint32_t  access,
IN uint32_t  deny,
OUT stateid4 stateid,
OUT open_delegation4 delegation 
)
static

Definition at line 157 of file recovery.c.

166 {
167  open_claim4 claim;
168  int status;
169 
170  if (delegation->type != OPEN_DELEGATE_NONE) {
171  /* attempt out-of-grace recovery with CLAIM_DELEGATE_PREV */
172  claim.claim = CLAIM_DELEGATE_PREV;
173  claim.u.deleg_prev.filename = &file->name;
174 
175  status = nfs41_open(session, parent, file, owner,
176  &claim, access, deny, OPEN4_NOCREATE, 0, NULL, FALSE,
177  stateid, delegation, NULL);
179  goto out;
180 
181  /* server support for CLAIM_DELEGATE_PREV is optional;
182  * fall back to CLAIM_NULL on errors */
183  }
184 
185  /* attempt out-of-grace recovery with CLAIM_NULL */
186  claim.claim = CLAIM_NULL;
187  claim.u.null.filename = &file->name;
188 
189  /* ask nicely for the delegation we had */
190  if (delegation->type == OPEN_DELEGATE_READ)
192  else if (delegation->type == OPEN_DELEGATE_WRITE)
194 
195  status = nfs41_open(session, parent, file, owner,
196  &claim, access, deny, OPEN4_NOCREATE, 0, NULL, FALSE,
197  stateid, delegation, NULL);
198 out:
199  return status;
200 }
char name[1]
Definition: fci.c:135
smooth NULL
Definition: ftsmooth.c:416
r parent
Definition: btrfs.c:2897
static FILE * out
Definition: regtests2xml.c:44
union __open_claim4::@40 u
int nfs41_open(IN nfs41_session *session, IN nfs41_path_fh *parent, IN nfs41_path_fh *file, IN state_owner4 *owner, IN open_claim4 *claim, IN uint32_t allow, IN uint32_t deny, IN uint32_t create, IN uint32_t how_mode, IN OPTIONAL nfs41_file_info *createattrs, IN bool_t try_recovery, OUT stateid4 *stateid, OUT open_delegation4 *delegation, OUT OPTIONAL nfs41_file_info *info)
Definition: nfs41_ops.c:366
struct __open_claim4::@40::__open_claim_null null
GLuint GLint GLboolean GLint GLenum access
Definition: glext.h:7866
struct __open_claim4::@40::__open_claim_deleg_prev deleg_prev
uint32_t claim
Definition: nfs41_ops.h:615
static SERVICE_STATUS status
Definition: service.c:31
Definition: fci.c:126
Definition: ps.c:97

Referenced by recover_delegation_open(), and recover_open().

◆ recover_stateid_delegation()

static bool_t recover_stateid_delegation ( IN nfs_argop4 argop,
IN stateid_arg stateid 
)
static

Definition at line 752 of file recovery.c.

755 {
756  bool_t retry = FALSE;
757 
758  if (stateid->open) {
759  /* if the source stateid is different, update and retry */
760  AcquireSRWLockShared(&stateid->open->lock);
761  if (argop->op == OP_OPEN && stateid->open->do_close) {
762  /* for nfs41_delegation_to_open(); if we've already reclaimed
763  * an open stateid, just fail this OPEN with BAD_STATEID */
764  } else if (stateid->open->delegation.state) {
765  nfs41_delegation_state *deleg = stateid->open->delegation.state;
766  stateid4 *source = &deleg->state.stateid;
767  AcquireSRWLockShared(&deleg->lock);
768  if (memcmp(&stateid->stateid, source, sizeof(stateid4))) {
769  memcpy(&stateid->stateid, source, sizeof(stateid4));
770  retry = TRUE;
771  }
772  ReleaseSRWLockShared(&deleg->lock);
773  }
774  ReleaseSRWLockShared(&stateid->open->lock);
775  } else if (stateid->delegation) {
776  nfs41_delegation_state *deleg = stateid->delegation;
777  stateid4 *source = &deleg->state.stateid;
778  AcquireSRWLockShared(&deleg->lock);
779  if (memcmp(&stateid->stateid, source, sizeof(stateid4))) {
780  memcpy(&stateid->stateid, source, sizeof(stateid4));
781  retry = TRUE;
782  }
783  ReleaseSRWLockShared(&deleg->lock);
784  }
785  return retry;
786 }
#define TRUE
Definition: types.h:120
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
int32_t bool_t
Definition: types.h:101
open_delegation4 state
Definition: nfs41.h:96
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
VOID WINAPI AcquireSRWLockShared(PSRWLOCK Lock)
Definition: sync.c:61
VOID WINAPI ReleaseSRWLockShared(PSRWLOCK Lock)
Definition: sync.c:89

Referenced by nfs41_recover_stateid().

◆ recover_stateid_lock()

static bool_t recover_stateid_lock ( IN nfs_argop4 argop,
IN stateid_arg stateid 
)
static

Definition at line 723 of file recovery.c.

726 {
727  bool_t retry = FALSE;
728 
729  if (stateid->open) {
730  stateid4 *source = &stateid->open->locks.stateid;
731 
732  /* if the source stateid is different, update and retry */
733  AcquireSRWLockShared(&stateid->open->lock);
734  if (memcmp(&stateid->stateid, source, sizeof(stateid4))) {
735  if (argop->op == OP_LOCK && source->seqid == 0) {
736  /* resend LOCK with an open stateid */
737  nfs41_lock_args *lock = (nfs41_lock_args*)argop->arg;
738  lock->locker.new_lock_owner = 1;
739  lock->locker.u.open_owner.open_stateid = stateid;
740  lock->locker.u.open_owner.lock_owner = &stateid->open->owner;
741  source = &stateid->open->stateid;
742  }
743 
744  memcpy(&stateid->stateid, source, sizeof(stateid4));
745  retry = TRUE;
746  }
747  ReleaseSRWLockShared(&stateid->open->lock);
748  }
749  return retry;
750 }
#define TRUE
Definition: types.h:120
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
rwlock_t lock
Definition: tcpcore.h:1163
int32_t bool_t
Definition: types.h:101
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
VOID WINAPI AcquireSRWLockShared(PSRWLOCK Lock)
Definition: sync.c:61
VOID WINAPI ReleaseSRWLockShared(PSRWLOCK Lock)
Definition: sync.c:89

Referenced by nfs41_recover_stateid().

◆ recover_stateid_open()

static bool_t recover_stateid_open ( IN nfs_argop4 argop,
IN stateid_arg stateid 
)
static

Definition at line 703 of file recovery.c.

706 {
707  bool_t retry = FALSE;
708 
709  if (stateid->open) {
710  stateid4 *source = &stateid->open->stateid;
711 
712  /* if the source stateid is different, update and retry */
713  AcquireSRWLockShared(&stateid->open->lock);
714  if (memcmp(&stateid->stateid, source, sizeof(stateid4))) {
715  memcpy(&stateid->stateid, source, sizeof(stateid4));
716  retry = TRUE;
717  }
718  ReleaseSRWLockShared(&stateid->open->lock);
719  }
720  return retry;
721 }
#define TRUE
Definition: types.h:120
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
int32_t bool_t
Definition: types.h:101
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
VOID WINAPI AcquireSRWLockShared(PSRWLOCK Lock)
Definition: sync.c:61
VOID WINAPI ReleaseSRWLockShared(PSRWLOCK Lock)
Definition: sync.c:89

Referenced by nfs41_recover_stateid().

◆ stateid_array()

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 
)
static

Definition at line 547 of file recovery.c.

552 {
553  struct list_entry *entry;
555  nfs41_delegation_state *deleg;
556  stateid_arg *stateids = NULL;
557  uint32_t *statuses = NULL;
558  uint32_t i = 0, count = 0;
559 
560  /* count how many stateids the client needs to test */
561  list_for_each(entry, delegations)
562  count++;
563  list_for_each(entry, opens)
564  count += 3; /* open and potentially lock and layout */
565 
566  if (count == 0)
567  goto out;
568 
569  /* allocate the stateid and status arrays */
570  stateids = calloc(count, sizeof(stateid_arg));
571  if (stateids == NULL)
572  goto out_err;
573  statuses = calloc(count, sizeof(uint32_t));
574  if (statuses == NULL)
575  goto out_err;
576  memset(statuses, NFS4ERR_BAD_STATEID, count * sizeof(uint32_t));
577 
578  /* copy stateids into the array */
579  list_for_each(entry, delegations) {
581  AcquireSRWLockShared(&deleg->lock);
582  /* delegation stateid */
583  memcpy(&stateids[i].stateid, &deleg->state.stateid, sizeof(stateid4));
584  stateids[i].type = STATEID_DELEG_FILE;
585  stateids[i].delegation = deleg;
586  i++;
587  ReleaseSRWLockShared(&deleg->lock);
588  }
589 
590  list_for_each(entry, opens) {
592 
593  AcquireSRWLockShared(&open->lock);
594  /* open stateid */
595  memcpy(&stateids[i].stateid, &open->stateid, sizeof(stateid4));
596  stateids[i].type = STATEID_OPEN;
597  stateids[i].open = open;
598  i++;
599 
600  if (open->locks.stateid.seqid) { /* lock stateid? */
601  memcpy(&stateids[i].stateid, &open->locks.stateid, sizeof(stateid4));
602  stateids[i].type = STATEID_LOCK;
603  stateids[i].open = open;
604  i++;
605  }
606 
607  if (open->layout) { /* layout stateid? */
608  AcquireSRWLockShared(&open->layout->lock);
609  if (open->layout->stateid.seqid) {
610  memcpy(&stateids[i].stateid, &open->layout->stateid, sizeof(stateid4));
611  stateids[i].type = STATEID_LAYOUT;
612  stateids[i].open = open;
613  i++;
614  }
615  ReleaseSRWLockShared(&open->layout->lock);
616  }
617  ReleaseSRWLockShared(&open->lock);
618  }
619 
620  count = i;
621  *stateids_out = stateids;
622  *statuses_out = statuses;
623 out:
624  return count;
625 
626 out_err:
627  free(stateids);
628  free(statuses);
629  count = 0;
630  goto out;
631 }
#define open
Definition: acwin.h:95
GLuint GLuint GLsizei count
Definition: gl.h:1545
#define free
Definition: debug_ros.c:5
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define list_for_each(entry, head)
Definition: list.h:36
smooth NULL
Definition: ftsmooth.c:416
#define list_container(entry, type, field)
Definition: list.h:33
#define client_entry(pos)
Definition: namespace.c:33
open_delegation4 state
Definition: nfs41.h:96
enum stateid_type type
Definition: nfs41_ops.h:285
nfs41_delegation_state * delegation
Definition: nfs41_ops.h:287
static FILE * out
Definition: regtests2xml.c:44
nfs41_open_state * open
Definition: nfs41_ops.h:286
uint32_t entry
Definition: isohybrid.c:63
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
Definition: list.h:27
UINT32 uint32_t
Definition: types.h:75
#define calloc
Definition: rosglue.h:14
#define memset(x, y, z)
Definition: compat.h:39
VOID WINAPI AcquireSRWLockShared(PSRWLOCK Lock)
Definition: sync.c:61
VOID WINAPI ReleaseSRWLockShared(PSRWLOCK Lock)
Definition: sync.c:89

Referenced by nfs41_client_state_revoked(), and nfs41_test_stateid().