nfs-ganesha 1.4
|
00001 /* 00002 * 00003 * 00004 * Copyright CEA/DAM/DIF (2008) 00005 * contributeur : Philippe DENIEL philippe.deniel@cea.fr 00006 * Thomas LEIBOVICI thomas.leibovici@cea.fr 00007 * 00008 * 00009 * This program is free software; you can redistribute it and/or 00010 * modify it under the terms of the GNU Lesser General Public 00011 * License as published by the Free Software Foundation; either 00012 * version 3 of the License, or (at your option) any later version. 00013 * 00014 * This program is distributed in the hope that it will be useful, 00015 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00017 * Lesser General Public License for more details. 00018 * 00019 * You should have received a copy of the GNU Lesser General Public 00020 * License along with this library; if not, write to the Free Software 00021 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00022 * 00023 * --------------------------------------- 00024 */ 00025 00036 #ifdef HAVE_CONFIG_H 00037 #include "config.h" 00038 #endif 00039 00040 /* fsal_types contains constants and type definitions for FSAL */ 00041 #include "fsal_types.h" 00042 #include "fsal.h" 00043 #include "mfsl_types.h" 00044 #include "mfsl.h" 00045 #include "common_utils.h" 00046 00047 extern mfsl_parameter_t mfsl_param; 00048 extern fsal_handle_t dir_handle_precreate; 00049 extern mfsl_synclet_data_t *synclet_data; 00050 00061 fsal_status_t MFSL_mkdir_async_op(mfsl_async_op_desc_t * popasyncdesc) 00062 { 00063 fsal_status_t fsal_status; 00064 fsal_attrib_list_t attrsrc, attrdest, chown_attr; 00065 fsal_handle_t handle; 00066 00067 attrsrc = attrdest = popasyncdesc->op_res.mkdir.attr; 00068 00069 LogDebug(COMPONENT_MFSL, 00070 "Renaming directory to complete asynchronous FSAL_mkdir for async op %p", 00071 popasyncdesc); 00072 00073 P(popasyncdesc->op_args.mkdir.pmfsl_obj_dirdest->lock); 00074 fsal_status = FSAL_rename(&dir_handle_precreate, 00075 &popasyncdesc->op_args.mkdir.precreate_name, 00076 &(popasyncdesc->op_args.mkdir.pmfsl_obj_dirdest->handle), 00077 &popasyncdesc->op_args.mkdir.dirname, 00078 &popasyncdesc->fsal_op_context, &attrsrc, &attrdest); 00079 00080 if(FSAL_IS_ERROR(fsal_status)) 00081 { 00082 V(popasyncdesc->op_args.mkdir.pmfsl_obj_dirdest->lock); 00083 00084 return fsal_status; 00085 } 00086 00087 /* Lookup to get the right attributes for the object */ 00088 fsal_status = FSAL_lookup(&(popasyncdesc->op_args.mkdir.pmfsl_obj_dirdest->handle), 00089 &popasyncdesc->op_args.mkdir.dirname, 00090 &popasyncdesc->fsal_op_context, 00091 &handle, &popasyncdesc->op_res.mkdir.attr); 00092 00093 V(popasyncdesc->op_args.mkdir.pmfsl_obj_dirdest->lock); 00094 00095 if(FSAL_IS_ERROR(fsal_status)) 00096 return fsal_status; 00097 00098 /* If user is not root, setattr to chown the entry */ 00099 if(popasyncdesc->op_args.mkdir.owner != 0) 00100 { 00101 chown_attr.asked_attributes = FSAL_ATTR_MODE | FSAL_ATTR_OWNER | FSAL_ATTR_GROUP; 00102 chown_attr.mode = popasyncdesc->op_args.mkdir.mode; 00103 chown_attr.owner = popasyncdesc->op_args.mkdir.owner; 00104 chown_attr.group = popasyncdesc->op_args.mkdir.group; 00105 00106 fsal_status = 00107 FSAL_setattrs(&handle, &popasyncdesc->fsal_op_context, &chown_attr, 00108 &popasyncdesc->op_res.mkdir.attr); 00109 } 00110 return fsal_status; 00111 } /* MFSL_mkdir_async_op */ 00112 00127 fsal_status_t MFSAL_mkdir_check_perms(mfsl_object_t * target_handle, 00128 fsal_name_t * p_dirname, 00129 fsal_op_context_t * p_context, 00130 mfsl_context_t * p_mfsl_context, 00131 fsal_attrib_list_t * object_attributes) 00132 { 00133 fsal_status_t fsal_status; 00134 00135 fsal_status = FSAL_create_access(p_context, object_attributes); 00136 00137 if(FSAL_IS_ERROR(fsal_status)) 00138 return fsal_status; 00139 00141 MFSL_return(ERR_FSAL_NO_ERROR, 0); 00142 } /* MFSL_mkdir_check_perms */ 00143 00161 fsal_status_t MFSL_mkdir(mfsl_object_t * parent_directory_handle, /* IN */ 00162 fsal_name_t * p_dirname, /* IN */ 00163 fsal_op_context_t * p_context, /* IN */ 00164 mfsl_context_t * p_mfsl_context, /* IN */ 00165 fsal_accessmode_t accessmode, /* IN */ 00166 mfsl_object_t * object_handle, /* OUT */ 00167 fsal_attrib_list_t * object_attributes, /* [ IN/OUT ] */ 00168 fsal_attrib_list_t * parent_attributes /* IN */ ) 00169 { 00170 fsal_status_t fsal_status; 00171 mfsl_async_op_desc_t *pasyncopdesc = NULL; 00172 mfsl_object_specific_data_t *newdir_pasyncdata = NULL; 00173 mfsl_object_t *pnewdir_handle = NULL; 00174 mfsl_precreated_object_t *pprecreated = NULL; 00175 00176 fsal_status = MFSAL_mkdir_check_perms(parent_directory_handle, 00177 p_dirname, 00178 p_context, p_mfsl_context, parent_attributes); 00179 00180 if(FSAL_IS_ERROR(fsal_status)) 00181 return fsal_status; 00182 00183 P(p_mfsl_context->lock); 00184 00185 pasyncopdesc = pool_alloc(p_mfsl_context->pool_async_op, NULL); 00186 00187 newdir_pasyncdata = pool_alloc(p_mfsl_context->pool_spec_data, NULL); 00188 00189 V(p_mfsl_context->lock); 00190 00191 if(pasyncopdesc == NULL) 00192 MFSL_return(ERR_FSAL_INVAL, 0); 00193 00194 if(gettimeofday(&pasyncopdesc->op_time, NULL) != 0) 00195 { 00196 /* Could'not get time of day... Stopping, this may need a major failure */ 00197 LogMajor(COMPONENT_MFSL, "MFSL_link: cannot get time of day... exiting"); 00198 exit(1); 00199 } 00200 00201 /* Now get a pre-allocated directory from the synclet data */ 00202 P(p_mfsl_context->lock); 00203 pprecreated = pool_alloc(p_mfsl_context->pool_dirs, NULL); 00204 V(p_mfsl_context->lock); 00205 00206 pnewdir_handle = &(pprecreated->mobject); 00207 00208 LogDebug(COMPONENT_MFSL, "Creating asyncop %p", 00209 pasyncopdesc); 00210 00211 pasyncopdesc->op_type = MFSL_ASYNC_OP_MKDIR; 00212 pasyncopdesc->op_args.mkdir.pmfsl_obj_dirdest = parent_directory_handle; 00213 pasyncopdesc->op_args.mkdir.precreate_name = pprecreated->name; 00214 pasyncopdesc->op_args.mkdir.dirname = *p_dirname; 00215 pasyncopdesc->op_args.mkdir.mode = accessmode; 00216 pasyncopdesc->op_args.mkdir.owner = FSAL_OP_CONTEXT_TO_UID(p_context); 00217 pasyncopdesc->op_args.mkdir.group = FSAL_OP_CONTEXT_TO_GID(p_context); 00218 pasyncopdesc->op_res.mkdir.attr.asked_attributes = object_attributes->asked_attributes; 00219 pasyncopdesc->op_res.mkdir.attr.supported_attributes = 00220 object_attributes->supported_attributes; 00221 00222 if(FSAL_IS_ERROR(fsal_status)) 00223 return fsal_status; 00224 00225 pasyncopdesc->op_func = MFSL_mkdir_async_op; 00226 //pasyncopdesc->fsal_op_context = p_context ; 00227 pasyncopdesc->fsal_op_context = 00228 synclet_data[pasyncopdesc->related_synclet_index].root_fsal_context; 00229 00230 pasyncopdesc->ptr_mfsl_context = (caddr_t) p_mfsl_context; 00231 00232 fsal_status = MFSL_async_post(pasyncopdesc); 00233 if(FSAL_IS_ERROR(fsal_status)) 00234 return fsal_status; 00235 00236 /* Update the asynchronous metadata */ 00237 newdir_pasyncdata->async_attr = pprecreated->attr; 00238 00239 newdir_pasyncdata->async_attr.type = FSAL_TYPE_DIR; 00240 newdir_pasyncdata->async_attr.filesize = DEV_BSIZE; 00241 newdir_pasyncdata->async_attr.spaceused = DEV_BSIZE; 00242 newdir_pasyncdata->async_attr.numlinks = 2; 00243 00244 newdir_pasyncdata->async_attr.owner = pasyncopdesc->op_args.mkdir.owner; 00245 newdir_pasyncdata->async_attr.group = pasyncopdesc->op_args.mkdir.group; 00246 00247 newdir_pasyncdata->async_attr.ctime.seconds = pasyncopdesc->op_time.tv_sec; 00248 newdir_pasyncdata->async_attr.ctime.nseconds = pasyncopdesc->op_time.tv_usec; 00250 newdir_pasyncdata->deleted = FALSE; 00251 00252 if(!mfsl_async_set_specdata(pnewdir_handle, newdir_pasyncdata)) 00253 MFSL_return(ERR_FSAL_SERVERFAULT, 0); 00254 00255 /* Return the correct attributes */ 00256 *object_attributes = newdir_pasyncdata->async_attr; 00257 *object_handle = pprecreated->mobject; 00258 object_handle->health = MFSL_ASYNC_NEVER_SYNCED; 00259 00260 /* Do not forget that the parent directory becomes asynchronous too */ 00261 parent_directory_handle->health = MFSL_ASYNC_ASYNCHRONOUS; 00262 00263 MFSL_return(ERR_FSAL_NO_ERROR, 0); 00264 } /* MFSL_mkdir */