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

Go to the source code of this file.

Macros

#define DELEGATION_RETURN_ON_CONFLICT
 

Functions

void nfs41_delegation_ref (IN nfs41_delegation_state *state)
 
void nfs41_delegation_deref (IN nfs41_delegation_state *state)
 
void nfs41_client_delegation_free (IN nfs41_client *client)
 
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)
 
int nfs41_delegate_open (IN nfs41_open_state *state, IN uint32_t create, IN OPTIONAL nfs41_file_info *createattrs, OUT nfs41_file_info *info)
 
int nfs41_delegation_to_open (IN nfs41_open_state *open, IN bool_t try_recovery)
 
void nfs41_delegation_remove_srvopen (IN nfs41_session *session, IN nfs41_path_fh *file)
 
int nfs41_delegation_return (IN nfs41_session *session, IN nfs41_path_fh *file, IN enum open_delegation_type4 access, IN bool_t truncate)
 
int nfs41_delegation_recall (IN nfs41_client *client, IN nfs41_fh *fh, IN const stateid4 *stateid, IN bool_t truncate)
 
int nfs41_delegation_getattr (IN nfs41_client *client, IN const nfs41_fh *fh, IN const bitmap4 *attr_request, OUT nfs41_file_info *info)
 
int nfs41_client_delegation_recovery (IN nfs41_client *client)
 
int nfs41_client_delegation_return_lru (IN nfs41_client *client)
 

Macro Definition Documentation

◆ DELEGATION_RETURN_ON_CONFLICT

#define DELEGATION_RETURN_ON_CONFLICT

Definition at line 29 of file delegation.h.

Function Documentation

◆ nfs41_client_delegation_free()

void nfs41_client_delegation_free ( IN nfs41_client client)

Definition at line 828 of file delegation.c.

Referenced by nfs41_client_free().

830 {
831  struct list_entry *entry, *tmp;
832 
833  EnterCriticalSection(&client->state.lock);
834  list_for_each_tmp (entry, tmp, &client->state.delegations) {
835  list_remove(entry);
837  }
838  LeaveCriticalSection(&client->state.lock);
839 }
#define deleg_entry(pos)
Definition: delegation.c:377
uint8_t entry
Definition: isohybrid.c:63
void nfs41_delegation_deref(IN nfs41_delegation_state *state)
Definition: delegation.c:79
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
__WINE_SERVER_LIST_INLINE void list_remove(struct list *elem)
Definition: list.h:108
static FILE * client
Definition: client.c:41
Definition: list.h:27
#define list_for_each_tmp(entry, tmp, head)
Definition: list.h:39
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)

◆ nfs41_client_delegation_recovery()

int nfs41_client_delegation_recovery ( IN nfs41_client client)

Definition at line 861 of file delegation.c.

Referenced by nfs41_client_state_revoked(), and nfs41_recover_client_state().

863 {
864  struct list_entry *entry, *tmp;
865  nfs41_delegation_state *deleg;
866  int status = NFS4_OK;
867 
868  list_for_each_tmp(entry, tmp, &client->state.delegations) {
870 
871  status = delegation_recovery_status(deleg);
872  switch (status) {
874  /* the delegation was reclaimed, but flagged as recalled;
875  * return it with try_recovery=FALSE */
876  status = delegation_return(client, deleg, FALSE, FALSE);
877  break;
878 
879  case NFS4ERR_BADHANDLE:
880  /* reclaim failed, so we have no delegation state on the server;
881  * 'forget' the delegation without trying to return it */
882  delegation_remove(client, deleg);
883  status = NFS4_OK;
884  break;
885  }
886 
887  if (status == NFS4ERR_BADSESSION)
888  goto out;
889  }
890 
891  /* use DELEGPURGE to indicate that we're done reclaiming delegations */
892  status = nfs41_delegpurge(client->session);
893 
894  /* support for DELEGPURGE is optional; ignore any errors but BADSESSION */
895  if (status != NFS4ERR_BADSESSION)
896  status = NFS4_OK;
897 out:
898  return status;
899 }
uint8_t entry
Definition: isohybrid.c:63
int nfs41_delegpurge(IN nfs41_session *session)
Definition: nfs41_ops.c:1666
static void delegation_remove(IN nfs41_client *client, IN nfs41_delegation_state *deleg)
Definition: delegation.c:91
#define list_container(entry, type, field)
Definition: list.h:33
#define client_entry(pos)
Definition: namespace.c:33
static int delegation_return(IN nfs41_client *client, IN nfs41_delegation_state *deleg, IN bool_t truncate, IN bool_t try_recovery)
Definition: delegation.c:264
static int delegation_recovery_status(IN nfs41_delegation_state *deleg)
Definition: delegation.c:842
static FILE * client
Definition: client.c:41
static FILE * out
Definition: regtests2xml.c:44
Definition: list.h:27
#define list_for_each_tmp(entry, tmp, head)
Definition: list.h:39
static SERVICE_STATUS status
Definition: service.c:31
Definition: ps.c:97

