Beispiel #1
0
/**
 * Get status of entry regarding 'shook' system
 * and convert it to robinhood status.
 * @return 0 on success, <0 on error.
 */
int ShookGetStatus(const char *path, file_status_t *p_status)
{
    shook_state st;
    int rc;

    if (shook_get_status(path, &st, FALSE) != 0) {
        rc = -errno;
        DisplayLog(LVL_CRIT, SHOOK_TAG, "ERROR getting state of %s: %s",
                   path, strerror(-rc));
        return rc;
    }

    if (st != SS_ONLINE)
        DisplayLog(LVL_FULL, SHOOK_TAG,
                   "shook indicates '%s' status is '%s'",
                   path, shook_attr_val[st]);

    *p_status = shook2rbh_status(st);
    if (*p_status == (file_status_t)-1) {
        DisplayLog(LVL_CRIT, SHOOK_TAG,
                   "ERROR getting state of %s: unknown status %d", path,
                   (int)st);
        return -EINVAL;
    }
    return 0;
}
fsal_status_t LUSTREFSAL_truncate(fsal_handle_t * p_filehandle,   /* IN */
                                  fsal_op_context_t * p_context,  /* IN */
                                  fsal_size_t length,   /* IN */
                                  fsal_file_t * file_descriptor,        /* Unused in this FSAL */
                                  fsal_attrib_list_t * p_object_attributes      /* [ IN/OUT ] */
    )
{

  int rc, errsv;
  fsal_path_t fsalpath;
  fsal_status_t st;
  int no_trunc = 0;

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

  /* get the path of the file and its handle */
  st = fsal_internal_Handle2FidPath(p_context, p_filehandle, &fsalpath);
  if(FSAL_IS_ERROR(st))
    ReturnStatus(st, INDEX_FSAL_truncate);

#ifdef _SHOOK
    /* If the file is not online:
     * - if truncate(0) => call tuncate(0), then "shook restore_trunc"
     * - if truncate(>0) => call "shook restore", then truncate
     */
    shook_state state;
    rc = shook_get_status(fsalpath.path, &state, FALSE);
    if (rc)
    {
        LogEvent(COMPONENT_FSAL, "Error retrieving shook status of %s: %s",
                 fsalpath.path, strerror(-rc));
        if (rc)
            Return(posix2fsal_error(-rc), -rc, INDEX_FSAL_truncate);
    }
    else if (state != SS_ONLINE)
    {
        if (length == 0)
        {
            LogInfo(COMPONENT_FSAL, "File is offline: calling shook restore_trunc");

            /* first truncate the file, them call the shook_svr to clear
             * the 'released' flag */

            TakeTokenFSCall();
            rc = truncate(fsalpath.path, 0);
            errsv = errno;
            ReleaseTokenFSCall();

            if (rc == 0)
            {
                /* use a short timeout of 2s */
                rc = shook_server_call(SA_RESTORE_TRUNC, ((lustrefsal_op_context_t *)p_context)->export_context->fsname,
                                       &((lustrefsal_handle_t *)p_filehandle)->data.fid, 2);
                if (rc)
                    Return(posix2fsal_error(-rc), -rc, INDEX_FSAL_truncate);
                else {
                    /* check that file is online, else operation is still
                     * in progress: return err jukebox */
                    rc = shook_get_status(fsalpath.path, &state, FALSE);
                    if (rc)
                    {
                        LogEvent(COMPONENT_FSAL, "Error retrieving shook status of %s: %s",
                                 fsalpath.path, strerror(-rc));
                        if (rc)
                            Return(posix2fsal_error(-rc), -rc, INDEX_FSAL_truncate);
                    }
                    else if (state != SS_ONLINE)
                        Return(ERR_FSAL_DELAY, -rc, INDEX_FSAL_truncate);
                    /* OK */
                }
                /* file is already truncated, no need to truncate again */
                no_trunc = 1;
            }
            else
            {
                  if(errsv == ENOENT)
                    Return(ERR_FSAL_STALE, errsv, INDEX_FSAL_truncate);
                  else
                    Return(posix2fsal_error(errsv), errsv, INDEX_FSAL_truncate);
            }
        }
        else /* length > 0 */
        {
            /* trigger restore. Give it a chance to retrieve the file in less than a second.
             * Else, it returns ETIME that is converted in ERR_DELAY */
            rc = shook_server_call(SA_RESTORE, ((lustrefsal_op_context_t *)p_context)->export_context->fsname,
                                   &((lustrefsal_handle_t *)p_filehandle)->data.fid, 1);
            if (rc)
                Return(posix2fsal_error(-rc), -rc, INDEX_FSAL_truncate);
            else {
                /* check that file is online, else operation is still
                 * in progress: return err jukebox */
                rc = shook_get_status(fsalpath.path, &state, FALSE);
                if (rc)
                {
                    LogEvent(COMPONENT_FSAL, "Error retrieving shook status of %s: %s",
                             fsalpath.path, strerror(-rc));
                    if (rc)
                        Return(posix2fsal_error(-rc), -rc, INDEX_FSAL_truncate);
                }
                else if (state != SS_ONLINE)
                    Return(ERR_FSAL_DELAY, -rc, INDEX_FSAL_truncate);
                /* OK */
            }

            /* if rc = 0, file can be opened */
        }
    }
    /* else file is on line */
#endif

  /* Executes the POSIX truncate operation */

  if (!no_trunc)
  {
    TakeTokenFSCall();
    rc = truncate(fsalpath.path, length);
    errsv = errno;
    ReleaseTokenFSCall();
  }

  /* convert return code */
  if(rc)
    {
      if(errsv == ENOENT)
        Return(ERR_FSAL_STALE, errsv, INDEX_FSAL_truncate);
      else
        Return(posix2fsal_error(errsv), errsv, INDEX_FSAL_truncate);
    }

  /* Optionally retrieve attributes */
  if(p_object_attributes)
    {

      fsal_status_t st;

      st = LUSTREFSAL_getattrs(p_filehandle, p_context, p_object_attributes);

      if(FSAL_IS_ERROR(st))
        {
          FSAL_CLEAR_MASK(p_object_attributes->asked_attributes);
          FSAL_SET_MASK(p_object_attributes->asked_attributes, FSAL_ATTR_RDATTR_ERR);
        }

    }

  /* No error occurred */
  Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_truncate);

}