ReactOS  0.4.12-dev-685-gf36cbf7
callback_server.c File Reference
#include <windows.h>
#include <strsafe.h>
#include "nfs41_ops.h"
#include "delegation.h"
#include "nfs41_callback.h"
#include "daemon_debug.h"
Include dependency graph for callback_server.c:

Go to the source code of this file.

Macros

#define CBSLVL   2 /* dprintf level for callback server logging */
 

Functions

static void replay_cache_write (IN nfs41_cb_session *session, IN struct cb_compound_args *args, IN struct cb_compound_res *res, IN bool_t cachethis)
 
void nfs41_callback_session_init (IN nfs41_session *session)
 
static enum_t handle_cb_layoutrecall (IN nfs41_rpc_clnt *rpc_clnt, IN struct cb_layoutrecall_args *args, OUT struct cb_layoutrecall_res *res)
 
static enum_t handle_cb_recall_slot (IN nfs41_rpc_clnt *rpc_clnt, IN struct cb_recall_slot_args *args, OUT struct cb_recall_slot_res *res)
 
static enum_t handle_cb_sequence (IN nfs41_rpc_clnt *rpc_clnt, IN struct cb_sequence_args *args, OUT struct cb_sequence_res *res, OUT nfs41_cb_session **session_out, OUT bool_t *cachethis)
 
static enum_t handle_cb_getattr (IN nfs41_rpc_clnt *rpc_clnt, IN struct cb_getattr_args *args, OUT struct cb_getattr_res *res)
 
static enum_t handle_cb_recall (IN nfs41_rpc_clnt *rpc_clnt, IN struct cb_recall_args *args, OUT struct cb_recall_res *res)
 
static enum_t handle_cb_notify_deviceid (IN nfs41_rpc_clnt *rpc_clnt, IN struct cb_notify_deviceid_args *args, OUT struct cb_notify_deviceid_res *res)
 
static void replay_cache_write (IN nfs41_cb_session *session, IN OPTIONAL struct cb_compound_args *args, IN struct cb_compound_res *res, IN bool_t cachethis)
 
static bool_t replay_validate_args (IN struct cb_compound_args *args, IN const struct replay_cache *cache)
 
static bool_t replay_validate_ops (IN const struct cb_compound_args *args, IN const struct cb_compound_res *res)
 
static int replay_cache_read (IN nfs41_cb_session *session, IN struct cb_compound_args *args, OUT struct cb_compound_res **res_out)
 
static void handle_cb_compound (nfs41_rpc_clnt *rpc_clnt, cb_req *req, struct cb_compound_res **reply)
 
int nfs41_handle_callback (void *rpc_clnt, void *cb, struct cb_compound_res **reply)
 

Variables

static const char g_server_tag [] = "ms-nfs41-callback"
 

Macro Definition Documentation

◆ CBSLVL

#define CBSLVL   2 /* dprintf level for callback server logging */

Definition at line 31 of file callback_server.c.

Function Documentation

◆ handle_cb_compound()

static void handle_cb_compound ( nfs41_rpc_clnt rpc_clnt,
cb_req req,
struct cb_compound_res **  reply 
)
static

Definition at line 354 of file callback_server.c.

