nfs-ganesha 1.4

mfsl_async_create.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 #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 */