/** * 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); }