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 #include "RW_Lock.h" 00047 00048 extern mfsl_parameter_t mfsl_param; 00049 extern fsal_handle_t dir_handle_precreate; 00050 extern mfsl_synclet_data_t *synclet_data; 00051 00062 fsal_status_t MFSL_create_async_op(mfsl_async_op_desc_t * popasyncdesc) 00063 { 00064 fsal_status_t fsal_status; 00065 fsal_attrib_list_t attrsrc, attrdest, chown_attr; 00066 fsal_handle_t handle; 00067 00068 attrsrc = attrdest = popasyncdesc->op_res.mkdir.attr; 00069 00070 LogDebug(COMPONENT_MFSL, 00071 "Renaming file to complete asynchronous FSAL_create for async op %p", 00072 popasyncdesc); 00073 00074 P(popasyncdesc->op_args.create.pmfsl_obj_dirdest->lock); 00075 fsal_status = FSAL_rename(&dir_handle_precreate, 00076 &popasyncdesc->op_args.create.precreate_name, 00077 &(popasyncdesc->op_args.create.pmfsl_obj_dirdest->handle), 00078 &popasyncdesc->op_args.create.filename, 00079 &popasyncdesc->fsal_op_context, &attrsrc, &attrdest); 00080 if(FSAL_IS_ERROR(fsal_status)) 00081 { 00082 V(popasyncdesc->op_args.create.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.create.pmfsl_obj_dirdest->handle), 00089 &popasyncdesc->op_args.create.filename, 00090 &popasyncdesc->fsal_op_context, 00091 &handle, &popasyncdesc->op_res.create.attr); 00092 00093 if(FSAL_IS_ERROR(fsal_status)) 00094 { 00095 V(popasyncdesc->op_args.create.pmfsl_obj_dirdest->lock); 00096 00097 return fsal_status; 00098 } 00099 00100 /* If user is not root, setattr to chown the entry */ 00101 if(popasyncdesc->op_args.create.owner != 0) 00102 { 00103 chown_attr.asked_attributes = FSAL_ATTR_MODE | FSAL_ATTR_OWNER | FSAL_ATTR_GROUP; 00104 chown_attr.mode = popasyncdesc->op_args.create.mode; 00105 chown_attr.owner = popasyncdesc->op_args.create.owner; 00106 chown_attr.group = popasyncdesc->op_args.create.group; 00107 00108 fsal_status = 00109 FSAL_setattrs(&handle, &popasyncdesc->fsal_op_context, &chown_attr, 00110 &popasyncdesc->op_res.create.attr); 00111 } 00112 00113 V(popasyncdesc->op_args.create.pmfsl_obj_dirdest->lock); 00114 00115 return fsal_status; 00116 } /* MFSL_create_async_op */ 00117 00131 fsal_status_t MFSAL_create_check_perms(mfsl_object_t * target_handle, 00132 fsal_name_t * p_dirname, 00133 fsal_op_context_t * p_context, 00134 mfsl_context_t * p_mfsl_context, 00135 fsal_attrib_list_t * object_attributes) 00136 { 00137 fsal_status_t fsal_status; 00138 00139 fsal_status = FSAL_create_access(p_context, object_attributes); 00140 00141 if(FSAL_IS_ERROR(fsal_status)) 00142 return fsal_status; 00143 00145 MFSL_return(ERR_FSAL_NO_ERROR, 0); 00146 } /* MFSL_create_check_perms */ 00147 00166 fsal_status_t MFSL_create(mfsl_object_t * parent_directory_handle, /* IN */ 00167 fsal_name_t * p_dirname, /* IN */ 00168 fsal_op_context_t * p_context, /* IN */ 00169 mfsl_context_t * p_mfsl_context, /* IN */ 00170 fsal_accessmode_t accessmode, /* IN */ 00171 mfsl_object_t * object_handle, /* OUT */ 00172 fsal_attrib_list_t * object_attributes, /* [ IN/OUT ] */ 00173 fsal_attrib_list_t * parent_attributes /* IN */ ) 00174 { 00175 fsal_status_t fsal_status; 00176 mfsl_async_op_desc_t *pasyncopdesc = NULL; 00177 mfsl_object_specific_data_t *newfile_pasyncdata = NULL; 00178 mfsl_object_t *pnewfile_handle = NULL; 00179 mfsl_precreated_object_t *pprecreated = NULL; 00180 00181 fsal_status = MFSAL_create_check_perms(parent_directory_handle, 00182 p_dirname, 00183 p_context, p_mfsl_context, parent_attributes); 00184 00185 if(FSAL_IS_ERROR(fsal_status)) 00186 return fsal_status; 00187 00188 P(p_mfsl_context->lock); 00189 00190 pasyncopdesc = pool_alloc(p_mfsl_context->pool_async_op, NULL); 00191 00192 newfile_pasyncdata = pool_alloc(p_mfsl_context->pool_spec_data, NULL); 00193 00194 V(p_mfsl_context->lock); 00195 00196 if(pasyncopdesc == NULL) 00197 MFSL_return(ERR_FSAL_INVAL, 0); 00198 00199 if(gettimeofday(&pasyncopdesc->op_time, NULL) != 0) 00200 { 00201 /* Could'not get time of day... Stopping, this may need a major failure */ 00202 LogMajor(COMPONENT_MFSL, "MFSL_create: cannot get time of day... exiting"); 00203 exit(1); 00204 } 00205 00206 /* Now get a pre-allocated directory from the synclet data */ 00207 P(p_mfsl_context->lock); 00208 pprecreated = pool_alloc(p_mfsl_context->pool_files, NULL); 00209 V(p_mfsl_context->lock); 00210 00211 pnewfile_handle = &(pprecreated->mobject); 00212 00213 LogDebug(COMPONENT_MFSL, "Creating asyncop %p", 00214 pasyncopdesc); 00215 00216 pasyncopdesc->op_type = MFSL_ASYNC_OP_CREATE; 00217 00218 pasyncopdesc->op_args.create.pmfsl_obj_dirdest = parent_directory_handle; 00219 pasyncopdesc->op_args.create.precreate_name = pprecreated->name; 00220 pasyncopdesc->op_args.create.filename = *p_dirname; 00221 pasyncopdesc->op_args.create.owner = FSAL_OP_CONTEXT_TO_UID(p_context); 00222 pasyncopdesc->op_args.create.group = FSAL_OP_CONTEXT_TO_GID(p_context); 00223 pasyncopdesc->op_args.create.mode = accessmode; 00224 pasyncopdesc->op_res.create.attr.asked_attributes = object_attributes->asked_attributes; 00225 pasyncopdesc->op_res.create.attr.supported_attributes = 00226 object_attributes->supported_attributes; 00227 00228 pasyncopdesc->ptr_mfsl_context = (caddr_t) p_mfsl_context; 00229 00230 if(FSAL_IS_ERROR(fsal_status)) 00231 return fsal_status; 00232 00233 pasyncopdesc->op_func = MFSL_create_async_op; 00234 //pasyncopdesc->fsal_op_context = p_context ; 00235 pasyncopdesc->fsal_op_context = 00236 synclet_data[pasyncopdesc->related_synclet_index].root_fsal_context; 00237 00238 fsal_status = MFSL_async_post(pasyncopdesc); 00239 if(FSAL_IS_ERROR(fsal_status)) 00240 return fsal_status; 00241 00242 /* Update the asynchronous metadata */ 00243 newfile_pasyncdata->async_attr = pprecreated->attr; 00244 00245 newfile_pasyncdata->async_attr.type = FSAL_TYPE_FILE; 00246 newfile_pasyncdata->async_attr.filesize = 0; /* New file */ 00247 newfile_pasyncdata->async_attr.spaceused = 0; 00248 newfile_pasyncdata->async_attr.numlinks = 1; /* New file */ 00249 00250 newfile_pasyncdata->async_attr.owner = pasyncopdesc->op_args.create.owner; 00251 newfile_pasyncdata->async_attr.group = pasyncopdesc->op_args.create.group; 00252 00253 newfile_pasyncdata->async_attr.ctime.seconds = pasyncopdesc->op_time.tv_sec; 00254 newfile_pasyncdata->async_attr.ctime.nseconds = pasyncopdesc->op_time.tv_usec; 00256 newfile_pasyncdata->deleted = FALSE; 00257 00258 if(!mfsl_async_set_specdata(pnewfile_handle, newfile_pasyncdata)) 00259 MFSL_return(ERR_FSAL_SERVERFAULT, 0); 00260 00261 /* Return the correct attributes */ 00262 *object_attributes = newfile_pasyncdata->async_attr; 00263 *object_handle = pprecreated->mobject; 00264 object_handle->health = MFSL_ASYNC_NEVER_SYNCED; 00265 00266 /* Do not forget that the parent directory becomes asynchronous too */ 00267 parent_directory_handle->health = MFSL_ASYNC_ASYNCHRONOUS; 00268 00269 MFSL_return(ERR_FSAL_NO_ERROR, 0); 00270 } /* MFSL_create */