◆ nfs41_client_delegation_return_lru()

int nfs41_client_delegation_return_lru ( IN nfs41_client client)

Definition at line 902 of file delegation.c.

Referenced by open_update_cache().

904 {
905  struct list_entry *entry;
908 
909  /* starting from the least recently opened, find and return
910  * the first delegation that's not 'in use' (currently open) */
911 
912  /* TODO: use a more robust algorithm, taking into account:
913  * -number of total opens
914  * -time since last operation on an associated open, or
915  * -number of operations/second over last n seconds */
916  EnterCriticalSection(&client->state.lock);
917  list_for_each(entry, &client->state.delegations) {
918  state = deleg_entry(entry);
919 
920  /* skip if it's currently in use for an open; note that ref_count
921  * can't go from 1 to 2 without holding client->state.lock */
922  if (state->ref_count > 1)
923  continue;
924 
925  AcquireSRWLockExclusive(&state->lock);
926  if (state->status == DELEGATION_GRANTED) {
927  /* start returning the delegation */
928  state->status = DELEGATION_RETURNING;
929  status = NFS4ERR_DELEG_REVOKED;
930  }
931  ReleaseSRWLockExclusive(&state->lock);
932 
933  if (status == NFS4ERR_DELEG_REVOKED)
934  break;
935  }
936  LeaveCriticalSection(&client->state.lock);
937 
938  if (status == NFS4ERR_DELEG_REVOKED)
939  status = delegation_return(client, state, FALSE, TRUE);
940  return status;
941 }
VOID WINAPI AcquireSRWLockExclusive(PSRWLOCK Lock)
Definition: sync.c:54
#define TRUE
Definition: types.h:120
#define deleg_entry(pos)
Definition: delegation.c:377
uint8_t entry
Definition: isohybrid.c:63
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
#define list_for_each(entry, head)
Definition: list.h:36
smooth NULL
Definition: ftsmooth.c:416
static int delegation_return(IN nfs41_client *client, IN nfs41_delegation_state *deleg, IN bool_t truncate, IN bool_t try_recovery)
Definition: delegation.c:264
static FILE * client
Definition: client.c:41
static int state
Definition: maze.c:121
VOID WINAPI ReleaseSRWLockExclusive(PSRWLOCK Lock)
Definition: sync.c:82
Definition: list.h:27
enum delegation_status status
Definition: nfs41.h:103
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
static SERVICE_STATUS status
Definition: service.c:31
Definition: ps.c:97

◆ nfs41_delegate_open()

int nfs41_delegate_open ( IN nfs41_open_state state,
IN uint32_t  create,
IN OPTIONAL nfs41_file_info createattrs,
OUT nfs41_file_info info 
)

Definition at line 462 of file delegation.c.

Referenced by open_or_delegate().

