nfs-ganesha 1.4
|
00001 /* 00002 * vim:expandtab:shiftwidth=8:tabstop=8: 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 00034 #ifdef HAVE_CONFIG_H 00035 #include "config.h" 00036 #endif 00037 00038 #include <string.h> 00039 #include "fsal.h" 00040 #include "fsal_internal.h" 00041 #include "fsal_convert.h" 00042 00070 fsal_status_t GPFSFSAL_lookup(fsal_handle_t * p_parent_directory_handle, /* IN */ 00071 fsal_name_t * p_filename, /* IN */ 00072 fsal_op_context_t * p_context, /* IN */ 00073 fsal_handle_t * object_handle, /* OUT */ 00074 fsal_attrib_list_t * p_object_attributes /* [ IN/OUT ] */ 00075 ) 00076 { 00077 fsal_status_t status; 00078 int parentfd; 00079 fsal_accessflags_t access_mask = 0; 00080 fsal_attrib_list_t parent_dir_attrs; 00081 gpfsfsal_handle_t *p_object_handle = (gpfsfsal_handle_t *)object_handle; 00082 00083 /* sanity checks 00084 * note : object_attributes is optional 00085 * parent_directory_handle may be null for getting FS root. 00086 */ 00087 if(!p_object_handle || !p_context) 00088 Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_lookup); 00089 00090 /* filename AND parent handle are NULL => lookup "/" */ 00091 if((p_parent_directory_handle && !p_filename) 00092 || (!p_parent_directory_handle && p_filename)) 00093 Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_lookup); 00094 00095 /* get information about root */ 00096 if(!p_parent_directory_handle) 00097 { 00098 gpfsfsal_handle_t *root_handle = &((gpfsfsal_op_context_t *)p_context)->export_context->mount_root_handle; 00099 00100 /* get handle for the mount point */ 00101 memcpy(p_object_handle->data.handle.f_handle, 00102 root_handle->data.handle.f_handle, 00103 sizeof(root_handle->data.handle.handle_size)); 00104 p_object_handle->data.handle.handle_size = root_handle->data.handle.handle_size; 00105 p_object_handle->data.handle.handle_key_size = root_handle->data.handle.handle_key_size; 00106 00107 /* get attributes, if asked */ 00108 if(p_object_attributes) 00109 { 00110 status = GPFSFSAL_getattrs(object_handle, p_context, p_object_attributes); 00111 if(FSAL_IS_ERROR(status)) 00112 { 00113 FSAL_CLEAR_MASK(p_object_attributes->asked_attributes); 00114 FSAL_SET_MASK(p_object_attributes->asked_attributes, FSAL_ATTR_RDATTR_ERR); 00115 } 00116 } 00117 /* Done */ 00118 Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_lookup); 00119 } 00120 00121 /* retrieve directory attributes */ 00122 TakeTokenFSCall(); 00123 status = 00124 fsal_internal_handle2fd(p_context, p_parent_directory_handle, &parentfd, O_RDONLY); 00125 ReleaseTokenFSCall(); 00126 if(FSAL_IS_ERROR(status)) 00127 ReturnStatus(status, INDEX_FSAL_lookup); 00128 00129 /* get directory metadata */ 00130 00131 parent_dir_attrs.asked_attributes = GPFS_SUPPORTED_ATTRIBUTES; 00132 status = GPFSFSAL_getattrs(p_parent_directory_handle, p_context, &parent_dir_attrs); 00133 if(FSAL_IS_ERROR(status)) 00134 { 00135 close(parentfd); 00136 ReturnStatus(status, INDEX_FSAL_lookup); 00137 } 00138 00139 /* Be careful about junction crossing, symlinks, hardlinks,... */ 00140 switch (parent_dir_attrs.type) 00141 { 00142 case FSAL_TYPE_DIR: 00143 // OK 00144 break; 00145 00146 case FSAL_TYPE_JUNCTION: 00147 // This is a junction 00148 close(parentfd); 00149 Return(ERR_FSAL_XDEV, 0, INDEX_FSAL_lookup); 00150 00151 case FSAL_TYPE_FILE: 00152 case FSAL_TYPE_LNK: 00153 case FSAL_TYPE_XATTR: 00154 // not a directory 00155 close(parentfd); 00156 Return(ERR_FSAL_NOTDIR, 0, INDEX_FSAL_lookup); 00157 00158 default: 00159 close(parentfd); 00160 Return(ERR_FSAL_SERVERFAULT, 0, INDEX_FSAL_lookup); 00161 } 00162 00163 // LogFullDebug(COMPONENT_FSAL, 00164 // "lookup of %#llx:%#x:%#x/%s", p_parent_directory_handle->seq, 00165 // p_parent_directory_handle->oid, p_parent_directory_handle->ver, 00166 // p_filename->name); 00167 00168 /* check rights to enter into the directory */ 00169 00170 /* Set both mode and ace4 mask */ 00171 access_mask = FSAL_MODE_MASK_SET(FSAL_R_OK | FSAL_X_OK) | 00172 FSAL_ACE4_MASK_SET(FSAL_ACE_PERM_LIST_DIR); 00173 00174 if(!p_context->export_context->fe_static_fs_info->accesscheck_support) 00175 status = fsal_internal_testAccess(p_context, access_mask, NULL, &parent_dir_attrs); 00176 else 00177 status = fsal_internal_access(p_context, p_parent_directory_handle, access_mask, 00178 &parent_dir_attrs); 00179 if(FSAL_IS_ERROR(status)) 00180 { 00181 close(parentfd); 00182 ReturnStatus(status, INDEX_FSAL_lookup); 00183 } 00184 00185 /* get file handle, it it exists */ 00186 /* This might be a race, but it's the best we can currently do */ 00187 status = fsal_internal_get_handle_at(parentfd, p_filename, object_handle); 00188 close(parentfd); 00189 00190 if(FSAL_IS_ERROR(status)) 00191 ReturnStatus(status, INDEX_FSAL_lookup); 00192 00193 /* get object attributes */ 00194 if(p_object_attributes) 00195 { 00196 status = GPFSFSAL_getattrs(object_handle, p_context, p_object_attributes); 00197 if(FSAL_IS_ERROR(status)) 00198 { 00199 FSAL_CLEAR_MASK(p_object_attributes->asked_attributes); 00200 FSAL_SET_MASK(p_object_attributes->asked_attributes, FSAL_ATTR_RDATTR_ERR); 00201 } 00202 } 00203 00204 /* lookup complete ! */ 00205 Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_lookup); 00206 } 00207 00230 fsal_status_t GPFSFSAL_lookupPath(fsal_path_t * p_path, /* IN */ 00231 fsal_op_context_t * p_context, /* IN */ 00232 fsal_handle_t * object_handle, /* OUT */ 00233 fsal_attrib_list_t * p_object_attributes /* [ IN/OUT ] */ 00234 ) 00235 { 00236 fsal_status_t status; 00237 00238 /* sanity checks 00239 * note : object_attributes is optionnal. 00240 */ 00241 00242 if(!object_handle || !p_context || !p_path) 00243 Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_lookupPath); 00244 00245 /* test whether the path begins with a slash */ 00246 00247 if(p_path->path[0] != '/') 00248 Return(ERR_FSAL_INVAL, 0, INDEX_FSAL_lookupPath); 00249 00250 /* directly call the lookup function */ 00251 00252 status = fsal_internal_get_handle(p_context, p_path, object_handle); 00253 if(FSAL_IS_ERROR(status)) 00254 ReturnStatus(status, INDEX_FSAL_lookupPath); 00255 00256 /* get object attributes */ 00257 if(p_object_attributes) 00258 { 00259 status = GPFSFSAL_getattrs(object_handle, p_context, p_object_attributes); 00260 if(FSAL_IS_ERROR(status)) 00261 { 00262 FSAL_CLEAR_MASK(p_object_attributes->asked_attributes); 00263 FSAL_SET_MASK(p_object_attributes->asked_attributes, FSAL_ATTR_RDATTR_ERR); 00264 } 00265 } 00266 00267 Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_lookupPath); 00268 00269 } 00270 00294 fsal_status_t GPFSFSAL_lookupJunction(fsal_handle_t * p_junction_handle, /* IN */ 00295 fsal_op_context_t * p_context, /* IN */ 00296 fsal_handle_t * p_fsoot_handle, /* OUT */ 00297 fsal_attrib_list_t * p_fsroot_attributes /* [ IN/OUT ] */ 00298 ) 00299 { 00300 Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_lookupJunction); 00301 }