ReactOS  0.4.14-dev-342-gdc047f9
ea.c File Reference
#include <windows.h>
#include <stdio.h>
#include <strsafe.h>
#include "from_kernel.h"
#include "nfs41_ops.h"
#include "delegation.h"
#include "upcall.h"
#include "daemon_debug.h"
Include dependency graph for ea.c:

Go to the source code of this file.

Macros

#define EALVL   2 /* dprintf level for extended attribute logging */
 
#define NEXT_ENTRY(ea)   ((PBYTE)(ea) + (ea)->NextEntryOffset)
 
#define READDIR_LEN_INITIAL   8192
 
#define READDIR_LEN_MIN   2048
 
#define ALIGNED_EASIZE(len)   (align4(sizeof(FILE_GET_EA_INFORMATION) + len))
 

Functions

static int set_ea_value (IN nfs41_session *session, IN nfs41_path_fh *parent, IN state_owner4 *owner, IN PFILE_FULL_EA_INFORMATION ea)
 
static int is_cygwin_ea (PFILE_FULL_EA_INFORMATION ea)
 
int nfs41_ea_set (IN nfs41_open_state *state, IN PFILE_FULL_EA_INFORMATION ea)
 
static int parse_setexattr (unsigned char *buffer, uint32_t length, nfs41_upcall *upcall)
 
static int handle_setexattr (nfs41_upcall *upcall)
 
static int marshall_setexattr (unsigned char *buffer, uint32_t *length, nfs41_upcall *upcall)
 
static int parse_getexattr (unsigned char *buffer, uint32_t length, nfs41_upcall *upcall)
 
static int read_entire_dir (IN nfs41_session *session, IN nfs41_path_fh *eadir, OUT unsigned char **buffer_out, OUT uint32_t *length_out)
 
static uint32_t calculate_ea_list_length (IN const unsigned char *position, IN uint32_t remaining)
 
static void populate_ea_list (IN const unsigned char *position, OUT PFILE_GET_EA_INFORMATION ea_list)
 
static int get_ea_list (IN OUT nfs41_open_state *state, IN nfs41_path_fh *eadir, OUT PFILE_GET_EA_INFORMATION *ealist_out, OUT uint32_t *eaindex_out)
 
static int get_ea_value (IN nfs41_session *session, IN nfs41_path_fh *parent, IN state_owner4 *owner, OUT PFILE_FULL_EA_INFORMATION ea, IN uint32_t length, OUT uint32_t *needed)
 
static int empty_ea_error (IN uint32_t index, IN BOOLEAN restart)
 
static int overflow_error (IN OUT getexattr_upcall_args *args, IN PFILE_FULL_EA_INFORMATION prev, IN uint32_t needed)
 
static int handle_getexattr (nfs41_upcall *upcall)
 
static int marshall_getexattr (unsigned char *buffer, uint32_t *length, nfs41_upcall *upcall)
 

Variables

const nfs41_upcall_op nfs41_op_setexattr
 
const nfs41_upcall_op nfs41_op_getexattr
 

Macro Definition Documentation

◆ ALIGNED_EASIZE

#define ALIGNED_EASIZE (   len)    (align4(sizeof(FILE_GET_EA_INFORMATION) + len))

Definition at line 320 of file ea.c.

◆ EALVL

#define EALVL   2 /* dprintf level for extended attribute logging */

Definition at line 33 of file ea.c.

◆ NEXT_ENTRY

#define NEXT_ENTRY (   ea)    ((PBYTE)(ea) + (ea)->NextEntryOffset)

Definition at line 114 of file ea.c.

◆ READDIR_LEN_INITIAL

#define READDIR_LEN_INITIAL   8192

Definition at line 235 of file ea.c.

◆ READDIR_LEN_MIN

#define READDIR_LEN_MIN   2048

Definition at line 236 of file ea.c.

Function Documentation

◆ calculate_ea_list_length()

static uint32_t calculate_ea_list_length ( IN const unsigned char position,
IN uint32_t  remaining 
)
static

Definition at line 322 of file ea.c.

325 {
326  const nfs41_readdir_entry *entry;
327  uint32_t length = 0;
328 
329  while (remaining) {
330  entry = (const nfs41_readdir_entry*)position;
331  length += ALIGNED_EASIZE(entry->name_len);
332 
333  if (!entry->next_entry_offset)
334  break;
335 
336  position += entry->next_entry_offset;
337  remaining -= entry->next_entry_offset;
338  }
339  return length;
340 }
Definition: nfs41_ops.h:710
GLenum GLuint GLenum GLsizei length
Definition: glext.h:5579
#define ALIGNED_EASIZE(len)
Definition: ea.c:320
uint32_t entry
Definition: isohybrid.c:63
UINT32 uint32_t
Definition: types.h:75

Referenced by get_ea_list().

◆ empty_ea_error()

static int empty_ea_error ( IN uint32_t  index,
IN BOOLEAN  restart 
)
static

Definition at line 496 of file ea.c.

499 {
500  /* choose an error value depending on the arguments */
501  if (index)
503 
504  if (!restart)
505  return ERROR_NO_MORE_FILES; /* -> STATUS_NO_MORE_EAS */
506 
507  return ERROR_FILE_NOT_FOUND; /* -> STATUS_NO_EAS_ON_FILE */
508 }
#define ERROR_INVALID_EA_HANDLE
Definition: winerror.h:299
GLuint index
Definition: glext.h:6031
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
#define ERROR_NO_MORE_FILES
Definition: winerror.h:121
void restart(int argc, const char *argv[])
Definition: cmds.c:2115