467 {
468  nfs41_client *client = state->session->client;
469  nfs41_path_fh *file = &state->file;
470  uint32_t access = state->share_access;
471  uint32_t deny = state->share_deny;
472  nfs41_delegation_state *deleg;
473  stateid_arg stateid;
474  int status;
475 
476  /* search for a delegation with this filehandle */
477  status = delegation_find(client, &file->fh, deleg_file_cmp, &deleg);
478  if (status)
479  goto out;
480 
481  AcquireSRWLockExclusive(&deleg->lock);
482  if (deleg->status != DELEGATION_GRANTED) {
483  /* the delegation is being returned, wait for it to finish */
484  while (deleg->status != DELEGATION_RETURNED)
485  SleepConditionVariableSRW(&deleg->cond, &deleg->lock, INFINITE, 0);
486  status = NFS4ERR_BADHANDLE;
487  }
488  else if (!delegation_compatible(deleg->state.type, create, access, deny)) {
489 #ifdef DELEGATION_RETURN_ON_CONFLICT
490  /* this open will conflict, start the delegation return */
491  deleg->status = DELEGATION_RETURNING;
492  status = NFS4ERR_DELEG_REVOKED;
493 #else
494  status = NFS4ERR_BADHANDLE;
495 #endif
496  } else if (create == OPEN4_CREATE) {
497  /* copy the stateid for SETATTR */
498  stateid.open = NULL;
499  stateid.delegation = deleg;
500  stateid.type = STATEID_DELEG_FILE;
501  memcpy(&stateid.stateid, &deleg->state.stateid, sizeof(stateid4));
502  }
503  if (!status) {
504  dprintf(1, "nfs41_delegate_open: updating srv_open from %x to %x\n",
505  deleg->srv_open, state->srv_open);
506  deleg->srv_open = state->srv_open;
507  }
508  ReleaseSRWLockExclusive(&deleg->lock);
509 
510  if (status == NFS4ERR_DELEG_REVOKED)
511  goto out_return;
512  if (status)
513  goto out_deleg;
514 
515  if (create == OPEN4_CREATE) {
516  memcpy(info, createattrs, sizeof(nfs41_file_info));
517 
518  /* write delegations allow us to simulate OPEN4_CREATE with SETATTR */
519  status = delegation_truncate(deleg, client, &stateid, info);
520  if (status)
521  goto out_deleg;
522  }
523 
524  /* TODO: check access against deleg->state.permissions or send ACCESS */
525 
526  state->delegation.state = deleg;
527  status = NFS4_OK;
528 out:
529  return status;
530 
531 out_return:
532  delegation_return(client, deleg, create == OPEN4_CREATE, TRUE);
533 
534 out_deleg:
535  nfs41_delegation_deref(deleg);
536  goto out;
537 }
static bool_t delegation_compatible(IN enum open_delegation_type4 type, IN uint32_t create, IN uint32_t access, IN uint32_t deny)
Definition: delegation.c:388
VOID WINAPI AcquireSRWLockExclusive(PSRWLOCK Lock)
Definition: sync.c:54
static int deleg_file_cmp(const struct list_entry *entry, const void *value)
Definition: delegation.c:379
#define TRUE
Definition: types.h:120
static int delegation_truncate(IN nfs41_delegation_state *deleg, IN nfs41_client *client, IN stateid_arg *stateid, IN nfs41_file_info *info)
Definition: delegation.c:440
void nfs41_delegation_deref(IN nfs41_delegation_state *state)
Definition: delegation.c:79
#define dprintf
Definition: regdump.c:33
smooth NULL
Definition: ftsmooth.c:416
static int delegation_return(IN nfs41_client *client, IN nfs41_delegation_state *deleg, IN bool_t truncate, IN bool_t try_recovery)
Definition: delegation.c:264
static int delegation_find(IN nfs41_client *client, IN const void *value, IN list_compare_fn cmp, OUT nfs41_delegation_state **deleg_out)
Definition: delegation.c:415
open_delegation4 state
Definition: nfs41.h:96
BOOL WINAPI SleepConditionVariableSRW(PCONDITION_VARIABLE ConditionVariable, PSRWLOCK Lock, DWORD Timeout, ULONG Flags)
Definition: sync.c:121
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 * client
Definition: client.c:41
static FILE * out
Definition: regtests2xml.c:44
nfs41_open_state * open
Definition: nfs41_ops.h:286
static int state
Definition: maze.c:121
VOID WINAPI ReleaseSRWLockExclusive(PSRWLOCK Lock)
Definition: sync.c:82
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
GLuint GLint GLboolean GLint GLenum access
Definition: glext.h:7866
stateid4 stateid
Definition: nfs41_ops.h:284
UINT32 uint32_t
Definition: types.h:75
enum delegation_status status
Definition: nfs41.h:103
CONDITION_VARIABLE cond
Definition: nfs41.h:105
#define INFINITE
Definition: serial.h:102
static const struct access_res create[16]
Definition: package.c:7720
static SERVICE_STATUS status
Definition: service.c:31
Definition: fci.c:126

◆ nfs41_delegation_deref()

void nfs41_delegation_deref ( IN nfs41_delegation_state state)

Definition at line 79 of file delegation.c.

