コード例 #1
0
/**
 *
 * proxy_Fattr_To_FSAL_attr: Converts NFSv4 attributes buffer to a FSAL attributes structure.
 *
 * Converts NFSv4 attributes buffer to a FSAL attributes structure.
 *
 * @param pFSAL_attr [OUT]  pointer to FSAL attributes.
 * @param Fattr      [IN] pointer to NFSv4 attributes.
 *
 * @return 1 if successful, 0 if not supported, -1 if argument is badly formed
 *
 */
int proxy_Fattr_To_FSAL_attr(fsal_attrib_list_t * pFSAL_attr,
                             proxyfsal_handle_t * phandle, fattr4 * Fattr)
{
  nfs_fh4 hdl4;

  if (Fattr4_To_FSAL_attr(pFSAL_attr, Fattr, &hdl4) != NFS4_OK)
      return -1;

  return fsal_internal_proxy_create_fh(&hdl4, pFSAL_attr->type, pFSAL_attr->fileid,
                                      (fsal_handle_t *)phandle);
}                               /* proxy_Fattr_To_FSAL_attr */
コード例 #2
0
ファイル: fsal_proxy_internal.c プロジェクト: ic-hep/emi3
/**
 *
 * proxy_Fattr_To_FSAL_attr: Converts NFSv4 attributes buffer to a FSAL attributes structure.
 *
 * Converts NFSv4 attributes buffer to a FSAL attributes structure.
 *
 * @param pFSAL_attr [OUT]  pointer to FSAL attributes.
 * @param Fattr      [IN] pointer to NFSv4 attributes.
 *
 * @return 1 if successful, 0 if not supported, -1 if argument is badly formed
 *
 */
