Beispiel #1
0
/**
 * FSAL_dynamic_fsinfo:
 * Return dynamic filesystem info such as
 * used size, free size, number of objects...
 *
 * \param filehandle (input):
 *        Handle of an object in the filesystem
 *        whom info is to be retrieved.
 * \param p_context (input):
 *        Authentication context for the operation (user,...).
 * \param dynamicinfo (output):
 *        Pointer to the static info of the filesystem.
 *
 * \return Major error codes:
 *      - ERR_FSAL_NO_ERROR     (no error)
 *      - ERR_FSAL_FAULT        (a NULL pointer was passed as mandatory argument)
 *      - Other error codes can be returned :
 *        ERR_FSAL_IO, ...
 */
fsal_status_t PROXYFSAL_dynamic_fsinfo(proxyfsal_handle_t * filehandle, /* IN */
                                       proxyfsal_op_context_t * p_context,      /* IN */
                                       fsal_dynamicfsinfo_t * dynamicinfo       /* OUT */
    )
{

  int rc;

  COMPOUND4args argnfs4;
  COMPOUND4res resnfs4;
  nfs_fh4 nfs4fh;
  bitmap4 bitmap;
  uint32_t bitmap_val[2];
  uint32_t bitmap_res[2];

#define FSAL_FSINFO_NB_OP_ALLOC 2
  nfs_argop4 argoparray[FSAL_FSINFO_NB_OP_ALLOC];
  nfs_resop4 resoparray[FSAL_FSINFO_NB_OP_ALLOC];

  fsal_proxy_internal_fattr_t fattr_internal;
  struct timeval timeout = TIMEOUTRPC;

  /* sanity checks. */
  if(!filehandle || !dynamicinfo || !p_context)
    Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_dynamic_fsinfo);

  /* >> get attributes from your filesystem << */
  /* Setup results structures */
  argnfs4.argarray.argarray_val = argoparray;
  resnfs4.resarray.resarray_val = resoparray;
  fsal_internal_proxy_setup_fattr(&fattr_internal);
  argnfs4.minorversion = 0;
  /* argnfs4.tag.utf8string_val = "GANESHA NFSv4 Proxy: Getattr" ; */
  argnfs4.tag.utf8string_val = NULL;
  argnfs4.tag.utf8string_len = 0;
  argnfs4.argarray.argarray_len = 0;

  bitmap.bitmap4_val = bitmap_val;
  bitmap.bitmap4_len = 2;

  fsal_internal_proxy_create_fattr_fsinfo_bitmap(&bitmap);

  /* Get NFSv4 File handle */
  if(fsal_internal_proxy_extract_fh(&nfs4fh, filehandle) == FALSE)
    Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_getattrs);

#define FSAL_FSINFO_IDX_OP_PUTFH     0
#define FSAL_FSINFO_IDX_OP_GETATTR   1
  COMPOUNDV4_ARG_ADD_OP_PUTFH(argnfs4, nfs4fh);
  COMPOUNDV4_ARG_ADD_OP_GETATTR(argnfs4, bitmap);

  resnfs4.resarray.resarray_val[FSAL_FSINFO_IDX_OP_GETATTR].nfs_resop4_u.opgetattr.
      GETATTR4res_u.resok4.obj_attributes.attrmask.bitmap4_val = bitmap_res;
  resnfs4.resarray.resarray_val[FSAL_FSINFO_IDX_OP_GETATTR].nfs_resop4_u.opgetattr.
      GETATTR4res_u.resok4.obj_attributes.attrmask.bitmap4_len = 2;

  resnfs4.resarray.resarray_val[FSAL_FSINFO_IDX_OP_GETATTR].nfs_resop4_u.opgetattr.
      GETATTR4res_u.resok4.obj_attributes.attr_vals.attrlist4_val =
      (char *)&fattr_internal;
  resnfs4.resarray.resarray_val[FSAL_FSINFO_IDX_OP_GETATTR].nfs_resop4_u.opgetattr.
      GETATTR4res_u.resok4.obj_attributes.attr_vals.attrlist4_len =
      sizeof(fattr_internal);

  TakeTokenFSCall();

  /* Call the NFSv4 function */
  COMPOUNDV4_EXECUTE(p_context, argnfs4, resnfs4, rc);
  if(rc != RPC_SUCCESS)
    {
      ReleaseTokenFSCall();

      Return(ERR_FSAL_IO, 0, INDEX_FSAL_dynamic_fsinfo);
    }

  ReleaseTokenFSCall();

  if(resnfs4.status != NFS4_OK)
    return fsal_internal_proxy_error_convert(resnfs4.status, INDEX_FSAL_dynamic_fsinfo);

  /* Use NFSv4 service function to build the FSAL_attr */
  if(proxy_Fattr_To_FSAL_dynamic_fsinfo(dynamicinfo,
                                        &resnfs4.resarray.resarray_val
                                        [FSAL_FSINFO_IDX_OP_GETATTR].
                                        nfs_resop4_u.opgetattr.GETATTR4res_u.resok4.
                                        obj_attributes) != 1)
    {
      memset((char *)dynamicinfo, 0, sizeof(fsal_dynamicfsinfo_t));
      Return(ERR_FSAL_INVAL, 0, INDEX_FSAL_dynamic_fsinfo);
    }

  Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_dynamic_fsinfo);

}                               /* FSAL_dynamic_fsinfo */
Beispiel #2
0
fsal_status_t FSAL_proxy_truncate_stateless(proxyfsal_handle_t * filehandle,    /* IN */
                                            proxyfsal_op_context_t * p_context, /* IN */
                                            fsal_size_t length, /* IN */
                                            fsal_attrib_list_t * object_attributes      /* [ IN/OUT ] */
    )
{
  int rc;

  COMPOUND4args argnfs4;
  COMPOUND4res resnfs4;
  nfs_fh4 nfs4fh;
  fsal_status_t fsal_status;
  fsal_attrib_list_t open_attrs;
  bitmap4 inbitmap;
  bitmap4 convert_bitmap;
  uint32_t inbitmap_val[2];
  uint32_t bitmap_res[2];
  uint32_t bitmap_set[2];
  uint32_t bitmap_conv_val[2];

#define FSAL_TRUNCATE_STATELESS_NB_OP_ALLOC 3
  nfs_argop4 argoparray[FSAL_TRUNCATE_STATELESS_NB_OP_ALLOC];
  nfs_resop4 resoparray[FSAL_TRUNCATE_STATELESS_NB_OP_ALLOC];

  fsal_attrib_list_t fsal_attr_set;
  fattr4 fattr_set;
  fsal_proxy_internal_fattr_t fattr_internal;
  struct timeval timeout = { 25, 0 };

  /* sanity checks.
   * note : object_attributes is optional.
   */
  if(!filehandle || !p_context)
    Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_truncate);

  if(filehandle->data.object_type_reminder != FSAL_TYPE_FILE)
    {
      Return(ERR_FSAL_INVAL, 0, INDEX_FSAL_truncate);
    }

  /* Setup results structures */
  argnfs4.argarray.argarray_val = argoparray;
  resnfs4.resarray.resarray_val = resoparray;
  fsal_internal_proxy_setup_fattr(&fattr_internal);
  argnfs4.minorversion = 0;
  /* argnfs4.tag.utf8string_val = "GANESHA NFSv4 Proxy: Truncate" ; */
  argnfs4.tag.utf8string_val = NULL;
  argnfs4.tag.utf8string_len = 0;
  argnfs4.argarray.argarray_len = 0;

  /* Get NFSv4 File handle */
  if(fsal_internal_proxy_extract_fh(&nfs4fh, filehandle) == FALSE)
    Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_truncate);

  /* Get prepared for truncate */
  fsal_attr_set.asked_attributes = FSAL_ATTR_SIZE;
  fsal_attr_set.filesize = length;

  convert_bitmap.bitmap4_val = bitmap_conv_val;
  convert_bitmap.bitmap4_len = 2;

  fsal_interval_proxy_fsalattr2bitmap4(&fsal_attr_set, &convert_bitmap);

  if(nfs4_FSALattr_To_Fattr(NULL,       /* no exportlist required here */
                            &fsal_attr_set, &fattr_set, NULL,   /* no compound data required here */
                            NULL,       /* No fh here, filehandle is not a settable attribute */
                            &convert_bitmap) == -1)
    Return(ERR_FSAL_INVAL, -1, INDEX_FSAL_truncate);

  inbitmap.bitmap4_val = inbitmap_val;
  inbitmap.bitmap4_len = 2;
  fsal_internal_proxy_create_fattr_bitmap(&inbitmap);

#define FSAL_TRUNCATE_STATELESS_IDX_OP_PUTFH     0
#define FSAL_TRUNCATE_STATELESS_IDX_OP_SETATTR   1
#define FSAL_TRUNCATE_STATELESS_IDX_OP_GETATTR   2
  COMPOUNDV4_ARG_ADD_OP_PUTFH(argnfs4, nfs4fh);
  COMPOUNDV4_ARG_ADD_OP_SETATTR(argnfs4, fattr_set);
  COMPOUNDV4_ARG_ADD_OP_GETATTR(argnfs4, inbitmap);

  /* For ATTR_SIZE, stateid is needed, we use the stateless "all-0's" stateid here */
  argnfs4.argarray.argarray_val[FSAL_TRUNCATE_STATELESS_IDX_OP_SETATTR].nfs_argop4_u.
      opsetattr.stateid.seqid = 0;
  memset(argnfs4.argarray.argarray_val[FSAL_TRUNCATE_STATELESS_IDX_OP_SETATTR].
         nfs_argop4_u.opsetattr.stateid.other, 0, 12);

  resnfs4.resarray.resarray_val[FSAL_TRUNCATE_STATELESS_IDX_OP_GETATTR].nfs_resop4_u.
      opgetattr.GETATTR4res_u.resok4.obj_attributes.attrmask.bitmap4_val = bitmap_res;
  resnfs4.resarray.resarray_val[FSAL_TRUNCATE_STATELESS_IDX_OP_GETATTR].nfs_resop4_u.
      opgetattr.GETATTR4res_u.resok4.obj_attributes.attrmask.bitmap4_len = 2;

  resnfs4.resarray.resarray_val[FSAL_TRUNCATE_STATELESS_IDX_OP_GETATTR].nfs_resop4_u.
      opgetattr.GETATTR4res_u.resok4.obj_attributes.attr_vals.attrlist4_val =
      (char *)&fattr_internal;
  resnfs4.resarray.resarray_val[FSAL_TRUNCATE_STATELESS_IDX_OP_GETATTR].nfs_resop4_u.
      opgetattr.GETATTR4res_u.resok4.obj_attributes.attr_vals.attrlist4_len =
      sizeof(fattr_internal);

  resnfs4.resarray.resarray_val[FSAL_TRUNCATE_STATELESS_IDX_OP_SETATTR].nfs_resop4_u.
      opsetattr.attrsset.bitmap4_val = bitmap_set;
  resnfs4.resarray.resarray_val[FSAL_TRUNCATE_STATELESS_IDX_OP_SETATTR].nfs_resop4_u.
      opsetattr.attrsset.bitmap4_len = 2;

  TakeTokenFSCall();

  COMPOUNDV4_EXECUTE(p_context, argnfs4, resnfs4, rc);
  if(rc != RPC_SUCCESS)
    {
      ReleaseTokenFSCall();

      Return(ERR_FSAL_IO, 0, INDEX_FSAL_truncate);
    }

  ReleaseTokenFSCall();

  if(resnfs4.status != NFS4_OK)
    return fsal_internal_proxy_error_convert(resnfs4.status, INDEX_FSAL_truncate);

  /* >> interpret error code << */

  /* >> Optionnaly retrieve post op attributes
   * If your filesystem truncate call can't return them,
   * you can proceed like this : <<
   */
  if(object_attributes)
    {
      if(nfs4_Fattr_To_FSAL_attr(object_attributes,
                                 &resnfs4.resarray.resarray_val
                                 [FSAL_TRUNCATE_STATELESS_IDX_OP_GETATTR].
                                 nfs_resop4_u.opgetattr.GETATTR4res_u.resok4.
                                 obj_attributes) != 1)
        {
          FSAL_CLEAR_MASK(object_attributes->asked_attributes);
          FSAL_SET_MASK(object_attributes->asked_attributes, FSAL_ATTR_RDATTR_ERR);

          Return(ERR_FSAL_INVAL, 0, INDEX_FSAL_truncate);
        }

    }

  /* No error occured */
  Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_truncate);
}                               /* FSAL_proxy_truncate_stateless */
Beispiel #3
0
fsal_status_t PROXYFSAL_lookup(proxyfsal_handle_t * parent_directory_handle,    /* IN */
                               fsal_name_t * p_filename,        /* IN */
                               proxyfsal_op_context_t * p_context,      /* IN */
                               proxyfsal_handle_t * object_handle,      /* OUT */
                               fsal_attrib_list_t * object_attributes   /* [ IN/OUT ] */
    )
{

  int rc;
  COMPOUND4args argnfs4;
  COMPOUND4res resnfs4;
  nfs_fh4 nfs4fh;
  bitmap4 bitmap;
  uint32_t bitmap_val[2];
  component4 name;
  char nameval[MAXNAMLEN];
  fsal_attrib_list_t attributes;
  unsigned int index_getfh = 0;
  unsigned int index_getattr = 0;

#define FSAL_LOOKUP_NB_OP_ALLOC 4
  nfs_argop4 argoparray[FSAL_LOOKUP_NB_OP_ALLOC];
  nfs_resop4 resoparray[FSAL_LOOKUP_NB_OP_ALLOC];
  uint32_t bitmap_res[2];

  fsal_proxy_internal_fattr_t fattr_internal;
  char padfilehandle[FSAL_PROXY_FILEHANDLE_MAX_LEN];

  struct timeval timeout = TIMEOUTRPC;
  /* sanity checks
   * note : object_attributes is optionnal
   *        parent_directory_handle may be null for getting FS root.
   */
  if(!object_handle || !p_context)
    Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_lookup);

  /* Setup results structures */
  argnfs4.argarray.argarray_val = argoparray;
  resnfs4.resarray.resarray_val = resoparray;
  fsal_internal_proxy_setup_fattr(&fattr_internal);
  argnfs4.minorversion = 0;
  argnfs4.argarray.argarray_len = 0;

  /* >> retrieve root handle filehandle here << */
  bitmap.bitmap4_val = bitmap_val;
  bitmap.bitmap4_len = 2;
  fsal_internal_proxy_create_fattr_bitmap(&bitmap);

  if(!parent_directory_handle)
    {

      /* check that p_filename is NULL,
       * else, parent_directory_handle should not
       * be NULL.
       */
      if(p_filename != NULL)
        Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_lookup);

      /* argnfs4.tag.utf8string_val = "GANESHA NFSv4 Proxy: Lookup Root" ; */
      argnfs4.tag.utf8string_val = NULL;
      argnfs4.tag.utf8string_len = 0;