Referenced by delegation_recall_thread(), delegation_remove(), nfs41_client_delegation_free(), nfs41_delegate_open(), nfs41_delegation_getattr(), nfs41_delegation_recall(), nfs41_delegation_remove_srvopen(), nfs41_delegation_return(), and open_state_free().

81 {
82  const LONG count = InterlockedDecrement(&state->ref_count);
83  dprintf(DGLVL, "nfs41_delegation_deref(%s) count %d\n",
84  state->path.path, count);
85  if (count == 0)
86  free(state);
87 }
GLuint GLuint GLsizei count
Definition: gl.h:1545
#define free
Definition: debug_ros.c:5
long LONG
Definition: pedump.c:60
#define dprintf
Definition: regdump.c:33
#define DGLVL
Definition: delegation.c:32
#define InterlockedDecrement
Definition: armddk.h:52
static int state
Definition: maze.c:121

◆ nfs41_delegation_getattr()

int nfs41_delegation_getattr ( IN nfs41_client client,
IN const nfs41_fh fh,
IN const bitmap4 attr_request,
OUT nfs41_file_info info 
)

Definition at line 783 of file delegation.c.

Referenced by handle_cb_getattr().

788 {
789  nfs41_delegation_state *deleg;
790  uint64_t fileid;
791  int status;
792 
793  dprintf(2, "--> nfs41_delegation_getattr()\n");
794 
795  /* search for a delegation on this file handle */
796  status = delegation_find(client, fh, deleg_fh_cmp, &deleg);
797  if (status)
798  goto out;
799 
800  AcquireSRWLockShared(&deleg->lock);
801  fileid = deleg->file.fh.fileid;
802  if (deleg->status != DELEGATION_GRANTED ||
803  deleg->state.type != OPEN_DELEGATE_WRITE) {
804  status = NFS4ERR_BADHANDLE;
805  }
806  ReleaseSRWLockShared(&deleg->lock);
807  if (status)
808  goto out_deleg;
809 
810  ZeroMemory(info, sizeof(nfs41_file_info));
811 
812  /* find attributes for the given fileid */
813  status = nfs41_attr_cache_lookup(
814  client_name_cache(client), fileid, info);
815  if (status) {
816  status = NFS4ERR_BADHANDLE;
817  goto out_deleg;
818  }
819 out_deleg:
820  nfs41_delegation_deref(deleg);
821 out:
822  dprintf(DGLVL, "<-- nfs41_delegation_getattr() returning %s\n",
823  nfs_error_string(status));
824  return status;
825 }
uint64_t fileid
Definition: nfs41_types.h:55
#define ZeroMemory
Definition: winbase.h:1635
void nfs41_delegation_deref(IN nfs41_delegation_state *state)
Definition: delegation.c:79
nfs41_path_fh file
Definition: nfs41.h:99
#define dprintf
Definition: regdump.c:33
#define DGLVL
Definition: delegation.c:32
static int delegation_find(IN nfs41_client *client, IN const void *value, IN list_compare_fn cmp, OUT nfs41_delegation_state **deleg_out)
Definition: delegation.c:415
open_delegation4 state
Definition: nfs41.h:96
static __inline struct nfs41_name_cache * client_name_cache(IN nfs41_client *client)
Definition: name_cache.h:28
enum open_delegation_type4 type
Definition: nfs41_types.h:154
static FILE * client
Definition: client.c:41
static FILE * out
Definition: regtests2xml.c:44
const char * nfs_error_string(int status)
Definition: daemon_debug.c:370
static int deleg_fh_cmp(const struct list_entry *entry, const void *value)
Definition: delegation.c:775
UINT64 uint64_t
Definition: types.h:77
enum delegation_status status
Definition: nfs41.h:103
int nfs41_attr_cache_lookup(IN struct nfs41_name_cache *cache, IN uint64_t fileid, OUT nfs41_file_info *info_out)
Definition: name_cache.c:859
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

◆ nfs41_delegation_granted()

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 at line 330 of file delegation.c.

Referenced by do_open(), and recover_open().

