Exemplo n.º 1
0
fsal_status_t MFSL_setattrs(mfsl_object_t * filehandle, /* IN */
                            fsal_op_context_t * p_context,      /* IN */
                            mfsl_context_t * p_mfsl_context,    /* IN */
                            fsal_attrib_list_t * attrib_set,    /* IN */
                            fsal_attrib_list_t * object_attributes      /* [ IN/OUT ] */
    )
{
  return FSAL_setattrs(&filehandle->handle, p_context, attrib_set, object_attributes);
}                               /* MFSL_setattrs */
Exemplo n.º 2
0
/**
 *
 * MFSL_create_async_op: Callback for asynchronous link. 
 *
 * Callback for asynchronous create. 
 *
 * @param popasyncdes [INOUT] asynchronous operation descriptor
 *
 * @return the status of the performed FSAL_create.
 */
fsal_status_t MFSL_create_async_op(mfsl_async_op_desc_t * popasyncdesc)
{
  fsal_status_t fsal_status;
  fsal_attrib_list_t attrsrc, attrdest, chown_attr;
  fsal_handle_t handle;

  attrsrc = attrdest = popasyncdesc->op_res.mkdir.attr;

  LogDebug(COMPONENT_MFSL,
                  "Renaming file to complete asynchronous FSAL_create for async op %p",
                  popasyncdesc);

  P(popasyncdesc->op_args.create.pmfsl_obj_dirdest->lock);
  fsal_status = FSAL_rename(&dir_handle_precreate,
                            &popasyncdesc->op_args.create.precreate_name,
                            &(popasyncdesc->op_args.create.pmfsl_obj_dirdest->handle),
                            &popasyncdesc->op_args.create.filename,
                            &popasyncdesc->fsal_op_context, &attrsrc, &attrdest);
  if(FSAL_IS_ERROR(fsal_status))
    {
      V(popasyncdesc->op_args.create.pmfsl_obj_dirdest->lock);

      return fsal_status;
    }

  /* Lookup to get the right attributes for the object */
  fsal_status = FSAL_lookup(&(popasyncdesc->op_args.create.pmfsl_obj_dirdest->handle),
                            &popasyncdesc->op_args.create.filename,
                            &popasyncdesc->fsal_op_context,
                            &handle, &popasyncdesc->op_res.create.attr);

  if(FSAL_IS_ERROR(fsal_status))
    {
      V(popasyncdesc->op_args.create.pmfsl_obj_dirdest->lock);

      return fsal_status;
    }

  /* If user is not root, setattr to chown the entry */
  if(popasyncdesc->op_args.create.owner != 0)
    {
      chown_attr.asked_attributes = FSAL_ATTR_MODE | FSAL_ATTR_OWNER | FSAL_ATTR_GROUP;
      chown_attr.mode = popasyncdesc->op_args.create.mode;
      chown_attr.owner = popasyncdesc->op_args.create.owner;
      chown_attr.group = popasyncdesc->op_args.create.group;

      fsal_status =
          FSAL_setattrs(&handle, &popasyncdesc->fsal_op_context, &chown_attr,
                        &popasyncdesc->op_res.create.attr);
    }

  V(popasyncdesc->op_args.create.pmfsl_obj_dirdest->lock);

  return fsal_status;
}                               /* MFSL_create_async_op */
Exemplo n.º 3
0
/**
 *
 * MFSL_setattr_async_op: Callback for asynchronous setattr. 
 *
 * Callback for asynchronous setattr. 
 *
 * @param popasyncdes [INOUT] asynchronous operation descriptor
 *
 * @return the status of the performed FSAL_setattrs.
 */