int proxy_Fattr_To_FSAL_attr(fsal_attrib_list_t * pFSAL_attr,
                             proxyfsal_handle_t * phandle, fattr4 * Fattr)
{
  u_int LastOffset = 0;
  unsigned int i = 0;
  char __attribute__ ((__unused__)) funcname[] = "proxy_Fattr_To_FSAL_attr";
  uint32_t attrmasklist[FATTR4_MOUNTED_ON_FILEID];      /* List cannot be longer than FATTR4_MOUNTED_ON_FILEID */
  uint32_t attrmasklen = 0;
  uint32_t attribute_to_set = 0;

  int len;
  char buffer[MAXNAMLEN];
  utf8string utf8buffer;

  fattr4_type attr_type;
  fattr4_fsid attr_fsid;
  fattr4_fileid attr_fileid;
  fattr4_time_modify_set attr_time_set;
  fattr4_rdattr_error rdattr_error;
  nfstime4 attr_time;
  fattr4_size attr_size;
  fattr4_change attr_change;
  fattr4_numlinks attr_numlinks;
  fattr4_rawdev attr_rawdev;
  fattr4_space_used attr_space_used;
  fattr4_time_access attr_time_access;
  fattr4_time_modify attr_time_modify;
  fattr4_time_metadata attr_time_metadata;

  nfs_fh4 nfshandle;
  bool_t compute_fh = FALSE;

  if(pFSAL_attr == NULL || Fattr == NULL)
    return -1;

  /* Check attributes data */
  if(Fattr->attr_vals.attrlist4_val == NULL)
    return -1;

  /* Convert the attribute bitmap to an attribute list */
  nfs4_bitmap4_to_list(&(Fattr->attrmask), &attrmasklen, attrmasklist);

  LogFullDebug(COMPONENT_NFS_V4, "nfs4_bitmap4_to_list ====> attrmasklen = %d\n", attrmasklen);

  /* Init */
  pFSAL_attr->asked_attributes = 0;

  for(i = 0; i < attrmasklen; i++)
    {
      attribute_to_set = attrmasklist[i];

      if(attrmasklist[i] > FATTR4_MOUNTED_ON_FILEID)
        {
          /* Erroneous value... skip */
          continue;
        }
      LogFullDebug(COMPONENT_NFS_V4, "=================> nfs4_Fattr_To_FSAL_attr: i=%u attr=%u\n", i,
             attrmasklist[i]);
      LogFullDebug(COMPONENT_NFS_V4, "Flag for Operation = %d|%d is ON,  name  = %s  reply_size = %d\n",
             attrmasklist[i], fattr4tab[attribute_to_set].val,
             fattr4tab[attribute_to_set].name, fattr4tab[attribute_to_set].size_fattr4);

      switch (attribute_to_set)
        {
        case FATTR4_TYPE:      /* Used only by FSAL_PROXY to reverse convert */
          memcpy((char *)&attr_type,
                 (char *)(Fattr->attr_vals.attrlist4_val + LastOffset),
                 sizeof(fattr4_type));

          switch (ntohl(attr_type))
            {
            case NF4REG:
              pFSAL_attr->type = FSAL_TYPE_FILE;
              break;

            case NF4DIR:
              pFSAL_attr->type = FSAL_TYPE_DIR;
              break;

            case NF4BLK:
              pFSAL_attr->type = FSAL_TYPE_BLK;
              break;

            case NF4CHR:
              pFSAL_attr->type = FSAL_TYPE_CHR;
              break;

            case NF4LNK:
              pFSAL_attr->type = FSAL_TYPE_LNK;
              break;

            case NF4SOCK:
              pFSAL_attr->type = FSAL_TYPE_SOCK;
              break;

            case NF4FIFO:
              pFSAL_attr->type = FSAL_TYPE_FIFO;
              break;

            default:           /* For wanting of a better solution */
              pFSAL_attr->type = 0;
              break;
            }                   /* switch( pattr->type ) */

          pFSAL_attr->asked_attributes |= FSAL_ATTR_TYPE;
          LastOffset += fattr4tab[attribute_to_set].size_fattr4;
          LogFullDebug(COMPONENT_NFS_V4, "SATTR: On voit le type %d\n", (int)pFSAL_attr->filesize);
          break;

        case FATTR4_FILEID:    /* Used only by FSAL_PROXY to reverse convert */
          /* The analog to the inode number. RFC3530 says "a number uniquely identifying the file within the filesystem"
           * I use hpss_GetObjId to extract this information from the Name Server's handle */
          memcpy((char *)&attr_fileid,
                 (char *)(Fattr->attr_vals.attrlist4_val + LastOffset),
                 sizeof(fattr4_fileid));
          pFSAL_attr->fileid = nfs_ntohl64(attr_fileid);

          pFSAL_attr->asked_attributes |= FSAL_ATTR_FILEID;
          LastOffset += fattr4tab[attribute_to_set].size_fattr4;

          break;

        case FATTR4_FSID:      /* Used only by FSAL_PROXY to reverse convert */
          memcpy((char *)&attr_fsid,
                 (char *)(Fattr->attr_vals.attrlist4_val + LastOffset),
                 sizeof(fattr4_fsid));
          pFSAL_attr->fsid.major = nfs_ntohl64(attr_fsid.major);
          pFSAL_attr->fsid.minor = nfs_ntohl64(attr_fsid.minor);

          pFSAL_attr->asked_attributes |= FSAL_ATTR_FSID;
          LastOffset += fattr4tab[attribute_to_set].size_fattr4;

          break;

        case FATTR4_NUMLINKS:  /* Used only by FSAL_PROXY to reverse convert */
          memcpy((char *)&attr_numlinks,
                 (char *)(Fattr->attr_vals.attrlist4_val + LastOffset),
                 sizeof(fattr4_numlinks));
          pFSAL_attr->numlinks = ntohl(attr_numlinks);

          pFSAL_attr->asked_attributes |= FSAL_ATTR_FILEID;
          LastOffset += fattr4tab[attribute_to_set].size_fattr4;

          break;

        case FATTR4_SIZE:
          memcpy((char *)&attr_size,
                 (char *)(Fattr->attr_vals.attrlist4_val + LastOffset),
                 sizeof(fattr4_size));

          /* Do not forget the XDR marshalling for the fattr4 stuff */
          pFSAL_attr->filesize = nfs_ntohl64(attr_size);

          pFSAL_attr->asked_attributes |= FSAL_ATTR_SIZE;
          LastOffset += fattr4tab[attribute_to_set].size_fattr4;
          LogFullDebug(COMPONENT_NFS_V4, "SATTR: On voit la taille %d\n", (int)pFSAL_attr->filesize);
          break;

        case FATTR4_MODE:
          memcpy((char *)&(pFSAL_attr->mode),
                 (char *)(Fattr->attr_vals.attrlist4_val + LastOffset),
                 sizeof(fattr4_mode));

          /* Do not forget the XDR marshalling for the fattr4 stuff */
          pFSAL_attr->mode = ntohl(pFSAL_attr->mode);

          pFSAL_attr->asked_attributes |= FSAL_ATTR_MODE;
          LastOffset += fattr4tab[attribute_to_set].size_fattr4;
          LogFullDebug(COMPONENT_NFS_V4, "SATTR: On voit le mode 0%o\n", pFSAL_attr->mode);
          break;

        case FATTR4_OWNER:
          memcpy(&len, (char *)(Fattr->attr_vals.attrlist4_val + LastOffset),
                 sizeof(u_int));
          len = ntohl(len);     /* xdr marshalling on fattr4 */
          LastOffset += sizeof(u_int);

          memcpy(buffer, (char *)(Fattr->attr_vals.attrlist4_val + LastOffset), len);
          buffer[len] = '\0';

          /* Do not forget that xdr_opaque are aligned on 32bit long words */
          while((len % 4) != 0)
            len += 1;

          LastOffset += len;

          utf8buffer.utf8string_val = buffer;
          utf8buffer.utf8string_len = strlen(buffer);

          utf82uid(&utf8buffer, &(pFSAL_attr->owner));
          pFSAL_attr->asked_attributes |= FSAL_ATTR_OWNER;

          LogFullDebug(COMPONENT_NFS_V4, "SATTR: On voit le owner %s len = %d\n", buffer, len);
          LogFullDebug(COMPONENT_NFS_V4, "SATTR: On voit le owner %d\n", pFSAL_attr->owner);

          break;

        case FATTR4_OWNER_GROUP:
          memcpy(&len, (char *)(Fattr->attr_vals.attrlist4_val + LastOffset),
                 sizeof(u_int));
          len = ntohl(len);
          LastOffset += sizeof(u_int);

          memcpy(buffer, (char *)(Fattr->attr_vals.attrlist4_val + LastOffset), len);
          buffer[len] = '\0';

          /* Do not forget that xdr_opaque are aligned on 32bit long words */
          while((len % 4) != 0)
            len += 1;

          LastOffset += len;

          utf8buffer.utf8string_val = buffer;
          utf8buffer.utf8string_len = strlen(buffer);

          utf82gid(&utf8buffer, &(pFSAL_attr->group));
          pFSAL_attr->asked_attributes |= FSAL_ATTR_GROUP;

          LogFullDebug(COMPONENT_NFS_V4, "SATTR: On voit le owner_group %s len = %d\n", buffer, len);
          LogFullDebug(COMPONENT_NFS_V4, "SATTR: On voit le owner_group %d\n", pFSAL_attr->group);

          break;

        case FATTR4_CHANGE:
          memcpy((char *)&attr_change,
                 (char *)(Fattr->attr_vals.attrlist4_val + LastOffset),
                 sizeof(fattr4_change));
          pFSAL_attr->chgtime.seconds = (uint32_t) nfs_ntohl64(attr_change);
          pFSAL_attr->chgtime.nseconds = 0;

          pFSAL_attr->change = nfs_ntohl64(attr_change);

          pFSAL_attr->asked_attributes |= FSAL_ATTR_CHGTIME;
          pFSAL_attr->asked_attributes |= FSAL_ATTR_CHANGE;
          LastOffset += fattr4tab[attribute_to_set].size_fattr4;

          break;

        case FATTR4_RAWDEV:    /* Used only by FSAL_PROXY to reverse convert */
          memcpy((char *)&attr_rawdev,
                 (char *)(Fattr->attr_vals.attrlist4_val + LastOffset),
                 sizeof(fattr4_rawdev));
          pFSAL_attr->rawdev.major = (uint32_t) nfs_ntohl64(attr_rawdev.specdata1);
          pFSAL_attr->rawdev.minor = (uint32_t) nfs_ntohl64(attr_rawdev.specdata2);

          pFSAL_attr->asked_attributes |= FSAL_ATTR_RAWDEV;
          LastOffset += fattr4tab[attribute_to_set].size_fattr4;

          break;

        case FATTR4_SPACE_USED:        /* Used only by FSAL_PROXY to reverse convert */
          memcpy((char *)&attr_space_used,
                 (char *)(Fattr->attr_vals.attrlist4_val + LastOffset),
                 sizeof(fattr4_space_used));
          pFSAL_attr->spaceused = (uint32_t) nfs_ntohl64(attr_space_used);

          pFSAL_attr->asked_attributes |= FSAL_ATTR_SPACEUSED;
          LastOffset += fattr4tab[attribute_to_set].size_fattr4;

          break;

        case FATTR4_TIME_ACCESS:       /* Used only by FSAL_PROXY to reverse convert */
          memcpy((char *)&attr_time_access.seconds,
                 (char *)(Fattr->attr_vals.attrlist4_val + LastOffset),
                 sizeof(uint64_t));
          LastOffset += sizeof( uint64_t ) ;

          memcpy((char *)&attr_time_access.nseconds,
                 (char *)(Fattr->attr_vals.attrlist4_val + LastOffset),
                 sizeof(uint32_t));
          LastOffset += sizeof( uint32_t ) ;

          pFSAL_attr->atime.seconds = (uint32_t) nfs_ntohl64(attr_time_access.seconds);
          pFSAL_attr->atime.nseconds = (uint32_t) ntohl(attr_time_access.nseconds);

          pFSAL_attr->asked_attributes |= FSAL_ATTR_ATIME;
          break;

        case FATTR4_TIME_METADATA:     /* Used only by FSAL_PROXY to reverse convert */
          memcpy((char *)&attr_time_metadata.seconds,
                 (char *)(Fattr->attr_vals.attrlist4_val + LastOffset),
                 sizeof(uint64_t));
          LastOffset += sizeof( uint64_t ) ;

          memcpy((char *)&attr_time_metadata.nseconds,
                 (char *)(Fattr->attr_vals.attrlist4_val + LastOffset),
                 sizeof(uint32_t));
          LastOffset += sizeof( uint32_t ) ;

          pFSAL_attr->ctime.seconds = (uint32_t) nfs_ntohl64(attr_time_metadata.seconds);
          pFSAL_attr->ctime.nseconds = (uint32_t) ntohl(attr_time_metadata.nseconds);

          pFSAL_attr->asked_attributes |= FSAL_ATTR_CTIME;
          break;

        case FATTR4_TIME_MODIFY:       /* Used only by FSAL_PROXY to reverse convert */
	  memcpy( (char *)&attr_time_modify.seconds,
	          (char *)(Fattr->attr_vals.attrlist4_val + LastOffset),
                  sizeof( uint64_t ) );
          LastOffset += sizeof( uint64_t ) ;

          memcpy((char *)&attr_time_modify.nseconds,
                 (char *)(Fattr->attr_vals.attrlist4_val + LastOffset),
                 sizeof(uint32_t) );
          LastOffset += sizeof( uint32_t ) ;

          pFSAL_attr->mtime.seconds = (uint32_t) nfs_ntohl64(attr_time_modify.seconds);
          pFSAL_attr->mtime.nseconds = (uint32_t) ntohl(attr_time_modify.nseconds);

          pFSAL_attr->asked_attributes |= FSAL_ATTR_MTIME;
          break;

        case FATTR4_TIME_ACCESS_SET:
          memcpy((char *)&attr_time_set,
                 (char *)(Fattr->attr_vals.attrlist4_val + LastOffset),
                 sizeof(fattr4_time_access_set));

          if(ntohl(attr_time_set.set_it) == SET_TO_SERVER_TIME4)
            {
              pFSAL_attr->atime.seconds = time(NULL);   /* Use current server's time */
              pFSAL_attr->atime.nseconds = 0;
            }
          else
            {
              /* Take care of XDR when dealing with fattr4 */
              attr_time = attr_time_set.settime4_u.time;
              attr_time.seconds = nfs_ntohl64(attr_time.seconds);
              attr_time.nseconds = ntohl(attr_time.nseconds);

              pFSAL_attr->atime.seconds = attr_time.seconds;
              pFSAL_attr->atime.nseconds = attr_time.nseconds;
            }
          pFSAL_attr->asked_attributes |= FSAL_ATTR_ATIME;
          LastOffset += fattr4tab[attribute_to_set].size_fattr4;

          break;

        case FATTR4_TIME_MODIFY_SET:
          memcpy((char *)&attr_time,
                 (char *)(Fattr->attr_vals.attrlist4_val + LastOffset),
                 sizeof(fattr4_time_modify_set));

          if(ntohl(attr_time_set.set_it) == SET_TO_SERVER_TIME4)
            {
              pFSAL_attr->mtime.seconds = time(NULL);   /* Use current server's time */
              pFSAL_attr->mtime.nseconds = 0;
            }
          else
            {
              /* Take care of XDR when dealing with fattr4 */
              attr_time = attr_time_set.settime4_u.time;
              attr_time.seconds = nfs_ntohl64(attr_time.seconds);
              attr_time.nseconds = ntohl(attr_time.nseconds);

              pFSAL_attr->mtime.seconds = attr_time.seconds;
              pFSAL_attr->mtime.nseconds = attr_time.nseconds;
            }

          pFSAL_attr->asked_attributes |= FSAL_ATTR_MTIME;
          LastOffset += fattr4tab[attribute_to_set].size_fattr4;

          break;

        case FATTR4_FILEHANDLE:
          memcpy(&len, (char *)(Fattr->attr_vals.attrlist4_val + LastOffset),
                 sizeof(u_int));
          len = ntohl(len);
          LastOffset += sizeof(u_int);

          /* Extract the file handle */
          nfshandle.nfs_fh4_len = len;
          nfshandle.nfs_fh4_val = (char *)(Fattr->attr_vals.attrlist4_val + LastOffset);

          /* Bogus there: FATTR4_FILEHANDLE = 19 < FATTR4_FILEID = 20... This means that the FH is
           * is processed BEFORE the fileid. At this point, pFSAL_attr->fileid has not yet been set
           * and has the value 0. A flag is kept in variable compute_fh to add the fileid later */
          fsal_internal_proxy_create_fh(&nfshandle, pFSAL_attr->type, pFSAL_attr->fileid,
                                        phandle);

          LastOffset += len;
          LogFullDebug(COMPONENT_NFS_V4, "SATTR: On a demande le filehandle len =%u\n", len);
          compute_fh = TRUE;
          break;

        case FATTR4_RDATTR_ERROR:
          memcpy((char *)&rdattr_error,
                 (char *)(Fattr->attr_vals.attrlist4_val + LastOffset),
                 sizeof(fattr4_rdattr_error));
          rdattr_error = ntohl(rdattr_error);
          LastOffset += fattr4tab[attribute_to_set].size_fattr4;

          break;

        default:
          LogFullDebug(COMPONENT_NFS_V4, "SATTR: Attribut no supporte %d name=%s\n", attribute_to_set,
                 fattr4tab[attribute_to_set].name);
          LastOffset += fattr4tab[attribute_to_set].size_fattr4;
          /* return 0 ; *//* Should not stop processing */
          break;
        }                       /* switch */
    }                           /* for */

  if(compute_fh)
    {
      phandle->data.fileid4 = pFSAL_attr->fileid;
    }
  return 1;
}                               /* proxy_Fattr_To_FSAL_attr */
コード例 #3
0
ファイル: fsal_lookup.c プロジェクト: chandra2/nfs-ganesha
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);

}
コード例 #4
0
ファイル: fsal_tools.c プロジェクト: jordan-dlh/nfs-ganesha
/**
 * FSAL_ExpandHandle :
 *  Convert a buffer extracted from NFS handles
 *  to an FSAL handle.
 *
 * \param in_type (input):
 *        Indicates the type of digest to be expanded.
 * \param in_buff (input):
 *        Pointer to the digest to be expanded.
 * \param out_fsal_handle (output):
 *        The handle built from digest.
 *
 * \return The major code is ERR_FSAL_NO_ERROR is no error occured.
 *         Else, it is a non null value.
 */