337 {
338  stateid_arg stateid;
339  nfs41_client *client = session->client;
341  int status = NO_ERROR;
342 
343  if (delegation->type != OPEN_DELEGATE_READ &&
344  delegation->type != OPEN_DELEGATE_WRITE)
345  goto out;
346 
347  if (delegation->recalled) {
348  status = NFS4ERR_DELEG_REVOKED;
349  goto out_return;
350  }
351 
352  /* allocate the delegation state */
353  status = delegation_create(parent, file, delegation, &state);
354  if (status)
355  goto out_return;
356 
357  /* register the delegation with the client */
358  EnterCriticalSection(&client->state.lock);
359  /* XXX: check for duplicates by fh and stateid? */
360  list_add_tail(&client->state.delegations, &state->client_entry);
361  LeaveCriticalSection(&client->state.lock);
362 
363  nfs41_delegation_ref(state); /* return a reference */
364  *deleg_out = state;
365 out:
366  return status;
367 
368 out_return: /* return the delegation on failure */
369  memcpy(&stateid.stateid, &delegation->stateid, sizeof(stateid4));
370  stateid.type = STATEID_DELEG_FILE;
371  stateid.open = NULL;
372  stateid.delegation = NULL;
373  nfs41_delegreturn(session, file, &stateid, try_recovery);
374  goto out;
375 }
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
#define NO_ERROR
Definition: dderror.h:5
void nfs41_delegation_ref(IN nfs41_delegation_state *state)
Definition: delegation.c:71
__WINE_SERVER_LIST_INLINE void list_add_tail(struct list *list, struct list *elem)
Definition: list.h:102
smooth NULL
Definition: ftsmooth.c:416
r parent
Definition: btrfs.c:2659
struct list_entry client_entry
Definition: nfs41.h:100
enum stateid_type type
Definition: nfs41_ops.h:285
nfs41_delegation_state * delegation
Definition: nfs41_ops.h:287
static FILE * client
Definition: client.c:41
static FILE * out
Definition: regtests2xml.c:44
int nfs41_delegreturn(IN nfs41_session *session, IN nfs41_path_fh *file, IN stateid_arg *stateid, IN bool_t try_recovery)
Definition: nfs41_ops.c:1693
nfs41_open_state * open
Definition: nfs41_ops.h:286
struct client_state state
Definition: nfs41.h:215
static int state
Definition: maze.c:121
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
static int delegation_create(IN const nfs41_path_fh *parent, IN const nfs41_path_fh *file, IN const open_delegation4 *delegation, OUT nfs41_delegation_state **deleg_out)
Definition: delegation.c:36
stateid4 stateid
Definition: nfs41_ops.h:284
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
static SERVICE_STATUS status
Definition: service.c:31
Definition: fci.c:126
Definition: ps.c:97

◆ nfs41_delegation_recall()

int nfs41_delegation_recall ( IN nfs41_client client,
IN nfs41_fh fh,
IN const stateid4 stateid,
IN bool_t  truncate 
)

Definition at line 703 of file delegation.c.

Referenced by handle_cb_recall().