#define FSAL_LOOKUP_IDX_OP_PUTROOTFH      0
#define FSAL_LOOKUP_IDX_OP_GETATTR_ROOT   1
#define FSAL_LOOKUP_IDX_OP_GETFH_ROOT     2
      COMPOUNDV4_ARG_ADD_OP_PUTROOTFH(argnfs4);
      COMPOUNDV4_ARG_ADD_OP_GETATTR(argnfs4, bitmap);
      COMPOUNDV4_ARG_ADD_OP_GETFH(argnfs4);

      index_getattr = FSAL_LOOKUP_IDX_OP_GETATTR_ROOT;
      index_getfh = FSAL_LOOKUP_IDX_OP_GETFH_ROOT;

      resnfs4.resarray.resarray_val[FSAL_LOOKUP_IDX_OP_GETATTR_ROOT].nfs_resop4_u.
          opgetattr.GETATTR4res_u.resok4.obj_attributes.attrmask.bitmap4_val = bitmap_res;
      resnfs4.resarray.resarray_val[FSAL_LOOKUP_IDX_OP_GETATTR_ROOT].nfs_resop4_u.
          opgetattr.GETATTR4res_u.resok4.obj_attributes.attrmask.bitmap4_len = 2;

      resnfs4.resarray.resarray_val[FSAL_LOOKUP_IDX_OP_GETATTR_ROOT].nfs_resop4_u.
          opgetattr.GETATTR4res_u.resok4.obj_attributes.attr_vals.attrlist4_val =
          (char *)&fattr_internal;
      resnfs4.resarray.resarray_val[FSAL_LOOKUP_IDX_OP_GETATTR_ROOT].nfs_resop4_u.
          opgetattr.GETATTR4res_u.resok4.obj_attributes.attr_vals.attrlist4_len =
          sizeof(fattr_internal);

      resnfs4.resarray.resarray_val[FSAL_LOOKUP_IDX_OP_GETFH_ROOT].nfs_resop4_u.opgetfh.
          GETFH4res_u.resok4.object.nfs_fh4_val = (char *)padfilehandle;
      resnfs4.resarray.resarray_val[FSAL_LOOKUP_IDX_OP_GETFH_ROOT].nfs_resop4_u.opgetfh.
          GETFH4res_u.resok4.object.nfs_fh4_len = FSAL_PROXY_FILEHANDLE_MAX_LEN;
    }
  else                          /* this is a real lookup(parent, name)  */
    {
      PRINT_HANDLE("PROXYFSAL_lookup parent", parent_directory_handle);

      /* the filename should not be null */
      if(p_filename == NULL)
        Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_lookup);

      /* >> Be careful about junction crossing, symlinks, hardlinks,...
       * You may check the parent type if it's sored into the handle <<
       */

      switch (parent_directory_handle->data.object_type_reminder)
        {
        case FSAL_TYPE_DIR:
          /* OK */
          break;

        case FSAL_TYPE_JUNCTION:
          /* This is a junction */
          Return(ERR_FSAL_XDEV, 0, INDEX_FSAL_lookup);

        case FSAL_TYPE_FILE:
        case FSAL_TYPE_LNK:
        case FSAL_TYPE_XATTR:
          /* not a directory */
          Return(ERR_FSAL_NOTDIR, 0, INDEX_FSAL_lookup);

        default:
          Return(ERR_FSAL_SERVERFAULT, 0, INDEX_FSAL_lookup);
        }

      /* >> Call your filesystem lookup function here << */
      if(fsal_internal_proxy_extract_fh(&nfs4fh, parent_directory_handle) == FALSE)
        Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_lookup);

      memset((char *)&name, 0, sizeof(component4));
      name.utf8string_val = nameval;
      if(fsal_internal_proxy_fsal_name_2_utf8(p_filename, &name) == FALSE)
        Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_lookup);

      if(!FSAL_namecmp(p_filename, (fsal_name_t *) & FSAL_DOT))
        {
          /* argnfs4.tag.utf8string_val = "GANESHA NFSv4 Proxy: Lookup current" ; */
          argnfs4.tag.utf8string_val = NULL;
          argnfs4.tag.utf8string_len = 0;

#define FSAL_LOOKUP_IDX_OP_DOT_PUTFH     0
#define FSAL_LOOKUP_IDX_OP_DOT_GETATTR   1
#define FSAL_LOOKUP_IDX_OP_DOT_GETFH     2
          COMPOUNDV4_ARG_ADD_OP_PUTFH(argnfs4, nfs4fh);
          COMPOUNDV4_ARG_ADD_OP_GETATTR(argnfs4, bitmap);
          COMPOUNDV4_ARG_ADD_OP_GETFH(argnfs4);

          index_getattr = FSAL_LOOKUP_IDX_OP_DOT_GETATTR;
          index_getfh = FSAL_LOOKUP_IDX_OP_DOT_GETFH;

          resnfs4.resarray.resarray_val[FSAL_LOOKUP_IDX_OP_DOT_GETATTR].nfs_resop4_u.
              opgetattr.GETATTR4res_u.resok4.obj_attributes.attrmask.bitmap4_val =
              bitmap_res;
          resnfs4.resarray.resarray_val[FSAL_LOOKUP_IDX_OP_DOT_GETATTR].nfs_resop4_u.
              opgetattr.GETATTR4res_u.resok4.obj_attributes.attrmask.bitmap4_len = 2;

          resnfs4.resarray.resarray_val[FSAL_LOOKUP_IDX_OP_DOT_GETATTR].nfs_resop4_u.
              opgetattr.GETATTR4res_u.resok4.obj_attributes.attr_vals.attrlist4_val =
              (char *)&fattr_internal;
          resnfs4.resarray.resarray_val[FSAL_LOOKUP_IDX_OP_DOT_GETATTR].nfs_resop4_u.
              opgetattr.GETATTR4res_u.resok4.obj_attributes.attr_vals.attrlist4_len =
              sizeof(fattr_internal);

          resnfs4.resarray.resarray_val[FSAL_LOOKUP_IDX_OP_DOT_GETFH].nfs_resop4_u.
              opgetfh.GETFH4res_u.resok4.object.nfs_fh4_val = (char *)padfilehandle;
          resnfs4.resarray.resarray_val[FSAL_LOOKUP_IDX_OP_DOT_GETFH].nfs_resop4_u.
              opgetfh.GETFH4res_u.resok4.object.nfs_fh4_len =
              FSAL_PROXY_FILEHANDLE_MAX_LEN;
        }
      else if(!FSAL_namecmp(p_filename, (fsal_name_t *) & FSAL_DOT_DOT))
        {
          /* argnfs4.tag.utf8string_val = "GANESHA NFSv4 Proxy: Lookup parent" ; */
          argnfs4.tag.utf8string_val = NULL;
          argnfs4.tag.utf8string_len = 0;

#define FSAL_LOOKUP_IDX_OP_DOT_DOT_PUTFH     0
#define FSAL_LOOKUP_IDX_OP_DOT_DOT_LOOKUPP   1
#define FSAL_LOOKUP_IDX_OP_DOT_DOT_GETATTR   2
#define FSAL_LOOKUP_IDX_OP_DOT_DOT_GETFH     3
          COMPOUNDV4_ARG_ADD_OP_PUTFH(argnfs4, nfs4fh);
          COMPOUNDV4_ARG_ADD_OP_LOOKUPP(argnfs4);
          COMPOUNDV4_ARG_ADD_OP_GETATTR(argnfs4, bitmap);
          COMPOUNDV4_ARG_ADD_OP_GETFH(argnfs4);

          index_getattr = FSAL_LOOKUP_IDX_OP_DOT_DOT_GETATTR;
          index_getfh = FSAL_LOOKUP_IDX_OP_DOT_DOT_GETFH;

          resnfs4.resarray.resarray_val[FSAL_LOOKUP_IDX_OP_DOT_DOT_GETATTR].nfs_resop4_u.
              opgetattr.GETATTR4res_u.resok4.obj_attributes.attrmask.bitmap4_val =
              bitmap_res;
          resnfs4.resarray.resarray_val[FSAL_LOOKUP_IDX_OP_DOT_DOT_GETATTR].nfs_resop4_u.
              opgetattr.GETATTR4res_u.resok4.obj_attributes.attrmask.bitmap4_len = 2;

          resnfs4.resarray.resarray_val[FSAL_LOOKUP_IDX_OP_DOT_DOT_GETATTR].nfs_resop4_u.
              opgetattr.GETATTR4res_u.resok4.obj_attributes.attr_vals.attrlist4_val =
              (char *)&fattr_internal;
          resnfs4.resarray.resarray_val[FSAL_LOOKUP_IDX_OP_DOT_DOT_GETATTR].nfs_resop4_u.
              opgetattr.GETATTR4res_u.resok4.obj_attributes.attr_vals.attrlist4_len =
              sizeof(fattr_internal);

          resnfs4.resarray.resarray_val[FSAL_LOOKUP_IDX_OP_DOT_DOT_GETFH].nfs_resop4_u.
              opgetfh.GETFH4res_u.resok4.object.nfs_fh4_val = (char *)padfilehandle;
          resnfs4.resarray.resarray_val[FSAL_LOOKUP_IDX_OP_DOT_DOT_GETFH].nfs_resop4_u.
              opgetfh.GETFH4res_u.resok4.object.nfs_fh4_len =
              FSAL_PROXY_FILEHANDLE_MAX_LEN;
        }
      else
        {
          /* argnfs4.tag.utf8string_val = "GANESHA NFSv4 Proxy: Lookup name" ; */
          argnfs4.tag.utf8string_val = NULL;
          argnfs4.tag.utf8string_len = 0;

#define FSAL_LOOKUP_IDX_OP_PUTFH     0
#define FSAL_LOOKUP_IDX_OP_LOOKUP    1
#define FSAL_LOOKUP_IDX_OP_GETATTR   2
#define FSAL_LOOKUP_IDX_OP_GETFH     3
          COMPOUNDV4_ARG_ADD_OP_PUTFH(argnfs4, nfs4fh);
          COMPOUNDV4_ARG_ADD_OP_LOOKUP(argnfs4, name);
          COMPOUNDV4_ARG_ADD_OP_GETATTR(argnfs4, bitmap);
          COMPOUNDV4_ARG_ADD_OP_GETFH(argnfs4);

          index_getattr = FSAL_LOOKUP_IDX_OP_GETATTR;
          index_getfh = FSAL_LOOKUP_IDX_OP_GETFH;

          resnfs4.resarray.resarray_val[FSAL_LOOKUP_IDX_OP_GETATTR].nfs_resop4_u.
              opgetattr.GETATTR4res_u.resok4.obj_attributes.attrmask.bitmap4_val =
              bitmap_res;
          resnfs4.resarray.resarray_val[FSAL_LOOKUP_IDX_OP_GETATTR].nfs_resop4_u.
              opgetattr.GETATTR4res_u.resok4.obj_attributes.attrmask.bitmap4_len = 2;

          resnfs4.resarray.resarray_val[FSAL_LOOKUP_IDX_OP_GETATTR].nfs_resop4_u.
              opgetattr.GETATTR4res_u.resok4.obj_attributes.attr_vals.attrlist4_val =
              (char *)&fattr_internal;
          resnfs4.resarray.resarray_val[FSAL_LOOKUP_IDX_OP_GETATTR].nfs_resop4_u.
              opgetattr.GETATTR4res_u.resok4.obj_attributes.attr_vals.attrlist4_len =
              sizeof(fattr_internal);

          resnfs4.resarray.resarray_val[FSAL_LOOKUP_IDX_OP_GETFH].nfs_resop4_u.opgetfh.
              GETFH4res_u.resok4.object.nfs_fh4_val = (char *)padfilehandle;
          resnfs4.resarray.resarray_val[FSAL_LOOKUP_IDX_OP_GETFH].nfs_resop4_u.opgetfh.
              GETFH4res_u.resok4.object.nfs_fh4_len = FSAL_PROXY_FILEHANDLE_MAX_LEN;
        }
    }

  TakeTokenFSCall();

  /* Call the NFSv4 function */
  COMPOUNDV4_EXECUTE(p_context, argnfs4, resnfs4, rc);
  if(rc != RPC_SUCCESS)
    {
      ReleaseTokenFSCall();

      Return(ERR_FSAL_IO, rc, INDEX_FSAL_lookup);
    }
  ReleaseTokenFSCall();

  if(resnfs4.status != NFS4_OK)
    return fsal_internal_proxy_error_convert(resnfs4.status, INDEX_FSAL_lookup);

  /* Use NFSv4 service function to build the FSAL_attr */
  if(nfs4_Fattr_To_FSAL_attr(&attributes,
                             &resnfs4.resarray.resarray_val[index_getattr].nfs_resop4_u.
                             opgetattr.GETATTR4res_u.resok4.obj_attributes) != NFS4_OK)
    {
      FSAL_CLEAR_MASK(object_attributes->asked_attributes);
      FSAL_SET_MASK(object_attributes->asked_attributes, FSAL_ATTR_RDATTR_ERR);

      Return(ERR_FSAL_INVAL, 0, INDEX_FSAL_lookup);
    }

  if(object_attributes)
    {
      memcpy(object_attributes, &attributes, sizeof(attributes));
    }

  /* Build the handle */
  if(fsal_internal_proxy_create_fh
     (&resnfs4.resarray.resarray_val[index_getfh].nfs_resop4_u.opgetfh.GETFH4res_u.
      resok4.object, attributes.type, attributes.fileid, object_handle) == FALSE)
    Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_lookup);

  PRINT_HANDLE("PROXYFSAL_lookup object found", object_handle);

  /* Return attributes if asked */
  if(object_attributes)
    {
      memcpy(object_attributes, &attributes, sizeof(attributes));
    }

  /* lookup complete ! */
  Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_lookup);

}
Beispiel #4
0
fsal_status_t PROXYFSAL_rename(fsal_handle_t * old_parent,       /* IN */
                               fsal_name_t * p_old_name,        /* IN */
                               fsal_handle_t * new_parent,       /* IN */
                               fsal_name_t * p_new_name,        /* IN */
                               fsal_op_context_t *context,      /* IN */
                               fsal_attrib_list_t * src_dir_attributes, /* [ IN/OUT ] */
                               fsal_attrib_list_t * tgt_dir_attributes  /* [ IN/OUT ] */
    )
{

  int rc;

  COMPOUND4args argnfs4;
  COMPOUND4res resnfs4;
  nfs_fh4 nfs4fh_old;
  nfs_fh4 nfs4fh_new;
  bitmap4 bitmap_old;
  uint32_t bitmap_val_old[2];
  bitmap4 bitmap_new;
  uint32_t bitmap_val_new[2];
  component4 oldname;
  char oldnameval[MAXNAMLEN];
  component4 newname;
  char newnameval[MAXNAMLEN];
  proxyfsal_handle_t * old_parentdir_handle = (proxyfsal_handle_t *)old_parent;
  proxyfsal_handle_t * new_parentdir_handle = (proxyfsal_handle_t *)new_parent;
  proxyfsal_op_context_t * p_context = (proxyfsal_op_context_t *)context;

#define FSAL_RENAME_NB_OP_ALLOC 7
  nfs_argop4 argoparray[FSAL_RENAME_NB_OP_ALLOC];
  nfs_resop4 resoparray[FSAL_RENAME_NB_OP_ALLOC];
  uint32_t bitmap_res_old[2];
  uint32_t bitmap_res_new[2];

  fsal_proxy_internal_fattr_t fattr_internal_new;
  fsal_proxy_internal_fattr_t fattr_internal_old;
  struct timeval timeout = TIMEOUTRPC;

  /* sanity checks.
   * note : src/tgt_dir_attributes are optional.
   */
  if(!old_parentdir_handle ||
     !new_parentdir_handle || !p_old_name || !p_new_name || !p_context)
    Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_rename);

  /* Setup results structures */
  argnfs4.argarray.argarray_val = argoparray;
  resnfs4.resarray.resarray_val = resoparray;
  fsal_internal_proxy_setup_fattr(&fattr_internal_new);
  fsal_internal_proxy_setup_fattr(&fattr_internal_old);
  argnfs4.minorversion = 0;
  /* argnfs4.tag.utf8string_val = "GANESHA NFSv4 Proxy: Rename" ; */
  argnfs4.tag.utf8string_val = NULL;
  argnfs4.tag.utf8string_len = 0;
  argnfs4.argarray.argarray_len = 0;

  /* Prepare the structures */
  bitmap_old.bitmap4_val = bitmap_val_old;
  bitmap_old.bitmap4_len = 2;

  fsal_internal_proxy_create_fattr_bitmap(&bitmap_old);

  if(fsal_internal_proxy_extract_fh(&nfs4fh_old, old_parent) == FALSE)
    Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_rename);

  memset((char *)&oldname, 0, sizeof(component4));
  oldname.utf8string_val = oldnameval;
  if(fsal_internal_proxy_fsal_name_2_utf8(p_old_name, &oldname) == FALSE)
    Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_rename);

  bitmap_new.bitmap4_val = bitmap_val_new;
  bitmap_new.bitmap4_len = 2;
  fsal_internal_proxy_create_fattr_bitmap(&bitmap_new);

  if(fsal_internal_proxy_extract_fh(&nfs4fh_new, new_parent) == FALSE)
    Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_rename);

  memset((char *)&newname, 0, sizeof(component4));
  newname.utf8string_val = newnameval;
  if(fsal_internal_proxy_fsal_name_2_utf8(p_new_name, &newname) == FALSE)
    Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_rename);

