/** * * 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_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_mkdir : posts an asynchronous mkdir and sets the cached attributes in return. * * Posts an asynchronous setattr 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 target_handle [IN] mfsl object to be operated on (object to be hard linked). * @param dir_handle [IN] mfsl object to be operated on (destination directory for the link). * @param p_context [IN] associated fsal context * @param p_mfsl_context [INOUT] associated mfsl context * @param attrib_set [IN] attributes to be set * @param tgt_attributes [INOUT] resulting attributes for target * @param dir_attributes [INOUT] resulting attributes for directory * * @return the same as FSAL_link */ fsal_status_t MFSL_mkdir(mfsl_object_t * parent_directory_handle, /* IN */ fsal_name_t * p_dirname, /* IN */ fsal_op_context_t * p_context, /* IN */ mfsl_context_t * p_mfsl_context, /* IN */ fsal_accessmode_t accessmode, /* IN */ mfsl_object_t * object_handle, /* OUT */ fsal_attrib_list_t * object_attributes, /* [ IN/OUT ] */ fsal_attrib_list_t * parent_attributes /* IN */ ) { fsal_status_t fsal_status; mfsl_async_op_desc_t *pasyncopdesc = NULL; mfsl_object_specific_data_t *newdir_pasyncdata = NULL; mfsl_object_t *pnewdir_handle = NULL; mfsl_precreated_object_t *pprecreated = NULL; fsal_status = MFSAL_mkdir_check_perms(parent_directory_handle, p_dirname, p_context, p_mfsl_context, parent_attributes); if(FSAL_IS_ERROR(fsal_status)) return fsal_status; P(p_mfsl_context->lock); GetFromPool(pasyncopdesc, &p_mfsl_context->pool_async_op, mfsl_async_op_desc_t); GetFromPool(newdir_pasyncdata, &p_mfsl_context->pool_spec_data, mfsl_object_specific_data_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_link: cannot get time of day... exiting"); exit(1); } /* Now get a pre-allocated directory from the synclet data */ P(p_mfsl_context->lock); GetFromPool(pprecreated, &p_mfsl_context->pool_dirs, mfsl_precreated_object_t); V(p_mfsl_context->lock); pnewdir_handle = &(pprecreated->mobject); LogDebug(COMPONENT_MFSL, "Creating asyncop %p", pasyncopdesc); pasyncopdesc->op_type = MFSL_ASYNC_OP_MKDIR; pasyncopdesc->op_args.mkdir.pmfsl_obj_dirdest = parent_directory_handle; pasyncopdesc->op_args.mkdir.precreate_name = pprecreated->name; pasyncopdesc->op_args.mkdir.dirname = *p_dirname; pasyncopdesc->op_args.mkdir.mode = accessmode; pasyncopdesc->op_args.mkdir.owner = FSAL_OP_CONTEXT_TO_UID(p_context); pasyncopdesc->op_args.mkdir.group = FSAL_OP_CONTEXT_TO_GID(p_context); pasyncopdesc->op_res.mkdir.attr.asked_attributes = object_attributes->asked_attributes; pasyncopdesc->op_res.mkdir.attr.supported_attributes = object_attributes->supported_attributes; if(FSAL_IS_ERROR(fsal_status)) return fsal_status; pasyncopdesc->op_func = MFSL_mkdir_async_op; //pasyncopdesc->fsal_op_context = p_context ; pasyncopdesc->fsal_op_context = synclet_data[pasyncopdesc->related_synclet_index].root_fsal_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 */ newdir_pasyncdata->async_attr = pprecreated->attr; newdir_pasyncdata->async_attr.type = FSAL_TYPE_DIR; newdir_pasyncdata->async_attr.filesize = DEV_BSIZE; newdir_pasyncdata->async_attr.spaceused = DEV_BSIZE; newdir_pasyncdata->async_attr.numlinks = 2; newdir_pasyncdata->async_attr.owner = pasyncopdesc->op_args.mkdir.owner; newdir_pasyncdata->async_attr.group = pasyncopdesc->op_args.mkdir.group; newdir_pasyncdata->async_attr.ctime.seconds = pasyncopdesc->op_time.tv_sec; newdir_pasyncdata->async_attr.ctime.nseconds = pasyncopdesc->op_time.tv_usec; /** @todo: there may be a coefficient to be applied here */ newdir_pasyncdata->deleted = FALSE; if(!mfsl_async_set_specdata(pnewdir_handle, newdir_pasyncdata)) MFSL_return(ERR_FSAL_SERVERFAULT, 0); /* Return the correct attributes */ *object_attributes = newdir_pasyncdata->async_attr; *object_handle = pprecreated->mobject; object_handle->health = MFSL_ASYNC_NEVER_SYNCED; /* Do not forget that the parent directory becomes asynchronous too */ parent_directory_handle->health = MFSL_ASYNC_ASYNCHRONOUS; MFSL_return(ERR_FSAL_NO_ERROR, 0); } /* MFSL_mkdir */
/** * * 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 */
fsal_status_t MFSL_symlink(mfsl_object_t * parent_directory_handle, /* IN */ fsal_name_t * p_linkname, /* IN */ fsal_path_t * p_linkcontent, /* IN */ fsal_op_context_t * p_context, /* IN */ mfsl_context_t * p_mfsl_context, /* IN */ fsal_accessmode_t accessmode, /* IN (ignored); */ mfsl_object_t * link_handle, /* OUT */ fsal_attrib_list_t * link_attributes /* [ IN/OUT ] */ ) { fsal_status_t fsal_status; mfsl_async_op_desc_t *pasyncopdesc = NULL; mfsl_object_specific_data_t *symlink_pasyncdata = NULL; mfsl_object_t *psymlink_handle = NULL; fsal_name_t tmp_fsal_name; char tmp_name[MAXNAMLEN]; static unsigned int counter = 0; snprintf(tmp_name, MAXNAMLEN, "%s.%u", p_linkname->name, counter); counter += 1; if(FSAL_IS_ERROR(FSAL_str2name(tmp_name, MAXNAMLEN, &tmp_fsal_name))) return fsal_status; fsal_status = MFSAL_symlink_check_perms(parent_directory_handle, p_linkname, p_context, p_mfsl_context, link_attributes); if(FSAL_IS_ERROR(fsal_status)) return fsal_status; P(parent_directory_handle->lock); fsal_status = FSAL_symlink(&tmp_symlink_dirhandle, &tmp_fsal_name, p_linkcontent, p_context, accessmode, &link_handle->handle, link_attributes); V(parent_directory_handle->lock); P(p_mfsl_context->lock); GET_PREALLOC(pasyncopdesc, p_mfsl_context->pool_async_op, mfsl_param.nb_pre_async_op_desc, mfsl_async_op_desc_t, next_alloc); GET_PREALLOC(symlink_pasyncdata, p_mfsl_context->pool_spec_data, mfsl_param.nb_pre_async_op_desc, mfsl_object_specific_data_t, next_alloc); 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_synlink: cannot get time of day... exiting"); exit(1); } LogDebug(COMPONENT_MFSL, "Creating asyncop %p", pasyncopdesc); pasyncopdesc->op_type = MFSL_ASYNC_OP_SYMLINK; pasyncopdesc->op_args.symlink.pmobject_dirdest = parent_directory_handle; pasyncopdesc->op_args.symlink.precreate_name = tmp_fsal_name; pasyncopdesc->op_args.symlink.linkname = *p_linkname; pasyncopdesc->op_res.symlink.attr.asked_attributes = link_attributes->asked_attributes; pasyncopdesc->op_res.symlink.attr.supported_attributes = link_attributes->supported_attributes; pasyncopdesc->ptr_mfsl_context = (caddr_t) p_mfsl_context; if(FSAL_IS_ERROR(fsal_status)) return fsal_status; pasyncopdesc->op_func = MFSL_symlink_async_op; //pasyncopdesc->fsal_op_context = p_context ; pasyncopdesc->fsal_op_context = synclet_data[pasyncopdesc->related_synclet_index].root_fsal_context; fsal_status = MFSL_async_post(pasyncopdesc); if(FSAL_IS_ERROR(fsal_status)) return fsal_status; /* Update the asynchronous metadata */ symlink_pasyncdata->async_attr = *link_attributes; symlink_pasyncdata->deleted = FALSE; if(!mfsl_async_set_specdata(link_handle, symlink_pasyncdata)) MFSL_return(ERR_FSAL_SERVERFAULT, 0); /* Return the correct attributes */ link_handle->health = MFSL_ASYNC_NEVER_SYNCED; /* Do not forget that the parent directory becomes asynchronous too */ parent_directory_handle->health = MFSL_ASYNC_ASYNCHRONOUS; MFSL_return(ERR_FSAL_NO_ERROR, 0); } /* MFSL_symlink */