708 {
709  nfs41_delegation_state *deleg;
710  struct recall_thread_args *args;
711  int status;
712 
713  dprintf(2, "--> nfs41_delegation_recall()\n");
714 
715  /* search for the delegation by stateid instead of filehandle;
716  * deleg_file_cmp() relies on a proper superblock and fileid,
717  * which we don't get with CB_RECALL */
718  status = delegation_find(client, stateid, deleg_stateid_cmp, &deleg);
719  if (status)
720  goto out;
721 
722  AcquireSRWLockExclusive(&deleg->lock);
723  if (deleg->state.recalled) {
724  /* return BADHANDLE if we've already responded to CB_RECALL */
725  status = NFS4ERR_BADHANDLE;
726  } else {
727  deleg->state.recalled = 1;
728 
729  if (deleg->status == DELEGATION_GRANTED) {
730  /* start the delegation return */
731  deleg->status = DELEGATION_RETURNING;
732  status = NFS4ERR_DELEG_REVOKED;
733  } /* else return NFS4_OK */
734  }
735  ReleaseSRWLockExclusive(&deleg->lock);
736 
737  if (status != NFS4ERR_DELEG_REVOKED)
738  goto out_deleg;
739 
740  /* allocate thread arguments */
741  args = calloc(1, sizeof(struct recall_thread_args));
742  if (args == NULL) {
743  status = NFS4ERR_SERVERFAULT;
744  eprintf("nfs41_delegation_recall() failed to allocate arguments\n");
745  goto out_deleg;
746  }
747 
748  /* hold a reference on the root */
749  nfs41_root_ref(client->root);
750  args->client = client;
751  args->delegation = deleg;
752  args->truncate = truncate;
753 
754  /* the callback thread can't make rpc calls, so spawn a separate thread */
755  if (_beginthreadex(NULL, 0, delegation_recall_thread, args, 0, NULL) == 0) {
756  status = NFS4ERR_SERVERFAULT;
757  eprintf("nfs41_delegation_recall() failed to start thread\n");
758  goto out_args;
759  }
760  status = NFS4_OK;
761 out:
762  dprintf(DGLVL, "<-- nfs41_delegation_recall() returning %s\n",
763  nfs_error_string(status));
764  return status;
765 
766 out_args:
767  free(args);
768  nfs41_root_deref(client->root);
769 out_deleg:
770  nfs41_delegation_deref(deleg);
771  goto out;
772 }
VOID WINAPI AcquireSRWLockExclusive(PSRWLOCK Lock)
Definition: sync.c:54
#define free
Definition: debug_ros.c:5
void eprintf(LPCSTR format,...)
Definition: daemon_debug.c:86
void nfs41_delegation_deref(IN nfs41_delegation_state *state)
Definition: delegation.c:79
_CRTIMP uintptr_t __cdecl _beginthreadex(_In_opt_ void *_Security, _In_ unsigned _StackSize, _In_ unsigned(__stdcall *_StartAddress)(void *), _In_opt_ void *_ArgList, _In_ unsigned _InitFlag, _Out_opt_ unsigned *_ThrdAddr)
nfs41_delegation_state * delegation
Definition: delegation.c:679
#define dprintf
Definition: regdump.c:33
#define DGLVL
Definition: delegation.c:32
smooth NULL
Definition: ftsmooth.c:416
void nfs41_root_ref(IN nfs41_root *root)
Definition: namespace.c:92
static int delegation_find(IN nfs41_client *client, IN const void *value, IN list_compare_fn cmp, OUT nfs41_delegation_state **deleg_out)
Definition: delegation.c:415
open_delegation4 state
Definition: nfs41.h:96
static FILE * client
Definition: client.c:41
static FILE * out
Definition: regtests2xml.c:44
const char * nfs_error_string(int status)
Definition: daemon_debug.c:370
nfs41_client * client
Definition: delegation.c:678
VOID WINAPI ReleaseSRWLockExclusive(PSRWLOCK Lock)
Definition: sync.c:82
static int deleg_stateid_cmp(const struct list_entry *entry, const void *value)
Definition: delegation.c:696
enum delegation_status status
Definition: nfs41.h:103
#define calloc
Definition: rosglue.h:14
void nfs41_root_deref(IN nfs41_root *root)
Definition: namespace.c:100
static SERVICE_STATUS status
Definition: service.c:31
#define args
Definition: format.c:66
static unsigned int WINAPI delegation_recall_thread(void *args)
Definition: delegation.c:683

◆ nfs41_delegation_ref()

void nfs41_delegation_ref ( IN nfs41_delegation_state state)

Definition at line 71 of file delegation.c.

Referenced by delegation_find(), and nfs41_delegation_granted().

73 {
74  const LONG count = InterlockedIncrement(&state->ref_count);
75  dprintf(DGLVL, "nfs41_delegation_ref(%s) count %d\n",
76  state->path.path, count);
77 }
GLuint GLuint GLsizei count
Definition: gl.h:1545
long LONG
Definition: pedump.c:60
#define dprintf
Definition: regdump.c:33
#define DGLVL
Definition: delegation.c:32
static int state
Definition: maze.c:121
#define InterlockedIncrement
Definition: armddk.h:53

◆ nfs41_delegation_remove_srvopen()

void nfs41_delegation_remove_srvopen ( IN nfs41_session session,
IN nfs41_path_fh file 
)

Definition at line 610 of file delegation.c.

Referenced by handle_close().