355 {
356  struct cb_compound_args args = { 0 };
357  struct cb_compound_res *res = NULL;
358  struct cb_argop *argop;
359  struct cb_resop *resop;
360  XDR *xdr = (XDR*)req->xdr;
361  nfs41_cb_session *session = NULL;
362  bool_t cachethis = FALSE;
364 
365  dprintf(CBSLVL, "--> handle_cb_compound()\n");
366 
367  /* decode the arguments */
368  if (!proc_cb_compound_args(xdr, &args)) {
370  eprintf("failed to decode compound arguments\n");
371  }
372 
373  /* allocate the compound results */
374  res = calloc(1, sizeof(struct cb_compound_res));
375  if (res == NULL) {
377  goto out;
378  }
379  res->status = status;
381  res->tag.str[CB_COMPOUND_MAX_TAG-1] = 0;
382  res->tag.len = (uint32_t)strlen(res->tag.str);
383  res->resarray = calloc(args.argarray_count, sizeof(struct cb_resop));
384  if (res->resarray == NULL) {
385  res->status = NFS4ERR_SERVERFAULT;
386  goto out;
387  }
388 
389  dprintf(CBSLVL, "CB_COMPOUND('%s', %u)\n", args.tag.str, args.argarray_count);
390  if (args.minorversion != 1) {
391  res->status = NFS4ERR_MINOR_VERS_MISMATCH; //XXXXX
392  eprintf("args.minorversion %u != 1\n", args.minorversion);
393  goto out;
394  }
395 
396  /* handle each operation in the compound */
397  for (i = 0; i < args.argarray_count && res->status == NFS4_OK; i++) {
398  argop = &args.argarray[i];
399  resop = &res->resarray[i];
400  resop->opnum = argop->opnum;
401  res->resarray_count++;
402 
403  /* 20.9.3: The error NFS4ERR_SEQUENCE_POS MUST be returned
404  * when CB_SEQUENCE is found in any position in a CB_COMPOUND
405  * beyond the first. If any other operation is in the first
406  * position of CB_COMPOUND, NFS4ERR_OP_NOT_IN_SESSION MUST
407  * be returned.
408  */
409  if (i == 0 && argop->opnum != OP_CB_SEQUENCE) {
410  res->status = resop->res.status = NFS4ERR_OP_NOT_IN_SESSION;
411  break;
412  }
413  if (i != 0 && argop->opnum == OP_CB_SEQUENCE) {
414  res->status = resop->res.status = NFS4ERR_SEQUENCE_POS;
415  break;
416  }
418  res->status = resop->res.status = status;
419  break;
420  }
421 
422  switch (argop->opnum) {
423  case OP_CB_LAYOUTRECALL:
424  dprintf(1, "OP_CB_LAYOUTRECALL\n");
425  res->status = handle_cb_layoutrecall(rpc_clnt,
426  &argop->args.layoutrecall, &resop->res.layoutrecall);
427  break;
428  case OP_CB_RECALL_SLOT:
429  dprintf(1, "OP_CB_RECALL_SLOT\n");
430  res->status = handle_cb_recall_slot(rpc_clnt,
431  &argop->args.recall_slot, &resop->res.recall_slot);
432  break;
433  case OP_CB_SEQUENCE:
434  dprintf(1, "OP_CB_SEQUENCE\n");
435  status = handle_cb_sequence(rpc_clnt, &argop->args.sequence,
436  &resop->res.sequence, &session, &cachethis);
437 
439  /* replace the current results with the cached response */
440  status = replay_cache_read(session, &args, &res);
441  if (status) res->status = status;
442  goto out;
443  }
444 
445  if (status == NFS4_OK)
446  res->status = resop->res.sequence.status;
447  break;
448  case OP_CB_GETATTR:
449  dprintf(1, "OP_CB_GETATTR\n");
450  res->status = handle_cb_getattr(rpc_clnt,
451  &argop->args.getattr, &resop->res.getattr);
452  break;
453  case OP_CB_RECALL:
454  dprintf(1, "OP_CB_RECALL\n");
455  res->status = handle_cb_recall(rpc_clnt,
456  &argop->args.recall, &resop->res.recall);
457  break;
458  case OP_CB_NOTIFY:
459  dprintf(1, "OP_CB_NOTIFY\n");
460  res->status = NFS4ERR_NOTSUPP;
461  break;
462  case OP_CB_PUSH_DELEG:
463  dprintf(1, "OP_CB_PUSH_DELEG\n");
464  res->status = NFS4ERR_NOTSUPP;
465  break;
466  case OP_CB_RECALL_ANY:
467  dprintf(1, "OP_CB_RECALL_ANY\n");
468  res->status = NFS4ERR_NOTSUPP;
469  break;
471  dprintf(1, "OP_CB_RECALLABLE_OBJ_AVAIL\n");
472  res->status = NFS4ERR_NOTSUPP;
473  break;
475  dprintf(1, "OP_CB_WANTS_CANCELLED\n");
476  res->status = NFS4ERR_NOTSUPP;
477  break;
478  case OP_CB_NOTIFY_LOCK:
479  dprintf(1, "OP_CB_NOTIFY_LOCK\n");
480  res->status = NFS4ERR_NOTSUPP;
481  break;
483  dprintf(1, "OP_CB_NOTIFY_DEVICEID\n");
484  res->status = NFS4_OK;
485  break;
486  case OP_CB_ILLEGAL:
487  dprintf(1, "OP_CB_ILLEGAL\n");
488  res->status = NFS4ERR_NOTSUPP;
489  break;
490  default:
491  eprintf("operation %u not supported\n", argop->opnum);
492  res->status = NFS4ERR_NOTSUPP;
493  break;
494  }
495  }
496 
497  /* always attempt to cache the reply */
498  if (session)
499  replay_cache_write(session, &args, res, cachethis);
500 out:
501  /* free the arguments */
502  xdr->x_op = XDR_FREE;
504 
505  *reply = res;
506  dprintf(CBSLVL, "<-- handle_cb_compound() returning %s (%u results)\n",
507  nfs_error_string(res ? res->status : status),
508  res ? res->resarray_count : 0);
509 }
struct cb_getattr_res getattr
void * xdr
Definition: clnt.h:156
struct cb_recall_slot_res recall_slot
static enum_t handle_cb_getattr(IN nfs41_rpc_clnt *rpc_clnt, IN struct cb_getattr_args *args, OUT struct cb_getattr_res *res)
struct cb_recall_args recall
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
int32_t bool_t
Definition: types.h:101
struct cb_recall_res recall
void eprintf(LPCSTR format,...)
Definition: daemon_debug.c:86
enum_t status
static const char g_server_tag[]
Definition: match.c:390
Definition: xdr.h:103
enum_t opnum
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
static enum_t handle_cb_layoutrecall(IN nfs41_rpc_clnt *rpc_clnt, IN struct cb_layoutrecall_args *args, OUT struct cb_layoutrecall_res *res)
#define dprintf
Definition: regdump.c:33
struct cb_layoutrecall_res layoutrecall
smooth NULL
Definition: ftsmooth.c:416
#define CB_COMPOUND_MAX_TAG
#define CBSLVL
enum xdr_op x_op
Definition: xdr.h:104
static FILE * out
Definition: regtests2xml.c:44
const char * nfs_error_string(int status)
Definition: daemon_debug.c:370
union cb_op_args args
static enum_t handle_cb_sequence(IN nfs41_rpc_clnt *rpc_clnt, IN struct cb_sequence_args *args, OUT struct cb_sequence_res *res, OUT nfs41_cb_session **session_out, OUT bool_t *cachethis)
struct cb_getattr_args getattr
union cb_op_res res
enum_t opnum
struct cb_layoutrecall_args layoutrecall
STRSAFEAPI StringCchCopyA(STRSAFE_LPSTR pszDest, size_t cchDest, STRSAFE_LPCSTR pszSrc)
Definition: strsafe.h:145
struct cb_sequence_args sequence
static enum_t handle_cb_recall_slot(IN nfs41_rpc_clnt *rpc_clnt, IN struct cb_recall_slot_args *args, OUT struct cb_recall_slot_res *res)
UINT32 uint32_t
Definition: types.h:75
static int replay_cache_read(IN nfs41_cb_session *session, IN struct cb_compound_args *args, OUT struct cb_compound_res **res_out)
struct cb_sequence_res sequence
static enum_t handle_cb_recall(IN nfs41_rpc_clnt *rpc_clnt, IN struct cb_recall_args *args, OUT struct cb_recall_res *res)
Definition: xdr.h:87
#define calloc
Definition: rosglue.h:14
GLuint res
Definition: glext.h:9613
static void replay_cache_write(IN nfs41_cb_session *session, IN struct cb_compound_args *args, IN struct cb_compound_res *res, IN bool_t cachethis)
bool_t proc_cb_compound_args(XDR *xdr, struct cb_compound_args *args)
Definition: callback_xdr.c:590
#define uint32_t
Definition: nsiface.idl:61
static SERVICE_STATUS status
Definition: service.c:31
struct cb_recall_slot_args recall_slot
Definition: ps.c:97

