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 #include "namespace.h"
00023 
00065 fsal_status_t FUSEFSAL_rename(fsal_handle_t * old_parent, /* IN */
00066                               fsal_name_t * p_old_name, /* IN */
00067                               fsal_handle_t * new_parent, /* IN */
00068                               fsal_name_t * p_new_name, /* IN */
00069                               fsal_op_context_t * p_context,        /* IN */
00070                               fsal_attrib_list_t * src_dir_attributes,  /* [ IN/OUT ] */
00071                               fsal_attrib_list_t * tgt_dir_attributes   /* [ IN/OUT ] */
00072     )
00073 {
00074   fusefsal_handle_t * old_parentdir_handle = (fusefsal_handle_t *)old_parent;
00075   fusefsal_handle_t * new_parentdir_handle = (fusefsal_handle_t *)new_parent;
00076   int rc = 0;
00077   char src_dir_path[FSAL_MAX_PATH_LEN];
00078   char tgt_dir_path[FSAL_MAX_PATH_LEN];
00079   char src_obj_path[FSAL_MAX_PATH_LEN];
00080   char tgt_obj_path[FSAL_MAX_PATH_LEN];
00081 
00082   /* sanity checks.
00083    * note : src/tgt_dir_attributes are optional.
00084    */
00085   if(!old_parentdir_handle ||
00086      !new_parentdir_handle || !p_old_name || !p_new_name || !p_context)
00087     Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_rename);
00088 
00089   if(!p_fs_ops->rename)
00090     Return(ERR_FSAL_NOTSUPP, 0, INDEX_FSAL_rename);
00091 
00092   /* get full path for parent source handle */
00093   rc = NamespacePath(old_parentdir_handle->data.inode, old_parentdir_handle->data.device,
00094                      old_parentdir_handle->data.validator, src_dir_path);
00095   if(rc)
00096     Return(ERR_FSAL_STALE, rc, INDEX_FSAL_rename);
00097 
00098   /* get full path for parent target handle */
00099   rc = NamespacePath(new_parentdir_handle->data.inode, new_parentdir_handle->data.device,
00100                      new_parentdir_handle->data.validator, tgt_dir_path);
00101   if(rc)
00102     Return(ERR_FSAL_STALE, rc, INDEX_FSAL_rename);
00103 
00104   /* build full path for source entry */
00105   FSAL_internal_append_path(src_obj_path, src_dir_path, p_old_name->name);
00106 
00107   /* build full path for target entry */
00108   FSAL_internal_append_path(tgt_obj_path, tgt_dir_path, p_new_name->name);
00109 
00110   /* set context for the next operation, so it can be retrieved by FS thread */
00111   fsal_set_thread_context(p_context);
00112 
00113   TakeTokenFSCall();
00114 
00115   rc = p_fs_ops->rename(src_obj_path, tgt_obj_path);
00116 
00117   ReleaseTokenFSCall();
00118 
00119   /* Regarding FALSE parameter of function fuse2fsal_error:
00120    * here, if error is ENOENT, we don't know weither the father handle is STALE
00121    * or if the source entry does not exist.
00122    * We choose returning ENOENT since the parent exists in the namespace,
00123    * so it it more likely to exist than the children.
00124    */
00125   if(rc)
00126     Return(fuse2fsal_error(rc, FALSE), rc, INDEX_FSAL_rename);
00127 
00128   /* If operation succeeded, impact the namespace */
00129   NamespaceRename(old_parentdir_handle->data.inode, old_parentdir_handle->data.device,
00130                   old_parentdir_handle->data.validator, p_old_name->name,
00131                   new_parentdir_handle->data.inode, new_parentdir_handle->data.device,
00132                   new_parentdir_handle->data.validator, p_new_name->name);
00133 
00134   /* Last parent post op attributes if asked */
00135 
00136   if(src_dir_attributes)
00137     {
00138       fsal_status_t st;
00139 
00140       st = FUSEFSAL_getattrs(old_parentdir_handle, p_context, src_dir_attributes);
00141 
00142       if(FSAL_IS_ERROR(st))
00143         {
00144           FSAL_CLEAR_MASK(src_dir_attributes->asked_attributes);
00145           FSAL_SET_MASK(src_dir_attributes->asked_attributes, FSAL_ATTR_RDATTR_ERR);
00146         }
00147 
00148     }
00149 
00150   /* New parent post op attributes if asked */
00151 
00152   if(tgt_dir_attributes)
00153     {
00154       fsal_status_t st;
00155 
00156       /* optimization when src=tgt : */
00157 
00158       if(!FUSEFSAL_handlecmp(old_parentdir_handle, new_parentdir_handle, &st)
00159          && src_dir_attributes)
00160         {
00161 
00162           /* If source dir = target dir, we just copy the attributes.
00163            * to avoid doing another getattr.
00164            */
00165 
00166           (*tgt_dir_attributes) = (*src_dir_attributes);
00167 
00168         }
00169       else
00170         {
00171 
00172           /* get attributes */
00173           st = FUSEFSAL_getattrs(new_parentdir_handle, p_context, tgt_dir_attributes);
00174 
00175           if(FSAL_IS_ERROR(st))
00176             {
00177               FSAL_CLEAR_MASK(tgt_dir_attributes->asked_attributes);
00178               FSAL_SET_MASK(tgt_dir_attributes->asked_attributes, FSAL_ATTR_RDATTR_ERR);
00179             }
00180 
00181         }
00182 
00183     }
00184 
00185   /* OK */
00186   Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_rename);
00187 
00188 }