613 {
614  nfs41_delegation_state *deleg = NULL;
615 
616  /* find a delegation for this file */
617  if (delegation_find(session->client, &file->fh, deleg_file_cmp, &deleg))
618  return;
619  dprintf(1, "nfs41_delegation_remove_srvopen: removing reference to "
620  "srv_open=%x\n", deleg->srv_open);
621  AcquireSRWLockExclusive(&deleg->lock);
622  deleg->srv_open = NULL;
623  ReleaseSRWLockExclusive(&deleg->lock);
624  nfs41_delegation_deref(deleg);
625 }
VOID WINAPI AcquireSRWLockExclusive(PSRWLOCK Lock)
Definition: sync.c:54
static int deleg_file_cmp(const struct list_entry *entry, const void *value)
Definition: delegation.c:379
void nfs41_delegation_deref(IN nfs41_delegation_state *state)
Definition: delegation.c:79
#define dprintf
Definition: regdump.c:33
smooth NULL
Definition: ftsmooth.c:416
static int delegation_find(IN nfs41_client *client, IN const void *value, IN list_compare_fn cmp, OUT nfs41_delegation_state **deleg_out)
Definition: delegation.c:415
VOID WINAPI ReleaseSRWLockExclusive(PSRWLOCK Lock)
Definition: sync.c:82
Definition: fci.c:126

◆ nfs41_delegation_return()

int nfs41_delegation_return ( IN nfs41_session session,
IN nfs41_path_fh file,
IN enum open_delegation_type4  access,
IN bool_t  truncate 
)

Definition at line 629 of file delegation.c.

Referenced by cancel_open(), handle_close(), handle_nfs41_remove(), handle_nfs41_set_size(), handle_open(), handle_setacl(), and handle_setexattr().

638 {
639  nfs41_client *client = session->client;
640  nfs41_delegation_state *deleg;
641  int status;
642 
643  /* find a delegation for this file */
644  status = delegation_find(client, &file->fh, deleg_file_cmp, &deleg);
645  if (status)
646  goto out;
647 
648  AcquireSRWLockExclusive(&deleg->lock);
649  if (deleg->status == DELEGATION_GRANTED) {
650  /* return unless delegation is write and access is read */
651  if (deleg->state.type != OPEN_DELEGATE_WRITE
652  || access != OPEN_DELEGATE_READ) {
653  deleg->status = DELEGATION_RETURNING;
654  status = NFS4ERR_DELEG_REVOKED;
655  }
656  } else {
657  /* the delegation is being returned, wait for it to finish */
658  while (deleg->status == DELEGATION_RETURNING)
659  SleepConditionVariableSRW(&deleg->cond, &deleg->lock, INFINITE, 0);
660  status = NFS4ERR_BADHANDLE;
661  }
662  ReleaseSRWLockExclusive(&deleg->lock);
663 
664  if (status == NFS4ERR_DELEG_REVOKED) {
665  delegation_return(client, deleg, truncate, TRUE);
666  status = NFS4_OK;
667  }
668 
669  nfs41_delegation_deref(deleg);
670 out:
671  return status;
672 }
VOID WINAPI AcquireSRWLockExclusive(PSRWLOCK Lock)
Definition: sync.c:54
static int deleg_file_cmp(const struct list_entry *entry, const void *value)
Definition: delegation.c:379
#define TRUE
Definition: types.h:120
void nfs41_delegation_deref(IN nfs41_delegation_state *state)
Definition: delegation.c:79
static int delegation_return(IN nfs41_client *client, IN nfs41_delegation_state *deleg, IN bool_t truncate, IN bool_t try_recovery)
Definition: delegation.c:264
static int delegation_find(IN nfs41_client *client, IN const void *value, IN list_compare_fn cmp, OUT nfs41_delegation_state **deleg_out)
Definition: delegation.c:415
open_delegation4 state
Definition: nfs41.h:96
BOOL WINAPI SleepConditionVariableSRW(PCONDITION_VARIABLE ConditionVariable, PSRWLOCK Lock, DWORD Timeout, ULONG Flags)
Definition: sync.c:121
enum open_delegation_type4 type
Definition: nfs41_types.h:154
static FILE * client
Definition: client.c:41
static FILE * out
Definition: regtests2xml.c:44
VOID WINAPI ReleaseSRWLockExclusive(PSRWLOCK Lock)
Definition: sync.c:82
GLuint GLint GLboolean GLint GLenum access
Definition: glext.h:7866
enum delegation_status status
Definition: nfs41.h:103
CONDITION_VARIABLE cond
Definition: nfs41.h:105
#define INFINITE
Definition: serial.h:102
static SERVICE_STATUS status
Definition: service.c:31
Definition: fci.c:126

◆ nfs41_delegation_to_open()