Referenced by nfs41_handle_callback().

◆ handle_cb_getattr()

static enum_t handle_cb_getattr ( IN nfs41_rpc_clnt rpc_clnt,
IN struct cb_getattr_args args,
OUT struct cb_getattr_res res 
)
static

Definition at line 174 of file callback_server.c.

178 {
179  /* look up cached attributes for the given filehandle */
180  res->status = nfs41_delegation_getattr(rpc_clnt->client,
181  &args->fh, &args->attr_request, &res->info);
182  return res->status;
183 }
Definition: match.c:390
int nfs41_delegation_getattr(IN nfs41_client *client, IN const nfs41_fh *fh, IN const bitmap4 *attr_request, OUT nfs41_file_info *info)
Definition: delegation.c:783
GLuint res
Definition: glext.h:9613

Referenced by handle_cb_compound().

◆ handle_cb_layoutrecall()

static enum_t handle_cb_layoutrecall ( IN nfs41_rpc_clnt rpc_clnt,
IN struct cb_layoutrecall_args args,
OUT struct cb_layoutrecall_res res 
)
static

Definition at line 60 of file callback_server.c.

64 {
65  enum pnfs_status status;
66 
67  status = pnfs_file_layout_recall(rpc_clnt->client, args);
68  switch (status) {
69  case PNFS_PENDING:
70  /* not enough information to process the recall yet */
71  res->status = NFS4ERR_DELAY;
72  break;
73  default:
74  /* forgetful model for layout recalls */
76  break;
77  }
78 
79  dprintf(CBSLVL, " OP_CB_LAYOUTRECALL { %s, %s, recall %u } %s\n",
81  pnfs_iomode_string(args->iomode), args->recall.type,
82  nfs_error_string(res->status));
83  return res->status;
84 }
pnfs_status
Definition: pnfs.h:58
const char * pnfs_iomode_string(enum pnfs_iomode iomode)
Definition: pnfs_debug.c:58
Definition: match.c:390
#define dprintf
Definition: regdump.c:33
const char * pnfs_layout_type_string(enum pnfs_layout_type type)
Definition: pnfs_debug.c:48
#define CBSLVL
const char * nfs_error_string(int status)
Definition: daemon_debug.c:370
GLuint res
Definition: glext.h:9613
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)
Definition: ps.c:97

