예제 #1
0
/**
 * fsal_internal_proxy_create_fh :
 *
 *
 * @param pnfs4_handle [IN]  the NFSv4 Handle
 * @param type         [IN]  the type of object for this entry
 * @param fileid       [IN]  the file id for this entry
 * @param pfsal_handle [OUT] the resulting FSAL Handle
 *
 * @return TRUE if OK, FALSE otherwise
 *
 */
int fsal_internal_proxy_create_fh(nfs_fh4 * pnfs4_handle,
                                  fsal_nodetype_t type,
                                  fsal_u64_t fileid, fsal_handle_t * fsal_handle)
{
  proxyfsal_handle_t * pfsal_handle = (proxyfsal_handle_t *) fsal_handle;

  if(pnfs4_handle == NULL || pfsal_handle == NULL)
    return FALSE;

  if(isFullDebug(COMPONENT_FSAL))
    {
      char outstr[1024];
      nfs4_sprint_fhandle(pnfs4_handle, outstr);
      LogFullDebug(COMPONENT_FSAL, "fsal_internal_proxy_create_fh: input nfsv4 server handle=%s", outstr);
    }
 
  memset( (char *)pfsal_handle, 0, sizeof( proxyfsal_handle_t ) ) ;

  pfsal_handle->data.object_type_reminder = type;
  pfsal_handle->data.fileid4 = fileid;
  pfsal_handle->data.timestamp = /** @todo fh should be volatile ? ServerBootTime ; */ 0;
  pfsal_handle->data.srv_handle_len = pnfs4_handle->nfs_fh4_len;
  memset(pfsal_handle->data.srv_handle_val, 0, FSAL_PROXY_FILEHANDLE_MAX_LEN);
  memcpy(pfsal_handle->data.srv_handle_val, pnfs4_handle->nfs_fh4_val,
         pnfs4_handle->nfs_fh4_len);

  if(isFullDebug(COMPONENT_FSAL))
    {
      char outstr[1024];
      if(type == FSAL_TYPE_FILE)
        {
          nfs_fh4 tmpfh;

          tmpfh.nfs_fh4_len = pfsal_handle->data.srv_handle_len;
          tmpfh.nfs_fh4_val = pfsal_handle->data.srv_handle_val;
          nfs4_sprint_fhandle(&tmpfh, outstr);
          LogFullDebug(COMPONENT_FSAL,
                       "fsal_internal_proxy_create_fh: output nfsv4 server handle= %s fileid=%llu",
                       outstr, fileid);
        }

      if(memcmp
         (pfsal_handle->data.srv_handle_val, pnfs4_handle->nfs_fh4_val, pnfs4_handle->nfs_fh4_len))
        LogFullDebug(COMPONENT_FSAL,
                     "CRITICAL ERROR: ==========> Filehandle mismatch n ifsal_internal_proxy_create");
    }

  return TRUE;
}                               /* fsal_internal_proxy_create_fh */
예제 #2
0
/**
 * fsal_internal_proxy_extract_fh :
 * Do the FSAL -> NFSv4 FH conversion
 *
 *
 * @param pnfs4_handle [OUT] the NFSv4 Handle
 * @param pfsal_handle [IN]  the resulting FSAL Handle
 *
 * @return TRUE if OK, FALSE otherwise
 *
 */
