nfs-ganesha 1.4

fsal_rename.c

Go to the documentation of this file.
00001 /*
00002  * vim:expandtab:shiftwidth=8:tabstop=8:
00003  */
00004 
00014 #ifdef HAVE_CONFIG_H
00015 #include "config.h"
00016 #endif
00017 
00018 #include "fsal.h"
00019 #include "fsal_internal.h"
00020 #include "fsal_convert.h"
00021 #include "fsal_common.h"
00022 
00064 fsal_status_t ZFSFSAL_rename(fsal_handle_t * old_parentdir_handle, /* IN */
00065                           fsal_name_t * p_old_name,     /* IN */
00066                           fsal_handle_t * new_parentdir_handle, /* IN */
00067                           fsal_name_t * p_new_name,     /* IN */
00068                           fsal_op_context_t * p_context,        /* IN */
00069                           fsal_attrib_list_t * src_dir_attributes,      /* [ IN/OUT ] */
00070                           fsal_attrib_list_t * tgt_dir_attributes       /* [ IN/OUT ] */
00071     )
00072 {
00073 
00074   int rc;
00075   creden_t cred;
00076 
00077   /* sanity checks.
00078    * note : src/tgt_dir_attributes are optional.
00079    */
00080   if(!old_parentdir_handle ||
00081      !new_parentdir_handle || !p_old_name || !p_new_name || !p_context)
00082     Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_rename);
00083 
00084   /* Hook to prenvet moving thing from or to a snapshot */
00085   if(((zfsfsal_handle_t *)old_parentdir_handle)->data.i_snap != 0 ||
00086      ((zfsfsal_handle_t *)new_parentdir_handle)->data.i_snap != 0)
00087   {
00088     LogDebug(COMPONENT_FSAL, "Trying to rename an object from/to a snapshot");
00089     Return(ERR_FSAL_ROFS, 0, INDEX_FSAL_rename);
00090   }
00091   cred.uid = p_context->credential.user;
00092   cred.gid = p_context->credential.group;
00093 
00094   TakeTokenFSCall();
00095 
00096   rc = libzfswrap_rename(((zfsfsal_op_context_t *)p_context)->export_context->p_vfs,
00097                          &cred,
00098                          ((zfsfsal_handle_t *)old_parentdir_handle)->data.zfs_handle,
00099                          p_old_name->name,
00100                          ((zfsfsal_handle_t *)new_parentdir_handle)->data.zfs_handle,
00101                          p_new_name->name);
00102 
00103   ReleaseTokenFSCall();
00104 
00105   /* >> interpret the returned error << */
00106   if(rc)
00107     Return(posix2fsal_error(rc), 0, INDEX_FSAL_rename);
00108 
00109   /* >> get last parent post op attributes if asked
00110    * For example : << */
00111 
00112   if(src_dir_attributes)
00113     {
00114       fsal_status_t st;
00115 
00116       st = ZFSFSAL_getattrs(old_parentdir_handle, p_context, src_dir_attributes);
00117 
00118       if(FSAL_IS_ERROR(st))
00119         {
00120           FSAL_CLEAR_MASK(src_dir_attributes->asked_attributes);
00121           FSAL_SET_MASK(src_dir_attributes->asked_attributes, FSAL_ATTR_RDATTR_ERR);
00122         }
00123 
00124     }
00125 
00126   /* >> get new parent post op attributes if asked
00127    * For example : << */
00128 
00129   if(tgt_dir_attributes)
00130     {
00131       fsal_status_t st;
00132 
00133       /* optimization when src=tgt : */
00134 
00135       if(!ZFSFSAL_handlecmp(old_parentdir_handle, new_parentdir_handle, &st)
00136          && src_dir_attributes)
00137         {
00138 
00139           /* If source dir = target dir, we just copy the attributes.
00140            * to avoid doing another getattr.
00141            */
00142 
00143           (*tgt_dir_attributes) = (*src_dir_attributes);
00144 
00145         }
00146       else
00147         {
00148 
00149           /* get attributes */
00150           st = ZFSFSAL_getattrs(new_parentdir_handle, p_context, tgt_dir_attributes);
00151 
00152           if(FSAL_IS_ERROR(st))
00153             {
00154               FSAL_CLEAR_MASK(tgt_dir_attributes->asked_attributes);
00155               FSAL_SET_MASK(tgt_dir_attributes->asked_attributes, FSAL_ATTR_RDATTR_ERR);
00156             }
00157 
00158         }
00159 
00160     }
00161 
00162   /* OK */
00163   Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_rename);
00164 
00165 }