Referenced by handle_cb_compound().

◆ handle_cb_notify_deviceid()

static enum_t handle_cb_notify_deviceid ( IN nfs41_rpc_clnt rpc_clnt,
IN struct cb_notify_deviceid_args args,
OUT struct cb_notify_deviceid_res res 
)
static

Definition at line 198 of file callback_server.c.

202 {
203  uint32_t i;
204  for (i = 0; i < args->change_count; i++) {
205  pnfs_file_device_notify(rpc_clnt->client->devices,
206  &args->change_list[i]);
207  }
208  res->status = NFS4_OK;
209  return res->status;
210 }
Definition: match.c:390
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
UINT32 uint32_t
Definition: types.h:75
GLuint res
Definition: glext.h:9613
enum pnfs_status pnfs_file_device_notify(IN struct pnfs_file_device_list *devices, IN const struct notify_deviceid4 *change)
Definition: pnfs_device.c:328

◆ handle_cb_recall()

static enum_t handle_cb_recall ( IN nfs41_rpc_clnt rpc_clnt,
IN struct cb_recall_args args,
OUT struct cb_recall_res res 
)
static

Definition at line 186 of file callback_server.c.

190 {
191  /* return the delegation asynchronously */
192  res->status = nfs41_delegation_recall(rpc_clnt->client,
193  &args->fh, &args->stateid, args->truncate);
194  return res->status;
195 }
int nfs41_delegation_recall(IN nfs41_client *client, IN nfs41_fh *fh, IN const stateid4 *stateid, IN bool_t truncate)
Definition: delegation.c:703
Definition: match.c:390
GLuint res
Definition: glext.h:9613

