ReactOS  0.4.13-dev-39-g8b6696f
callback_server.c
Go to the documentation of this file.
1 /* NFSv4.1 client for Windows
2  * Copyright 2012 The Regents of the University of Michigan
3  *
4  * Olga Kornievskaia <aglo@umich.edu>
5  * Casey Bodley <cbodley@umich.edu>
6  *
7  * This library is free software; you can redistribute it and/or modify it
8  * under the terms of the GNU Lesser General Public License as published by
9  * the Free Software Foundation; either version 2.1 of the License, or (at
10  * your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful, but
13  * without any warranty; without even the implied warranty of merchantability
14  * or fitness for a particular purpose. See the GNU Lesser General Public
15  * License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public License
18  * along with this library; if not, write to the Free Software Foundation,
19  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20  */
21 
22 #include <windows.h>
23 #include <strsafe.h>
24 
25 #include "nfs41_ops.h"
26 #include "delegation.h"
27 #include "nfs41_callback.h"
28 #include "daemon_debug.h"
29 
30 
31 #define CBSLVL 2 /* dprintf level for callback server logging */
32 
33 
34 static const char g_server_tag[] = "ms-nfs41-callback";
35 
36 
37 /* callback session */
38 static void replay_cache_write(
39  IN nfs41_cb_session *session,
40  IN struct cb_compound_args *args,
41  IN struct cb_compound_res *res,
42  IN bool_t cachethis);
43 
45  IN nfs41_session *session)
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 }
57 
58 
59 /* OP_CB_LAYOUTRECALL */
61  IN nfs41_rpc_clnt *rpc_clnt,
63  OUT struct cb_layoutrecall_res *res)
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 }
85 
86 /* OP_CB_RECALL_SLOT */
88  IN nfs41_rpc_clnt *rpc_clnt,
89  IN struct cb_recall_slot_args *args,
90  OUT struct cb_recall_slot_res *res)
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 }
99 
100 /* OP_CB_SEQUENCE */
102  IN nfs41_rpc_clnt *rpc_clnt,
103  IN struct cb_sequence_args *args,
104  OUT struct cb_sequence_res *res,
105  OUT nfs41_cb_session **session_out,
106  OUT bool_t *cachethis)
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 }
172 
173 /* OP_CB_GETATTR */
175  IN nfs41_rpc_clnt *rpc_clnt,
176  IN struct cb_getattr_args *args,
177  OUT struct cb_getattr_res *res)
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 }
184 
185 /* OP_CB_RECALL */
187  IN nfs41_rpc_clnt *rpc_clnt,
188  IN struct cb_recall_args *args,
189  OUT struct cb_recall_res *res)
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 }
196 
197 /* OP_CB_NOTIFY_DEVICEID */
199  IN nfs41_rpc_clnt *rpc_clnt,
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 }
211 
212 static void replay_cache_write(
213  IN nfs41_cb_session *session,
215  IN struct cb_compound_res *res,
216  IN bool_t cachethis)
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 }
254 
256  IN struct cb_compound_args *args,
257  IN const struct replay_cache *cache)
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 }
275 
277  IN const struct cb_compound_args *args,
278  IN const struct cb_compound_res *res)
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 }
295 
296 static int replay_cache_read(
297  IN nfs41_cb_session *session,
298  IN struct cb_compound_args *args,
299  OUT struct cb_compound_res **res_out)
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 }
352 
353 /* CB_COMPOUND */
354 static void handle_cb_compound(nfs41_rpc_clnt *rpc_clnt, cb_req *req, struct cb_compound_res **reply)
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 }
510 
511 #ifdef __REACTOS__
512 int nfs41_handle_callback(void *rpc_clnt, void *cb, void * dummy)
513 {
514  struct cb_compound_res **reply = dummy;
515 #else
516 int nfs41_handle_callback(void *rpc_clnt, void *cb, struct cb_compound_res **reply)
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 }
pnfs_status
Definition: pnfs.h:58
Definition: cache.c:46
struct cb_getattr_res getattr
#define IN
Definition: typedefs.h:38
static bool_t replay_validate_args(IN struct cb_compound_args *args, IN const struct replay_cache *cache)
void * xdr
Definition: clnt.h:156
#define TRUE
Definition: types.h:120
const char * pnfs_iomode_string(enum pnfs_iomode iomode)
Definition: pnfs_debug.c:58
#define XDR_GETPOS(xdrs)
Definition: xdr.h:199
struct cb_recall_slot_res recall_slot
static bool_t replay_validate_ops(IN const struct cb_compound_args *args, IN const struct cb_compound_res *res)
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
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
#define NFS4_SESSIONID_SIZE
Definition: nfs41_const.h:32
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
int32_t bool_t
Definition: types.h:101
struct cb_recall_res recall
static void handle_cb_compound(nfs41_rpc_clnt *rpc_clnt, cb_req *req, struct cb_compound_res **reply)
void nfs41_callback_session_init(IN nfs41_session *session)
int nfs41_delegation_recall(IN nfs41_client *client, IN nfs41_fh *fh, IN const stateid4 *stateid, IN bool_t truncate)
Definition: delegation.c:703
GLuint buffer
Definition: glext.h:5915
void eprintf(LPCSTR format,...)
Definition: daemon_debug.c:86
enum_t status
const unsigned char * cb_sessionid
Definition: nfs41.h:250
#define NFS41_RPC_CBPROGRAM
Definition: nfs41_const.h:80
static const char g_server_tag[]
Definition: match.c:390
Definition: xdr.h:103
enum_t opnum
int nfs41_handle_callback(void *rpc_clnt, void *cb, struct cb_compound_res **reply)
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)
struct __nfs41_cb_session::@28 replay
#define dprintf
Definition: regdump.c:33
struct cb_layoutrecall_res layoutrecall
const char * pnfs_layout_type_string(enum pnfs_layout_type type)
Definition: pnfs_debug.c:48
int nfs41_session_recall_slot(IN nfs41_session *session, IN OUT uint32_t target_highest_slotid)
smooth NULL
Definition: ftsmooth.c:416
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)
#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
Definition: clnt.h:152
static DWORD cb
Definition: integrity.c:41
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)
int32_t enum_t
Definition: types.h:102
struct cb_getattr_args getattr
Definition: xdr.h:85
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
union cb_op_res res
enum_t opnum
#define NFS41_MAX_SERVER_CACHE
Definition: nfs41_const.h:39
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
unsigned char dummy
Definition: maze.c:118
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)
void xdrmem_create(XDR *xdrs, char *addr, u_int size, enum xdr_op op)
Definition: xdr_mem.c:94
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
UINT32 uint32_t
Definition: types.h:75
Definition: tftpd.h:85
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
#define OUT
Definition: typedefs.h:39
GLuint res
Definition: glext.h:9613
Definition: xdr.h:86
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
bool_t proc_cb_compound_res(XDR *xdr, struct cb_compound_res *res)
Definition: callback_xdr.c:638
#define uint32_t
Definition: nsiface.idl:61
uint32_t cb_seqnum
Definition: nfs41.h:251
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 pnfs_status pnfs_file_device_notify(IN struct pnfs_file_device_list *devices, IN const struct notify_deviceid4 *change)
Definition: pnfs_device.c:328
struct cb_recall_slot_args recall_slot
Definition: ps.c:97
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68