fsal_status_t MFSL_setattr_async_op(mfsl_async_op_desc_t * popasyncdesc)
{
  fsal_status_t fsal_status;

  LogDebug(COMPONENT_MFSL, "Making asynchronous FSAL_setattrs for async op %p",
                  popasyncdesc);

  P(popasyncdesc->op_args.setattr.pmobject->lock);
  fsal_status = FSAL_setattrs(&(popasyncdesc->op_args.setattr.pmobject->handle),
                              &popasyncdesc->fsal_op_context,
                              &popasyncdesc->op_args.setattr.attr,
                              &popasyncdesc->op_res.setattr.attr);
  V(popasyncdesc->op_args.setattr.pmobject->lock);

  return fsal_status;
}                               /* MFSL_setattr_async_op */
Exemplo n.º 4
0
fsal_status_t MFSL_setattrs(mfsl_object_t * filehandle, /* IN */
                            fsal_op_context_t * p_context,      /* IN */
                            mfsl_context_t * p_mfsl_context,    /* IN */
                            fsal_attrib_list_t * attrib_set,    /* IN */
                            fsal_attrib_list_t * object_attributes,      /* [ IN/OUT ] */
			    void * pextra
    )
{
  struct timeval start, stop, delta ;
  fsal_status_t fsal_status = { ERR_FSAL_NO_ERROR, 0 } ;
  
  gettimeofday( &start, 0 ) ; 
  fsal_status = FSAL_setattrs(&filehandle->handle, p_context, attrib_set, object_attributes);
  gettimeofday( &stop, 0 ) ; 
  delta = mfsl_timer_diff( &stop, &start ) ;
  LogFullDebug( COMPONENT_MFSL, "%s: duration=%ld.%06ld", __FUNCTION__, delta.tv_sec, delta.tv_usec ) ;
  return fsal_status ;
}                               /* MFSL_setattrs */
Exemplo n.º 5
0
/**
 *
 * cache_inode_setattrs: set the attributes for an entry located in the cache by its address. 
 * 
 * Sets the attributes for an entry located in the cache by its address. Attributes are provided 
 * with compliance to the underlying FSAL semantics. Attributes that are set are returned in "*pattr".
 *
 * @param pentry_parent [IN] entry for the parent directory to be managed.
 * @param pattr [INOUT] attributes for the entry that we have found. Out: attributes set.
 * @param ht [INOUT] hash table used for the cache, unused in this call.
 * @param pclient [INOUT] ressource allocated by the client for the nfs management.
 * @param pcontext [IN] FSAL credentials 
 * @param pstatus [OUT] returned status.
 * 
 * @return CACHE_INODE_SUCCESS if operation is a success \n
 * @return CACHE_INODE_LRU_ERROR if allocation error occured when validating the entry
 *
 */
