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/access_check.h" 00042 #include "fsal_convert.h" 00043 00070 fsal_status_t VFSFSAL_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 * p_object_handle, /* OUT */ 00074 fsal_attrib_list_t * p_object_attributes /* [ IN/OUT ] */ 00075 ) 00076 { 00077 vfsfsal_handle_t * vfs_handle = (vfsfsal_handle_t *)p_object_handle; 00078 vfsfsal_op_context_t *vfs_context = (vfsfsal_op_context_t *)p_context; 00079 int rc, errsv; 00080 fsal_status_t status; 00081 struct stat buffstat; 00082 int parentfd; 00083 00084 /* sanity checks 00085 * note : object_attributes is optionnal 00086 * parent_directory_handle may be null for getting FS root. 00087 */ 00088 if(!p_object_handle || !p_context) 00089 Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_lookup); 00090 00091 /* filename AND parent handle are NULL => lookup "/" */ 00092 if((p_parent_directory_handle && !p_filename) 00093 || (!p_parent_directory_handle && p_filename)) 00094 Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_lookup); 00095 00096 /* get information about root */ 00097 if(!p_parent_directory_handle) 00098 { 00099 /* Copy the root handle */ 00100 memcpy( (char *)&vfs_handle->data.vfs_handle, 00101 (char *)&vfs_context->export_context->root_handle, 00102 sizeof( vfs_file_handle_t ) ) ; 00103 00104 /* get attributes, if asked */ 00105 if(p_object_attributes) 00106 { 00107 status = VFSFSAL_getattrs(p_object_handle, p_context, p_object_attributes); 00108 if(FSAL_IS_ERROR(status)) 00109 { 00110 FSAL_CLEAR_MASK(p_object_attributes->asked_attributes); 00111 FSAL_SET_MASK(p_object_attributes->asked_attributes, FSAL_ATTR_RDATTR_ERR); 00112 } 00113 } 00114 /* Done */ 00115 Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_lookup); 00116 } 00117 00118 /* retrieve directory attributes */ 00119 TakeTokenFSCall(); 00120 status = 00121 fsal_internal_handle2fd(p_context, p_parent_directory_handle, &parentfd, O_RDONLY); 00122 ReleaseTokenFSCall(); 00123 if(FSAL_IS_ERROR(status)) 00124 ReturnStatus(status, INDEX_FSAL_lookup); 00125 00126 /* get directory metadata */ 00127 TakeTokenFSCall(); 00128 rc = fstat(parentfd, &buffstat); 00129 errsv = errno; 00130 ReleaseTokenFSCall(); 00131 00132 if(rc) 00133 { 00134 close( parentfd ) ; 00135 00136 if(errsv == ENOENT) 00137 Return(ERR_FSAL_STALE, errsv, INDEX_FSAL_lookup); 00138 else 00139 Return(posix2fsal_error(errsv), errsv, INDEX_FSAL_lookup); 00140 } 00141 00142 /* Be careful about junction crossing, symlinks, hardlinks,... */ 00143 switch (posix2fsal_type(buffstat.st_mode)) 00144 { 00145 case FSAL_TYPE_DIR: 00146 // OK 00147 break; 00148 00149 case FSAL_TYPE_JUNCTION: 00150 // This is a junction 00151 close( parentfd ) ; 00152 Return(ERR_FSAL_XDEV, 0, INDEX_FSAL_lookup); 00153 00154 case FSAL_TYPE_FILE: 00155 case FSAL_TYPE_LNK: 00156 case FSAL_TYPE_XATTR: 00157 // not a directory 00158 close( parentfd ) ; 00159 Return(ERR_FSAL_NOTDIR, 0, INDEX_FSAL_lookup); 00160 00161 default: 00162 close( parentfd ) ; 00163 Return(ERR_FSAL_SERVERFAULT, 0, INDEX_FSAL_lookup); 00164 } 00165 00166 LogFullDebug(COMPONENT_FSAL, "lookup of inode=%"PRIu64"/%s", buffstat.st_ino, 00167 p_filename->name); 00168 00169 /* check rights to enter into the directory */ 00170 status = fsal_check_access(p_context, FSAL_X_OK, &buffstat, NULL); 00171 if(FSAL_IS_ERROR(status)) 00172 ReturnStatus(status, INDEX_FSAL_lookup); 00173 00174 /* get file handle, it it exists */ 00175 TakeTokenFSCall(); 00176 00177 vfs_handle->data.vfs_handle.handle_bytes = VFS_HANDLE_LEN ; 00178 if( vfs_name_by_handle_at( parentfd, p_filename->name, 00179 &vfs_handle->data.vfs_handle) != 0 ) 00180 { 00181 errsv = errno; 00182 ReleaseTokenFSCall(); 00183 close( parentfd ) ; 00184 Return(posix2fsal_error(errsv), errsv, INDEX_FSAL_lookup); 00185 } 00186 00187 ReleaseTokenFSCall(); 00188 close( parentfd ) ; 00189 00190 00191 /* get object attributes */ 00192 if(p_object_attributes) 00193 { 00194 status = VFSFSAL_getattrs(p_object_handle, p_context, p_object_attributes); 00195 if(FSAL_IS_ERROR(status)) 00196 { 00197 FSAL_CLEAR_MASK(p_object_attributes->asked_attributes); 00198 FSAL_SET_MASK(p_object_attributes->asked_attributes, FSAL_ATTR_RDATTR_ERR); 00199 } 00200 } 00201 00202 /* lookup complete ! */ 00203 Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_lookup); 00204 00205 } 00206 00229 fsal_status_t VFSFSAL_lookupPath(fsal_path_t * p_path, /* IN */ 00230 fsal_op_context_t * p_context, /* IN */ 00231 fsal_handle_t * object_handle, /* OUT */ 00232 fsal_attrib_list_t * p_object_attributes /* [ IN/OUT ] */ 00233 ) 00234 { 00235 fsal_status_t status; 00236 00237 /* sanity checks 00238 * note : object_attributes is optional. 00239 */ 00240 00241 if(!object_handle || !p_context || !p_path) 00242 Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_lookupPath); 00243 00244 /* test whether the path begins with a slash */ 00245 00246 if(p_path->path[0] != '/') 00247 Return(ERR_FSAL_INVAL, 0, INDEX_FSAL_lookupPath); 00248 00249 /* directly call the lookup function */ 00250 00251 status = fsal_internal_Path2Handle(p_context, p_path, object_handle); 00252 if(FSAL_IS_ERROR(status)) 00253 ReturnStatus(status, INDEX_FSAL_lookupPath); 00254 00255 /* get object attributes */ 00256 if(p_object_attributes) 00257 { 00258 status = VFSFSAL_getattrs(object_handle, p_context, p_object_attributes); 00259 if(FSAL_IS_ERROR(status)) 00260 { 00261 FSAL_CLEAR_MASK(p_object_attributes->asked_attributes); 00262 FSAL_SET_MASK(p_object_attributes->asked_attributes, FSAL_ATTR_RDATTR_ERR); 00263 } 00264 } 00265 00266 Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_lookupPath); 00267 00268 } 00269 00293 fsal_status_t VFSFSAL_lookupJunction(fsal_handle_t * p_junction_handle, /* IN */ 00294 fsal_op_context_t * p_context, /* IN */ 00295 fsal_handle_t * p_fsoot_handle, /* OUT */ 00296 fsal_attrib_list_t * p_fsroot_attributes /* [ IN/OUT ] */ 00297 ) 00298 { 00299 Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_lookupJunction); 00300 }