int fsal_internal_proxy_extract_fh(nfs_fh4 * pnfs4_handle,
                                   proxyfsal_handle_t * pfsal_handle)
{
  if(pnfs4_handle == NULL || pfsal_handle == NULL)
    return FALSE;

  pnfs4_handle->nfs_fh4_len = pfsal_handle->data.srv_handle_len;
  pnfs4_handle->nfs_fh4_val = pfsal_handle->data.srv_handle_val;

  if(isFullDebug(COMPONENT_FSAL))
    {
      char outstr[1024];
      nfs4_sprint_fhandle(pnfs4_handle, outstr);
      LogFullDebug(COMPONENT_FSAL, "fsal_internal_proxy_extract_fh: input nfsv4 server handle=%s\n", outstr);
    }

  return TRUE;
}                               /* fsal_internal_proxy_extract_fh */
예제 #3
0
int CreateROOTFH4(nfs_fh4 * fh, compound_data_t * data)
{
  pseudofs_entry_t psfsentry;
  int status = 0;
  char fhstr[LEN_FH_STR];

  psfsentry = *(data->pseudofs->reverse_tab[0]);

  if((status = nfs4_AllocateFH(&(data->rootFH))) != NFS4_OK)
    return status;

  if(!nfs4_PseudoToFhandle(&(data->rootFH), &psfsentry))
    {
      return NFS4ERR_BADHANDLE;
    }

  /* Test */
  nfs4_sprint_fhandle(&data->rootFH, fhstr);
  LogDebug(COMPONENT_NFS_V4, "CREATE ROOTFH: %s", fhstr);

  return NFS4_OK;
}                               /* CreateROOTFH4 */
예제 #4
0
int nfs4_op_putfh(struct nfs_argop4 *op, compound_data_t * data, struct nfs_resop4 *resp)
{
  int rc;
  int error;
  fsal_attrib_list_t attr;
  char outstr[1024];

  char __attribute__ ((__unused__)) funcname[] = "nfs4_op_putfh";

  resp->resop = NFS4_OP_PUTFH;
  res_PUTFH4.status = NFS4_OK;

  /* If there is no FH */
  if(nfs4_Is_Fh_Empty(&(arg_PUTFH4.object)))
    {
      res_PUTFH4.status = NFS4ERR_NOFILEHANDLE;
      return res_PUTFH4.status;
    }

  /* If the filehandle is invalid */
  if(nfs4_Is_Fh_Invalid(&(arg_PUTFH4.object)))
    {
      res_PUTFH4.status = NFS4ERR_BADHANDLE;
      return res_PUTFH4.status;
    }

  /* Tests if teh Filehandle is expired (for volatile filehandle) */
  if(nfs4_Is_Fh_Expired(&(arg_PUTFH4.object)))
    {
      res_PUTFH4.status = NFS4ERR_FHEXPIRED;
      return res_PUTFH4.status;
    }

  /* If no currentFH were set, allocate one */
  if(data->currentFH.nfs_fh4_len == 0)
    {
      if((error = nfs4_AllocateFH(&(data->currentFH))) != NFS4_OK)
        {
          res_PUTFH4.status = error;
          return res_PUTFH4.status;
        }
    }

  /* The same is to be done with mounted_on_FH */
  if(data->mounted_on_FH.nfs_fh4_len == 0)
    {
      if((error = nfs4_AllocateFH(&(data->mounted_on_FH))) != NFS4_OK)
        {
          res_PUTFH4.status = error;
          return res_PUTFH4.status;
        }
    }

  /* Copy the filehandle from the reply structure */
  data->currentFH.nfs_fh4_len = arg_PUTFH4.object.nfs_fh4_len;
  data->mounted_on_FH.nfs_fh4_len = arg_PUTFH4.object.nfs_fh4_len;

  /* Put the data in place */
  memcpy(data->currentFH.nfs_fh4_val, arg_PUTFH4.object.nfs_fh4_val,
         arg_PUTFH4.object.nfs_fh4_len);
  memcpy(data->mounted_on_FH.nfs_fh4_val, arg_PUTFH4.object.nfs_fh4_val,
         arg_PUTFH4.object.nfs_fh4_len);

  nfs4_sprint_fhandle(&arg_PUTFH4.object, outstr);
  LogDebug(COMPONENT_NFS_V4, "NFS4_OP_PUTFH CURRENTFH BEFORE: File handle = %s", outstr);

  /* If the filehandle is not pseudo hs file handle, get the entry related to it, otherwise use fake values */
  if(nfs4_Is_Fh_Pseudo(&(data->currentFH)))
    {
      data->current_entry = NULL;
      data->current_filetype = DIR_BEGINNING;
      data->pexport = NULL;     /* No exportlist is related to pseudo fs */
    }
  else
    {
      /* If data->exportp is null, a junction from pseudo fs was traversed, credp and exportp have to be updated */
      if(data->pexport == NULL)
        {
          if((error = nfs4_SetCompoundExport(data)) != NFS4_OK)
            {
              res_PUTFH4.status = error;
              return res_PUTFH4.status;
            }
        }

      /* Build the pentry */
      if((data->current_entry = nfs_FhandleToCache(NFS_V4,
                                                   NULL,
                                                   NULL,
                                                   &(data->currentFH),
                                                   NULL,
                                                   NULL,
                                                   &(res_PUTFH4.status),
                                                   &attr,
                                                   data->pcontext,
                                                   data->pclient, data->ht, &rc)) == NULL)
        {
          res_PUTFH4.status = NFS4ERR_BADHANDLE;
          return res_PUTFH4.status;
        }

      /* Extract the filetype */
      data->current_filetype = cache_inode_fsal_type_convert(attr.type);

    }

  /* Trace */

  return NFS4_OK;
}                               /* nfs4_op_putfh */
예제 #5
0
int nfs4_op_putrootfh(struct nfs_argop4 *op,
                      compound_data_t * data, struct nfs_resop4 *resp)
{
  int error;

  char __attribute__ ((__unused__)) funcname[] = "nfs4_op_putrootfh";
  char fhstr[LEN_FH_STR];

  /* This NFS4 Operation has no argument, it just get then ROOTFH (replace MOUNTPROC3_MNT) */

  /* First of all, set the reply to zero to make sure it contains no parasite information */
  memset(resp, 0, sizeof(struct nfs_resop4));

  resp->resop = NFS4_OP_PUTROOTFH;
  resp->nfs_resop4_u.opputrootfh.status = NFS4_OK;

  if((error = CreateROOTFH4(&(data->rootFH), data)) != NFS4_OK)
    {
      res_PUTROOTFH4.status = error;
      return res_PUTROOTFH4.status;
    }
  data->current_entry = NULL;   /* No cache inode entry for the directory within pseudo fs */
  data->current_filetype = DIR_BEGINNING;       /* Only directory in the pseudo fs */

  /* I copy the root FH to the currentFH and, if not already done, to the publicFH */
  /* For the moment, I choose to have rootFH = publicFH */
  /* For initial mounted_on_FH, I'll use the rootFH, this will change at junction traversal */
  if(data->currentFH.nfs_fh4_len == 0)
    {
      if((error = nfs4_AllocateFH(&(data->currentFH))) != NFS4_OK)
        {
          resp->nfs_resop4_u.opputrootfh.status = error;
          return error;
        }
    }
  memcpy((char *)(data->currentFH.nfs_fh4_val), (char *)(data->rootFH.nfs_fh4_val),
         data->rootFH.nfs_fh4_len);
  data->currentFH.nfs_fh4_len = data->rootFH.nfs_fh4_len;

  if(data->mounted_on_FH.nfs_fh4_len == 0)
    {
      if((error = nfs4_AllocateFH(&(data->mounted_on_FH))) != NFS4_OK)
        {
          resp->nfs_resop4_u.opputrootfh.status = error;
          return error;
        }
    }
  memcpy((char *)(data->mounted_on_FH.nfs_fh4_val), (char *)(data->rootFH.nfs_fh4_val),
         data->rootFH.nfs_fh4_len);
  data->mounted_on_FH.nfs_fh4_len = data->rootFH.nfs_fh4_len;

  if(data->publicFH.nfs_fh4_len == 0)
    {
      if((error = nfs4_AllocateFH(&(data->publicFH))) != NFS4_OK)
        {
          resp->nfs_resop4_u.opputrootfh.status = error;
          return error;
        }
    }
  /* Copy the data where they are supposed to be */
  memcpy((char *)(data->publicFH.nfs_fh4_val), (char *)(data->rootFH.nfs_fh4_val),
         data->rootFH.nfs_fh4_len);
  data->publicFH.nfs_fh4_len = data->rootFH.nfs_fh4_len;

  /* Test */
  nfs4_sprint_fhandle(&data->rootFH, fhstr);
  LogDebug(COMPONENT_NFS_V4, "NFS4 PUTROOTFH: rootFH=%s", fhstr);
  nfs4_sprint_fhandle(&data->currentFH, fhstr);
  LogDebug(COMPONENT_NFS_V4, "NFS4 PUTROOTFH: currentFH=%s", fhstr);

  LogFullDebug(COMPONENT_NFS_V4,
                    "NFS4 PUTROOTFH: Ending on status %d",
                    resp->nfs_resop4_u.opputrootfh.status);

  return resp->nfs_resop4_u.opputrootfh.status;
}                               /* nfs4_op_putrootfh */
예제 #6
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 */