Referenced by handle_cb_compound().

◆ handle_cb_recall_slot()

static enum_t handle_cb_recall_slot ( IN nfs41_rpc_clnt rpc_clnt,
IN struct cb_recall_slot_args args,
OUT struct cb_recall_slot_res res 
)
static

Definition at line 87 of file callback_server.c.

91 {
92  res->status = nfs41_session_recall_slot(rpc_clnt->client->session,
93  args->target_highest_slotid);
94 
95  dprintf(CBSLVL, " OP_CB_RECALL_SLOT { %u } %s\n",
96  args->target_highest_slotid, nfs_error_string(res->status));
97  return res->status;
98 }
Definition: match.c:390
#define dprintf
Definition: regdump.c:33
int nfs41_session_recall_slot(IN nfs41_session *session, IN OUT uint32_t target_highest_slotid)
#define CBSLVL
const char * nfs_error_string(int status)
Definition: daemon_debug.c:370
GLuint res
Definition: glext.h:9613

Referenced by handle_cb_compound().

◆ handle_cb_sequence()

static enum_t handle_cb_sequence ( IN nfs41_rpc_clnt rpc_clnt,
IN struct cb_sequence_args args,
OUT struct cb_sequence_res res,
OUT nfs41_cb_session **  session_out,
OUT bool_t cachethis 
)
static

Definition at line 101 of file callback_server.c.

