nfs-ganesha 1.4

mfsl_async_symlink.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 "log.h"
00042 #include "fsal_types.h"
00043 #include "fsal.h"
00044 #include "mfsl_types.h"
00045 #include "mfsl.h"
00046 #include "common_utils.h"
00047 
00048 #include <pthread.h>
00049 #include <errno.h>
00050 
00051 extern fsal_handle_t tmp_symlink_dirhandle;
00052 extern mfsl_parameter_t mfsl_param;
00053 extern mfsl_synclet_data_t *synclet_data;
00054 
00065 fsal_status_t MFSL_symlink_async_op(mfsl_async_op_desc_t * popasyncdesc)
00066 {
00067   fsal_status_t fsal_status;
00068   fsal_attrib_list_t attrsrc, attrdest, chown_attr;
00069   fsal_handle_t handle;
00070 
00071   attrsrc = attrdest = popasyncdesc->op_res.mkdir.attr;
00072 
00073   LogDebug(COMPONENT_MFSL,
00074                   "Renaming file to complete asynchronous FSAL_symlink for async op %p",
00075                   popasyncdesc);
00076 
00077   P(popasyncdesc->op_args.symlink.pmobject_dirdest->lock);
00078   fsal_status = FSAL_rename(&tmp_symlink_dirhandle,
00079                             &popasyncdesc->op_args.symlink.precreate_name,
00080                             &(popasyncdesc->op_args.symlink.pmobject_dirdest->handle),
00081                             &popasyncdesc->op_args.symlink.linkname,
00082                             &popasyncdesc->fsal_op_context, &attrsrc, &attrdest);
00083   if(FSAL_IS_ERROR(fsal_status))
00084     {
00085       V(popasyncdesc->op_args.symlink.pmobject_dirdest->lock);
00086 
00087       return fsal_status;
00088     }
00089 
00090   V(popasyncdesc->op_args.symlink.pmobject_dirdest->lock);
00091 
00092   return fsal_status;
00093 }                               /* MFSL_symlink_async_op */
00094 
00108 fsal_status_t MFSAL_symlink_check_perms(mfsl_object_t * target_handle,
00109                                         fsal_name_t * p_dirname,
00110                                         fsal_op_context_t * p_context,
00111                                         mfsl_context_t * p_mfsl_context,
00112                                         fsal_attrib_list_t * object_attributes)
00113 {
00114   fsal_status_t fsal_status;
00115 
00116   fsal_status = FSAL_create_access(p_context, object_attributes);
00117 
00118   if(FSAL_IS_ERROR(fsal_status))
00119     return fsal_status;
00120 
00122   MFSL_return(ERR_FSAL_NO_ERROR, 0);
00123 }                               /* MFSL_symlink_check_perms */
00124 
00142 extern fsal_handle_t tmp_symlink_dirhandle;  
00144 fsal_status_t MFSL_symlink(mfsl_object_t * parent_directory_handle,     /* IN */
00145                            fsal_name_t * p_linkname,    /* IN */
00146                            fsal_path_t * p_linkcontent, /* IN */
00147                            fsal_op_context_t * p_context,       /* IN */
00148                            mfsl_context_t * p_mfsl_context,     /* IN */
00149                            fsal_accessmode_t accessmode,        /* IN (ignored); */
00150                            mfsl_object_t * link_handle, /* OUT */
00151                            fsal_attrib_list_t * link_attributes /* [ IN/OUT ] */ )
00152 {
00153   fsal_status_t fsal_status;
00154   mfsl_async_op_desc_t *pasyncopdesc = NULL;
00155   mfsl_object_specific_data_t *symlink_pasyncdata = NULL;
00156   mfsl_object_t *psymlink_handle = NULL;
00157   fsal_name_t tmp_fsal_name;
00158   char tmp_name[MAXNAMLEN];
00159   static unsigned int counter = 0;
00160 
00161   snprintf(tmp_name, MAXNAMLEN, "%s.%u", p_linkname->name, counter);
00162   counter += 1;
00163 
00164   if(FSAL_IS_ERROR(FSAL_str2name(tmp_name, MAXNAMLEN, &tmp_fsal_name)))
00165     return fsal_status;
00166 
00167   fsal_status = MFSAL_symlink_check_perms(parent_directory_handle,
00168                                           p_linkname,
00169                                           p_context, p_mfsl_context, link_attributes);
00170 
00171   if(FSAL_IS_ERROR(fsal_status))
00172     return fsal_status;
00173 
00174   P(parent_directory_handle->lock);
00175   fsal_status = FSAL_symlink(&tmp_symlink_dirhandle,
00176                              &tmp_fsal_name,
00177                              p_linkcontent,
00178                              p_context,
00179                              accessmode, &link_handle->handle, link_attributes);
00180   V(parent_directory_handle->lock);
00181 
00182   P(p_mfsl_context->lock);
00183 
00184   pasyncopdesc = pool_alloc(p_mfsl_context->pool_async_op, NULL);
00185 
00186   symlink_pasyncdata = pool_alloc(p_mfsl_context->pool_spec_data, NULL);
00187 
00188   V(p_mfsl_context->lock);
00189 
00190   if(pasyncopdesc == NULL)
00191     MFSL_return(ERR_FSAL_INVAL, 0);
00192 
00193   if(gettimeofday(&pasyncopdesc->op_time, NULL) != 0)
00194     {
00195       /* Could'not get time of day... Stopping, this may need a major failure */
00196       LogMajor(COMPONENT_MFSL, "MFSL_synlink: cannot get time of day... exiting");
00197       exit(1);
00198     }
00199 
00200   LogDebug(COMPONENT_MFSL,  "Creating asyncop %p",
00201                     pasyncopdesc);
00202 
00203   pasyncopdesc->op_type = MFSL_ASYNC_OP_SYMLINK;
00204 
00205   pasyncopdesc->op_args.symlink.pmobject_dirdest = parent_directory_handle;
00206   pasyncopdesc->op_args.symlink.precreate_name = tmp_fsal_name;
00207   pasyncopdesc->op_args.symlink.linkname = *p_linkname;
00208 
00209   pasyncopdesc->op_res.symlink.attr.asked_attributes = link_attributes->asked_attributes;
00210   pasyncopdesc->op_res.symlink.attr.supported_attributes =
00211       link_attributes->supported_attributes;
00212 
00213   pasyncopdesc->ptr_mfsl_context = (caddr_t) p_mfsl_context;
00214 
00215   if(FSAL_IS_ERROR(fsal_status))
00216     return fsal_status;
00217 
00218   pasyncopdesc->op_func = MFSL_symlink_async_op;
00219   //pasyncopdesc->fsal_op_context = p_context ;
00220   pasyncopdesc->fsal_op_context =
00221       synclet_data[pasyncopdesc->related_synclet_index].root_fsal_context;
00222 
00223   fsal_status = MFSL_async_post(pasyncopdesc);
00224   if(FSAL_IS_ERROR(fsal_status))
00225     return fsal_status;
00226 
00227   /* Update the asynchronous metadata */
00228   symlink_pasyncdata->async_attr = *link_attributes;
00229   symlink_pasyncdata->deleted = FALSE;
00230 
00231   if(!mfsl_async_set_specdata(link_handle, symlink_pasyncdata))
00232     MFSL_return(ERR_FSAL_SERVERFAULT, 0);
00233 
00234   /* Return the correct attributes */
00235   link_handle->health = MFSL_ASYNC_NEVER_SYNCED;
00236 
00237   /* Do not forget that the parent directory becomes asynchronous too */
00238   parent_directory_handle->health = MFSL_ASYNC_ASYNCHRONOUS;
00239 
00240   MFSL_return(ERR_FSAL_NO_ERROR, 0);
00241 }                               /* MFSL_symlink */
00242 
00243 #ifdef _HAVE_SYNCHRONOUS_SYMLINK
00244 fsal_status_t MFSL_symlink(mfsl_object_t * parent_directory_handle,     /* IN */
00245                            fsal_name_t * p_linkname,    /* IN */
00246                            fsal_path_t * p_linkcontent, /* IN */
00247                            fsal_op_context_t * p_context,       /* IN */
00248                            mfsl_context_t * p_mfsl_context,     /* IN */
00249                            fsal_accessmode_t accessmode,        /* IN (ignored); */
00250                            mfsl_object_t * link_handle, /* OUT */
00251                            fsal_attrib_list_t * link_attributes /* [ IN/OUT ] */
00252     )
00253 {
00254   fsal_status_t fsal_status;
00255 
00256   P(parent_directory_handle->lock);
00257   fsal_status = FSAL_symlink(&parent_directory_handle->handle,
00258                              p_linkname,
00259                              p_linkcontent,
00260                              p_context,
00261                              accessmode, &link_handle->handle, link_attributes);
00262   V(parent_directory_handle->lock);
00263 
00264   if(FSAL_IS_ERROR(fsal_status))
00265     return fsal_status;
00266 
00267   /* If successful, the symlink's mobject should be clearly indentified as a symbolic link: a symbolic link can't be an asynchronous 
00268    * object and it has to remain synchronous everywhere */
00269   link_handle->health = MFSL_ASYNC_IS_SYMLINK;
00270 
00271   MFSL_return(ERR_FSAL_NO_ERROR, 0);
00272 }                               /* MFSL_symlink */
00273 #endif