/** * * MFSL_unlink : posts an asynchronous unlink and sets the cached attributes in return. * * Posts an asynchronous unlink and sets the cached attributes in return. * If an object is not asynchronous, then the content of object attributes structure for result will be used to populate it. * * @param parentdir_handle [IN] mfsl object to be operated on (source directory for the unlink) * @param p_object_name [IN] name of the object to be destroyed * @param p_context [IN] associated fsal context * @param p_mfsl_context [INOUT] associated mfsl context * @param parentdir_attributes [INOUT] resulting attributes for directory * * @return the same as FSAL_unlink */ fsal_status_t MFSL_unlink(mfsl_object_t * dir_handle, /* IN */ fsal_name_t * p_object_name, /* IN */ mfsl_object_t * object_handle, /* INOUT */ fsal_op_context_t * p_context, /* IN */ mfsl_context_t * p_mfsl_context, /* IN */ fsal_attrib_list_t * dir_attributes /* [ IN/OUT ] */ ) { fsal_status_t fsal_status; mfsl_async_op_desc_t *pasyncopdesc = NULL; mfsl_object_specific_data_t *dir_pasyncdata = NULL; mfsl_object_specific_data_t *obj_pasyncdata = NULL; GetFromPool(pasyncopdesc, &p_mfsl_context->pool_async_op, mfsl_async_op_desc_t); if(pasyncopdesc == NULL) MFSL_return(ERR_FSAL_INVAL, 0); if(gettimeofday(&pasyncopdesc->op_time, NULL) != 0) { /* Could'not get time of day... Stopping, this may need a major failure */ LogMajor(COMPONENT_MFSL, "MFSL_link: cannot get time of day... exiting"); exit(1); } if(!mfsl_async_get_specdata(dir_handle, &dir_pasyncdata)) { /* Target is not yet asynchronous */ GetFromPool(dir_pasyncdata, &p_mfsl_context->pool_spec_data, mfsl_object_specific_data_t); /* In this case use object_attributes parameter to initiate asynchronous object */ dir_pasyncdata->async_attr = *dir_attributes; } fsal_status = MFSAL_unlink_check_perms(dir_handle, dir_pasyncdata, p_object_name, dir_attributes, p_context, p_mfsl_context); if(FSAL_IS_ERROR(fsal_status)) return fsal_status; LogDebug(COMPONENT_MFSL, "Creating asyncop %p", pasyncopdesc); pasyncopdesc->op_type = MFSL_ASYNC_OP_REMOVE; pasyncopdesc->op_args.remove.pmobject = dir_handle; pasyncopdesc->op_args.remove.name = *p_object_name; pasyncopdesc->op_res.remove.attr = *dir_attributes; pasyncopdesc->op_func = MFSL_unlink_async_op; pasyncopdesc->fsal_op_context = *p_context; pasyncopdesc->ptr_mfsl_context = (caddr_t) p_mfsl_context; fsal_status = MFSL_async_post(pasyncopdesc); if(FSAL_IS_ERROR(fsal_status)) return fsal_status; /* Update the asynchronous metadata */ dir_pasyncdata->async_attr.ctime.seconds = pasyncopdesc->op_time.tv_sec; dir_pasyncdata->async_attr.ctime.nseconds = pasyncopdesc->op_time.tv_usec; /** @todo: there may be a coefficient to be applied here */ dir_handle->health = MFSL_ASYNC_ASYNCHRONOUS; if(!mfsl_async_set_specdata(dir_handle, dir_pasyncdata)) MFSL_return(ERR_FSAL_SERVERFAULT, 0); if(!mfsl_async_get_specdata(object_handle, &obj_pasyncdata)) { /* The object to be deleted is not asynchronous, but it has * has to become asynchronous to be correctly managed until the FSAL deletes it */ GetFromPool(obj_pasyncdata, &p_mfsl_context->pool_spec_data, mfsl_object_specific_data_t); /* Possible bug here with getattr because it has not data */ } /* Depending on the value of numlinks, the object should be deleted or not */ if((obj_pasyncdata->async_attr.numlinks > 1) && (obj_pasyncdata->async_attr.type == FSAL_TYPE_FILE)) obj_pasyncdata->async_attr.numlinks -= 1; else obj_pasyncdata->deleted = TRUE; if(!mfsl_async_set_specdata(object_handle, obj_pasyncdata)) MFSL_return(ERR_FSAL_SERVERFAULT, 0); /* Return the correct attributes */ *dir_attributes = dir_pasyncdata->async_attr; MFSL_return(ERR_FSAL_NO_ERROR, 0); } /* MFSL_unlink */
/** * * MFSL_truncate : posts an asynchronous truncate and sets the cached attributes in return. * * Posts an asynchronous truncate and sets the cached attributes in return. * If the object is not asynchronous, then the content of object attributes will be used to populate it. * * @param filehandle [IN] mfsl object to be operated on. * @param p_context [IN] associated fsal context * @param p_mfsl_context [INOUT] associated mfsl context * @param size [IN] new size * @param file_descriptor [UNUSED] should be removed as stateful FSAL_truncate is removed from FSAL_PROXY * @param object_attributes [INOUT] resulting attributes * * @return the same as FSAL_truncate */ fsal_status_t MFSL_truncate(mfsl_object_t * filehandle, /* IN */ fsal_op_context_t * p_context, /* IN */ mfsl_context_t * p_mfsl_context, /* IN */ fsal_size_t length, fsal_file_t * file_descriptor, /* INOUT */ fsal_attrib_list_t * object_attributes /* [ IN/OUT ] */ ) { fsal_status_t fsal_status; mfsl_async_op_desc_t *pasyncopdesc = NULL; mfsl_object_specific_data_t *pasyncdata = NULL; P(p_mfsl_context->lock); GetFromPool(pasyncopdesc, &p_mfsl_context->pool_async_op, mfsl_async_op_desc_t); V(p_mfsl_context->lock); if(pasyncopdesc == NULL) MFSL_return(ERR_FSAL_INVAL, 0); if(gettimeofday(&pasyncopdesc->op_time, NULL) != 0) { /* Could'not get time of day... Stopping, this may need a major failure */ LogMajor(COMPONENT_MFSL, "MFSL_truncate: cannot get time of day... exiting"); exit(1); } /* Is the object asynchronous ? */ if(!mfsl_async_get_specdata(filehandle, &pasyncdata)) { /* Not yet asynchronous object */ P(p_mfsl_context->lock); GetFromPool(pasyncdata, &p_mfsl_context->pool_spec_data, mfsl_object_specific_data_t); V(p_mfsl_context->lock); /* In this case use object_attributes parameter to initiate asynchronous object */ pasyncdata->async_attr = *object_attributes; } fsal_status = MFSAL_truncate_check_perms(filehandle, pasyncdata, p_context, p_mfsl_context); if(FSAL_IS_ERROR(fsal_status)) return fsal_status; LogDebug(COMPONENT_MFSL, "Creating asyncop %p", pasyncopdesc); pasyncopdesc->op_type = MFSL_ASYNC_OP_TRUNCATE; pasyncopdesc->op_mobject = filehandle; pasyncopdesc->op_args.truncate.pmobject = filehandle; pasyncopdesc->op_args.truncate.size = length; pasyncopdesc->op_res.truncate.attr = *object_attributes; pasyncopdesc->op_func = MFSL_truncate_async_op; pasyncopdesc->fsal_op_context = *p_context; pasyncopdesc->ptr_mfsl_context = (caddr_t) p_mfsl_context; fsal_status = MFSL_async_post(pasyncopdesc); if(FSAL_IS_ERROR(fsal_status)) return fsal_status; /* Update the associated times for this object */ pasyncdata->async_attr = *object_attributes; pasyncdata->async_attr.ctime.seconds = pasyncopdesc->op_time.tv_sec; pasyncdata->async_attr.ctime.nseconds = pasyncopdesc->op_time.tv_usec; /** @todo: there may be a coefficient to be applied here */ filehandle->health = MFSL_ASYNC_ASYNCHRONOUS; /* Set output attributes */ *object_attributes = pasyncdata->async_attr; if(!mfsl_async_set_specdata(filehandle, pasyncdata)) MFSL_return(ERR_FSAL_SERVERFAULT, 0); MFSL_return(ERR_FSAL_NO_ERROR, 0); } /* MFSL_truncate */
/** * * MFSL_setattrs : posts an asynchronous setattr and sets the cached attributes in return. * * Posts an asynchronous setattr and sets the cached attributes in return. * If the object is not asynchronous, then the content of object attributes will be used to populate it. * * @param filehandle [IN] mfsl object to be operated on. * @param p_context [IN] associated fsal context * @param p_mfsl_context [INOUT] associated mfsl context * @param attrib_set [IN] attributes to be set * @param object_attributes [INOUT] resulting attributes * * @return the same as FSAL_setattrs */ 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 ) { fsal_status_t fsal_status; mfsl_async_op_desc_t *pasyncopdesc = NULL; mfsl_object_specific_data_t *pasyncdata = NULL; P(p_mfsl_context->lock); GetFromPool(pasyncopdesc, &p_mfsl_context->pool_async_op, mfsl_async_op_desc_t); V(p_mfsl_context->lock); if(pasyncopdesc == NULL) MFSL_return(ERR_FSAL_INVAL, 0); if(gettimeofday(&pasyncopdesc->op_time, NULL) != 0) { /* Could'not get time of day... Stopping, this may need a major failure */ LogMajor(COMPONENT_MFSL, "MFSL_setattrs: cannot get time of day... exiting"); exit(1); } /* Is the object asynchronous ? */ if(!mfsl_async_get_specdata(filehandle, &pasyncdata)) { /* Not yet asynchronous object */ P(p_mfsl_context->lock); GetFromPool(pasyncdata, &p_mfsl_context->pool_spec_data, mfsl_object_specific_data_t); V(p_mfsl_context->lock); /* In this case use object_attributes parameter to initiate asynchronous object */ pasyncdata->async_attr = *object_attributes; } fsal_status = MFSL_setattrs_check_perms(filehandle, pasyncdata, p_context, p_mfsl_context, attrib_set); if(FSAL_IS_ERROR(fsal_status)) return fsal_status; LogDebug(COMPONENT_MFSL, "Creating asyncop %p", pasyncopdesc); pasyncopdesc->op_type = MFSL_ASYNC_OP_SETATTR; pasyncopdesc->op_mobject = filehandle; pasyncopdesc->op_args.setattr.pmobject = filehandle; pasyncopdesc->op_args.setattr.attr = *attrib_set; pasyncopdesc->op_res.setattr.attr = *attrib_set; pasyncopdesc->op_func = MFSL_setattr_async_op; pasyncopdesc->fsal_op_context = *p_context; pasyncopdesc->ptr_mfsl_context = (caddr_t) p_mfsl_context; fsal_status = MFSL_async_post(pasyncopdesc); if(FSAL_IS_ERROR(fsal_status)) return fsal_status; /* Update the associated times for this object */ pasyncdata->async_attr.ctime.seconds = pasyncopdesc->op_time.tv_sec; pasyncdata->async_attr.ctime.nseconds = pasyncopdesc->op_time.tv_usec; /** @todo: there may be a coefficient to be applied here */ filehandle->health = MFSL_ASYNC_ASYNCHRONOUS; /* merge the attributes to the asynchronous attributes */ if((attrib_set->asked_attributes & FSAL_ATTR_SIZE) || (attrib_set->asked_attributes & FSAL_ATTR_SPACEUSED)) { /* Operation on a non data cached file */ pasyncdata->async_attr.filesize = attrib_set->filesize; pasyncdata->async_attr.spaceused = attrib_set->spaceused; } if(attrib_set->asked_attributes & (FSAL_ATTR_MODE | FSAL_ATTR_OWNER | FSAL_ATTR_GROUP)) { if(attrib_set->asked_attributes & FSAL_ATTR_MODE) pasyncdata->async_attr.mode = attrib_set->mode; if(attrib_set->asked_attributes & FSAL_ATTR_OWNER) pasyncdata->async_attr.owner = attrib_set->owner; if(attrib_set->asked_attributes & FSAL_ATTR_GROUP) pasyncdata->async_attr.group = attrib_set->group; } if(attrib_set->asked_attributes & (FSAL_ATTR_ATIME | FSAL_ATTR_MTIME)) { if(attrib_set->asked_attributes & FSAL_ATTR_ATIME) pasyncdata->async_attr.atime = attrib_set->atime; if(attrib_set->asked_attributes & FSAL_ATTR_MTIME) pasyncdata->async_attr.mtime = attrib_set->mtime; } /* Set output attributes */ *object_attributes = pasyncdata->async_attr; if(!mfsl_async_set_specdata(filehandle, pasyncdata)) MFSL_return(ERR_FSAL_SERVERFAULT, 0); MFSL_return(ERR_FSAL_NO_ERROR, 0); } /* MFSL_setattr */
/** * * MFSL_getattrs : performs getattr but takes care of the asynchronous logic. * * Performs getattr but takes care of the asynchronous logic. * * @param filehandle [IN] mfsl object related to the object * @param p_context [IN] associated fsal context * @param p_mfsl_context [INOUT] associated mfsl context * @param object_attributes [INOUT] attributes for the object * * @return the same as FSAL_getattrs */ fsal_status_t MFSL_getattrs(mfsl_object_t * filehandle, /* IN */ fsal_op_context_t * p_context, /* IN */ mfsl_context_t * p_mfsl_context, /* IN */ fsal_attrib_list_t * object_attributes /* [ IN/OUT ] */ ) { fsal_status_t fsal_status; mfsl_object_specific_data_t *pasyncdata; if(mfsl_async_get_specdata(filehandle, &pasyncdata)) { P(filehandle->lock); fsal_status = MFSAL_getattrs_check_perms(filehandle, pasyncdata, p_context, p_mfsl_context, object_attributes); V(filehandle->lock); if(FSAL_IS_ERROR(fsal_status)) return fsal_status; /* Is the object deleted ? */ if(pasyncdata->deleted == TRUE) MFSL_return(ERR_FSAL_NOENT, ENOENT); /* merge the attributes to the asynchronous attributes */ if((object_attributes->asked_attributes & FSAL_ATTR_SIZE) || (object_attributes->asked_attributes & FSAL_ATTR_SPACEUSED)) { /* Operation on a non data cached file */ object_attributes->filesize = pasyncdata->async_attr.filesize; object_attributes->spaceused = pasyncdata->async_attr.spaceused; } if(object_attributes->asked_attributes & (FSAL_ATTR_MODE | FSAL_ATTR_OWNER | FSAL_ATTR_GROUP)) { if(object_attributes->asked_attributes & FSAL_ATTR_MODE) object_attributes->mode = pasyncdata->async_attr.mode; if(object_attributes->asked_attributes & FSAL_ATTR_OWNER) object_attributes->owner = pasyncdata->async_attr.owner; if(object_attributes->asked_attributes & FSAL_ATTR_GROUP) object_attributes->group = pasyncdata->async_attr.group; } if(object_attributes->asked_attributes & (FSAL_ATTR_ATIME | FSAL_ATTR_MTIME)) { if(object_attributes->asked_attributes & FSAL_ATTR_ATIME) object_attributes->atime = pasyncdata->async_attr.atime; if(object_attributes->asked_attributes & FSAL_ATTR_MTIME) object_attributes->mtime = pasyncdata->async_attr.mtime; } /* Regular exit */ MFSL_return(ERR_FSAL_NO_ERROR, 0); } else { return FSAL_getattrs(&filehandle->handle, p_context, object_attributes); } } /* MFSL_getattrs */