#define FSAL_RENAME_IDX_OP_PUTFH_OLD      0
#define FSAL_RENAME_IDX_OP_SAVEFH         1
#define FSAL_RENAME_IDX_OP_PUTFH_NEW      2
#define FSAL_RENAME_IDX_OP_RENAME         3
#define FSAL_RENAME_IDX_OP_GETATTR_NEW    4
#define FSAL_RENAME_IDX_OP_RESTOREFH      5
#define FSAL_RENAME_IDX_OP_GETATTR_OLD    6

  COMPOUNDV4_ARG_ADD_OP_PUTFH(argnfs4, nfs4fh_old);
  COMPOUNDV4_ARG_ADD_OP_SAVEFH(argnfs4);
  COMPOUNDV4_ARG_ADD_OP_PUTFH(argnfs4, nfs4fh_new);
  COMPOUNDV4_ARG_ADD_OP_RENAME(argnfs4, oldname, newname);
  COMPOUNDV4_ARG_ADD_OP_GETATTR(argnfs4, bitmap_new);
  COMPOUNDV4_ARG_ADD_OP_RESTOREFH(argnfs4);
  COMPOUNDV4_ARG_ADD_OP_GETATTR(argnfs4, bitmap_old);

  resnfs4.resarray.resarray_val[FSAL_RENAME_IDX_OP_GETATTR_NEW].nfs_resop4_u.opgetattr.
      GETATTR4res_u.resok4.obj_attributes.attrmask.bitmap4_val = bitmap_res_new;
  resnfs4.resarray.resarray_val[FSAL_RENAME_IDX_OP_GETATTR_NEW].nfs_resop4_u.opgetattr.
      GETATTR4res_u.resok4.obj_attributes.attrmask.bitmap4_len = 2;

  resnfs4.resarray.resarray_val[FSAL_RENAME_IDX_OP_GETATTR_NEW].nfs_resop4_u.opgetattr.
      GETATTR4res_u.resok4.obj_attributes.attr_vals.attrlist4_val =
      (char *)&fattr_internal_new;
  resnfs4.resarray.resarray_val[FSAL_RENAME_IDX_OP_GETATTR_NEW].nfs_resop4_u.opgetattr.
      GETATTR4res_u.resok4.obj_attributes.attr_vals.attrlist4_len =
      sizeof(fattr_internal_new);

  resnfs4.resarray.resarray_val[FSAL_RENAME_IDX_OP_GETATTR_OLD].nfs_resop4_u.opgetattr.
      GETATTR4res_u.resok4.obj_attributes.attrmask.bitmap4_val = bitmap_res_old;
  resnfs4.resarray.resarray_val[FSAL_RENAME_IDX_OP_GETATTR_OLD].nfs_resop4_u.opgetattr.
      GETATTR4res_u.resok4.obj_attributes.attrmask.bitmap4_len = 2;

  resnfs4.resarray.resarray_val[FSAL_RENAME_IDX_OP_GETATTR_OLD].nfs_resop4_u.opgetattr.
      GETATTR4res_u.resok4.obj_attributes.attr_vals.attrlist4_val =
      (char *)&fattr_internal_old;
  resnfs4.resarray.resarray_val[FSAL_RENAME_IDX_OP_GETATTR_OLD].nfs_resop4_u.opgetattr.
      GETATTR4res_u.resok4.obj_attributes.attr_vals.attrlist4_len =
      sizeof(fattr_internal_old);

  TakeTokenFSCall();

  /* Call the NFSv4 function */
  COMPOUNDV4_EXECUTE(p_context, argnfs4, resnfs4, rc);
  if(rc != RPC_SUCCESS)
    {
      ReleaseTokenFSCall();

      Return(ERR_FSAL_IO, rc, INDEX_FSAL_rename);
    }

  ReleaseTokenFSCall();

  if(resnfs4.status != NFS4_OK)
    return fsal_internal_proxy_error_convert(resnfs4.status, INDEX_FSAL_rename);

  /* >> get last parent post op attributes if asked
   * For example : << */

  if(src_dir_attributes)
    {
      if(nfs4_Fattr_To_FSAL_attr(src_dir_attributes,
                                 &resnfs4.resarray.resarray_val
                                 [FSAL_RENAME_IDX_OP_GETATTR_OLD].nfs_resop4_u.
                                 opgetattr.GETATTR4res_u.resok4.obj_attributes) != NFS4_OK)
        {
          FSAL_CLEAR_MASK(src_dir_attributes->asked_attributes);
          FSAL_SET_MASK(src_dir_attributes->asked_attributes, FSAL_ATTR_RDATTR_ERR);

          Return(ERR_FSAL_INVAL, 0, INDEX_FSAL_rename);
        }

    }

  /* >> get new parent post op attributes if asked
   * For example : << */

  if(tgt_dir_attributes)
    {
      if(nfs4_Fattr_To_FSAL_attr(tgt_dir_attributes,
                                 &resnfs4.resarray.resarray_val
                                 [FSAL_RENAME_IDX_OP_GETATTR_NEW].nfs_resop4_u.
                                 opgetattr.GETATTR4res_u.resok4.obj_attributes) != NFS4_OK)
        {
          FSAL_CLEAR_MASK(tgt_dir_attributes->asked_attributes);
          FSAL_SET_MASK(tgt_dir_attributes->asked_attributes, FSAL_ATTR_RDATTR_ERR);

          Return(ERR_FSAL_INVAL, 0, INDEX_FSAL_rename);
        }

    }

  /* OK */
  Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_rename);

}
Beispiel #5
0
fsal_status_t PROXYFSAL_readdir(fsal_dir_t * dir_desc,       /* IN */
                                fsal_cookie_t start_pos,      /* IN */
                                fsal_attrib_mask_t get_attr_mask,       /* IN */
                                fsal_mdsize_t buffersize,       /* IN */
                                fsal_dirent_t * pdirent,        /* OUT */
                                fsal_cookie_t * end_position,      /* OUT */
                                fsal_count_t * nb_entries,      /* OUT */
                                fsal_boolean_t * end_of_dir     /* OUT */
    )
{
  nfs_fh4 nfs4fh;
  bitmap4 bitmap;
  uint32_t bitmap_val[2];
  count4 nbreaddir;
  int rc = 0;
  int i = 0;
  int cpt = 0;
  entry4 *piter_entry = NULL;
  entry4 tabentry4[FSAL_READDIR_SIZE];
  //char tabentry4name[FSAL_READDIR_SIZE][MAXNAMLEN];
  char * tabentry4name = NULL ;
  uint32_t tabentry4bitmap[FSAL_READDIR_SIZE][2];
  struct timeval timeout = TIMEOUTRPC;
  //fsal_proxy_internal_fattr_readdir_t tabentry4attr[FSAL_READDIR_SIZE];
  fsal_proxy_internal_fattr_readdir_t * tabentry4attr = NULL ;
#define FSAL_READDIR_NB_OP_ALLOC 2
  nfs_argop4 argoparray[FSAL_READDIR_NB_OP_ALLOC];
  nfs_resop4 resoparray[FSAL_READDIR_NB_OP_ALLOC];
  COMPOUND4args argnfs4;
  COMPOUND4res resnfs4;
  proxyfsal_dir_t * dir_descriptor = (proxyfsal_dir_t *)dir_desc;
  proxyfsal_cookie_t start_position;

  /* sanity checks */

  if(!dir_descriptor || !pdirent || !end_position || !nb_entries || !end_of_dir)
    Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_readdir);

  if( ( tabentry4name = Mem_Alloc( FSAL_READDIR_SIZE * MAXNAMLEN ) ) == NULL )
    Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_readdir);

  if( ( tabentry4attr =
	 (fsal_proxy_internal_fattr_readdir_t *)Mem_Alloc( sizeof( fsal_proxy_internal_fattr_readdir_t ) * FSAL_READDIR_SIZE ) ) == NULL )
   {
     Mem_Free( tabentry4name ) ;
     Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_readdir);
   }

  start_position.data = (nfs_cookie4)start_pos.data;

  LogFullDebug(COMPONENT_FSAL, "---> Readdir Offset=%llu sizeof(entry4)=%lu sizeof(fsal_dirent_t)=%lu \n",
               (unsigned long long)start_position.data, sizeof(entry4), sizeof(fsal_dirent_t));

  /* >> retrieve root handle filehandle here << */
  bitmap.bitmap4_len = 2;
  bitmap.bitmap4_val = bitmap_val;
  fsal_internal_proxy_create_fattr_readdir_bitmap(&bitmap);

  /* Setup results structures */
  argnfs4.argarray.argarray_val = argoparray;
  resnfs4.resarray.resarray_val = resoparray;
  argnfs4.minorversion = 0;
  /* argnfs4.tag.utf8string_val = "GANESHA NFSv4 Proxy: Readdir" ; */
  argnfs4.tag.utf8string_val = NULL;
  argnfs4.tag.utf8string_len = 0;
  argnfs4.argarray.argarray_len = 0;

