nfs-ganesha 1.4
|
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 }