◆ get_ea_list()

static int get_ea_list ( IN OUT nfs41_open_state state,
IN nfs41_path_fh eadir,
OUT PFILE_GET_EA_INFORMATION ealist_out,
OUT uint32_t eaindex_out 
)
static

Definition at line 366 of file ea.c.

371 {
372  unsigned char *entry_list;
373  PFILE_GET_EA_INFORMATION ea_list;
374  uint32_t entry_len, ea_size;
375  int status = NO_ERROR;
376 
377  EnterCriticalSection(&state->ea.lock);
378 
379  if (state->ea.list != INVALID_HANDLE_VALUE) {
380  /* use cached ea names */
381  *ealist_out = state->ea.list;
382  *eaindex_out = state->ea.index;
383  goto out;
384  }
385 
386  /* read the entire directory into a nfs41_readdir_entry buffer */
387  status = read_entire_dir(state->session, eadir, &entry_list, &entry_len);
388  if (status)
389  goto out;
390 
391  ea_size = calculate_ea_list_length(entry_list, entry_len);
392  if (ea_size == 0) {
393  *ealist_out = state->ea.list = NULL;
394  goto out_free;
395  }
396  ea_list = calloc(1, ea_size);
397  if (ea_list == NULL) {
398  status = GetLastError();
399  goto out_free;
400  }
401 
402  populate_ea_list(entry_list, ea_list);
403 
404  *ealist_out = state->ea.list = ea_list;
405  *eaindex_out = state->ea.index;
406 out_free:
407  free(entry_list); /* allocated by read_entire_dir() */
408 out:
409  LeaveCriticalSection(&state->ea.lock);
410  return status;
411 }
static int read_entire_dir(IN nfs41_session *session, IN nfs41_path_fh *eadir, OUT unsigned char **buffer_out, OUT uint32_t *length_out)
Definition: ea.c:239
static uint32_t calculate_ea_list_length(IN const unsigned char *position, IN uint32_t remaining)
Definition: ea.c:322
#define free
Definition: debug_ros.c:5
#define INVALID_HANDLE_VALUE
Definition: compat.h:399
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
#define NO_ERROR
Definition: dderror.h:5
smooth NULL
Definition: ftsmooth.c:416
static FILE * out
Definition: regtests2xml.c:44
static int state
Definition: maze.c:121
static void populate_ea_list(IN const unsigned char *position, OUT PFILE_GET_EA_INFORMATION ea_list)
Definition: ea.c:342
UINT32 uint32_t
Definition: types.h:75
#define calloc
Definition: rosglue.h:14
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
static SERVICE_STATUS status
Definition: service.c:31
Definition: ps.c:97

◆ get_ea_value()

static int get_ea_value ( IN nfs41_session session,
IN nfs41_path_fh parent,
IN state_owner4 owner,
OUT PFILE_FULL_EA_INFORMATION  ea,
IN uint32_t  length,
OUT uint32_t needed 
)
static

Definition at line 413 of file ea.c.

420 {
421  nfs41_path_fh file = { 0 };
422  open_claim4 claim;
423  stateid_arg stateid;
426  unsigned char *buffer;
427  uint32_t diff, bytes_read;
428  bool_t eof;
429  int status;
430 
431  if (parent->fh.len == 0) /* no named attribute directory */
432  goto out_empty;
433 
434  claim.claim = CLAIM_NULL;
435  claim.u.null.filename = &file.name;
436  file.name.name = ea->EaName;
437  file.name.len = ea->EaNameLength;
438 
439  status = nfs41_open(session, parent, &file, owner, &claim,
442  &stateid.stateid, &delegation, &info);
443  if (status) {
444  eprintf("nfs41_open() failed with %s\n", nfs_error_string(status));
445  if (status == NFS4ERR_NOENT)
446  goto out_empty;
447  goto out;
448  }
449 
450  if (info.size > NFS4_EASIZE) {
452  eprintf("EA value for '%s' longer than maximum %u "
453  "(%llu bytes), returning %s\n", ea->EaName, NFS4_EASIZE,
454  info.size, nfs_error_string(status));
455  goto out_close;
456  }
457 
458  buffer = (unsigned char*)ea->EaName + ea->EaNameLength + 1;
459  diff = (uint32_t)(buffer - (unsigned char*)ea);
460 
461  /* make sure we have room for the value */
462  if (length < diff + info.size) {
463  *needed = (uint32_t)(sizeof(FILE_FULL_EA_INFORMATION) +
464  ea->EaNameLength + info.size);
466  goto out_close;
467  }
468 
469  /* read directly into the ea buffer */
470  status = nfs41_read(session, &file, &stateid,
471  0, length - diff, buffer, &bytes_read, &eof);
472  if (status) {
473  eprintf("nfs41_read() failed with %s\n", nfs_error_string(status));
474  goto out_close;
475  }
476  if (!eof) {
477  *needed = (uint32_t)(sizeof(FILE_FULL_EA_INFORMATION) +
478  ea->EaNameLength + NFS4_EASIZE);
480  goto out_close;
481  }
482 
483  ea->EaValueLength = (USHORT)bytes_read;
484 
485 out_close:
486  nfs41_close(session, &file, &stateid);
487 out:
488  return status;
489 
490 out_empty: /* return an empty value */
491  ea->EaValueLength = 0;
492  status = NFS4_OK;
493  goto out;
494 }
#define TRUE
Definition: types.h:120
int32_t bool_t
Definition: types.h:101
void eprintf(LPCSTR format,...)
Definition: daemon_debug.c:86
GLuint buffer
Definition: glext.h:5915
struct _test_info info[]
Definition: SetCursorPos.c:19
nfs41_delegation_state * delegation
Definition: delegation.c:679
char name[1]
Definition: fci.c:135
smooth NULL
Definition: ftsmooth.c:416
r parent
Definition: btrfs.c:2869
GLenum GLuint GLenum GLsizei length
Definition: glext.h:5579
static FILE * out
Definition: regtests2xml.c:44
const char * nfs_error_string(int status)
Definition: daemon_debug.c:370
union __open_claim4::@40 u
int nfs41_read(IN nfs41_session *session, IN nfs41_path_fh *file, IN stateid_arg *stateid, IN uint64_t offset, IN uint32_t count, OUT unsigned char *data_out, OUT uint32_t *data_len_out, OUT bool_t *eof_out)
Definition: nfs41_ops.c:774
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
_Check_return_ _CRTIMP int __cdecl __cdecl eof(_In_ int _FileHandle)
struct __open_claim4::@40::__open_claim_null null
unsigned short USHORT
Definition: pedump.c:61
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
uint32_t claim
Definition: nfs41_ops.h:615
#define uint32_t
Definition: nsiface.idl:61
static SERVICE_STATUS status
Definition: service.c:31
#define NFS4_EASIZE
Definition: nfs41_const.h:34
Definition: fci.c:126
Definition: ps.c:97

