nfs-ganesha 1.4

mfsl_async_mkdir.c

Go to the documentation of this file.
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 */