nfs-ganesha 1.4

mfsl_async_rename.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 
00060 fsal_status_t MFSL_rename_async_op(mfsl_async_op_desc_t * popasyncdesc)
00061 {
00062   fsal_status_t fsal_status;
00063 
00064   LogDebug(COMPONENT_MFSL, "Making asynchronous FSAL_rename for async op %p",
00065                   popasyncdesc);
00066 
00067   if(popasyncdesc->op_args.rename.pmobject_src !=
00068      popasyncdesc->op_args.rename.pmobject_dirdest)
00069     {
00070       P(popasyncdesc->op_args.rename.pmobject_src->lock);
00071       P(popasyncdesc->op_args.rename.pmobject_dirdest->lock);
00072     }
00073   else
00074     P(popasyncdesc->op_args.rename.pmobject_src->lock);
00075 
00076   fsal_status = FSAL_rename(&(popasyncdesc->op_args.rename.pmobject_src->handle),
00077                             &popasyncdesc->op_args.rename.name_src,
00078                             &(popasyncdesc->op_args.rename.pmobject_dirdest->handle),
00079                             &popasyncdesc->op_args.rename.name_dest,
00080                             &popasyncdesc->fsal_op_context,
00081                             &popasyncdesc->op_res.rename.attrsrc,
00082                             &popasyncdesc->op_res.rename.attrdest);
00083 
00084   if(popasyncdesc->op_args.rename.pmobject_src !=
00085      popasyncdesc->op_args.rename.pmobject_dirdest)
00086     {
00087       V(popasyncdesc->op_args.rename.pmobject_src->lock);
00088       V(popasyncdesc->op_args.rename.pmobject_dirdest->lock);
00089     }
00090   else
00091     V(popasyncdesc->op_args.rename.pmobject_src->lock);
00092 
00093   return fsal_status;
00094 }                               /* MFSL_rename_async_op */
00095 
00113 fsal_status_t MFSAL_rename_check_perms(mfsl_object_t * old_parentdir_handle,    /* IN */
00114                                        fsal_name_t * p_old_name,        /* IN */
00115                                        fsal_attrib_list_t * src_dir_attributes, /* [ IN/OUT ] */
00116                                        mfsl_object_t * new_parentdir_handle,    /* IN */
00117                                        fsal_name_t * p_new_name,        /* IN */
00118                                        fsal_attrib_list_t * tgt_dir_attributes, /* [ IN/OUT ] */
00119                                        fsal_op_context_t * p_context,   /* IN */
00120                                        mfsl_context_t * p_mfsl_context /* IN */ )
00121 {
00122   fsal_status_t fsal_status;
00123 
00124   /* Check for the attributes first */
00125   fsal_status = FSAL_rename_access(p_context, src_dir_attributes, tgt_dir_attributes);
00126 
00127   if(FSAL_IS_ERROR(fsal_status))
00128     return fsal_status;
00129 
00131   MFSL_return(ERR_FSAL_NO_ERROR, 0);
00132 }                               /* MFSL_rename_check_perms */
00133 
00152 fsal_status_t MFSL_rename(mfsl_object_t * old_parentdir_handle, /* IN */
00153                           fsal_name_t * p_old_name,     /* IN */
00154                           mfsl_object_t * new_parentdir_handle, /* IN */
00155                           fsal_name_t * p_new_name,     /* IN */
00156                           fsal_op_context_t * p_context,        /* IN */
00157                           mfsl_context_t * p_mfsl_context,      /* IN */
00158                           fsal_attrib_list_t * src_dir_attributes,      /* [ IN/OUT ] */
00159                           fsal_attrib_list_t * tgt_dir_attributes /* [ IN/OUT ] */ )
00160 {
00161   fsal_status_t fsal_status;
00162   mfsl_async_op_desc_t *pasyncopdesc = NULL;
00163   mfsl_object_specific_data_t *old_parentdir_pasyncdata = NULL;
00164   mfsl_object_specific_data_t *new_parentdir_pasyncdata = NULL;
00165 
00166   P(p_mfsl_context->lock);
00167 
00168   pasyncopdesc = pool_alloc(p_mfsl_context->pool_async_op, NULL);
00169 
00170   V(p_mfsl_context->lock);
00171 
00172   if(pasyncopdesc == NULL)
00173     MFSL_return(ERR_FSAL_INVAL, 0);
00174 
00175   if(gettimeofday(&pasyncopdesc->op_time, NULL) != 0)
00176     {
00177       /* Could'not get time of day... Stopping, this may need a major failure */
00178       LogMajor(COMPONENT_MFSL,"MFSL_link: cannot get time of day... exiting");
00179       exit(1);
00180     }
00181 
00182   if(!mfsl_async_get_specdata(old_parentdir_handle, &old_parentdir_pasyncdata))
00183     {
00184       /* Target is not yet asynchronous */
00185       P(p_mfsl_context->lock);
00186 
00187       old_parentdir_pasyncdata
00188            = pool_alloc(p_mfsl_context->pool_spec_data, NULL);
00189 
00190       V(p_mfsl_context->lock);
00191 
00192       /* In this case use object_attributes parameter to initiate asynchronous object */
00193       old_parentdir_pasyncdata->async_attr = *src_dir_attributes;
00194     }
00195 
00196   if(!mfsl_async_get_specdata(new_parentdir_handle, &new_parentdir_pasyncdata))
00197     {
00198       /* Target is not yet asynchronous */
00199       P(p_mfsl_context->lock);
00200 
00201       new_parentdir_pasyncdata
00202            = pool_alloc(p_mfsl_context->pool_spec_data, NULL);
00203 
00204       V(p_mfsl_context->lock);
00205 
00206       /* In this case use object_attributes parameter to initiate asynchronous object */
00207       new_parentdir_pasyncdata->async_attr = *tgt_dir_attributes;
00208     }
00209 
00210   fsal_status = MFSAL_rename_check_perms(old_parentdir_handle,
00211                                          p_old_name,
00212                                          src_dir_attributes,
00213                                          new_parentdir_handle,
00214                                          p_new_name,
00215                                          tgt_dir_attributes, p_context, p_mfsl_context);
00216 
00217   if(FSAL_IS_ERROR(fsal_status))
00218     return fsal_status;
00219 
00220   LogDebug(COMPONENT_MFSL, "Creating asyncop %p",
00221                     pasyncopdesc);
00222 
00223   pasyncopdesc->op_type = MFSL_ASYNC_OP_RENAME;
00224 
00225   pasyncopdesc->op_args.rename.pmobject_src = old_parentdir_handle;
00226   pasyncopdesc->op_args.rename.name_src = *p_old_name;
00227   pasyncopdesc->op_res.rename.attrsrc = *src_dir_attributes;
00228 
00229   pasyncopdesc->op_args.rename.pmobject_dirdest = new_parentdir_handle;
00230   pasyncopdesc->op_args.rename.name_dest = *p_new_name;
00231   pasyncopdesc->op_res.rename.attrdest = *tgt_dir_attributes;
00232 
00233   pasyncopdesc->op_func = MFSL_rename_async_op;
00234   pasyncopdesc->fsal_op_context = *p_context;
00235 
00236   pasyncopdesc->ptr_mfsl_context = (caddr_t) p_mfsl_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   old_parentdir_pasyncdata->async_attr.ctime.seconds = pasyncopdesc->op_time.tv_sec;
00244   old_parentdir_pasyncdata->async_attr.ctime.nseconds = pasyncopdesc->op_time.tv_usec;  
00245   old_parentdir_handle->health = MFSL_ASYNC_ASYNCHRONOUS;
00246 
00247   new_parentdir_pasyncdata->async_attr.ctime.seconds = pasyncopdesc->op_time.tv_sec;
00248   new_parentdir_pasyncdata->async_attr.ctime.nseconds = pasyncopdesc->op_time.tv_usec;  
00249   new_parentdir_handle->health = MFSL_ASYNC_ASYNCHRONOUS;
00250 
00251   if(!mfsl_async_set_specdata(old_parentdir_handle, old_parentdir_pasyncdata))
00252     MFSL_return(ERR_FSAL_SERVERFAULT, 0);
00253 
00254   if(!mfsl_async_set_specdata(new_parentdir_handle, new_parentdir_pasyncdata))
00255     MFSL_return(ERR_FSAL_SERVERFAULT, 0);
00256 
00257   /* Return the correct attributes */
00258   *src_dir_attributes = old_parentdir_pasyncdata->async_attr;
00259   *tgt_dir_attributes = new_parentdir_pasyncdata->async_attr;
00260 
00261   MFSL_return(ERR_FSAL_NO_ERROR, 0);
00262 }                               /* MFSL_rename */