◆ handle_getexattr()

static int handle_getexattr ( nfs41_upcall upcall)
static

Definition at line 530 of file ea.c.

531 {
532  getexattr_upcall_args *args = &upcall->args.getexattr;
534  PFILE_FULL_EA_INFORMATION ea, prev = NULL;
535  nfs41_open_state *state = upcall->state_ref;
536  nfs41_path_fh parent = { 0 };
537  uint32_t remaining, needed, index = 0;
538  int status;
539 
540  status = nfs41_rpc_openattr(state->session, &state->file, FALSE, &parent.fh);
541  if (status == NFS4ERR_NOENT) { /* no named attribute directory */
542  dprintf(EALVL, "no named attribute directory for '%s'\n", args->path);
543  if (query == NULL) {
544  status = empty_ea_error(args->eaindex, args->restart);
545  goto out;
546  }
547  } else if (status) {
548  eprintf("nfs41_rpc_openattr() failed with %s\n",
551  goto out;
552  }
553 
554  if (query == NULL) {
555  /* if no names are queried, use READDIR to list them all */
556  uint32_t i;
558  if (status)
559  goto out;
560 
561  if (query == NULL) { /* the file has no EAs */
562  dprintf(EALVL, "empty named attribute directory for '%s'\n",
563  args->path);
564  status = empty_ea_error(args->eaindex, args->restart);
565  goto out;
566  }
567 
568  if (args->eaindex)
569  index = args->eaindex - 1; /* convert to zero-based index */
570  else if (args->restart)
571  index = 0;
572 
573  /* advance the list to the specified index */
574  for (i = 0; i < index; i++) {
575  if (query->NextEntryOffset == 0) {
576  if (args->eaindex)
578  else
579  status = ERROR_NO_MORE_FILES; /* STATUS_NO_MORE_EAS */
580  goto out;
581  }
583  }
584  }
585 
586  /* returned ea information can't exceed the downcall buffer size */
587  if (args->buf_len > UPCALL_BUF_SIZE - 2 * sizeof(uint32_t))
588  args->buf_len = UPCALL_BUF_SIZE - 2 * sizeof(uint32_t);
589 
590  args->buf = malloc(args->buf_len);
591  if (args->buf == NULL) {
592  status = GetLastError();
593  goto out;
594  }
595 
596  ea = (PFILE_FULL_EA_INFORMATION)args->buf;
597  remaining = args->buf_len;
598 
599  for (;;) {
600  /* make sure we have room for at least the name */
601  needed = sizeof(FILE_FULL_EA_INFORMATION) + query->EaNameLength;
602  if (needed > remaining) {
603  status = overflow_error(args, prev, needed + NFS4_EASIZE);
604  goto out;
605  }
606 
607  ea->EaNameLength = query->EaNameLength;
608  StringCchCopy(ea->EaName, ea->EaNameLength + 1, query->EaName);
609  ea->Flags = 0;
610 
611  /* read the value from file */
612  status = get_ea_value(state->session, &parent,
613  &state->owner, ea, remaining, &needed);
614  if (status == NFS4ERR_TOOSMALL) {
615  status = overflow_error(args, prev, needed);
616  goto out;
617  }
618  if (status) {
620  goto out_free;
621  }
622 
623  needed = align4(FIELD_OFFSET(FILE_FULL_EA_INFORMATION, EaName) +
624  ea->EaNameLength + 1 + ea->EaValueLength);
625 
626  if (remaining < needed) {
627  /* align4 may push NextEntryOffset past our buffer, but we
628  * were still able to fit the ea value. set remaining = 0
629  * so we'll fail on the next ea (if any) */
630  remaining = 0;
631  } else
632  remaining -= needed;
633 
634  index++;
635  if (query->NextEntryOffset == 0 || args->single)
636  break;
637 
638  prev = ea;
639  ea->NextEntryOffset = needed;
642  }
643 
644  ea->NextEntryOffset = 0;
645  args->buf_len -= remaining;
646 out:
647  if (args->ealist == NULL) { /* update the ea index */
648  EnterCriticalSection(&state->ea.lock);
649  state->ea.index = index;
650  if (status == NO_ERROR && !args->overflow && !args->single) {
651  /* listing was completed, free the cache */
652  free(state->ea.list);
653  state->ea.list = INVALID_HANDLE_VALUE;
654  }
655  LeaveCriticalSection(&state->ea.lock);
656  }
657  return status;
658 
659 out_free:
660  free(args->buf);
661  goto out;
662 }
int nfs_to_windows_error(int status, int default_error)
Definition: util.c:235
static int get_ea_list(IN OUT nfs41_open_state *state, IN nfs41_path_fh *eadir, OUT PFILE_GET_EA_INFORMATION *ealist_out, OUT uint32_t *eaindex_out)
Definition: ea.c:366
#define ERROR_INVALID_EA_HANDLE
Definition: winerror.h:299
struct _FILE_FULL_EA_INFORMATION * PFILE_FULL_EA_INFORMATION
#define free
Definition: debug_ros.c:5
struct _FILE_GET_EA_INFORMATION * PFILE_GET_EA_INFORMATION
#define INVALID_HANDLE_VALUE
Definition: compat.h:399
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
void eprintf(LPCSTR format,...)
Definition: daemon_debug.c:86
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
#define NO_ERROR
Definition: dderror.h:5
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
#define dprintf
Definition: regdump.c:33
smooth NULL
Definition: ftsmooth.c:416
GLuint index
Definition: glext.h:6031
#define ERROR_NO_MORE_FILES
Definition: winerror.h:121
enum nfsstat4 nfs41_rpc_openattr(IN nfs41_session *session, IN nfs41_path_fh *file, IN bool_t createdir, OUT nfs41_fh *fh_out)
Definition: nfs41_ops.c:2145
__inline uint32_t align4(uint32_t offset)
Definition: util.h:198
r parent
Definition: btrfs.c:2869
if(!(yy_init))
Definition: macro.lex.yy.c:714
static FILE * out
Definition: regtests2xml.c:44
#define for
Definition: utility.h:88
const char * nfs_error_string(int status)
Definition: daemon_debug.c:370
#define ERROR_EA_FILE_CORRUPT
Definition: winerror.h:297
#define NEXT_ENTRY(ea)
Definition: ea.c:114
#define index(s, c)
Definition: various.h:29
#define StringCchCopy
Definition: strsafe.h:139
static int state
Definition: maze.c:121
struct _FILE_FULL_EA_INFORMATION FILE_FULL_EA_INFORMATION
#define EALVL
Definition: ea.c:33
#define UPCALL_BUF_SIZE
Definition: nfs41_const.h:42
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:254
UINT32 uint32_t
Definition: types.h:75
nfs41_updowncall_list upcall
Definition: nfs41_driver.c:273
static int get_ea_value(IN nfs41_session *session, IN nfs41_path_fh *parent, IN state_owner4 *owner, OUT PFILE_FULL_EA_INFORMATION ea, IN uint32_t length, OUT uint32_t *needed)
Definition: ea.c:413
static int empty_ea_error(IN uint32_t index, IN BOOLEAN restart)
Definition: ea.c:496
#define malloc
Definition: debug_ros.c:4
#define ERROR_EAS_NOT_SUPPORTED
Definition: winerror.h:300
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
static SERVICE_STATUS status
Definition: service.c:31
static int overflow_error(IN OUT getexattr_upcall_args *args, IN PFILE_FULL_EA_INFORMATION prev, IN uint32_t needed)
Definition: ea.c:510
#define NFS4_EASIZE
Definition: nfs41_const.h:34
Definition: ps.c:97

◆ handle_setexattr()

static int handle_setexattr ( nfs41_upcall upcall)
static

Definition at line 162 of file ea.c.

163 {
164  int status;
165  setexattr_upcall_args *args = &upcall->args.setexattr;
166  nfs41_open_state *state = upcall->state_ref;
169 
170  /* break read delegations before SETATTR */
171  nfs41_delegation_return(state->session, &state->file,
173 
174  if (strncmp("NfsV3Attributes", ea->EaName, ea->EaNameLength) == 0
175  && sizeof("NfsV3Attributes")-1 == ea->EaNameLength) {
177  stateid_arg stateid;
178 
179  nfs41_open_stateid_arg(state, &stateid);
180 
181  info.mode = args->mode;
182  info.attrmask.arr[0] = 0;
183  info.attrmask.arr[1] = FATTR4_WORD1_MODE;
184  info.attrmask.count = 2;
185 
186  status = nfs41_setattr(state->session, &state->file, &stateid, &info);
187  if (status) {
188  dprintf(1, "nfs41_setattr() failed with error %s.\n",
190  goto out;
191  }
192 
193  args->ctime = info.change;
194  goto out;
195  }
196 
197  status = nfs41_ea_set(state, ea);
198 out:
200 }
int nfs_to_windows_error(int status, int default_error)
Definition: util.c:235
int nfs41_setattr(IN nfs41_session *session, IN nfs41_path_fh *file, IN stateid_arg *stateid, IN nfs41_file_info *info)
Definition: nfs41_ops.c:1351
struct _FILE_FULL_EA_INFORMATION * PFILE_FULL_EA_INFORMATION
Definition: match.c:390
unsigned int count
Definition: notification.c:64
struct _test_info info[]
Definition: SetCursorPos.c:19
#define dprintf
Definition: regdump.c:33
void nfs41_open_stateid_arg(IN nfs41_open_state *state, OUT struct __stateid_arg *arg)
int nfs41_delegation_return(IN nfs41_session *session, IN nfs41_path_fh *file, IN enum open_delegation_type4 access, IN bool_t truncate)
Definition: delegation.c:629
int strncmp(const char *String1, const char *String2, ACPI_SIZE Count)
Definition: utclib.c:534
static FILE * out
Definition: regtests2xml.c:44
const char * nfs_error_string(int status)
Definition: daemon_debug.c:370
static int state
Definition: maze.c:121
int nfs41_ea_set(IN nfs41_open_state *state, IN PFILE_FULL_EA_INFORMATION ea)
Definition: ea.c:116
nfs41_updowncall_list upcall
Definition: nfs41_driver.c:273
#define ERROR_NOT_SUPPORTED
Definition: compat.h:90
static SERVICE_STATUS status
Definition: service.c:31
Definition: ps.c:97

◆ is_cygwin_ea()

static int is_cygwin_ea ( PFILE_FULL_EA_INFORMATION  ea)
static

Definition at line 103 of file ea.c.

105 {
106  return (strncmp("NfsV3Attributes", ea->EaName, ea->EaNameLength) == 0
107  && sizeof("NfsV3Attributes")-1 == ea->EaNameLength)
108  || (strncmp("NfsActOnLink", ea->EaName, ea->EaNameLength) == 0
109  && sizeof("NfsActOnLink")-1 == ea->EaNameLength)
110  || (strncmp("NfsSymlinkTargetName", ea->EaName, ea->EaNameLength) == 0
111  && sizeof("NfsSymlinkTargetName")-1 == ea->EaNameLength);
112 }
int strncmp(const char *String1, const char *String2, ACPI_SIZE Count)
Definition: utclib.c:534

Referenced by nfs41_ea_set().

◆ marshall_getexattr()

static int marshall_getexattr ( unsigned char buffer,
uint32_t length,
nfs41_upcall upcall 
)
static

Definition at line 664 of file ea.c.

665 {
666  int status = NO_ERROR;
667  getexattr_upcall_args *args = &upcall->args.getexattr;
668 
669  status = safe_write(&buffer, length, &args->overflow, sizeof(args->overflow));
670  if (status) goto out;
671  status = safe_write(&buffer, length, &args->buf_len, sizeof(args->buf_len));
672  if (status) goto out;
673  if (args->overflow == ERROR_INSUFFICIENT_BUFFER)
674  goto out;
675  status = safe_write(&buffer, length, args->buf, args->buf_len);
676  if (status) goto out;
677 out:
678  free(args->buf);
679  return status;
680 }
#define free
Definition: debug_ros.c:5
GLuint buffer
Definition: glext.h:5915
#define NO_ERROR
Definition: dderror.h:5
Definition: match.c:390
GLenum GLuint GLenum GLsizei length
Definition: glext.h:5579
static FILE * out
Definition: regtests2xml.c:44
int safe_write(unsigned char **pos, uint32_t *remaining, void *src, uint32_t src_len)
Definition: util.c:44
nfs41_updowncall_list upcall
Definition: nfs41_driver.c:273
static SERVICE_STATUS status
Definition: service.c:31
#define ERROR_INSUFFICIENT_BUFFER
Definition: dderror.h:10
Definition: ps.c:97

◆ marshall_setexattr()

static int marshall_setexattr ( unsigned char buffer,
uint32_t length,
nfs41_upcall upcall 
)
static

Definition at line 202 of file ea.c.

203 {
204  setexattr_upcall_args *args = &upcall->args.setexattr;
205  return safe_write(&buffer, length, &args->ctime, sizeof(args->ctime));
206 }
GLuint buffer
Definition: glext.h:5915
Definition: match.c:390
GLenum GLuint GLenum GLsizei length
Definition: glext.h:5579
int safe_write(unsigned char **pos, uint32_t *remaining, void *src, uint32_t src_len)
Definition: util.c:44
nfs41_updowncall_list upcall
Definition: nfs41_driver.c:273

◆ nfs41_ea_set()

int nfs41_ea_set ( IN nfs41_open_state state,
IN PFILE_FULL_EA_INFORMATION  ea 
)

Definition at line 116 of file ea.c.

119 {
120  nfs41_path_fh attrdir = { 0 };
121  int status;
122 
123  status = nfs41_rpc_openattr(state->session, &state->file, TRUE, &attrdir.fh);
124  if (status) {
125  eprintf("nfs41_rpc_openattr() failed with error %s\n",
127  goto out;
128  }
129 
130  while (status == NFS4_OK) {
131  if (!is_cygwin_ea(ea))
132  status = set_ea_value(state->session, &attrdir, &state->owner, ea);
133 
134  if (ea->NextEntryOffset == 0)
135  break;
137  }
138 out:
139  return status;
140 }
#define TRUE
Definition: types.h:120
struct _FILE_FULL_EA_INFORMATION * PFILE_FULL_EA_INFORMATION
static int set_ea_value(IN nfs41_session *session, IN nfs41_path_fh *parent, IN state_owner4 *owner, IN PFILE_FULL_EA_INFORMATION ea)
Definition: ea.c:36
void eprintf(LPCSTR format,...)
Definition: daemon_debug.c:86
enum nfsstat4 nfs41_rpc_openattr(IN nfs41_session *session, IN nfs41_path_fh *file, IN bool_t createdir, OUT nfs41_fh *fh_out)
Definition: nfs41_ops.c:2145
static FILE * out
Definition: regtests2xml.c:44
const char * nfs_error_string(int status)
Definition: daemon_debug.c:370
#define NEXT_ENTRY(ea)
Definition: ea.c:114
static int state
Definition: maze.c:121
static SERVICE_STATUS status
Definition: service.c:31
static int is_cygwin_ea(PFILE_FULL_EA_INFORMATION ea)
Definition: ea.c:103
Definition: ps.c:97

Referenced by handle_open(), and handle_setexattr().

◆ overflow_error()

static int overflow_error ( IN OUT getexattr_upcall_args args,
IN PFILE_FULL_EA_INFORMATION  prev,
IN uint32_t  needed 
)
static

Definition at line 510 of file ea.c.

514 {
515  if (prev) {
516  /* unlink the overflowing entry, but copy the entries that fit */
517  prev->NextEntryOffset = 0;
518  args->overflow = ERROR_BUFFER_OVERFLOW;
519  } else {
520  /* no entries fit; return only the length needed */
521  args->buf_len = needed;
522  args->overflow = ERROR_INSUFFICIENT_BUFFER;
523  }
524 
525  /* in either case, the upcall must return NO_ERROR so we
526  * can copy this information down to the driver */
527  return NO_ERROR;
528 }
#define ERROR_BUFFER_OVERFLOW
Definition: winerror.h:185
#define NO_ERROR
Definition: dderror.h:5
Definition: match.c:390
#define ERROR_INSUFFICIENT_BUFFER
Definition: dderror.h:10

◆ parse_getexattr()

static int parse_getexattr ( unsigned char buffer,
uint32_t  length,
nfs41_upcall upcall 
)
static

Definition at line 210 of file ea.c.

211 {
212  int status;
213  getexattr_upcall_args *args = &upcall->args.getexattr;
214 
215  status = get_name(&buffer, &length, &args->path);
216  if (status) goto out;
217  status = safe_read(&buffer, &length, &args->eaindex, sizeof(args->eaindex));
218  if (status) goto out;
219  status = safe_read(&buffer, &length, &args->restart, sizeof(args->restart));
220  if (status) goto out;
221  status = safe_read(&buffer, &length, &args->single, sizeof(args->single));
222  if (status) goto out;
223  status = safe_read(&buffer, &length, &args->buf_len, sizeof(args->buf_len));
224  if (status) goto out;
225  status = safe_read(&buffer, &length, &args->ealist_len, sizeof(args->ealist_len));
226  if (status) goto out;
227  args->ealist = args->ealist_len ? buffer : NULL;
228 
229  dprintf(1, "parsing NFS41_EA_GET: buf_len=%d Index %d Restart %d "
230  "Single %d\n", args->buf_len,args->eaindex, args->restart, args->single);
231 out:
232  return status;
233 }
GLuint buffer
Definition: glext.h:5915
Definition: match.c:390
#define dprintf
Definition: regdump.c:33
int get_name(unsigned char **pos, uint32_t *remaining, const char **out_name)
Definition: util.c:55
smooth NULL
Definition: ftsmooth.c:416
GLenum GLuint GLenum GLsizei length
Definition: glext.h:5579
static FILE * out
Definition: regtests2xml.c:44
nfs41_updowncall_list upcall
Definition: nfs41_driver.c:273
int safe_read(unsigned char **pos, uint32_t *remaining, void *dest, uint32_t dest_len)
Definition: util.c:33
static SERVICE_STATUS status
Definition: service.c:31
Definition: ps.c:97

◆ parse_setexattr()

static int parse_setexattr ( unsigned char buffer,
uint32_t  length,
nfs41_upcall upcall 
)
static

Definition at line 144 of file ea.c.

145 {
146  int status;
147  setexattr_upcall_args *args = &upcall->args.setexattr;
148 
149  status = get_name(&buffer, &length, &args->path);
150  if (status) goto out;
151  status = safe_read(&buffer, &length, &args->mode, sizeof(args->mode));
152  if (status) goto out;
153  status = safe_read(&buffer, &length, &args->buf_len, sizeof(args->buf_len));
154  if (status) goto out;
155  args->buf = buffer;
156 
157  dprintf(1, "parsing NFS41_EA_SET: mode=%o\n", args->mode);
158 out:
159  return status;
160 }
GLuint buffer
Definition: glext.h:5915
Definition: match.c:390
#define dprintf
Definition: regdump.c:33
int get_name(unsigned char **pos, uint32_t *remaining, const char **out_name)
Definition: util.c:55
GLenum GLuint GLenum GLsizei length
Definition: glext.h:5579
static FILE * out
Definition: regtests2xml.c:44
nfs41_updowncall_list upcall
Definition: nfs41_driver.c:273
int safe_read(unsigned char **pos, uint32_t *remaining, void *dest, uint32_t dest_len)
Definition: util.c:33
static SERVICE_STATUS status
Definition: service.c:31
Definition: ps.c:97

◆ populate_ea_list()

static void populate_ea_list ( IN const unsigned char position,
OUT PFILE_GET_EA_INFORMATION  ea_list 
)
static

Definition at line 342 of file ea.c.

345 {
346  const nfs41_readdir_entry *entry;
347  PFILE_GET_EA_INFORMATION ea = ea_list, prev = NULL;
348 
349  for (;;) {
350  entry = (const nfs41_readdir_entry*)position;
351  StringCchCopyA(ea->EaName, entry->name_len, entry->name);
352  ea->EaNameLength = (UCHAR)entry->name_len - 1;
353 
354  if (!entry->next_entry_offset) {
355  ea->NextEntryOffset = 0;
356  break;
357  }
358 
359  prev = ea;
362  position += entry->next_entry_offset;
363  }
364 }
Definition: nfs41_ops.h:710
struct _FILE_GET_EA_INFORMATION * PFILE_GET_EA_INFORMATION
smooth NULL
Definition: ftsmooth.c:416
if(!(yy_init))
Definition: macro.lex.yy.c:714
#define ALIGNED_EASIZE(len)
Definition: ea.c:320
#define NEXT_ENTRY(ea)
Definition: ea.c:114
unsigned char UCHAR
Definition: xmlstorage.h:181
uint32_t entry
Definition: isohybrid.c:63
STRSAFEAPI StringCchCopyA(STRSAFE_LPSTR pszDest, size_t cchDest, STRSAFE_LPCSTR pszSrc)
Definition: strsafe.h:145

Referenced by get_ea_list().

◆ read_entire_dir()

static int read_entire_dir ( IN nfs41_session session,
IN nfs41_path_fh eadir,
OUT unsigned char **  buffer_out,
OUT uint32_t length_out 
)
static

Definition at line 239 of file ea.c.

244 {
245  nfs41_readdir_cookie cookie = { 0 };
246  bitmap4 attr_request;
247  nfs41_readdir_entry *last_entry;
248  unsigned char *buffer;
249  uint32_t buffer_len, len, total_len;
250  bool_t eof;
251  int status = NO_ERROR;
252 
253  attr_request.count = 0; /* don't request attributes */
254 
255  /* allocate the buffer for readdir entries */
256  buffer_len = READDIR_LEN_INITIAL;
257  buffer = calloc(1, buffer_len);
258  if (buffer == NULL) {
259  status = GetLastError();
260  goto out;
261  }
262 
263  last_entry = NULL;
264  total_len = 0;
265  eof = FALSE;
266 
267  while (!eof) {
268  len = buffer_len - total_len;
269  if (len < READDIR_LEN_MIN) {
270  const ptrdiff_t diff = (unsigned char*)last_entry - buffer;
271  /* realloc the buffer to fit more entries */
272  unsigned char *tmp = realloc(buffer, buffer_len * 2);
273  if (tmp == NULL) {
274  status = GetLastError();
275  goto out_free;
276  }
277 
278  if (last_entry) /* fix last_entry pointer */
279  last_entry = (nfs41_readdir_entry*)(tmp + diff);
280  buffer = tmp;
281  buffer_len *= 2;
282  len = buffer_len - total_len;
283  }
284 
285  /* fetch the next group of entries */
286  status = nfs41_readdir(session, eadir, &attr_request,
287  &cookie, buffer + total_len, &len, &eof);
288  if (status)
289  goto out_free;
290 
291  if (last_entry == NULL) {
292  /* initialize last_entry to the front of the list */
293  last_entry = (nfs41_readdir_entry*)(buffer + total_len);
294  } else if (len) {
295  /* link the previous list to the new one */
296  last_entry->next_entry_offset = (uint32_t)FIELD_OFFSET(
297  nfs41_readdir_entry, name) + last_entry->name_len;
298  }
299 
300  /* find the new last entry */
301  while (last_entry->next_entry_offset) {
302  last_entry = (nfs41_readdir_entry*)((char*)last_entry +
303  last_entry->next_entry_offset);
304  }
305 
306  cookie.cookie = last_entry->cookie;
307  total_len += len;
308  }
309 
310  *buffer_out = buffer;
311  *length_out = total_len;
312 out:
313  return status;
314 
315 out_free:
316  free(buffer);
317  goto out;
318 }
#define realloc
Definition: debug_ros.c:6
Definition: nfs41_ops.h:710
int32_t bool_t
Definition: types.h:101
#define free
Definition: debug_ros.c:5
int nfs41_readdir(IN nfs41_session *session, IN nfs41_path_fh *file, IN bitmap4 *attr_request, IN nfs41_readdir_cookie *cookie, OUT unsigned char *entries, IN OUT uint32_t *entries_len, OUT bool_t *eof_out)
Definition: nfs41_ops.c:1010
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
uint64_t cookie
Definition: nfs41_ops.h:711
GLuint buffer
Definition: glext.h:5915
#define READDIR_LEN_INITIAL
Definition: ea.c:235
#define NO_ERROR
Definition: dderror.h:5
uint32_t count
Definition: nfs41_types.h:96
smooth NULL
Definition: ftsmooth.c:416
uint32_t next_entry_offset
Definition: nfs41_ops.h:713
#define READDIR_LEN_MIN
Definition: ea.c:236
static FILE * out
Definition: regtests2xml.c:44
GLenum GLsizei len
Definition: glext.h:6722
uint32_t name_len
Definition: nfs41_ops.h:712
_Check_return_ _CRTIMP int __cdecl __cdecl eof(_In_ int _FileHandle)
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:254
__kernel_ptrdiff_t ptrdiff_t
Definition: linux.h:247
UINT32 uint32_t
Definition: types.h:75
Definition: name.c:36
#define calloc
Definition: rosglue.h:14
#define uint32_t
Definition: nsiface.idl:61
static SERVICE_STATUS status
Definition: service.c:31
Definition: ps.c:97

Referenced by get_ea_list().

◆ set_ea_value()

static int set_ea_value ( IN nfs41_session session,
IN nfs41_path_fh parent,
IN state_owner4 owner,
IN PFILE_FULL_EA_INFORMATION  ea 
)
static

Definition at line 36 of file ea.c.

41 {
42  nfs41_path_fh file = { 0 };
43  nfs41_file_info createattrs;
44  open_claim4 claim;
45  stateid_arg stateid;
47  nfs41_write_verf verf;
48  uint32_t bytes_written;
49  int status;
50 
51  /* don't allow values larger than NFS4_EASIZE */
52  if (ea->EaValueLength > NFS4_EASIZE) {
53  eprintf("trying to write extended attribute value of size %d, "
54  "max allowed %d\n", ea->EaValueLength, NFS4_EASIZE);
56  goto out;
57  }
58  /* remove the file on empty value */
59  if (ea->EaValueLength == 0) {
61  name.name = ea->EaName;
62  name.len = ea->EaNameLength;
63  nfs41_remove(session, parent, &name, 0);
64  status = NFS4_OK;
65  goto out;
66  }
67 
68  claim.claim = CLAIM_NULL;
69  claim.u.null.filename = &file.name;
70  file.name.name = ea->EaName;
71  file.name.len = ea->EaNameLength;
72 
73  createattrs.attrmask.count = 2;
74  createattrs.attrmask.arr[0] = FATTR4_WORD0_SIZE;
75  createattrs.attrmask.arr[1] = FATTR4_WORD1_MODE;
76  createattrs.size = 0;
77  createattrs.mode = 0664;
78 
79  status = nfs41_open(session, parent, &file, owner, &claim,
82  &createattrs, TRUE, &stateid.stateid, &delegation, NULL);
83  if (status) {
84  eprintf("nfs41_open() failed with %s\n", nfs_error_string(status));
85  goto out;
86  }
87 
88  status = nfs41_write(session, &file, &stateid,
89  (unsigned char*)ea->EaName + ea->EaNameLength + 1,
90  ea->EaValueLength, 0, FILE_SYNC4, &bytes_written,
91  &verf, NULL);
92  if (status) {
93  eprintf("nfs41_write() failed with %s\n", nfs_error_string(status));
94  goto out_close;
95  }
96 
97 out_close:
98  nfs41_close(session, &file, &stateid);
99 out:
100  return status;
101 }
int nfs41_remove(IN nfs41_session *session, IN nfs41_path_fh *parent, IN const nfs41_component *target, IN uint64_t fileid)
Definition: nfs41_ops.c:1180
#define TRUE
Definition: types.h:120
int nfs41_write(IN nfs41_session *session, IN nfs41_path_fh *file, IN stateid_arg *stateid, IN unsigned char *data, IN uint32_t data_len, IN uint64_t offset, IN enum stable_how4 stable, OUT uint32_t *bytes_written, OUT nfs41_write_verf *verf, OUT nfs41_file_info *cinfo)
Definition: nfs41_ops.c:685
void eprintf(LPCSTR format,...)
Definition: daemon_debug.c:86
uint32_t arr[3]
Definition: nfs41_types.h:97
nfs41_delegation_state * delegation
Definition: delegation.c:679
char name[1]
Definition: fci.c:135
uint32_t count
Definition: nfs41_types.h:96
smooth NULL
Definition: ftsmooth.c:416
r parent
Definition: btrfs.c:2869
static FILE * out
Definition: regtests2xml.c:44
const char * nfs_error_string(int status)
Definition: daemon_debug.c:370
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
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
Definition: name.c:36
uint32_t claim
Definition: nfs41_ops.h:615
static SERVICE_STATUS status
Definition: service.c:31
#define NFS4_EASIZE
Definition: nfs41_const.h:34
WCHAR * name
Definition: name.c:40
Definition: fci.c:126
Definition: ps.c:97
GLuint const GLchar * name
Definition: glext.h:6031

Referenced by nfs41_ea_set().

Variable Documentation

◆ nfs41_op_getexattr

const nfs41_upcall_op nfs41_op_getexattr
Initial value:
= {
}
static int handle_getexattr(nfs41_upcall *upcall)
Definition: ea.c:530
static int marshall_getexattr(unsigned char *buffer, uint32_t *length, nfs41_upcall *upcall)
Definition: ea.c:664
static int parse_getexattr(unsigned char *buffer, uint32_t length, nfs41_upcall *upcall)
Definition: ea.c:210

Definition at line 689 of file ea.c.

◆ nfs41_op_setexattr

const nfs41_upcall_op nfs41_op_setexattr
Initial value:
= {
}
static int handle_setexattr(nfs41_upcall *upcall)
Definition: ea.c:162
static int parse_setexattr(unsigned char *buffer, uint32_t length, nfs41_upcall *upcall)
Definition: ea.c:144
static int marshall_setexattr(unsigned char *buffer, uint32_t *length, nfs41_upcall *upcall)
Definition: ea.c:202

Definition at line 683 of file ea.c.