#define FSAL_READDIR_IDX_OP_PUTFH      0
#define FSAL_READDIR_IDX_OP_READDIR    1

  /* Set up reply structure */
  resnfs4.resarray.resarray_val = resoparray;

  /* How much data should I read ? */
  nbreaddir = buffersize / (sizeof(fsal_dirent_t));
  if(nbreaddir > FSAL_READDIR_SIZE)
    nbreaddir = FSAL_READDIR_SIZE;

  memset((char *)tabentry4, 0, FSAL_READDIR_SIZE * sizeof(entry4));
  memset((char *)tabentry4name, 0, FSAL_READDIR_SIZE * MAXNAMLEN);
  memset((char *)tabentry4attr, 0,
         FSAL_READDIR_SIZE * sizeof(fsal_proxy_internal_fattr_readdir_t));
  for(i = 0; i < nbreaddir; i++)
    {
      fsal_internal_proxy_setup_readdir_fattr(&tabentry4attr[i]);

      tabentry4[i].name.utf8string_val = (char *)(tabentry4name+i*MAXNAMLEN*sizeof(char) ) ;
      tabentry4[i].name.utf8string_len = MAXNAMLEN;

      tabentry4[i].attrs.attr_vals.attrlist4_val = (char *)&(tabentry4attr[i]);
      tabentry4[i].attrs.attr_vals.attrlist4_len =
          sizeof(fsal_proxy_internal_fattr_readdir_t);

      tabentry4[i].attrs.attrmask.bitmap4_val = tabentry4bitmap[i];
      tabentry4[i].attrs.attrmask.bitmap4_len = 2;
    }
  resnfs4.resarray.resarray_val[FSAL_READDIR_IDX_OP_READDIR].nfs_resop4_u.opreaddir.
      READDIR4res_u.resok4.reply.entries = (entry4 *) tabentry4;

  /* >> Call your filesystem lookup function here << */
  if(fsal_internal_proxy_extract_fh(&nfs4fh, (fsal_handle_t *) &dir_descriptor->fhandle) == FALSE)
   {
    Mem_Free( tabentry4attr ) ;
    Mem_Free( tabentry4name ) ;
    Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_readdir);
   }
  /** @todo : use NFS4_OP_VERIFY to implement a cache validator, BUGAZOMEU */
  COMPOUNDV4_ARG_ADD_OP_PUTFH(argnfs4, nfs4fh);
  COMPOUNDV4_ARG_ADD_OP_READDIR(argnfs4, start_position.data, nbreaddir,
                                dir_descriptor->verifier, bitmap);

  TakeTokenFSCall();
  /* Call the NFSv4 function */
  COMPOUNDV4_EXECUTE(dir_descriptor->pcontext, argnfs4, resnfs4, rc);
  if(rc != RPC_SUCCESS)
    {
      ReleaseTokenFSCall();

      Mem_Free( tabentry4attr ) ;
      Mem_Free( tabentry4name ) ;
      Return(ERR_FSAL_IO, rc, INDEX_FSAL_readdir);
    }
  ReleaseTokenFSCall();

  if(resnfs4.status != NFS4_OK)
    return fsal_internal_proxy_error_convert(resnfs4.status, INDEX_FSAL_readdir);

  /* Set the reply structure */
  if(resnfs4.resarray.resarray_val[FSAL_READDIR_IDX_OP_READDIR].nfs_resop4_u.opreaddir.
     READDIR4res_u.resok4.reply.eof == TRUE)
    {
      *end_of_dir = TRUE;
    }

  /* >> convert error code and return on error << */

  /* >> fill the output dirent array << */

  /* until the requested count is reached
   * or the end of dir is reached...
   */

  /* Don't forget setting output vars : end_position, nb_entries, end_of_dir  */
  for(piter_entry =
      resnfs4.resarray.resarray_val[FSAL_READDIR_IDX_OP_READDIR].nfs_resop4_u.opreaddir.
      READDIR4res_u.resok4.reply.entries; piter_entry != NULL;
      piter_entry = piter_entry->nextentry)
    {
      if(proxy_Fattr_To_FSAL_attr(&pdirent[cpt].attributes,
                                  (proxyfsal_handle_t *) &(pdirent[cpt].handle), &(piter_entry->attrs)) != 1)
        {
          FSAL_CLEAR_MASK(pdirent[cpt].attributes.asked_attributes);
          FSAL_SET_MASK(pdirent[cpt].attributes.asked_attributes, FSAL_ATTR_RDATTR_ERR);

          Mem_Free( tabentry4attr ) ;
          Mem_Free( tabentry4name ) ;
          Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_readdir);
        }

      if(fsal_internal_proxy_fsal_utf8_2_name(&(pdirent[cpt].name),
                                              &(piter_entry->name)) == FALSE)
        {
          Mem_Free( tabentry4attr ) ;
          Mem_Free( tabentry4name ) ;
          Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_readdir);
        }

      /* Link the entries together */
      pdirent[cpt].nextentry = NULL;    /* Will be overwritten if there is an entry behind, stay NULL if not */
      if(cpt != 0)
        pdirent[cpt - 1].nextentry = &pdirent[cpt];

      /* Set end position */
      ((proxyfsal_cookie_t *)end_position)->data = piter_entry->cookie;

      /* Get ready for next pdirent */
      cpt += 1;

      if(cpt >= FSAL_READDIR_SIZE)
        break;
    }

  /* The number of entries to be returned */
  *nb_entries = cpt;

  Mem_Free( tabentry4attr ) ;
  Mem_Free( tabentry4name ) ;
  Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_readdir);

}
fsal_status_t FSAL_proxy_open_confirm(proxyfsal_file_t * pfd)
{
  fsal_status_t fsal_status;
  int rc;
  

  COMPOUND4args argnfs4;
  COMPOUND4res resnfs4;
  nfs_fh4 nfs4fh;

#define FSAL_PROXY_OPEN_CONFIRM_NB_OP_ALLOC 2
#define FSAL_PROXY_OPEN_CONFIRM_IDX_OP_PUTFH        0
#define FSAL_PROXY_OPEN_CONFIRM_IDX_OP_OPEN_CONFIRM 1
  nfs_argop4 argoparray[FSAL_PROXY_OPEN_CONFIRM_NB_OP_ALLOC];
  nfs_resop4 resoparray[FSAL_PROXY_OPEN_CONFIRM_NB_OP_ALLOC];
  struct timeval timeout = TIMEOUTRPC;

  if(pfd == NULL)
    {
      fsal_status.major = ERR_FSAL_FAULT;
      fsal_status.minor = 0;

      return fsal_status;
    }

  if(pfd->pcontext == NULL)
    {
      LogFullDebug(COMPONENT_FSAL, "===================> FSAL_proxy_open_confirm: Non initialized fd !!!!!");
      fsal_status.major = ERR_FSAL_FAULT;
      fsal_status.minor = 0;

      return fsal_status;
    }
  /* Get NFSv4 File handle */
  if(fsal_internal_proxy_extract_fh(&nfs4fh, (fsal_handle_t *) &pfd->fhandle) == FALSE)
    {
      fsal_status.major = ERR_FSAL_FAULT;
      fsal_status.minor = 0;

      return fsal_status;
    }

  /* Setup results structures */
  argnfs4.argarray.argarray_val = argoparray;
  resnfs4.resarray.resarray_val = resoparray;
  argnfs4.minorversion = 0;
  argnfs4.tag.utf8string_val = NULL;
  argnfs4.tag.utf8string_len = 0;
  argnfs4.argarray.argarray_len = 0;

  COMPOUNDV4_ARG_ADD_OP_PUTFH(argnfs4, nfs4fh);
  argnfs4.argarray.argarray_val[FSAL_PROXY_OPEN_CONFIRM_IDX_OP_OPEN_CONFIRM].argop =
      NFS4_OP_OPEN_CONFIRM;
  argnfs4.argarray.argarray_val[FSAL_PROXY_OPEN_CONFIRM_IDX_OP_OPEN_CONFIRM].nfs_argop4_u.
      opopen_confirm.open_stateid.seqid = pfd->stateid.seqid;
  memcpy((char *)argnfs4.argarray.
         argarray_val[FSAL_PROXY_OPEN_CONFIRM_IDX_OP_OPEN_CONFIRM].nfs_argop4_u.
         opopen_confirm.open_stateid.other, (char *)pfd->stateid.other, 12);
  argnfs4.argarray.argarray_val[FSAL_PROXY_OPEN_CONFIRM_IDX_OP_OPEN_CONFIRM].nfs_argop4_u.
      opopen_confirm.seqid = pfd->stateid.seqid + 1;
  argnfs4.argarray.argarray_len = 2;

  TakeTokenFSCall();
  /* Call the NFSv4 function */
  COMPOUNDV4_EXECUTE(pfd->pcontext, argnfs4, resnfs4, rc);
  if(rc != RPC_SUCCESS)
    {
      ReleaseTokenFSCall();

      fsal_status.major = ERR_FSAL_IO;
      fsal_status.minor = resnfs4.status;

      return fsal_status;
    }
  ReleaseTokenFSCall();

  /* set the error is res if not NFS4_OK */
  if(resnfs4.status != NFS4_OK)
    {
      fsal_status.major = ERR_FSAL_IO;
      fsal_status.minor = resnfs4.status;

      return fsal_status;
    }
  /* Update the file descriptor with the new stateid */
  pfd->stateid.seqid =
      resnfs4.resarray.resarray_val[FSAL_PROXY_OPEN_CONFIRM_IDX_OP_OPEN_CONFIRM].
      nfs_resop4_u.opopen_confirm.OPEN_CONFIRM4res_u.resok4.open_stateid.seqid;
  memcpy((char *)pfd->stateid.other,
         (char *)resnfs4.resarray.
         resarray_val[FSAL_PROXY_OPEN_CONFIRM_IDX_OP_OPEN_CONFIRM].nfs_resop4_u.
         opopen_confirm.OPEN_CONFIRM4res_u.resok4.open_stateid.other, 12);

  fsal_status.major = ERR_FSAL_NO_ERROR;
  fsal_status.minor = NFS4_OK;

  return fsal_status;
}                               /* FSAL_proxy_open_confirm */
Beispiel #7
0
fsal_status_t PROXYFSAL_symlink(proxyfsal_handle_t * parent_directory_handle,   /* IN */
                                fsal_name_t * p_linkname,       /* IN */
                                fsal_path_t * p_linkcontent,    /* IN */
                                proxyfsal_op_context_t * p_context,     /* IN */
                                fsal_accessmode_t accessmode,   /* IN (ignored) */
                                proxyfsal_handle_t * link_handle,       /* OUT */
                                fsal_attrib_list_t * link_attributes    /* [ IN/OUT ] */
    )
{

  int rc;

  COMPOUND4args argnfs4;
  COMPOUND4res resnfs4;
  nfs_fh4 nfs4fh;
  bitmap4 bitmap;
  uint32_t bitmap_val[2];
  uint32_t bitmap_res[2];
  uint32_t bitmap_mkdir[2];
  uint32_t bitmap_getattr_res[2];
  uint32_t bitmap_conv_val[2];
  fattr4 input_attr;
  bitmap4 convert_bitmap;
  component4 name;
  char nameval[MAXNAMLEN];
  component4 linkname;
  char linknameval[MAXNAMLEN];
  char padfilehandle[FSAL_PROXY_FILEHANDLE_MAX_LEN];

  fsal_proxy_internal_fattr_t fattr_internal;
  fsal_attrib_list_t create_mode_attr;
  fsal_attrib_list_t attributes;

#define FSAL_SYMLINK_NB_OP_ALLOC 4
#define FSAL_SYMLINK_VAL_BUFFER  1024

  nfs_argop4 argoparray[FSAL_SYMLINK_NB_OP_ALLOC];
  nfs_resop4 resoparray[FSAL_SYMLINK_NB_OP_ALLOC];

  char fattr_val[FSAL_SYMLINK_VAL_BUFFER];
  struct timeval timeout = TIMEOUTRPC;

  /* sanity checks.
   * note : link_attributes is optional.
   */
  if(!parent_directory_handle ||
     !p_context || !link_handle || !p_linkname || !p_linkcontent)
    Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_symlink);

  /* Tests if symlinking is allowed by configuration. */

  if(!global_fs_info.symlink_support)
    Return(ERR_FSAL_NOTSUPP, 0, INDEX_FSAL_symlink);

  /* Setup results structures */
  argnfs4.argarray.argarray_val = argoparray;
  resnfs4.resarray.resarray_val = resoparray;
  argnfs4.minorversion = 0;
  /* argnfs4.tag.utf8string_val = "GANESHA NFSv4 Proxy: Symlink" ; */
  argnfs4.tag.utf8string_val = NULL;
  argnfs4.tag.utf8string_len = 0;
  argnfs4.argarray.argarray_len = 0;

  input_attr.attrmask.bitmap4_val = bitmap_val;
  input_attr.attrmask.bitmap4_len = 2;

  input_attr.attr_vals.attrlist4_val = fattr_val;
  input_attr.attr_vals.attrlist4_len = FSAL_SYMLINK_VAL_BUFFER;

  fsal_internal_proxy_setup_fattr(&fattr_internal);

  convert_bitmap.bitmap4_val = bitmap_conv_val;
  convert_bitmap.bitmap4_len = 2;

  memset((char *)&name, 0, sizeof(component4));
  name.utf8string_val = nameval;
  if(fsal_internal_proxy_fsal_name_2_utf8(p_linkname, &name) == FALSE)
    Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_symlink);

  memset((char *)&linkname, 0, sizeof(component4));
  linkname.utf8string_val = linknameval;
  if(fsal_internal_proxy_fsal_path_2_utf8(p_linkcontent, &linkname) == FALSE)
    Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_symlink);

  /* Get NFSv4 File handle */
  if(fsal_internal_proxy_extract_fh(&nfs4fh, parent_directory_handle) == FALSE)
    Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_symlink);

  bitmap.bitmap4_val = bitmap_mkdir;
  bitmap.bitmap4_len = 2;
  fsal_internal_proxy_create_fattr_bitmap(&bitmap);

  create_mode_attr.asked_attributes = FSAL_ATTR_MODE;
  create_mode_attr.mode = accessmode;
  fsal_interval_proxy_fsalattr2bitmap4(&create_mode_attr, &convert_bitmap);

  if(nfs4_FSALattr_To_Fattr(NULL,       /* no exportlist required here */
                            &create_mode_attr, &input_attr, NULL,       /* no compound data required here */
                            NULL,       /* No fh here, filehandle is not a settable attribute */
                            &convert_bitmap) == -1)
    Return(ERR_FSAL_INVAL, -1, INDEX_FSAL_symlink);