fsal_status_t PROXYFSAL_ExpandHandle(proxyfsal_export_context_t * p_expcontext, /* IN */
                                     fsal_digesttype_t in_type, /* IN */
                                     caddr_t in_buff,   /* IN */
                                     proxyfsal_handle_t * out_fsal_handle       /* OUT */
    )
{
  fsal_nodetype_t nodetype;
  fsal_u64_t fileid;
  nfs_fh4 nfs4fh;
#ifdef _HANDLE_MAPPING
  nfs23_map_handle_t map_hdl;
  proxyfsal_handle_t tmp_hdl;
  int rc;
#endif

  /* sanity checks */
  if(!out_fsal_handle || !in_buff || !p_expcontext)
    ReturnCode(ERR_FSAL_FAULT, 0);

  switch (in_type)
    {

    case FSAL_DIGEST_NFSV2:
    case FSAL_DIGEST_NFSV3:

#ifdef _HANDLE_MAPPING
      if(!global_fsal_proxy_specific_info.enable_handle_mapping)
        ReturnCode(ERR_FSAL_NOTSUPP, 0);

      /* retrieve significant info */
      memcpy(&map_hdl, in_buff, sizeof(nfs23_map_handle_t));

      rc = HandleMap_GetFH(&map_hdl, &tmp_hdl);

      if(isFullDebug(COMPONENT_FSAL))
        {
          if(rc == HANDLEMAP_STALE)
            LogFullDebug(COMPONENT_FSAL, "File id=%llu : HandleMap_GetFH returns HANDLEMAP_STALE\n",
                         map_hdl.object_id);
          else if(rc == 0)
            LogFullDebug(COMPONENT_FSAL, "File id=%llu : HandleMap_GetFH returns HANDLEMAP_SUCCESS\n",
                         map_hdl.object_id);
          else
            LogFullDebug(COMPONENT_FSAL, "File id=%llu : HandleMap_GetFH returns error %d\n",
                         map_hdl.object_id, rc);
        }

      if(rc == HANDLEMAP_STALE)
        ReturnCode(ERR_FSAL_STALE, rc);
      else if(rc != 0)
        ReturnCode(ERR_FSAL_SERVERFAULT, rc);

      /* The fsal_handle we get may not be up-to-date
       * so we pass an extract of its content to fsal_internal_proxy_create_fh()
       */
      fsal_internal_proxy_extract_fh(&nfs4fh, &tmp_hdl);

      if(fsal_internal_proxy_create_fh
         (&nfs4fh, tmp_hdl.data.object_type_reminder, tmp_hdl.data.fileid4,
          out_fsal_handle) != TRUE)
        ReturnCode(ERR_FSAL_FAULT, 0);

#else
      /* Proxy works only on NFSv4 requests */
      ReturnCode(ERR_FSAL_NOTSUPP, 0);
#endif
      break;

    case FSAL_DIGEST_NFSV4:
      /* take the file id */
      memcpy((char *)&fileid, in_buff, sizeof(fsal_u64_t));

      /* Keep  the type of then object at the beginning */
      memcpy((char *)&nodetype, (char *)(in_buff + sizeof(fsal_u64_t)),
             sizeof(unsigned int));

      /* Then the len of the file handle */
      memcpy((char *)&(nfs4fh.nfs_fh4_len),
             (char *)(in_buff + sizeof(fsal_u64_t) + sizeof(unsigned int)),
             sizeof(unsigned int));

      /* Then keep the value of the buff */
      nfs4fh.nfs_fh4_val =
          (char *)(in_buff + sizeof(fsal_u64_t) + 2 * sizeof(unsigned int));

      if(fsal_internal_proxy_create_fh(&nfs4fh, nodetype, fileid, out_fsal_handle) !=
         TRUE)
        ReturnCode(ERR_FSAL_FAULT, 0);

      break;

    default:
      /* Invalid input digest type. */
      ReturnCode(ERR_FSAL_INVAL, 0);
    }

  ReturnCode(ERR_FSAL_NO_ERROR, 0);
}
コード例 #5
0
ファイル: fsal_symlinks.c プロジェクト: ic-hep/emi3
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);
}
コード例 #6
0
ファイル: fsal_create.c プロジェクト: alangenfeld/cloud-nfs
/**
 * 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 */