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; P(parent_directory_handle->lock); fsal_status = FSAL_symlink(&parent_directory_handle->handle, p_linkname, p_linkcontent, p_context, accessmode, &link_handle->handle, link_attributes); V(parent_directory_handle->lock); if(FSAL_IS_ERROR(fsal_status)) return fsal_status; /* If successful, the symlink's mobject should be clearly indentified as a symbolic link: a symbolic link can't be an asynchronous * object and it has to remain synchronous everywhere */ link_handle->health = MFSL_ASYNC_IS_SYMLINK; MFSL_return(ERR_FSAL_NO_ERROR, 0); } /* MFSL_symlink */
/** * * MFSL_setattrs_check_perms : Checks authorization to perform an asynchronous setattr. * * Checks authorization to perform an asynchronous setattr. * * @param filehandle [IN] mfsl object to be operated on. * @param pspecdata [INOUT] mfsl object associated specific data * @param p_context [IN] associated fsal context * @param p_mfsl_context [INOUT] associated mfsl context * @param attrib_set [IN] attributes to be set * * @return always FSAL_NO_ERROR (not yet implemented */ fsal_status_t MFSL_setattrs_check_perms(mfsl_object_t * filehandle, /* IN */ mfsl_object_specific_data_t * pspecdata, /* IN */ fsal_op_context_t * p_context, /* IN */ mfsl_context_t * p_mfsl_context, /* IN */ fsal_attrib_list_t * attrib_set /* IN */ ) { fsal_status_t fsal_status; /* Root is the only one that can chown or chgrp */ if(attrib_set->asked_attributes & (FSAL_ATTR_OWNER | FSAL_ATTR_GROUP)) { if(p_context->user_credential.user != 0) MFSL_return(ERR_FSAL_ACCESS, 0); } fsal_status = FSAL_setattr_access(p_context, attrib_set, &pspecdata->async_attr); if(FSAL_IS_ERROR(fsal_status)) return fsal_status; MFSL_return(ERR_FSAL_NO_ERROR, 0); } /* MFSL_setattr_check_perms */
/** * * MFSAL_truncate_check_perms : Checks authorization to perform an asynchronous truncate. * * Checks authorization to perform an asynchronous truncate. * * @param filehandle [IN] mfsl object to be operated on. * @param pspecdata [INOUT] mfsl object associated specific data * @param p_context [IN] associated fsal context * @param p_mfsl_context [INOUT] associated mfsl context * @param attrib_set [IN] attributes to be set * * @return always FSAL_NO_ERROR (not yet implemented */ fsal_status_t MFSAL_truncate_check_perms(mfsl_object_t * filehandle, mfsl_object_specific_data_t * pspecdata, fsal_op_context_t * p_context, mfsl_context_t * p_mfsl_context) { fsal_status_t fsal_status; fsal_status = FSAL_test_access(p_context, FSAL_W_OK, &pspecdata->async_attr); if(FSAL_IS_ERROR(fsal_status)) return fsal_status; MFSL_return(ERR_FSAL_NO_ERROR, 0); } /* MFSL_truncate_check_perms */
/** * * MFSAL_getattrs_check_perms : Checks authorization to perform an asynchronous getattr. * * Checks authorization to perform an asynchronous getattr. * * @param target_handle [IN] mfsl object to be operated on. * @param pspecdata [IN] object's specific data * @param p_context [IN] associated fsal context * @param object_attributes [INOUT] attributes for the objet * * @return always FSAL_NO_ERROR (not yet implemented */ fsal_status_t MFSAL_getattrs_check_perms(mfsl_object_t * filehandle, /* IN */ mfsl_object_specific_data_t * pspecdata, /* IN */ fsal_op_context_t * p_context, /* IN */ mfsl_context_t * p_mfsl_context, /* IN */ fsal_attrib_list_t * object_attributes /* IN */ ) { fsal_status_t fsal_status; fsal_status = FSAL_test_access(p_context, FSAL_R_OK, object_attributes); if(FSAL_IS_ERROR(fsal_status)) return fsal_status; MFSL_return(ERR_FSAL_NO_ERROR, 0); } /* MFSL_setattr_check_perms */
/** * * MFSAL_mkdir_check_perms : Checks authorization to perform an asynchronous mkdir. * * Checks authorization to perform an asynchronous mkdir. * * @param target_handle [IN] mfsl object to be operated on. * @param p_dirname [IN] name of the object to be created * @param p_context [IN] associated fsal context * @param p_mfsl_context [INOUT] associated mfsl context * @param object_attributes [IN] object-attributes * * @return always FSAL_NO_ERROR (not yet implemented */ fsal_status_t MFSAL_mkdir_check_perms(mfsl_object_t * target_handle, fsal_name_t * p_dirname, fsal_op_context_t * p_context, mfsl_context_t * p_mfsl_context, fsal_attrib_list_t * object_attributes) { fsal_status_t fsal_status; fsal_status = FSAL_create_access(p_context, object_attributes); if(FSAL_IS_ERROR(fsal_status)) return fsal_status; /** @todo : put some stuff in this function */ MFSL_return(ERR_FSAL_NO_ERROR, 0); } /* MFSL_mkdir_check_perms */
/** * * MFSAL_link_check_perms : Checks authorization to perform an asynchronous setattr. * * Checks authorization to perform an asynchronous link. * * @param target_handle [IN] mfsl object to be operated on. * @param dir_handle [IN] mfsl object to be operated on. * @param tgt_pspecdata [INOUT] mfsl object associated specific data * @param dir_pspecdata [INOUT] mfsl object associated specific data * @param p_context [IN] associated fsal context * @param p_mfsl_context [INOUT] associated mfsl context * * @return always FSAL_NO_ERROR (not yet implemented */ fsal_status_t MFSAL_unlink_check_perms(mfsl_object_t * dir_handle, /* IN */ mfsl_object_specific_data_t * dir_pspecdata, /* IN */ fsal_name_t * p_object_name, /* IN */ fsal_attrib_list_t * dir_attributes, /* [ IN/OUT ] */ fsal_op_context_t * p_context, /* IN */ mfsl_context_t * p_mfsl_context /* IN */ ) { fsal_status_t fsal_status; fsal_status = FSAL_unlink_access(p_context, dir_attributes); if(FSAL_IS_ERROR(fsal_status)) return fsal_status; /** @todo : put some stuff in this function */ MFSL_return(ERR_FSAL_NO_ERROR, 0); } /* MFSL_unlink_check_perms */
/** * * 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_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_Init(mfsl_parameter_t * init_info /* IN */ ) { unsigned long i = 0; unsigned int rc = 0; pthread_attr_t attr_thr; LRU_status_t lru_status; /* Keep the parameter in mind */ mfsl_param = *init_info; /* Init for thread parameter (mostly for scheduling) */ pthread_attr_init(&attr_thr); pthread_attr_setscope(&attr_thr, PTHREAD_SCOPE_SYSTEM); pthread_attr_setdetachstate(&attr_thr, PTHREAD_CREATE_JOINABLE); /* Allocate the synclet related structure */ if((mfsl_async_synclet_thrid = gsh_malloc(init_info->nb_synclet * sizeof(pthread_t))) == NULL) MFSL_return(ERR_FSAL_NOMEM, errno); if((synclet_data = gsh_calloc(init_info->nb_synclet, sizeof(mfsl_synclet_data_t))) == NULL) MFSL_return(ERR_FSAL_NOMEM, errno); for(i = 0; i < init_info->nb_synclet; i++) { synclet_data[i].my_index = i; if(pthread_cond_init(&synclet_data[i].op_condvar, NULL) != 0) MFSL_return(ERR_FSAL_INVAL, 0); if(pthread_mutex_init(&synclet_data[i].mutex_op_condvar, NULL) != 0) MFSL_return(ERR_FSAL_INVAL, 0); if(pthread_mutex_init(&synclet_data[i].mutex_op_lru, NULL) != 0) MFSL_return(ERR_FSAL_INVAL, 0); if((synclet_data[i].op_lru = LRU_Init(mfsl_param.lru_param, &lru_status)) == NULL) MFSL_return(ERR_FSAL_INVAL, 0); synclet_data[i].passcounter = 0; } /* for */ /* Now start the threads */ if((rc = pthread_create(&mfsl_async_adt_thrid, &attr_thr, mfsl_async_asynchronous_dispatcher_thread, (void *)NULL)) != 0) MFSL_return(ERR_FSAL_SERVERFAULT, -rc); for(i = 0; i < init_info->nb_synclet; i++) { if((rc = pthread_create(&mfsl_async_synclet_thrid[i], &attr_thr, mfsl_async_synclet_thread, (void *)i)) != 0) MFSL_return(ERR_FSAL_SERVERFAULT, -rc); } if(!mfsl_async_hash_init()) MFSL_return(ERR_FSAL_SERVERFAULT, 0); /* Regular Exit */ MFSL_return(ERR_FSAL_NO_ERROR, 0); }
/** * * 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_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 */
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 */