#define FSAL_SYMLINK_IDX_OP_PUTFH     0
#define FSAL_SYMLINK_IDX_OP_SYMLINK   1
#define FSAL_SYMLINK_IDX_OP_GETFH     2
#define FSAL_SYMLINK_IDX_OP_GETATTR   3
  COMPOUNDV4_ARG_ADD_OP_PUTFH(argnfs4, nfs4fh);
  COMPOUNDV4_ARG_ADD_OP_SYMLINK(argnfs4, name, linkname, input_attr);
  COMPOUNDV4_ARG_ADD_OP_GETFH(argnfs4);
  COMPOUNDV4_ARG_ADD_OP_GETATTR(argnfs4, bitmap);

  resnfs4.resarray.resarray_val[FSAL_SYMLINK_IDX_OP_SYMLINK].nfs_resop4_u.opcreate.
      CREATE4res_u.resok4.attrset.bitmap4_val = bitmap_res;
  resnfs4.resarray.resarray_val[FSAL_SYMLINK_IDX_OP_SYMLINK].nfs_resop4_u.opcreate.
      CREATE4res_u.resok4.attrset.bitmap4_len = 2;

  resnfs4.resarray.resarray_val[FSAL_SYMLINK_IDX_OP_GETFH].nfs_resop4_u.opgetfh.
      GETFH4res_u.resok4.object.nfs_fh4_val = (char *)padfilehandle;
  resnfs4.resarray.resarray_val[FSAL_SYMLINK_IDX_OP_GETFH].nfs_resop4_u.opgetfh.
      GETFH4res_u.resok4.object.nfs_fh4_len = FSAL_PROXY_FILEHANDLE_MAX_LEN;

  resnfs4.resarray.resarray_val[FSAL_SYMLINK_IDX_OP_GETATTR].nfs_resop4_u.opgetattr.
      GETATTR4res_u.resok4.obj_attributes.attrmask.bitmap4_val = bitmap_getattr_res;
  resnfs4.resarray.resarray_val[FSAL_SYMLINK_IDX_OP_GETATTR].nfs_resop4_u.opgetattr.
      GETATTR4res_u.resok4.obj_attributes.attrmask.bitmap4_len = 2;

  resnfs4.resarray.resarray_val[FSAL_SYMLINK_IDX_OP_GETATTR].nfs_resop4_u.opgetattr.
      GETATTR4res_u.resok4.obj_attributes.attr_vals.attrlist4_val =
      (char *)&fattr_internal;
  resnfs4.resarray.resarray_val[FSAL_SYMLINK_IDX_OP_GETATTR].nfs_resop4_u.opgetattr.
      GETATTR4res_u.resok4.obj_attributes.attr_vals.attrlist4_len =
      sizeof(fattr_internal);

  TakeTokenFSCall();

  /* Call the NFSv4 function */
  COMPOUNDV4_EXECUTE(p_context, argnfs4, resnfs4, rc);
  if(rc != RPC_SUCCESS)
    {
      ReleaseTokenFSCall();

      Return(ERR_FSAL_IO, 0, INDEX_FSAL_symlink);
    }

  ReleaseTokenFSCall();

  /* >> convert error code, and return on error << */
  if(resnfs4.status != NFS4_OK)
    return fsal_internal_proxy_error_convert(resnfs4.status, INDEX_FSAL_symlink);

  /* Use NFSv4 service function to build the FSAL_attr */
  if(nfs4_Fattr_To_FSAL_attr(&attributes,
                             &resnfs4.resarray.resarray_val[FSAL_SYMLINK_IDX_OP_GETATTR].
                             nfs_resop4_u.opgetattr.GETATTR4res_u.resok4.
                             obj_attributes) != NFS4_OK)
    {
      FSAL_CLEAR_MASK(attributes.asked_attributes);
      FSAL_SET_MASK(attributes.asked_attributes, FSAL_ATTR_RDATTR_ERR);

      Return(ERR_FSAL_INVAL, 0, INDEX_FSAL_symlink);
    }

  if(link_attributes)
    {
      memcpy(link_attributes, &attributes, sizeof(attributes));
    }

  if(fsal_internal_proxy_create_fh
     (&
      (resnfs4.resarray.resarray_val[FSAL_SYMLINK_IDX_OP_GETFH].nfs_resop4_u.opgetfh.
       GETFH4res_u.resok4.object), FSAL_TYPE_LNK, attributes.fileid,
      link_handle) == FALSE)
    Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_symlink);

  /* OK */
  Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_symlink);
}
Beispiel #8
0
fsal_status_t PROXYFSAL_readlink(proxyfsal_handle_t * linkhandle,       /* IN */
                                 proxyfsal_op_context_t * p_context,    /* IN */
                                 fsal_path_t * p_link_content,  /* OUT */
                                 fsal_attrib_list_t * link_attributes   /* [ IN/OUT ] */
    )
{

  int rc;

  COMPOUND4args argnfs4;
  COMPOUND4res resnfs4;
  nfs_fh4 nfs4fh;
  bitmap4 bitmap;
  uint32_t bitmap_val[2];
  fsal_attrib_list_t attributes;

#define FSAL_READLINK_NB_OP_ALLOC 4
  nfs_argop4 argoparray[FSAL_READLINK_NB_OP_ALLOC];
  nfs_resop4 resoparray[FSAL_READLINK_NB_OP_ALLOC];
  uint32_t bitmap_res[2];

  fsal_proxy_internal_fattr_t fattr_internal;
  char padpath[FSAL_MAX_PATH_LEN];

  struct timeval timeout = TIMEOUTRPC;

  /* sanity checks.
   * note : link_attributes is optional.
   */
  if(!linkhandle || !p_context || !p_link_content)
    Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_readlink);

  /* Setup results structures */
  argnfs4.argarray.argarray_val = argoparray;
  resnfs4.resarray.resarray_val = resoparray;
  fsal_internal_proxy_setup_fattr(&fattr_internal);
  argnfs4.minorversion = 0;
  /* argnfs4.tag.utf8string_val = "GANESHA NFSv4 Proxy: Readlink" ; */
  argnfs4.tag.utf8string_val = NULL;
  argnfs4.tag.utf8string_len = 0;
  argnfs4.argarray.argarray_len = 0;

  /* >> retrieve root handle filehandle here << */
  bitmap.bitmap4_val = bitmap_val;
  bitmap.bitmap4_len = 2;
  fsal_internal_proxy_create_fattr_bitmap(&bitmap);

  if(fsal_internal_proxy_extract_fh(&nfs4fh, linkhandle) == FALSE)
    Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_readlink);

#define FSAL_READLINK_IDX_OP_PUTFH     0
#define FSAL_READLINK_IDX_OP_READLINK  1
#define FSAL_READLINK_IDX_OP_GETATTR   2

  COMPOUNDV4_ARG_ADD_OP_PUTFH(argnfs4, nfs4fh);
  COMPOUNDV4_ARG_ADD_OP_READLINK(argnfs4);
  COMPOUNDV4_ARG_ADD_OP_GETATTR(argnfs4, bitmap);

  resnfs4.resarray.resarray_val[FSAL_READLINK_IDX_OP_GETATTR].nfs_resop4_u.opgetattr.
      GETATTR4res_u.resok4.obj_attributes.attrmask.bitmap4_val = bitmap_res;
  resnfs4.resarray.resarray_val[FSAL_READLINK_IDX_OP_GETATTR].nfs_resop4_u.opgetattr.
      GETATTR4res_u.resok4.obj_attributes.attrmask.bitmap4_len = 2;

  resnfs4.resarray.resarray_val[FSAL_READLINK_IDX_OP_GETATTR].nfs_resop4_u.opgetattr.
      GETATTR4res_u.resok4.obj_attributes.attr_vals.attrlist4_val =
      (char *)&fattr_internal;
  resnfs4.resarray.resarray_val[FSAL_READLINK_IDX_OP_GETATTR].nfs_resop4_u.opgetattr.
      GETATTR4res_u.resok4.obj_attributes.attr_vals.attrlist4_len =
      sizeof(fattr_internal);

  resnfs4.resarray.resarray_val[FSAL_READLINK_IDX_OP_READLINK].nfs_resop4_u.opreadlink.
      READLINK4res_u.resok4.link.utf8string_val = (char *)padpath;
  resnfs4.resarray.resarray_val[FSAL_READLINK_IDX_OP_READLINK].nfs_resop4_u.opreadlink.
      READLINK4res_u.resok4.link.utf8string_len = FSAL_MAX_PATH_LEN;

  TakeTokenFSCall();

  /* Call the NFSv4 function */
  COMPOUNDV4_EXECUTE(p_context, argnfs4, resnfs4, rc);
  if(rc != RPC_SUCCESS)
    {
      ReleaseTokenFSCall();

      Return(ERR_FSAL_IO, rc, INDEX_FSAL_readlink);
    }

  ReleaseTokenFSCall();

  /* >> convert error code and return on error << */
  if(resnfs4.status != NFS4_OK)
    return fsal_internal_proxy_error_convert(resnfs4.status, INDEX_FSAL_readlink);

  /* >> convert fs output to fsal_path_t
   * for example, if this is a char * (link_content_out) :
   */

  if(fsal_internal_proxy_fsal_utf8_2_path(p_link_content,
                                          &(resnfs4.resarray.resarray_val
                                            [FSAL_READLINK_IDX_OP_READLINK].
                                            nfs_resop4_u.opreadlink.READLINK4res_u.resok4.
                                            link)) == FALSE)

    Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_readlink);

  /* retrieves object attributes, if asked */
  if(link_attributes)
    {
      /* Use NFSv4 service function to build the FSAL_attr */
      if(nfs4_Fattr_To_FSAL_attr(&attributes,
                                 &resnfs4.resarray.
                                 resarray_val[FSAL_READLINK_IDX_OP_GETATTR].nfs_resop4_u.
                                 opgetattr.GETATTR4res_u.resok4.obj_attributes) != NFS4_OK)
        {
          FSAL_CLEAR_MASK(link_attributes->asked_attributes);
          FSAL_SET_MASK(link_attributes->asked_attributes, FSAL_ATTR_RDATTR_ERR);

          Return(ERR_FSAL_INVAL, 0, INDEX_FSAL_readlink);
        }

      memcpy(link_attributes, &attributes, sizeof(attributes));

    }

  Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_readlink);

}
Beispiel #9
0
fsal_status_t PROXYFSAL_unlink(proxyfsal_handle_t * parentdir_handle,   /* IN */
                               fsal_name_t * p_object_name,     /* IN */
                               proxyfsal_op_context_t * p_context,      /* IN */
                               fsal_attrib_list_t * parentdir_attributes        /* [IN/OUT ] */
    )
{
  int rc;
  COMPOUND4args argnfs4;
  COMPOUND4res resnfs4;
  nfs_fh4 nfs4fh;
  bitmap4 bitmap;
  uint32_t bitmap_val[2];
  component4 name;
  char nameval[MAXNAMLEN];

#define FSAL_UNLINK_NB_OP_ALLOC 3
  nfs_argop4 argoparray[FSAL_UNLINK_NB_OP_ALLOC];
  nfs_resop4 resoparray[FSAL_UNLINK_NB_OP_ALLOC];
  uint32_t bitmap_res[2];

  fsal_proxy_internal_fattr_t fattr_internal;
  struct timeval timeout = TIMEOUTRPC;

  /* sanity checks.
   * note : parentdir_attributes are optional.
   *        parentdir_handle is mandatory,
   *        because, we do not allow to delete FS root !
   */
  if(!parentdir_handle || !p_context || !p_object_name)
    Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_unlink);

  /* Setup results structures */
  argnfs4.argarray.argarray_val = argoparray;
  resnfs4.resarray.resarray_val = resoparray;
  fsal_internal_proxy_setup_fattr(&fattr_internal);
  argnfs4.minorversion = 0;
  /* argnfs4.tag.utf8string_val = "GANESHA NFSv4 Proxy: Unlink" ; */
  argnfs4.tag.utf8string_val = NULL;
  argnfs4.tag.utf8string_len = 0;
  argnfs4.argarray.argarray_len = 0;

  /* >> retrieve root handle filehandle here << */
  bitmap.bitmap4_val = bitmap_val;
  bitmap.bitmap4_len = 2;

  fsal_internal_proxy_create_fattr_bitmap(&bitmap);

  if(fsal_internal_proxy_extract_fh(&nfs4fh, parentdir_handle) == FALSE)
    Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_unlink);

  memset((char *)&name, 0, sizeof(component4));
  name.utf8string_val = nameval;
  if(fsal_internal_proxy_fsal_name_2_utf8(p_object_name, &name) == FALSE)
    Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_unlink);