int nfs41_delegation_to_open ( IN nfs41_open_state open,
IN bool_t  try_recovery 
)

Definition at line 539 of file delegation.c.

Referenced by delegation_return(), and handle_lock().

542 {
544  open_claim4 claim;
545  stateid4 open_stateid = { 0 };
546  stateid_arg deleg_stateid;
547  int status = NFS4_OK;
548 
550  if (open->delegation.state == NULL) /* no delegation to reclaim */
551  goto out_unlock;
552 
553  if (open->do_close) /* already have an open stateid */
554  goto out_unlock;
555 
556  /* if another thread is reclaiming the open stateid,
557  * wait for it to finish before returning success */
558  if (open->delegation.reclaim) {
559  do {
560  SleepConditionVariableSRW(&open->delegation.cond, &open->lock,
561  INFINITE, 0);
562  } while (open->delegation.reclaim);
563  if (open->do_close)
564  goto out_unlock;
565  }
566  open->delegation.reclaim = 1;
567 
568  AcquireSRWLockShared(&open->delegation.state->lock);
569  deleg_stateid.open = open;
570  deleg_stateid.delegation = NULL;
571  deleg_stateid.type = STATEID_DELEG_FILE;
572  memcpy(&deleg_stateid.stateid, &open->delegation.state->state.stateid,
573  sizeof(stateid4));
574  ReleaseSRWLockShared(&open->delegation.state->lock);
575 
577 
578  /* send OPEN with CLAIM_DELEGATE_CUR */
579  claim.claim = CLAIM_DELEGATE_CUR;
580  claim.u.deleg_cur.delegate_stateid = &deleg_stateid;
581  claim.u.deleg_cur.name = &open->file.name;
582 
583  status = nfs41_open(open->session, &open->parent, &open->file,
584  &open->owner, &claim, open->share_access, open->share_deny,
585  OPEN4_NOCREATE, 0, NULL, try_recovery, &open_stateid, &ignore, NULL);
586 
588  if (status == NFS4_OK) {
589  /* save the new open stateid */
590  memcpy(&open->stateid, &open_stateid, sizeof(stateid4));
591  open->do_close = 1;
592  } else if (open->do_close && (status == NFS4ERR_BAD_STATEID ||
593  status == NFS4ERR_STALE_STATEID || status == NFS4ERR_EXPIRED)) {
594  /* something triggered client state recovery, and the open stateid
595  * has already been reclaimed; see recover_stateid_delegation() */
596  status = NFS4_OK;
597  }
598  open->delegation.reclaim = 0;
599 
600  /* signal anyone waiting on the open stateid */
601  WakeAllConditionVariable(&open->delegation.cond);
602 out_unlock:
604  if (status)
605  eprintf("nfs41_delegation_to_open(%p) failed with %s\n",
606  open, nfs_error_string(status));
607  return status;
608 }
VOID WINAPI AcquireSRWLockExclusive(PSRWLOCK Lock)
Definition: sync.c:54
char * name
Definition: wpp.c:36
#define open
Definition: acwin.h:71
int ignore(int trapCode, ppc_trap_frame_t *trap)
Definition: mmuobject.c:296
struct __open_claim4::@40::__open_claim_deleg_cur deleg_cur
void eprintf(LPCSTR format,...)
Definition: daemon_debug.c:86
VOID WINAPI WakeAllConditionVariable(PCONDITION_VARIABLE ConditionVariable)
Definition: sync.c:137
smooth NULL
Definition: ftsmooth.c:416
BOOL WINAPI SleepConditionVariableSRW(PCONDITION_VARIABLE ConditionVariable, PSRWLOCK Lock, DWORD Timeout, ULONG Flags)
Definition: sync.c:121
enum stateid_type type
Definition: nfs41_ops.h:285
nfs41_delegation_state * delegation
Definition: nfs41_ops.h:287
const char * nfs_error_string(int status)
Definition: daemon_debug.c:370
union __open_claim4::@40 u
nfs41_open_state * open
Definition: nfs41_ops.h:286
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
VOID WINAPI ReleaseSRWLockExclusive(PSRWLOCK Lock)
Definition: sync.c:82
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
stateid4 stateid
Definition: nfs41_ops.h:284
uint32_t claim
Definition: nfs41_ops.h:615
#define INFINITE
Definition: serial.h:102
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
Definition: ps.c:97