Ejemplo n.º 1
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);
}
Ejemplo n.º 2
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);

}
Ejemplo n.º 3
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 */