#define FSAL_UNLINK_IDX_OP_PUTFH      0
#define FSAL_UNLINK_IDX_OP_REMOVE     1
#define FSAL_UNLINK_IDX_OP_GETATTR    2

  COMPOUNDV4_ARG_ADD_OP_PUTFH(argnfs4, nfs4fh);
  COMPOUNDV4_ARG_ADD_OP_REMOVE(argnfs4, name);
  COMPOUNDV4_ARG_ADD_OP_GETATTR(argnfs4, bitmap);

  resnfs4.resarray.resarray_val[FSAL_UNLINK_IDX_OP_GETATTR].nfs_resop4_u.opgetattr.
      GETATTR4res_u.resok4.obj_attributes.attrmask.bitmap4_val = bitmap_res;
  resnfs4.resarray.resarray_val[FSAL_UNLINK_IDX_OP_GETATTR].nfs_resop4_u.opgetattr.
      GETATTR4res_u.resok4.obj_attributes.attrmask.bitmap4_len = 2;

  resnfs4.resarray.resarray_val[FSAL_UNLINK_IDX_OP_GETATTR].nfs_resop4_u.opgetattr.
      GETATTR4res_u.resok4.obj_attributes.attr_vals.attrlist4_val =
      (char *)&fattr_internal;
  resnfs4.resarray.resarray_val[FSAL_UNLINK_IDX_OP_GETATTR].nfs_resop4_u.opgetattr.
      GETATTR4res_u.resok4.obj_attributes.attr_vals.attrlist4_len =
      sizeof(fattr_internal);

  TakeTokenFSCall();

  /* Call the NFSv4 function */
  COMPOUNDV4_EXECUTE(p_context, argnfs4, resnfs4, rc);
  if(rc != RPC_SUCCESS)
    {
      ReleaseTokenFSCall();

      Return(ERR_FSAL_IO, rc, INDEX_FSAL_unlink);
    }

  ReleaseTokenFSCall();

  if(resnfs4.status != NFS4_OK)
    return fsal_internal_proxy_error_convert(resnfs4.status, INDEX_FSAL_unlink);

  /* >> get post op attributes for the parent, if they are asked,
   * and your filesystem didn't return them << */

  if(parentdir_attributes)
    {

      if(nfs4_Fattr_To_FSAL_attr(parentdir_attributes,
                                 &resnfs4.resarray.
                                 resarray_val[FSAL_UNLINK_IDX_OP_GETATTR].nfs_resop4_u.
                                 opgetattr.GETATTR4res_u.resok4.obj_attributes) != NFS4_OK)
        {
          FSAL_CLEAR_MASK(parentdir_attributes->asked_attributes);
          FSAL_SET_MASK(parentdir_attributes->asked_attributes, FSAL_ATTR_RDATTR_ERR);

          Return(ERR_FSAL_INVAL, 0, INDEX_FSAL_unlink);
        }

    }

  /* OK */
  Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_unlink);

}
Beispiel #10
0
/**
 * FSAL_create:
 * Create a regular file.
 *
 * \param parent_directory_handle (input):
 *        Handle of the parent directory where the file is to be created.
 * \param p_filename (input):
 *        Pointer to the name of the file to be created.
 * \param cred (input):
 *        Authentication context for the operation (user, export...).
 * \param accessmode (input):
 *        Mode for the file to be created.
 *        (the umask defined into the FSAL configuration file
 *        will be applied on it).
 * \param object_handle (output):
 *        Pointer to the handle of the created file.
 * \param object_attributes (optionnal input/output): 
 *        The postop attributes of the created file.
 *        As input, it defines the attributes that the caller
 *        wants to retrieve (by positioning flags into this structure)
 *        and the output is built considering this input
 *        (it fills the structure according to the flags it contains).
 *        Can be NULL.
 *
 * \return Major error codes :
 *        - ERR_FSAL_NO_ERROR     (no error)
 *        - ERR_FSAL_STALE        (parent_directory_handle does not address an existing object)
 *        - ERR_FSAL_FAULT        (a NULL pointer was passed as mandatory argument)
 *        - Other error codes can be returned :
 *          ERR_FSAL_ACCESS, ERR_FSAL_EXIST, ERR_FSAL_IO, ...
 *            
 *        NB: if getting postop attributes failed,
 *        the function does not return an error
 *        but the FSAL_ATTR_RDATTR_ERR bit is set in
 *        the object_attributes->asked_attributes field.
 */
fsal_status_t PROXYFSAL_create(proxyfsal_handle_t * parent_directory_handle,    /* IN */
                               fsal_name_t * p_filename,        /* IN */
                               proxyfsal_op_context_t * p_context,      /* IN */
                               fsal_accessmode_t accessmode,    /* IN */
                               proxyfsal_handle_t * object_handle,      /* OUT */
                               fsal_attrib_list_t * object_attributes   /* [ IN/OUT ] */
    )
{
  int rc;
  COMPOUND4args argnfs4;
  COMPOUND4res resnfs4;
  nfs_fh4 nfs4fh;
  bitmap4 bitmap;
  uint32_t bitmap_val[2];
  uint32_t bitmap_res[2];
  uint32_t bitmap_conv_val[2];
  uint32_t bitmap_create[2];
  uint32_t bitmap_getattr_res[2];
  fattr4 input_attr;
  bitmap4 convert_bitmap;
  component4 name;
  char nameval[MAXNAMLEN];
  char padfilehandle[FSAL_PROXY_FILEHANDLE_MAX_LEN];
  fsal_status_t fsal_status;
  proxyfsal_file_t fd;

#define FSAL_CREATE_NB_OP_ALLOC 4
#define FSAL_CREATE_VAL_BUFFER  1024

  fsal_proxy_internal_fattr_t fattr_internal;
  fsal_attrib_list_t create_mode_attr;
  fsal_attrib_list_t attributes;
  nfs_argop4 argoparray[FSAL_CREATE_NB_OP_ALLOC];
  nfs_resop4 resoparray[FSAL_CREATE_NB_OP_ALLOC];
  char fattr_val[FSAL_CREATE_VAL_BUFFER];
  struct timeval timeout = { 25, 0 };
  char owner_val[FSAL_PROXY_OWNER_LEN];
  unsigned int owner_len = 0;

  /* sanity checks.
   * note : object_attributes is optional.
   */
  if(!parent_directory_handle || !p_context || !object_handle || !p_filename)
    Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_create);

  PRINT_HANDLE("FSAL_create", parent_directory_handle);

  /* Create the owner */
  snprintf(owner_val, FSAL_PROXY_OWNER_LEN, "GANESHA/PROXY: pid=%u ctx=%p file=%llu",
           getpid(), p_context, (unsigned long long int)p_context->file_counter);
  owner_len = strnlen(owner_val, FSAL_PROXY_OWNER_LEN);
  p_context->file_counter += 1;

  /* Setup results structures */
  argnfs4.argarray.argarray_val = argoparray;
  resnfs4.resarray.resarray_val = resoparray;
  argnfs4.minorversion = 0;
  /* argnfs4.tag.utf8string_val = "GANESHA NFSv4 Proxy: Mkdir" ; */
  argnfs4.tag.utf8string_val = NULL;
  argnfs4.tag.utf8string_len = 0;
  argnfs4.argarray.argarray_len = 0;

  input_attr.attrmask.bitmap4_val = bitmap_val;
  input_attr.attrmask.bitmap4_len = 2;

  input_attr.attr_vals.attrlist4_val = fattr_val;
  input_attr.attr_vals.attrlist4_len = FSAL_CREATE_VAL_BUFFER;

  fsal_internal_proxy_setup_fattr(&fattr_internal);

  convert_bitmap.bitmap4_val = bitmap_conv_val;
  convert_bitmap.bitmap4_len = 2;

  memset((char *)&name, 0, sizeof(component4));
  name.utf8string_val = nameval;
  if(fsal_internal_proxy_fsal_name_2_utf8(p_filename, &name) == FALSE)
    Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_create);

  /* Get NFSv4 File handle */
  if(fsal_internal_proxy_extract_fh(&nfs4fh, parent_directory_handle) == FALSE)
    Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_create);

  if(isFullDebug(COMPONENT_FSAL))
    {
      char outstr[1024];

      nfs4_sprint_fhandle(&nfs4fh, outstr);
      LogFullDebug(COMPONENT_FSAL, "FSAL_CREATE: extracted server (as client) parent handle=%s\n",
                   outstr);
    }

  bitmap.bitmap4_val = bitmap_create;
  bitmap.bitmap4_len = 2;
  fsal_internal_proxy_create_fattr_bitmap(&bitmap);

  create_mode_attr.asked_attributes = FSAL_ATTR_MODE;
  create_mode_attr.mode = accessmode;
  fsal_interval_proxy_fsalattr2bitmap4(&create_mode_attr, &convert_bitmap);

  if(nfs4_FSALattr_To_Fattr(NULL,       /* no exportlist required here */
                            &create_mode_attr, &input_attr, NULL,       /* no compound data required here */
                            NULL,       /* No fh here, filehandle is not a settable attribute */
                            &convert_bitmap) == -1)
    Return(ERR_FSAL_INVAL, -1, INDEX_FSAL_create);