cache_inode_status_t cache_inode_setattr(cache_entry_t * pentry, fsal_attrib_list_t * pattr, hash_table_t * ht, /* Unused, kept for protototype's homogeneity */
                                         cache_inode_client_t * pclient,
                                         fsal_op_context_t * pcontext,
                                         cache_inode_status_t * pstatus)
{
  fsal_handle_t *pfsal_handle = NULL;
  fsal_status_t fsal_status;
  fsal_attrib_list_t *p_object_attributes = NULL;
  fsal_attrib_list_t result_attributes;
  fsal_attrib_list_t truncate_attributes;

  /* Set the return default to CACHE_INODE_SUCCESS */
  *pstatus = CACHE_INODE_SUCCESS;

  /* stat */
  pclient->stat.nb_call_total += 1;
  pclient->stat.func_stats.nb_call[CACHE_INODE_SETATTR] += 1;

  /* Lock the entry */
  P_w(&pentry->lock);

  switch (pentry->internal_md.type)
    {
    case REGULAR_FILE:
      pfsal_handle = &pentry->object.file.handle;
      break;

    case SYMBOLIC_LINK:
      assert(pentry->object.symlink);
      pfsal_handle = &pentry->object.symlink->handle;
      break;

    case FS_JUNCTION:
    case DIRECTORY:
      pfsal_handle = &pentry->object.dir.handle;
      break;

    case CHARACTER_FILE:
    case BLOCK_FILE:
    case SOCKET_FILE:
    case FIFO_FILE:
      pfsal_handle = &pentry->object.special_obj.handle;
      break;

    case UNASSIGNED:
    case RECYCLED:
      LogCrit(COMPONENT_CACHE_INODE,
              "WARNING: unknown source pentry type: internal_md.type=%d, line %d in file %s",
              pentry->internal_md.type, __LINE__, __FILE__);
      *pstatus = CACHE_INODE_BAD_TYPE;
      return *pstatus;
    }

  /* Call FSAL to set the attributes */
  /* result_attributes.asked_attributes = pattr->asked_attributes ; */

  /* mod Th.Leibovici on 2006/02/13
   * We ask back all standard attributes, in case they have been modified
   * by another program (pftp, rcpd...)
   */

  memset(&result_attributes, 0, sizeof(fsal_attrib_list_t));
  result_attributes.asked_attributes = pclient->attrmask;
  /* end of mod */

#ifdef _USE_MFSL
  fsal_status =
      MFSL_setattrs(&pentry->mobject, pcontext, &pclient->mfsl_context, pattr,
                    &result_attributes, NULL);
#else
  fsal_status = FSAL_setattrs(pfsal_handle, pcontext, pattr, &result_attributes);
#endif
  if(FSAL_IS_ERROR(fsal_status))
    {
      *pstatus = cache_inode_error_convert(fsal_status);
      V_w(&pentry->lock);

      /* stat */
      pclient->stat.func_stats.nb_err_unrecover[CACHE_INODE_SETATTR] += 1;

      if(fsal_status.major == ERR_FSAL_STALE)
        {
          cache_inode_status_t kill_status;

          LogEvent(COMPONENT_CACHE_INODE,
                   "cache_inode_setattr: Stale FSAL File Handle detected for pentry = %p",
                   pentry);

          if(cache_inode_kill_entry(pentry, NO_LOCK, ht, pclient, &kill_status) !=
             CACHE_INODE_SUCCESS)
            LogCrit(COMPONENT_CACHE_INODE,
                    "cache_inode_setattr: Could not kill entry %p, status = %u",
                    pentry, kill_status);

          *pstatus = CACHE_INODE_FSAL_ESTALE;
        }

      return *pstatus;
    }

  if(pattr->asked_attributes & FSAL_ATTR_SIZE)
    {
      truncate_attributes.asked_attributes = pclient->attrmask;

      fsal_status = FSAL_truncate(pfsal_handle,
                                  pcontext, pattr->filesize, NULL, &truncate_attributes);
      if(FSAL_IS_ERROR(fsal_status))
        {
          *pstatus = cache_inode_error_convert(fsal_status);
          V_w(&pentry->lock);

          /* stat */
          pclient->stat.func_stats.nb_err_unrecover[CACHE_INODE_SETATTR] += 1;

          if(fsal_status.major == ERR_FSAL_STALE)
            {
              cache_inode_status_t kill_status;

              LogEvent(COMPONENT_CACHE_INODE,
                       "cache_inode_setattr: Stale FSAL File Handle detected for pentry = %p",
                       pentry);

              if(cache_inode_kill_entry(pentry, NO_LOCK, ht, pclient, &kill_status) !=
                 CACHE_INODE_SUCCESS)
                LogCrit(COMPONENT_CACHE_INODE,
                        "cache_inode_setattr: Could not kill entry %p, status = %u",
                        pentry, kill_status);

              *pstatus = CACHE_INODE_FSAL_ESTALE;
            }

          return *pstatus;
        }

    }

  /* Keep the new attribute in cache */
  switch (pentry->internal_md.type)
    {
    case REGULAR_FILE:
      p_object_attributes = &(pentry->object.file.attributes);
      break;

    case SYMBOLIC_LINK:
      assert(pentry->object.symlink);
      p_object_attributes = &(pentry->object.symlink->attributes);
      break;

    case FS_JUNCTION:
    case DIRECTORY:
      p_object_attributes = &(pentry->object.dir.attributes);
      break;

    case CHARACTER_FILE:
    case BLOCK_FILE:
    case SOCKET_FILE:
    case FIFO_FILE:
      p_object_attributes = &(pentry->object.special_obj.attributes);
      break;

    case UNASSIGNED:
    case RECYCLED:
      LogCrit(COMPONENT_CACHE_INODE,
              "WARNING: unknown source pentry type: internal_md.type=%d, line %d in file %s",
              pentry->internal_md.type, __LINE__, __FILE__);
      *pstatus = CACHE_INODE_BAD_TYPE;
      return *pstatus;
    }

  /* Update the cached attributes */
  if((result_attributes.asked_attributes & FSAL_ATTR_SIZE) ||
     (result_attributes.asked_attributes & FSAL_ATTR_SPACEUSED))
    {

      if(pentry->internal_md.type == REGULAR_FILE)
        {
          if(pentry->object.file.pentry_content == NULL)
            {
              /* Operation on a non data cached file */
              p_object_attributes->filesize = result_attributes.filesize;
              p_object_attributes->spaceused = result_attributes.filesize;      /* Unclear hook here. BUGAZOMEU */
            }
          else
            {
              /* Data cached file */
              /* Do not set the p_object_attributes->filesize and p_object_attributes->spaceused  in this case 
               * This will lead to a situation where (for example) untar-ing a file will produced invalid files 
               * with a size of 0 despite the fact that they are not empty */

              LogFullDebug(COMPONENT_CACHE_INODE,
                           "cache_inode_setattr with FSAL_ATTR_SIZE on data cached entry");
            }
        }
      else if(pattr->asked_attributes & FSAL_ATTR_SIZE)
        LogCrit(COMPONENT_CACHE_INODE,
                "WARNING !!! cache_inode_setattr tried to set size on a non REGULAR_FILE type=%d",
                pentry->internal_md.type);
    }

  if(result_attributes.asked_attributes &
     (FSAL_ATTR_MODE | FSAL_ATTR_OWNER | FSAL_ATTR_GROUP))
    {
      if(result_attributes.asked_attributes & FSAL_ATTR_MODE)
        p_object_attributes->mode = result_attributes.mode;

      if(result_attributes.asked_attributes & FSAL_ATTR_OWNER)
        p_object_attributes->owner = result_attributes.owner;

      if(result_attributes.asked_attributes & FSAL_ATTR_GROUP)
        p_object_attributes->group = result_attributes.group;
    }

  if(result_attributes.asked_attributes &
     (FSAL_ATTR_ATIME | FSAL_ATTR_CTIME | FSAL_ATTR_MTIME))
    {
      if(result_attributes.asked_attributes & FSAL_ATTR_ATIME)
        p_object_attributes->atime = result_attributes.atime;

      if(result_attributes.asked_attributes & FSAL_ATTR_CTIME)
        p_object_attributes->ctime = result_attributes.ctime;

      if(result_attributes.asked_attributes & FSAL_ATTR_MTIME)
        p_object_attributes->mtime = result_attributes.mtime;
    }
  
#ifdef _USE_NFS4_ACL
  if(result_attributes.asked_attributes & FSAL_ATTR_ACL)
    {
      LogDebug(COMPONENT_CACHE_INODE, "cache_inode_setattr: old acl = %p, new acl = %p",
               p_object_attributes->acl, result_attributes.acl);

      /* Release previous acl entry. */
      if(p_object_attributes->acl)
        {
          fsal_acl_status_t status;
          nfs4_acl_release_entry(p_object_attributes->acl, &status);
          if(status != NFS_V4_ACL_SUCCESS)
            LogEvent(COMPONENT_CACHE_INODE, "cache_inode_setattr: Failed to release old acl:"
                     " status = %d", status);
        }

      /* Update with new acl entry. */
      p_object_attributes->acl = result_attributes.acl;
    }
#endif                          /* _USE_NFS4_ACL */

  /* Return the attributes as set */
  *pattr = *p_object_attributes;

  /* validate the entry */
  *pstatus = cache_inode_valid(pentry, CACHE_INODE_OP_SET, pclient);

  /* Release the entry */
  V_w(&pentry->lock);

  /* stat */
  if(*pstatus != CACHE_INODE_SUCCESS)
    pclient->stat.func_stats.nb_err_retryable[CACHE_INODE_SETATTR] += 1;
  else
    pclient->stat.func_stats.nb_success[CACHE_INODE_SETATTR] += 1;

  return *pstatus;
}                               /* cache_inode_setattr */
Exemplo n.º 6
0
cache_inode_status_t
cache_inode_setattr(cache_entry_t *entry,
                    fsal_attrib_list_t *attr,
                    fsal_op_context_t *context,
                    int is_open_write,
                    cache_inode_status_t *status)
{
     fsal_status_t fsal_status = {0, 0};
     int           got_content_lock = FALSE;
#ifdef _USE_NFS4_ACL
     fsal_acl_t *saved_acl = NULL;
     fsal_acl_status_t acl_status = 0;
#endif /* _USE_NFS4_ACL */

     if ((entry->type == UNASSIGNED) ||
         (entry->type == RECYCLED)) {
          LogWarn(COMPONENT_CACHE_INODE,
                  "WARNING: unknown source entry type: type=%d, "
                  "line %d in file %s", entry->type, __LINE__, __FILE__);
          *status = CACHE_INODE_BAD_TYPE;
          goto out;
     }

     if ((attr->asked_attributes & FSAL_ATTR_SIZE) &&
         (entry->type != REGULAR_FILE)) {
          LogWarn(COMPONENT_CACHE_INODE,
                   "Attempt to truncate non-regular file: type=%d",
                   entry->type);
          *status = CACHE_INODE_BAD_TYPE;
          goto out;
     }

     /* Get wrlock on attr_lock and verify attrs */
     *status = cache_inode_lock_trust_attrs(entry, context, TRUE);
     if(*status != CACHE_INODE_SUCCESS)
       return *status;

     /* Do permission checks */
     if(cache_inode_check_setattr_perms(entry,
                                        attr,
                                        context,
                                        is_open_write,
                                        status) != CACHE_INODE_SUCCESS)
       {
         goto unlock;
       }

     if (attr->asked_attributes & FSAL_ATTR_SIZE) {
          PTHREAD_RWLOCK_WRLOCK(&entry->content_lock);
          got_content_lock = TRUE;
     }

#ifdef _USE_NFS4_ACL
     saved_acl = entry->attributes.acl;
#endif /* _USE_NFS4_ACL */
     fsal_status = FSAL_setattrs(&entry->handle, context, attr,
                                 &entry->attributes);
     if (FSAL_IS_ERROR(fsal_status)) {
          *status = cache_inode_error_convert(fsal_status);
          if (fsal_status.major == ERR_FSAL_STALE) {
               LogEvent(COMPONENT_CACHE_INODE,
                       "FSAL returned STALE from setattrs");
               cache_inode_kill_entry(entry);
          }
          goto unlock;
     } else {
#ifdef _USE_NFS4_ACL
          /* Decrement refcount on saved ACL */
         nfs4_acl_release_entry(saved_acl, &acl_status);
         if (acl_status != NFS_V4_ACL_SUCCESS) {
              LogCrit(COMPONENT_CACHE_INODE,
                      "Failed to release old acl, status=%d",
                      acl_status);
         }
#endif /* _USE_NFS4_ACL */
     }

     cache_inode_fixup_md(entry);
     /* Copy the complete set of new attributes out. */

     *attr = entry->attributes;
     set_mounted_on_fileid(entry, attr, context->export_context->fe_export);

     *status = CACHE_INODE_SUCCESS;

unlock:
     if(got_content_lock) {
          PTHREAD_RWLOCK_UNLOCK(&entry->content_lock);
     }
     PTHREAD_RWLOCK_UNLOCK(&entry->attr_lock);

out:

     return *status;
} /* cache_inode_setattr */