107 {
108  nfs41_cb_session *cb_session = &rpc_clnt->client->session->cb_session;
110  res->status = NFS4_OK;
111 
112  *session_out = cb_session;
113 
114  /* validate the sessionid */
115  if (memcmp(cb_session->cb_sessionid, args->sessionid,
117  eprintf("[cb] received sessionid doesn't match session\n");
118  res->status = NFS4ERR_BADSESSION;
119  goto out;
120  }
121 
122  /* we only support 1 slot for the back channel so slotid MUST be 0 */
123  if (args->slotid != 0) {
124  eprintf("[cb] received unexpected slotid=%d\n", args->slotid);
125  res->status = NFS4ERR_BADSLOT;
126  goto out;
127  }
128  if (args->highest_slotid != 0) {
129  eprintf("[cb] received unexpected highest_slotid=%d\n",
130  args->highest_slotid);
131  res->status = NFS4ERR_BAD_HIGH_SLOT;
132  goto out;
133  }
134 
135  /* check for a retry with the same seqid */
136  if (args->sequenceid == cb_session->cb_seqnum) {
137  if (!cb_session->replay.res.length) {
138  /* return success for sequence, but fail the next operation */
139  res->status = NFS4_OK;
141  } else {
142  /* return NFS4ERR_SEQ_FALSE_RETRY for all replays; if the retry
143  * turns out to be valid, this response will be replaced anyway */
144  status = res->status = NFS4ERR_SEQ_FALSE_RETRY;
145  }
146  goto out;
147  }
148 
149  /* error on any unexpected seqids */
150  if (args->sequenceid != cb_session->cb_seqnum+1) {
151  eprintf("[cb] bad received seq#=%d, expected=%d\n",
152  args->sequenceid, cb_session->cb_seqnum+1);
153  res->status = NFS4ERR_SEQ_MISORDERED;
154  goto out;
155  }
156 
157  cb_session->cb_seqnum = args->sequenceid;
158  *cachethis = args->cachethis;
159 
160  memcpy(res->ok.sessionid, args->sessionid, NFS4_SESSIONID_SIZE);
161  res->ok.sequenceid = args->sequenceid;
162  res->ok.slotid = args->slotid;
163  res->ok.highest_slotid = args->highest_slotid;
164  res->ok.target_highest_slotid = args->highest_slotid;
165 
166 out:
167  dprintf(CBSLVL, " OP_CB_SEQUENCE { seqid %u, slot %u, cachethis %d } "
168  "%s\n", args->sequenceid, args->slotid, args->cachethis,
169  nfs_error_string(res->status));
170  return status;
171 }
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
#define NFS4_SESSIONID_SIZE
Definition: nfs41_const.h:32
void eprintf(LPCSTR format,...)
Definition: daemon_debug.c:86
const unsigned char * cb_sessionid
Definition: nfs41.h:250
Definition: match.c:390
struct __nfs41_cb_session::@28 replay
#define dprintf
Definition: regdump.c:33
#define CBSLVL
static FILE * out
Definition: regtests2xml.c:44
const char * nfs_error_string(int status)
Definition: daemon_debug.c:370
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
UINT32 uint32_t
Definition: types.h:75
GLuint res
Definition: glext.h:9613
uint32_t cb_seqnum
Definition: nfs41.h:251
static SERVICE_STATUS status
Definition: service.c:31
Definition: ps.c:97

Referenced by handle_cb_compound().

◆ nfs41_callback_session_init()

void nfs41_callback_session_init ( IN nfs41_session session)

Definition at line 44 of file callback_server.c.

46 {
47  /* initialize the replay cache with status NFS4ERR_SEQ_MISORDERED */
48  struct cb_compound_res res = { 0 };
50  res.tag.len = sizeof(g_server_tag);
51  res.status = NFS4ERR_SEQ_MISORDERED;
52 
53  session->cb_session.cb_sessionid = session->session_id;
54 
55  replay_cache_write(&session->cb_session, NULL, &res, FALSE);
56 }
static const char g_server_tag[]
smooth NULL
Definition: ftsmooth.c:416
#define CB_COMPOUND_MAX_TAG
STRSAFEAPI StringCchCopyA(STRSAFE_LPSTR pszDest, size_t cchDest, STRSAFE_LPCSTR pszSrc)
Definition: strsafe.h:145
GLuint res
Definition: glext.h:9613
static void replay_cache_write(IN nfs41_cb_session *session, IN struct cb_compound_args *args, IN struct cb_compound_res *res, IN bool_t cachethis)

Referenced by session_alloc().

◆ nfs41_handle_callback()

int nfs41_handle_callback ( void rpc_clnt,
void cb,
struct cb_compound_res **  reply 
)

Definition at line 516 of file callback_server.c.

517 {
518 #endif
519  nfs41_rpc_clnt *rpc = (nfs41_rpc_clnt *)rpc_clnt;
520  cb_req *request = (cb_req *)cb;
521  uint32_t status = 0;
522 
523  dprintf(1, "nfs41_handle_callback: received call\n");
524  if (request->rq_prog != NFS41_RPC_CBPROGRAM) {
525  eprintf("invalid rpc program %u\n", request->rq_prog);
526  status = 2;
527  goto out;
528  }
529 
530  switch (request->rq_proc) {
531  case CB_NULL:
532  dprintf(1, "CB_NULL\n");
533  break;
534 
535  case CB_COMPOUND:
536  dprintf(1, "CB_COMPOUND\n");
537  handle_cb_compound(rpc, request, reply);
538  break;
539 
540  default:
541  dprintf(1, "invalid rpc procedure %u\n", request->rq_proc);
542  status = 3;
543  goto out;
544  }
545 out:
546  return status;
547 }
static void handle_cb_compound(nfs41_rpc_clnt *rpc_clnt, cb_req *req, struct cb_compound_res **reply)
void eprintf(LPCSTR format,...)
Definition: daemon_debug.c:86
#define NFS41_RPC_CBPROGRAM
Definition: nfs41_const.h:80
#define dprintf
Definition: regdump.c:33
static FILE * out
Definition: regtests2xml.c:44
Definition: clnt.h:152
static DWORD cb
Definition: integrity.c:41
UINT32 uint32_t
Definition: types.h:75
Definition: tftpd.h:85
static SERVICE_STATUS status
Definition: service.c:31
Definition: ps.c:97

Referenced by get_client_for_netaddr().

◆ replay_cache_read()

static int replay_cache_read ( IN nfs41_cb_session session,
IN struct cb_compound_args args,
OUT struct cb_compound_res **  res_out 
)
static

Definition at line 296 of file callback_server.c.

300 {
301  XDR xdr;
302  struct cb_compound_res *replay;
303  struct cb_compound_res *res = *res_out;
305 
306  replay = calloc(1, sizeof(struct cb_compound_res));
307  if (replay == NULL) {
308  eprintf("[cb] failed to allocate replay buffer\n");
310  goto out;
311  }
312 
313  /* decode the response from the replay cache */
314  xdrmem_create(&xdr, (char*)session->replay.res.buffer,
316  if (!proc_cb_compound_res(&xdr, replay)) {
317  eprintf("[cb] failed to decode replay buffer\n");
319  goto out_free_replay;
320  }
321 
322  /* if we cached the arguments, use them to validate the retry */
323  if (session->replay.arg.length) {
324  if (!replay_validate_args(args, &session->replay.arg)) {
325  eprintf("[cb] retry attempt with different arguments\n");
327  goto out_free_replay;
328  }
329  } else { /* otherwise, comparing opnums is the best we can do */
330  if (!replay_validate_ops(args, replay)) {
331  eprintf("[cb] retry attempt with different operations\n");
333  goto out_free_replay;
334  }
335  }
336 
337  /* free previous response and replace it with the replay */
338  xdr.x_op = XDR_FREE;
339  proc_cb_compound_res(&xdr, res);
340 
341  dprintf(2, "[cb] retry: returning cached response\n");
342 
343  *res_out = replay;
344 out:
345  return status;
346 
347 out_free_replay:
348  xdr.x_op = XDR_FREE;
349  proc_cb_compound_res(&xdr, replay);
350  goto out;
351 }
static bool_t replay_validate_args(IN struct cb_compound_args *args, IN const struct replay_cache *cache)
static bool_t replay_validate_ops(IN const struct cb_compound_args *args, IN const struct cb_compound_res *res)
void eprintf(LPCSTR format,...)
Definition: daemon_debug.c:86
Definition: match.c:390
Definition: xdr.h:103
#define dprintf
Definition: regdump.c:33
smooth NULL
Definition: ftsmooth.c:416
enum xdr_op x_op
Definition: xdr.h:104
static FILE * out
Definition: regtests2xml.c:44
#define NFS41_MAX_SERVER_CACHE
Definition: nfs41_const.h:39
void xdrmem_create(XDR *xdrs, char *addr, u_int size, enum xdr_op op)
Definition: xdr_mem.c:94
UINT32 uint32_t
Definition: types.h:75
Definition: xdr.h:87
#define calloc
Definition: rosglue.h:14
GLuint res
Definition: glext.h:9613
Definition: xdr.h:86
bool_t proc_cb_compound_res(XDR *xdr, struct cb_compound_res *res)
Definition: callback_xdr.c:638
static SERVICE_STATUS status
Definition: service.c:31
Definition: ps.c:97

Referenced by handle_cb_compound().

◆ replay_cache_write() [1/2]

static void replay_cache_write ( IN nfs41_cb_session session,
IN struct cb_compound_args args,
IN struct cb_compound_res res,
IN bool_t  cachethis 
)
static

◆ replay_cache_write() [2/2]

static void replay_cache_write ( IN nfs41_cb_session session,
IN OPTIONAL struct cb_compound_args args,
IN struct cb_compound_res res,
IN bool_t  cachethis 
)
static

Definition at line 212 of file callback_server.c.

217 {
218  XDR xdr;
219  uint32_t i;
220 
221  session->replay.arg.length = 0;
222  session->replay.res.length = 0;
223 
224  /* encode the reply directly into the replay cache */
225  xdrmem_create(&xdr, (char*)session->replay.res.buffer,
227 
228  /* always try to cache the result */
229  if (proc_cb_compound_res(&xdr, res)) {
230  session->replay.res.length = XDR_GETPOS(&xdr);
231 
232  if (args) {
233  /* encode the arguments into the request cache */
234  xdrmem_create(&xdr, (char*)session->replay.arg.buffer,
236 
237  if (proc_cb_compound_args(&xdr, args))
238  session->replay.arg.length = XDR_GETPOS(&xdr);
239  }
240  } else if (cachethis) {
241  /* on failure, only return errors if caching was requested */
243 
244  /* find the first operation that failed to encode */
245  for (i = 0; i < res->resarray_count; i++) {
246  if (!res->resarray[i].xdr_ok) {
247  res->resarray[i].res.status = NFS4ERR_REP_TOO_BIG_TO_CACHE;
248  res->resarray_count = i + 1;
249  break;
250  }
251  }
252  }
253 }
#define XDR_GETPOS(xdrs)
Definition: xdr.h:199
Definition: match.c:390
Definition: xdr.h:103
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
Definition: xdr.h:85
#define NFS41_MAX_SERVER_CACHE
Definition: nfs41_const.h:39
void xdrmem_create(XDR *xdrs, char *addr, u_int size, enum xdr_op op)
Definition: xdr_mem.c:94
UINT32 uint32_t
Definition: types.h:75
GLuint res
Definition: glext.h:9613
bool_t proc_cb_compound_args(XDR *xdr, struct cb_compound_args *args)
Definition: callback_xdr.c:590
bool_t proc_cb_compound_res(XDR *xdr, struct cb_compound_res *res)
Definition: callback_xdr.c:638

◆ replay_validate_args()

static bool_t replay_validate_args ( IN struct cb_compound_args args,
IN const struct replay_cache cache 
)
static

Definition at line 255 of file callback_server.c.

258 {
260  XDR xdr;
261 
262  /* encode the current arguments into a temporary buffer */
264 
265  if (!proc_cb_compound_args(&xdr, args))
266  return FALSE;
267 
268  /* must match the cached length */
269  if (XDR_GETPOS(&xdr) != cache->length)
270  return FALSE;
271 
272  /* must match the cached buffer contents */
273  return memcmp(cache->buffer, buffer, cache->length) == 0;
274 }
Definition: cache.c:46
#define XDR_GETPOS(xdrs)
Definition: xdr.h:199
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
GLuint buffer
Definition: glext.h:5915
Definition: match.c:390
Definition: xdr.h:103
Definition: xdr.h:85
#define NFS41_MAX_SERVER_CACHE
Definition: nfs41_const.h:39
void xdrmem_create(XDR *xdrs, char *addr, u_int size, enum xdr_op op)
Definition: xdr_mem.c:94
bool_t proc_cb_compound_args(XDR *xdr, struct cb_compound_args *args)
Definition: callback_xdr.c:590

Referenced by replay_cache_read().

◆ replay_validate_ops()

static bool_t replay_validate_ops ( IN const struct cb_compound_args args,
IN const struct cb_compound_res res 
)
static

Definition at line 276 of file callback_server.c.

279 {
280  uint32_t i;
281  for (i = 0; i < res->resarray_count; i++) {
282  /* can't have more operations than the request */
283  if (i >= args->argarray_count)
284  return FALSE;
285 
286  /* each opnum must match the request */
287  if (args->argarray[i].opnum != res->resarray[i].opnum)
288  return FALSE;
289 
290  if (res->resarray[i].res.status)
291  break;
292  }
293  return TRUE;
294 }
#define TRUE
Definition: types.h:120
Definition: match.c:390
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
UINT32 uint32_t
Definition: types.h:75
GLuint res
Definition: glext.h:9613

Referenced by replay_cache_read().

Variable Documentation

◆ g_server_tag

const char g_server_tag[] = "ms-nfs41-callback"
static

Definition at line 34 of file callback_server.c.

Referenced by handle_cb_compound(), and nfs41_callback_session_init().