#define FSAL_CREATE_IDX_OP_PUTFH       0
#define FSAL_CREATE_IDX_OP_OPEN_CREATE 1
#define FSAL_CREATE_IDX_OP_GETFH       2
#define FSAL_CREATE_IDX_OP_GETATTR     3
  COMPOUNDV4_ARG_ADD_OP_PUTFH(argnfs4, nfs4fh);
  COMPOUNDV4_ARG_ADD_OP_OPEN_CREATE(argnfs4, name, input_attr, p_context->clientid,
                                    owner_val, owner_len);
  COMPOUNDV4_ARG_ADD_OP_GETFH(argnfs4);
  COMPOUNDV4_ARG_ADD_OP_GETATTR(argnfs4, bitmap);

  resnfs4.resarray.resarray_val[FSAL_CREATE_IDX_OP_OPEN_CREATE].nfs_resop4_u.opopen.
      OPEN4res_u.resok4.attrset.bitmap4_val = bitmap_res;
  resnfs4.resarray.resarray_val[FSAL_CREATE_IDX_OP_OPEN_CREATE].nfs_resop4_u.opopen.
      OPEN4res_u.resok4.attrset.bitmap4_len = 2;

  resnfs4.resarray.resarray_val[FSAL_CREATE_IDX_OP_GETFH].nfs_resop4_u.opgetfh.
      GETFH4res_u.resok4.object.nfs_fh4_val = (char *)padfilehandle;
  resnfs4.resarray.resarray_val[FSAL_CREATE_IDX_OP_GETFH].nfs_resop4_u.opgetfh.
      GETFH4res_u.resok4.object.nfs_fh4_len = FSAL_PROXY_FILEHANDLE_MAX_LEN;

  resnfs4.resarray.resarray_val[FSAL_CREATE_IDX_OP_GETATTR].nfs_resop4_u.opgetattr.
      GETATTR4res_u.resok4.obj_attributes.attrmask.bitmap4_val = bitmap_getattr_res;
  resnfs4.resarray.resarray_val[FSAL_CREATE_IDX_OP_GETATTR].nfs_resop4_u.opgetattr.
      GETATTR4res_u.resok4.obj_attributes.attrmask.bitmap4_len = 2;

  resnfs4.resarray.resarray_val[FSAL_CREATE_IDX_OP_GETATTR].nfs_resop4_u.opgetattr.
      GETATTR4res_u.resok4.obj_attributes.attr_vals.attrlist4_val =
      (char *)&fattr_internal;
  resnfs4.resarray.resarray_val[FSAL_CREATE_IDX_OP_GETATTR].nfs_resop4_u.opgetattr.
      GETATTR4res_u.resok4.obj_attributes.attr_vals.attrlist4_len =
      sizeof(fattr_internal);

  TakeTokenFSCall();

  /* Call the NFSv4 function */
  COMPOUNDV4_EXECUTE(p_context, argnfs4, resnfs4, rc);
  if(rc != RPC_SUCCESS)
    {
      ReleaseTokenFSCall();

      Return(ERR_FSAL_IO, rc, INDEX_FSAL_create);
    }

  ReleaseTokenFSCall();

  /* >> convert error code, and return on error << */
  if(resnfs4.status != NFS4_OK)
    return fsal_internal_proxy_error_convert(resnfs4.status, INDEX_FSAL_create);

  /* Use NFSv4 service function to build the FSAL_attr */
  if(nfs4_Fattr_To_FSAL_attr(&attributes,
                             &resnfs4.resarray.resarray_val[FSAL_CREATE_IDX_OP_GETATTR].
                             nfs_resop4_u.opgetattr.GETATTR4res_u.resok4.
                             obj_attributes) != 1)
    {
      FSAL_CLEAR_MASK(attributes.asked_attributes);
      FSAL_SET_MASK(attributes.asked_attributes, FSAL_ATTR_RDATTR_ERR);

      Return(ERR_FSAL_INVAL, 0, INDEX_FSAL_create);

    }

  /* Return attributes if asked */
  if(object_attributes)
    {
      memcpy(object_attributes, &attributes, sizeof(attributes));
    }

  if(isFullDebug(COMPONENT_FSAL))
    {
      char outstr[1024];

      nfs4_sprint_fhandle(&nfs4fh, outstr);
      LogFullDebug(COMPONENT_FSAL, "FSAL_CREATE: extracted server (as client) created file handle=%s\n",
           outstr);
    }

  if(fsal_internal_proxy_create_fh
     (&
      (resnfs4.resarray.resarray_val[FSAL_CREATE_IDX_OP_GETFH].nfs_resop4_u.opgetfh.
       GETFH4res_u.resok4.object), FSAL_TYPE_FILE, attributes.fileid,
      object_handle) == FALSE)
    Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_create);

  /* Keep the information into the file descriptor as well */
  memcpy((char *)&fd.fhandle, (char *)object_handle, sizeof(fd.fhandle));

  fd.openflags = FSAL_O_RDWR;
  fd.current_offset = 0;
  fd.pcontext = p_context;

  /* Keep the returned stateid for later use */
  fd.stateid.seqid =
      resnfs4.resarray.resarray_val[FSAL_CREATE_IDX_OP_OPEN_CREATE].nfs_resop4_u.opopen.
      OPEN4res_u.resok4.stateid.seqid;
  memcpy((char *)fd.stateid.other,
         resnfs4.resarray.resarray_val[FSAL_CREATE_IDX_OP_OPEN_CREATE].nfs_resop4_u.
         opopen.OPEN4res_u.resok4.stateid.other, 12);

  /* See if a OPEN_CONFIRM is required */
  if(resnfs4.resarray.resarray_val[FSAL_CREATE_IDX_OP_OPEN_CREATE].nfs_resop4_u.opopen.
     OPEN4res_u.resok4.rflags & OPEN4_RESULT_CONFIRM)
    {
      fsal_status = FSAL_proxy_open_confirm(&fd);
      if(FSAL_IS_ERROR(fsal_status))
        Return(fsal_status.major, fsal_status.minor, INDEX_FSAL_create);
    }
#ifdef _FSAL_CREATE_CLOSE_FILE
  /* The craeted file is still opened, to preserve the correct seqid for later use, we close it */
  fsal_status = FSAL_close(&fd);
  if(FSAL_IS_ERROR(fsal_status))
    Return(fsal_status.major, fsal_status.minor, INDEX_FSAL_create);
#endif

  /* OK */
  Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_create);
}                               /* FSAL_create */
Beispiel #11
0
/**
 * FSAL_link:
 * Create a hardlink.
 *
 * \param target_handle (input):
 *        Handle of the target object.
 * \param dir_handle (input):
 *        Pointer to the directory handle where
 *        the hardlink is to be created.
 * \param p_link_name (input):
 *        Pointer to the name of the hardlink to be created.
 * \param cred (input):
 *        Authentication context for the operation (user,...).
 * \param accessmode (input):
 *        Mode for the directory to be created.
 *        (the umask defined into the FSAL configuration file
 *        will be applied on it).
 * \param attributes (optionnal input/output): 
 *        The post_operation attributes of the linked object.
 *        As input, it defines the attributes that the caller
 *        wants to retrieve (by positioning flags into this structure)
 *        and the output is built considering this input
 *        (it fills the structure according to the flags it contains).
 *        May be NULL.
 *
 * \return Major error codes :
 *        - ERR_FSAL_NO_ERROR     (no error)
 *        - ERR_FSAL_STALE        (target_handle or dir_handle does not address an existing object)
 *        - ERR_FSAL_FAULT        (a NULL pointer was passed as mandatory argument)
 *        - Other error codes can be returned :
 *          ERR_FSAL_ACCESS, ERR_FSAL_EXIST, ERR_FSAL_IO, ...
 *            
 *        NB: if getting postop attributes failed,
 *        the function does not return an error
 *        but the FSAL_ATTR_RDATTR_ERR bit is set in
 *        the attributes->asked_attributes field.
 */
fsal_status_t PROXYFSAL_link(proxyfsal_handle_t * target_handle,        /* IN */
                             proxyfsal_handle_t * dir_handle,   /* IN */
                             fsal_name_t * p_link_name, /* IN */
                             proxyfsal_op_context_t * p_context,        /* IN */
                             fsal_attrib_list_t * attributes    /* [ IN/OUT ] */
    )
{
  int rc;

  COMPOUND4args argnfs4;
  COMPOUND4res resnfs4;
  nfs_fh4 nfs4fh_target;
  nfs_fh4 nfs4fh_dest;
  bitmap4 bitmap;
  uint32_t bitmap_val[2];
  uint32_t bitmap_res[2];
  component4 name;
  char nameval[MAXNAMLEN];

  fsal_proxy_internal_fattr_t fattr_internal;

  struct timeval timeout = { 25, 0 };

  /* sanity checks.
   * note : attributes is optional.
   */
  if(!target_handle || !dir_handle || !p_context || !p_link_name)
    Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_link);

  /* Tests if hardlinking is allowed by configuration. */

  if(!global_fs_info.link_support)
    Return(ERR_FSAL_NOTSUPP, 0, INDEX_FSAL_link);

#define FSAL_LINK_NB_OP_ALLOC 6
  nfs_argop4 argoparray[FSAL_LINK_NB_OP_ALLOC];
  nfs_resop4 resoparray[FSAL_LINK_NB_OP_ALLOC];

  /* Setup results structures */
  argnfs4.argarray.argarray_val = argoparray;
  resnfs4.resarray.resarray_val = resoparray;
  fsal_internal_proxy_setup_fattr(&fattr_internal);
  argnfs4.minorversion = 0;
  /* argnfs4.tag.utf8string_val = "GANESHA NFSv4 Proxy: Link" ; */
  argnfs4.tag.utf8string_val = NULL;
  argnfs4.tag.utf8string_len = 0;
  argnfs4.argarray.argarray_len = 0;

  bitmap.bitmap4_val = bitmap_val;
  bitmap.bitmap4_len = 2;
  fsal_internal_proxy_create_fattr_bitmap(&bitmap);

  if(fsal_internal_proxy_extract_fh(&nfs4fh_target, target_handle) == FALSE)
    Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_link);

  if(fsal_internal_proxy_extract_fh(&nfs4fh_dest, dir_handle) == FALSE)
    Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_link);

  memset((char *)&name, 0, sizeof(component4));
  name.utf8string_val = nameval;
  if(fsal_internal_proxy_fsal_name_2_utf8(p_link_name, &name) == FALSE)
    Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_link);

#define FSAL_LINK_IDX_OP_PUTFH_TARGET 0
#define FSAL_LINK_IDX_OP_SAVEFH       1
#define FSAL_LINK_IDX_OP_PUTFH_DEST   2
#define FSAL_LINK_IDX_OP_LINK         3
#define FSAL_LINK_IDX_OP_RESTOREFH    4
#define FSAL_LINK_IDX_OP_GETATTR      5
  COMPOUNDV4_ARG_ADD_OP_PUTFH(argnfs4, nfs4fh_target);
  COMPOUNDV4_ARG_ADD_OP_SAVEFH(argnfs4);
  COMPOUNDV4_ARG_ADD_OP_PUTFH(argnfs4, nfs4fh_dest);
  COMPOUNDV4_ARG_ADD_OP_LINK(argnfs4, name);
  COMPOUNDV4_ARG_ADD_OP_RESTOREFH(argnfs4);
  COMPOUNDV4_ARG_ADD_OP_GETATTR(argnfs4, bitmap);

  resnfs4.resarray.resarray_val[FSAL_LINK_IDX_OP_GETATTR].nfs_resop4_u.opgetattr.
      GETATTR4res_u.resok4.obj_attributes.attrmask.bitmap4_val = bitmap_res;
  resnfs4.resarray.resarray_val[FSAL_LINK_IDX_OP_GETATTR].nfs_resop4_u.opgetattr.
      GETATTR4res_u.resok4.obj_attributes.attrmask.bitmap4_len = 2;

  resnfs4.resarray.resarray_val[FSAL_LINK_IDX_OP_GETATTR].nfs_resop4_u.opgetattr.
      GETATTR4res_u.resok4.obj_attributes.attr_vals.attrlist4_val =
      (char *)&fattr_internal;
  resnfs4.resarray.resarray_val[FSAL_LINK_IDX_OP_GETATTR].nfs_resop4_u.opgetattr.
      GETATTR4res_u.resok4.obj_attributes.attr_vals.attrlist4_len =
      sizeof(fattr_internal);

  TakeTokenFSCall();

  /* Call the NFSv4 function */
  COMPOUNDV4_EXECUTE(p_context, argnfs4, resnfs4, rc);
  if(rc != RPC_SUCCESS)
    {
      ReleaseTokenFSCall();

      Return(ERR_FSAL_IO, rc, INDEX_FSAL_link);
    }

  ReleaseTokenFSCall();

  if(resnfs4.status != NFS4_OK)
    return fsal_internal_proxy_error_convert(resnfs4.status, INDEX_FSAL_link);

  if(attributes)
    {
      /* Use NFSv4 service function to build the FSAL_attr */
      if(nfs4_Fattr_To_FSAL_attr(attributes,
                                 &resnfs4.resarray.
                                 resarray_val[FSAL_LINK_IDX_OP_GETATTR].nfs_resop4_u.
                                 opgetattr.GETATTR4res_u.resok4.obj_attributes) != 1)
        {
          FSAL_CLEAR_MASK(attributes->asked_attributes);
          FSAL_SET_MASK(attributes->asked_attributes, FSAL_ATTR_RDATTR_ERR);

          Return(ERR_FSAL_INVAL, 0, INDEX_FSAL_link);
        }
    }

  /* OK */
  Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_link);

}
Beispiel #12
0
fsal_status_t PROXYFSAL_truncate(fsal_handle_t * file_hdl,       /* IN */
                                 fsal_op_context_t * context,    /* IN */
                                 fsal_size_t length,    /* IN */
                                 fsal_file_t * file_descriptor, /* [IN|OUT] */
                                 fsal_attrib_list_t * object_attributes /* [ IN/OUT ] */
    )
{

  int rc;

  COMPOUND4args argnfs4;
  COMPOUND4res resnfs4;
  nfs_fh4 nfs4fh;
  uint64_t fileid;
  fsal_status_t fsal_status;
  fsal_attrib_list_t open_attrs;
  bitmap4 inbitmap;
  bitmap4 convert_bitmap;
  uint32_t inbitmap_val[2];
  uint32_t bitmap_res[2];
  uint32_t bitmap_set[2];
  uint32_t bitmap_conv_val[2];
  proxyfsal_handle_t * filehandle = (proxyfsal_handle_t *)file_hdl;
  proxyfsal_op_context_t * p_context = (proxyfsal_op_context_t *)context;

#define FSAL_TRUNCATE_NB_OP_ALLOC 3
  nfs_argop4 argoparray[FSAL_TRUNCATE_NB_OP_ALLOC];
  nfs_resop4 resoparray[FSAL_TRUNCATE_NB_OP_ALLOC];

  fsal_attrib_list_t fsal_attr_set;
  fattr4 fattr_set;
  fsal_proxy_internal_fattr_t fattr_internal;
  struct timeval timeout = TIMEOUTRPC;

  /* sanity checks.
   * note : object_attributes is optional.
   */
  if(!filehandle || !p_context)
    Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_truncate);

  if(filehandle->data.object_type_reminder != FSAL_TYPE_FILE)
    {
      Return(ERR_FSAL_INVAL, 0, INDEX_FSAL_truncate);
    }

  if(file_descriptor == NULL)
    {
      /* Use the stateless version */
      fsal_status = FSAL_proxy_truncate_stateless(file_hdl,
                                                  context, length, object_attributes);
      Return(fsal_status.major, fsal_status.minor, INDEX_FSAL_truncate);
    }

  /* First, we need to get the fileid on a filehandle base */
  fsal_status = FSAL_DigestHandle(context->export_context,
                                  FSAL_DIGEST_FILEID4, file_hdl, (caddr_t) & fileid);
  if(FSAL_IS_ERROR(fsal_status))
    {
      Return(fsal_status.major, fsal_status.minor, INDEX_FSAL_truncate);
    }

  /* Then we have of open the file by fileid */
  open_attrs.asked_attributes = FSAL_ATTRS_POSIX;
  fsal_status = FSAL_open_by_fileid(file_hdl,
                                    fileid,
                                    context, FSAL_O_RDWR, file_descriptor, &open_attrs);
  if(FSAL_IS_ERROR(fsal_status))
    {
      Return(fsal_status.major, fsal_status.minor, INDEX_FSAL_truncate);
    }

  /* Setup results structures */
  argnfs4.argarray.argarray_val = argoparray;
  resnfs4.resarray.resarray_val = resoparray;
  fsal_internal_proxy_setup_fattr(&fattr_internal);
  argnfs4.minorversion = 0;
  /* argnfs4.tag.utf8string_val = "GANESHA NFSv4 Proxy: Truncate" ; */
  argnfs4.tag.utf8string_val = NULL;
  argnfs4.tag.utf8string_len = 0;
  argnfs4.argarray.argarray_len = 0;

  /* Get NFSv4 File handle */
  if(fsal_internal_proxy_extract_fh(&nfs4fh, file_hdl) == FALSE)
    Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_truncate);

  /* Get prepared for truncate */
  fsal_attr_set.asked_attributes = FSAL_ATTR_SIZE;
  fsal_attr_set.filesize = length;

  convert_bitmap.bitmap4_val = bitmap_conv_val;
  convert_bitmap.bitmap4_len = 2;

  fsal_interval_proxy_fsalattr2bitmap4(&fsal_attr_set, &convert_bitmap);

  if(nfs4_FSALattr_To_Fattr(NULL,       /* no exportlist required here */
                            &fsal_attr_set, &fattr_set, NULL,   /* no compound data required here */
                            NULL,       /* No fh here, filehandle is not a settable attribute */
                            &convert_bitmap) == -1)
    Return(ERR_FSAL_INVAL, -1, INDEX_FSAL_truncate);

  inbitmap.bitmap4_val = inbitmap_val;
  inbitmap.bitmap4_len = 2;
  fsal_internal_proxy_create_fattr_bitmap(&inbitmap);

