nfs-ganesha 1.4

mfsl_async_link.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 
00059 fsal_status_t MFSL_link_async_op(mfsl_async_op_desc_t * popasyncdesc)
00060 {
00061   fsal_status_t fsal_status;
00062 
00063   LogDebug(COMPONENT_MFSL, "Making asynchronous FSAL_link for async op %p",
00064                   popasyncdesc);
00065 
00066   if(popasyncdesc->op_args.link.pmobject_src !=
00067      popasyncdesc->op_args.link.pmobject_dirdest)
00068     {
00069       P(popasyncdesc->op_args.link.pmobject_src->lock);
00070       P(popasyncdesc->op_args.link.pmobject_dirdest->lock);
00071     }
00072   else
00073     {
00074       P(popasyncdesc->op_args.link.pmobject_src->lock);
00075     }
00076 
00077   fsal_status = FSAL_link(&popasyncdesc->op_args.link.pmobject_src->handle,
00078                           &popasyncdesc->op_args.link.pmobject_dirdest->handle,
00079                           &popasyncdesc->op_args.link.name_link,
00080                           &popasyncdesc->fsal_op_context,
00081                           &popasyncdesc->op_res.link.attr);
00082 
00083   if(popasyncdesc->op_args.link.pmobject_src !=
00084      popasyncdesc->op_args.link.pmobject_dirdest)
00085     {
00086       V(popasyncdesc->op_args.link.pmobject_src->lock);
00087       V(popasyncdesc->op_args.link.pmobject_dirdest->lock);
00088     }
00089   else
00090     {
00091       V(popasyncdesc->op_args.link.pmobject_src->lock);
00092     }
00093 
00094   return fsal_status;
00095 }                               /* MFSL_link_async_op */
00096 
00112 fsal_status_t MFSAL_link_check_perms(mfsl_object_t * target_handle,     /* IN */
00113                                      mfsl_object_t * dir_handle,        /* IN */
00114                                      fsal_name_t * p_link_name, /* IN */
00115                                      mfsl_object_specific_data_t * tgt_pspecdata,       /* IN */
00116                                      mfsl_object_specific_data_t * dir_pspecdata,       /* IN */
00117                                      fsal_op_context_t * p_context,     /* IN */
00118                                      mfsl_context_t * p_mfsl_context /* IN */ )
00119 {
00120   fsal_status_t fsal_status;
00121 
00122   fsal_status = FSAL_link_access(p_context, &dir_pspecdata->async_attr);
00123 
00124   if(FSAL_IS_ERROR(fsal_status))
00125     return fsal_status;
00126 
00128   MFSL_return(ERR_FSAL_NO_ERROR, 0);
00129 }                               /* MFSL_link_check_perms */
00130 
00148 fsal_status_t MFSL_link(mfsl_object_t * target_handle,  /* IN */
00149                         mfsl_object_t * dir_handle,     /* IN */
00150                         fsal_name_t * p_link_name,      /* IN */
00151                         fsal_op_context_t * p_context,  /* IN */
00152                         mfsl_context_t * p_mfsl_context,        /* IN */
00153                         fsal_attrib_list_t * tgt_attributes,    /* [ IN/OUT ] */
00154                         fsal_attrib_list_t * dir_attributes /* [ IN/OUT ] */ )
00155 {
00156   fsal_status_t fsal_status;
00157   mfsl_async_op_desc_t *pasyncopdesc = NULL;
00158   mfsl_object_specific_data_t *tgt_pasyncdata = NULL;
00159   mfsl_object_specific_data_t *dir_pasyncdata = NULL;
00160 
00161   P(p_mfsl_context->lock);
00162 
00163   pasyncopdesc = pool_alloc(p_mfsl_context->pool_async_op, NULL);
00164 
00165   V(p_mfsl_context->lock);
00166 
00167   if(pasyncopdesc == NULL)
00168     MFSL_return(ERR_FSAL_INVAL, 0);
00169 
00170   if(gettimeofday(&pasyncopdesc->op_time, NULL) != 0)
00171     {
00172       /* Could'not get time of day... Stopping, this may need a major failure */
00173       LogMajor(COMPONENT_MFSL, "MFSL_link: cannot get time of day... exiting");
00174       exit(1);
00175     }
00176 
00177   if(!mfsl_async_get_specdata(target_handle, &tgt_pasyncdata))
00178     {
00179       /* Target is not yet asynchronous */
00180       P(p_mfsl_context->lock);
00181 
00182       tgt_pasyncdata = pool_alloc(p_mfsl_context->pool_spec_data, NULL);
00183 
00184       V(p_mfsl_context->lock);
00185 
00186       /* In this case use object_attributes parameter to initiate asynchronous object */
00187       tgt_pasyncdata->async_attr = *tgt_attributes;
00188     }
00189 
00190   if(!mfsl_async_get_specdata(dir_handle, &dir_pasyncdata))
00191     {
00192       /* Target is not yet asynchronous */
00193       P(p_mfsl_context->lock);
00194 
00195       dir_pasyncdata = pool_alloc(p_mfsl_context->pool_spec_data, NULL);
00196 
00197       V(p_mfsl_context->lock);
00198 
00199       /* In this case use object_attributes parameter to initiate asynchronous object */
00200       dir_pasyncdata->async_attr = *dir_attributes;
00201     }
00202 
00203   fsal_status = MFSAL_link_check_perms(target_handle,
00204                                        dir_handle,
00205                                        p_link_name,
00206                                        tgt_pasyncdata,
00207                                        dir_pasyncdata, p_context, p_mfsl_context);
00208 
00209   if(FSAL_IS_ERROR(fsal_status))
00210     return fsal_status;
00211 
00212   LogDebug(COMPONENT_MFSL,  "Creating asyncop %p",
00213                     pasyncopdesc);
00214 
00215   pasyncopdesc->op_type = MFSL_ASYNC_OP_LINK;
00216   pasyncopdesc->op_args.link.pmobject_src = target_handle;
00217   pasyncopdesc->op_args.link.pmobject_dirdest = dir_handle;
00218   pasyncopdesc->op_args.link.name_link = *p_link_name;
00219   pasyncopdesc->op_res.link.attr = *tgt_attributes;
00220 
00221   pasyncopdesc->op_func = MFSL_link_async_op;
00222   pasyncopdesc->fsal_op_context = *p_context;
00223 
00224   pasyncopdesc->ptr_mfsl_context = (caddr_t) p_mfsl_context;
00225 
00226   fsal_status = MFSL_async_post(pasyncopdesc);
00227   if(FSAL_IS_ERROR(fsal_status))
00228     return fsal_status;
00229 
00230   /* Update the asynchronous metadata */
00231   tgt_pasyncdata->async_attr.ctime.seconds = pasyncopdesc->op_time.tv_sec;
00232   tgt_pasyncdata->async_attr.ctime.nseconds = pasyncopdesc->op_time.tv_usec;  
00233   tgt_pasyncdata->async_attr.numlinks += 1;
00234 
00235   dir_pasyncdata->async_attr.ctime.seconds = pasyncopdesc->op_time.tv_sec;
00236   dir_pasyncdata->async_attr.ctime.nseconds = pasyncopdesc->op_time.tv_usec;  
00238   if(!mfsl_async_set_specdata(target_handle, tgt_pasyncdata))
00239     MFSL_return(ERR_FSAL_SERVERFAULT, 0);
00240 
00241   if(!mfsl_async_set_specdata(dir_handle, dir_pasyncdata))
00242     MFSL_return(ERR_FSAL_SERVERFAULT, 0);
00243 
00244   target_handle->health = MFSL_ASYNC_ASYNCHRONOUS;
00245   dir_handle->health = MFSL_ASYNC_ASYNCHRONOUS;
00246 
00247   /* Return the correct attributes */
00248   *tgt_attributes = tgt_pasyncdata->async_attr;
00249   *dir_attributes = dir_pasyncdata->async_attr;
00250 
00251   MFSL_return(ERR_FSAL_NO_ERROR, 0);
00252 }                               /* MFSL_link */