#define FSAL_TRUNCATE_IDX_OP_PUTFH     0
#define FSAL_TRUNCATE_IDX_OP_SETATTR   1
#define FSAL_TRUNCATE_IDX_OP_GETATTR   2
  COMPOUNDV4_ARG_ADD_OP_PUTFH(argnfs4, nfs4fh);
  COMPOUNDV4_ARG_ADD_OP_SETATTR(argnfs4, fattr_set);
  COMPOUNDV4_ARG_ADD_OP_GETATTR(argnfs4, inbitmap);

  /* For ATTR_SIZE, stateid is needed */
  argnfs4.argarray.argarray_val[FSAL_TRUNCATE_IDX_OP_SETATTR].nfs_argop4_u.opsetattr.
      stateid.seqid = ((proxyfsal_file_t *)file_descriptor)->stateid.seqid;
  memcpy(argnfs4.argarray.argarray_val[FSAL_TRUNCATE_IDX_OP_SETATTR].nfs_argop4_u.
         opsetattr.stateid.other, ((proxyfsal_file_t *)file_descriptor)->stateid.other, 12);

  resnfs4.resarray.resarray_val[FSAL_TRUNCATE_IDX_OP_GETATTR].nfs_resop4_u.opgetattr.
      GETATTR4res_u.resok4.obj_attributes.attrmask.bitmap4_val = bitmap_res;
  resnfs4.resarray.resarray_val[FSAL_TRUNCATE_IDX_OP_GETATTR].nfs_resop4_u.opgetattr.
      GETATTR4res_u.resok4.obj_attributes.attrmask.bitmap4_len = 2;

  resnfs4.resarray.resarray_val[FSAL_TRUNCATE_IDX_OP_GETATTR].nfs_resop4_u.opgetattr.
      GETATTR4res_u.resok4.obj_attributes.attr_vals.attrlist4_val =
      (char *)&fattr_internal;
  resnfs4.resarray.resarray_val[FSAL_TRUNCATE_IDX_OP_GETATTR].nfs_resop4_u.opgetattr.
      GETATTR4res_u.resok4.obj_attributes.attr_vals.attrlist4_len =
      sizeof(fattr_internal);

  resnfs4.resarray.resarray_val[FSAL_TRUNCATE_IDX_OP_SETATTR].nfs_resop4_u.opsetattr.
      attrsset.bitmap4_val = bitmap_set;
  resnfs4.resarray.resarray_val[FSAL_TRUNCATE_IDX_OP_SETATTR].nfs_resop4_u.opsetattr.
      attrsset.bitmap4_len = 2;

  TakeTokenFSCall();

  COMPOUNDV4_EXECUTE(p_context, argnfs4, resnfs4, rc);
  if(rc != RPC_SUCCESS)
    {
      ReleaseTokenFSCall();

      Return(ERR_FSAL_IO, 0, INDEX_FSAL_truncate);
    }

  ReleaseTokenFSCall();

  if(resnfs4.status != NFS4_OK)
    return fsal_internal_proxy_error_convert(resnfs4.status, INDEX_FSAL_truncate);

  /* >> interpret error code << */

  /* >> Optionnaly retrieve post op attributes
   * If your filesystem truncate call can't return them,
   * you can proceed like this : <<
   */
  if(object_attributes)
    {
      if(nfs4_Fattr_To_FSAL_attr(object_attributes,
                                 &resnfs4.resarray.
                                 resarray_val[FSAL_TRUNCATE_IDX_OP_GETATTR].nfs_resop4_u.
                                 opgetattr.GETATTR4res_u.resok4.obj_attributes) != NFS4_OK)
        {
          FSAL_CLEAR_MASK(object_attributes->asked_attributes);
          FSAL_SET_MASK(object_attributes->asked_attributes, FSAL_ATTR_RDATTR_ERR);

          Return(ERR_FSAL_INVAL, 0, INDEX_FSAL_truncate);
        }

    }

  /* Close the previously opened filedescriptor */
  fsal_status = FSAL_close_by_fileid(file_descriptor, fileid);
  if(FSAL_IS_ERROR(fsal_status))
    {
      Return(fsal_status.major, fsal_status.minor, INDEX_FSAL_truncate);
    }

  /* No error occured */
  Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_truncate);
}
Beispiel #13
0
/**
 * PROXYFSAL_access :
 * Tests whether the user or entity identified by the p_context structure
 * can access the object identified by object_handle,
 * as indicated by the access_type parameter.
 *
 * \param object_handle (input):
 *        The handle of the object to test permissions on.
 * \param p_context (input):
 *        Authentication context for the operation (export entry, user,...).
 * \param access_type (input):
 *        Indicates the permissions to be tested.
 *        This is an inclusive OR of the permissions
 *        to be checked for the user specified by p_context.
 *        Permissions constants are :
 *        - FSAL_R_OK : test for read permission
 *        - FSAL_W_OK : test for write permission
 *        - FSAL_X_OK : test for exec permission
 *        - FSAL_F_OK : test for file existence
 * \param object_attributes (optional input/output):
 *        The post operation attributes for the object.
 *        As input, it defines the attributes that the caller
 *        wants to retrieve (by positioning flags into this structure)
 *        and the output is built considering this input
 *        (it fills the structure according to the flags it contains).
 *        Can be NULL.
 *
 * \return Major error codes :
 *        - ERR_FSAL_NO_ERROR     (no error, asked permission is granted)
 *        - ERR_FSAL_ACCESS       (object permissions doesn't fit asked access type)
 *        - ERR_FSAL_STALE        (object_handle does not address an existing object)
 *        - ERR_FSAL_FAULT        (a NULL pointer was passed as mandatory argument)
 *        - Other error codes when something anormal occurs.
 */
fsal_status_t PROXYFSAL_access(fsal_handle_t * object_handle,      /* IN */
                               fsal_op_context_t *context,      /* IN */
                               fsal_accessflags_t access_type,  /* IN */
                               fsal_attrib_list_t * object_attributes   /* [ IN/OUT ] */
    )
{

  int rc;
  COMPOUND4args argnfs4;
  COMPOUND4res resnfs4;
  bitmap4 bitmap;
  uint32_t bitmap_val[2];
  uint32_t bitmap_res[2];
  uint32_t accessflag = 0;
  proxyfsal_op_context_t * p_context = (proxyfsal_op_context_t *)context;

  fsal_proxy_internal_fattr_t fattr_internal;

  struct timeval __attribute__ ((__unused__)) timeout = TIMEOUTRPC;
  nfs_fh4 nfs4fh;

#define FSAL_ACCESS_NB_OP_ACCESS 3

  nfs_argop4 argoparray[FSAL_ACCESS_NB_OP_ACCESS];
  nfs_resop4 resoparray[FSAL_ACCESS_NB_OP_ACCESS];

  /* sanity checks.
   * note : object_attributes is optional in PROXYFSAL_access.
   */
  if(!object_handle || !p_context)
    Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_access);

  /* Setup results structures */
  argnfs4.argarray.argarray_val = argoparray;
  resnfs4.resarray.resarray_val = resoparray;
  fsal_internal_proxy_setup_fattr(&fattr_internal);
  argnfs4.minorversion = 0;
  /* argnfs4.tag.utf8string_val = "GANESHA NFSv4 Proxy: Access" ; */
  argnfs4.tag.utf8string_val = NULL;
  argnfs4.tag.utf8string_len = 0;
  argnfs4.argarray.argarray_len = 0;

  bitmap.bitmap4_val = bitmap_val;
  bitmap.bitmap4_len = 2;
  fsal_internal_proxy_create_fattr_bitmap(&bitmap);

  /* Set up access flags */
  if(access_type & FSAL_R_OK)
    accessflag |= ACCESS4_READ;

  if(access_type & FSAL_X_OK)
    accessflag |= ACCESS4_LOOKUP;

  if(access_type & FSAL_W_OK)
    accessflag |= (ACCESS4_MODIFY & ACCESS4_EXTEND);

  if(access_type & FSAL_F_OK)
    accessflag |= ACCESS4_LOOKUP;

  /* >> convert your fsal access type to your FS access type << */

  /* Get NFSv4 File handle */
  if(fsal_internal_proxy_extract_fh(&nfs4fh, object_handle) == FALSE)
    Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_access);

#define FSAL_ACCESS_IDX_OP_PUTFH    0
#define FSAL_ACCESS_IDX_OP_ACCESS   1
#define FSAL_ACCESS_IDX_OP_GETATTR  2

  COMPOUNDV4_ARG_ADD_OP_PUTFH(argnfs4, nfs4fh);
  COMPOUNDV4_ARG_ADD_OP_ACCESS(argnfs4, accessflag);
  COMPOUNDV4_ARG_ADD_OP_GETATTR(argnfs4, bitmap);

  resnfs4.resarray.resarray_val[FSAL_ACCESS_IDX_OP_GETATTR].nfs_resop4_u.opgetattr.
      GETATTR4res_u.resok4.obj_attributes.attrmask.bitmap4_val = bitmap_res;
  resnfs4.resarray.resarray_val[FSAL_ACCESS_IDX_OP_GETATTR].nfs_resop4_u.opgetattr.
      GETATTR4res_u.resok4.obj_attributes.attrmask.bitmap4_len = 2;

  resnfs4.resarray.resarray_val[FSAL_ACCESS_IDX_OP_GETATTR].nfs_resop4_u.opgetattr.
      GETATTR4res_u.resok4.obj_attributes.attr_vals.attrlist4_val =
      (char *)&fattr_internal;
  resnfs4.resarray.resarray_val[FSAL_ACCESS_IDX_OP_GETATTR].nfs_resop4_u.opgetattr.
      GETATTR4res_u.resok4.obj_attributes.attr_vals.attrlist4_len =
      sizeof(fattr_internal);

  TakeTokenFSCall();

  /* Call the NFSv4 function */
  COMPOUNDV4_EXECUTE(p_context, argnfs4, resnfs4, rc);
  if(rc != RPC_SUCCESS)
    {
      ReleaseTokenFSCall();

      Return(ERR_FSAL_IO, resnfs4.status, INDEX_FSAL_access);
    }

  ReleaseTokenFSCall();

  /* >> convert the returned code, an return it on error << */
  if(resnfs4.status != NFS4_OK)
    return fsal_internal_proxy_error_convert(resnfs4.status, INDEX_FSAL_access);

  /* get attributes if object_attributes is not null.
   * If an error occures during getattr operation,
   * an error bit is set in the output structure.
   */
  if(object_attributes)
    {
      /* Use NFSv4 service function to build the FSAL_attr */
      if(nfs4_Fattr_To_FSAL_attr(object_attributes,
                                 &resnfs4.resarray.
                                 resarray_val[FSAL_ACCESS_IDX_OP_GETATTR].nfs_resop4_u.
                                 opgetattr.GETATTR4res_u.resok4.obj_attributes) != NFS4_OK)
        {
          FSAL_CLEAR_MASK(object_attributes->asked_attributes);
          FSAL_SET_MASK(object_attributes->asked_attributes, FSAL_ATTR_RDATTR_ERR);

          Return(ERR_FSAL_INVAL, 0, INDEX_FSAL_access);
        }

    }

  Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_access);

}