nfs-ganesha 1.4
|
00001 /* 00002 * vim:expandtab:shiftwidth=8:tabstop=8: 00003 */ 00004 00013 #ifdef HAVE_CONFIG_H 00014 #include "config.h" 00015 #endif 00016 00017 #include <string.h> 00018 #include "fsal.h" 00019 #include "fsal_internal.h" 00020 #include "fsal_convert.h" 00021 00049 fsal_status_t POSIXFSAL_lookup(fsal_handle_t * parent_directory_handle, /* IN */ 00050 fsal_name_t * p_filename, /* IN */ 00051 fsal_op_context_t * context, /* IN */ 00052 fsal_handle_t * object_handle, /* OUT */ 00053 fsal_attrib_list_t * p_object_attributes /* [ IN/OUT ] */ 00054 ) 00055 { 00056 posixfsal_handle_t * p_parent_directory_handle 00057 = (posixfsal_handle_t *) parent_directory_handle; 00058 posixfsal_op_context_t * p_context = (posixfsal_op_context_t *) context; 00059 posixfsal_handle_t * p_object_handle = (posixfsal_handle_t *) object_handle; 00060 int rc, errsv; 00061 fsal_status_t status; 00062 /* fsal_posixdb_status_t statusdb; */ 00063 fsal_posixdb_fileinfo_t infofs; 00064 struct stat buffstat; 00065 fsal_path_t pathfsal; 00066 00067 /* sanity checks 00068 * note : object_attributes is optionnal 00069 * parent_directory_handle may be null for getting FS root. 00070 */ 00071 if(!p_object_handle || !p_context) 00072 Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_lookup); 00073 00074 /* filename is NULL => lookup "/" */ 00075 if((p_parent_directory_handle && !p_filename) 00076 || (!p_parent_directory_handle && p_filename)) 00077 Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_lookup); 00078 00079 /* get informations about the parent */ 00080 if(!p_parent_directory_handle) 00081 { /* lookup '/' */ 00082 TakeTokenFSCall(); 00083 rc = lstat("/", &buffstat); 00084 errsv = errno; 00085 ReleaseTokenFSCall(); 00086 if(rc) 00087 Return(posix2fsal_error(errsv), errsv, INDEX_FSAL_lookup); 00088 } 00089 else 00090 { 00091 status = 00092 fsal_internal_getPathFromHandle(p_context, p_parent_directory_handle, 1, 00093 &pathfsal, &buffstat); 00094 if(FSAL_IS_ERROR(status)) 00095 Return(status.major, status.minor, INDEX_FSAL_lookup); 00096 } 00097 00098 /* Be careful about junction crossing, symlinks, hardlinks,... */ 00099 switch (posix2fsal_type(buffstat.st_mode)) 00100 { 00101 case FSAL_TYPE_DIR: 00102 // OK 00103 break; 00104 00105 case FSAL_TYPE_JUNCTION: 00106 // This is a junction 00107 Return(ERR_FSAL_XDEV, 0, INDEX_FSAL_lookup); 00108 00109 case FSAL_TYPE_FILE: 00110 case FSAL_TYPE_LNK: 00111 case FSAL_TYPE_XATTR: 00112 // not a directory 00113 Return(ERR_FSAL_NOTDIR, 0, INDEX_FSAL_lookup); 00114 00115 default: 00116 Return(ERR_FSAL_SERVERFAULT, 0, INDEX_FSAL_lookup); 00117 } 00118 00119 if(!p_parent_directory_handle) 00120 { /* lookup '/' */ 00121 /* convert struct stat to fsal_posixdb_fileinfo_t */ 00122 00123 if(FSAL_IS_ERROR(status = fsal_internal_posix2posixdb_fileinfo(&buffstat, &infofs))) 00124 Return(status.major, status.minor, INDEX_FSAL_lookup); 00125 00126 /* get The handle of '/' */ 00127 status = 00128 fsal_internal_getInfoFromName(p_context, NULL, NULL, &infofs, p_object_handle); 00129 if(FSAL_IS_ERROR(status)) 00130 Return(status.major, status.minor, INDEX_FSAL_lookup); 00131 00132 } 00133 else 00134 { 00135 00136 LogFullDebug(COMPONENT_FSAL, "lookup of %llu.%i/%s\n", p_parent_directory_handle->data.id, 00137 p_parent_directory_handle->data.ts, p_filename->name); 00138 00139 /* check rights to enter into the directory */ 00140 status = fsal_internal_testAccess(p_context, FSAL_X_OK, &buffstat, NULL); 00141 if(FSAL_IS_ERROR(status)) 00142 Return(status.major, status.minor, INDEX_FSAL_lookup); 00143 00144 /* stat the file to see if it exists and get some information */ 00145 status = fsal_internal_appendFSALNameToFSALPath(&pathfsal, p_filename); 00146 if(FSAL_IS_ERROR(status)) 00147 Return(status.major, status.minor, INDEX_FSAL_lookup); 00148 00149 TakeTokenFSCall(); 00150 rc = lstat(pathfsal.path, &buffstat); 00151 errsv = errno; 00152 ReleaseTokenFSCall(); 00153 if(rc) 00154 Return(posix2fsal_error(errsv), errsv, INDEX_FSAL_lookup); 00155 00156 /* getHandleFromName */ 00157 if(!FSAL_namecmp(p_filename, (fsal_name_t *) & FSAL_DOT)) 00158 { 00159 /* lookup "." */ 00160 memcpy(p_object_handle, p_parent_directory_handle, sizeof(posixfsal_handle_t)); 00161 00162 } 00163 else if(!FSAL_namecmp(p_filename, (fsal_name_t *) & FSAL_DOT_DOT)) 00164 { 00165 /* lookup ".." */ 00166 /* statusdb = */(void) fsal_posixdb_getParentDirHandle(p_context->p_conn, 00167 p_parent_directory_handle, 00168 p_object_handle); 00169 } 00170 else 00171 { 00172 /* convert struct stat to fsal_posixdb_fileinfo_t */ 00173 if(FSAL_IS_ERROR 00174 (status = fsal_internal_posix2posixdb_fileinfo(&buffstat, &infofs))) 00175 Return(status.major, status.minor, INDEX_FSAL_lookup); 00176 00177 /* get The handle of the file */ 00178 status = 00179 fsal_internal_getInfoFromName(p_context, p_parent_directory_handle, 00180 p_filename, &infofs, p_object_handle); 00181 if(FSAL_IS_ERROR(status)) 00182 Return(status.major, status.minor, INDEX_FSAL_lookup); 00183 } 00184 00185 } 00186 00187 if(p_object_attributes) 00188 { 00189 00190 /* convert posix attributes to fsal attributes */ 00191 status = posix2fsal_attributes(&buffstat, p_object_attributes); 00192 00193 if(FSAL_IS_ERROR(status)) 00194 { 00195 FSAL_CLEAR_MASK(p_object_attributes->asked_attributes); 00196 FSAL_SET_MASK(p_object_attributes->asked_attributes, FSAL_ATTR_RDATTR_ERR); 00197 } 00198 } 00199 00200 /* lookup complete ! */ 00201 Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_lookup); 00202 00203 } 00204 00227 fsal_status_t POSIXFSAL_lookupPath(fsal_path_t * p_path, /* IN */ 00228 fsal_op_context_t * context, /* IN */ 00229 fsal_handle_t * object_hdl, /* OUT */ 00230 fsal_attrib_list_t * object_attributes /* [ IN/OUT ] */ 00231 ) 00232 { 00233 posixfsal_op_context_t * p_context = (posixfsal_op_context_t *) context; 00234 posixfsal_handle_t * object_handle = (posixfsal_handle_t *) object_hdl; 00235 fsal_name_t obj_name = FSAL_NAME_INITIALIZER; /* empty string */ 00236 char *ptr_str; 00237 posixfsal_handle_t out_hdl; 00238 fsal_status_t status; 00239 int b_is_last = FALSE; /* is it the last lookup ? */ 00240 00241 /* sanity checks 00242 * note : object_attributes is optionnal. 00243 */ 00244 00245 if(!object_handle || !p_context || !p_path) 00246 Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_lookupPath); 00247 00248 /* test whether the path begins with a slash */ 00249 00250 if(p_path->path[0] != '/') 00251 Return(ERR_FSAL_INVAL, 0, INDEX_FSAL_lookupPath); 00252 00253 /* the pointer now points on the next name in the path, 00254 * skipping slashes. 00255 */ 00256 00257 ptr_str = p_path->path + 1; 00258 while(ptr_str[0] == '/') 00259 ptr_str++; 00260 00261 /* is the next name empty ? */ 00262 00263 if(ptr_str[0] == '\0') 00264 b_is_last = TRUE; 00265 00266 /* retrieves root directory */ 00267 00268 status = POSIXFSAL_lookup(NULL, /* looking up for root */ 00269 NULL, /* empty string to get root handle */ 00270 p_context, /* user's p_contextentials */ 00271 &out_hdl, /* output root handle */ 00272 /* retrieves attributes if this is the last lookup : */ 00273 (b_is_last ? object_attributes : NULL)); 00274 00275 if(FSAL_IS_ERROR(status)) 00276 Return(status.major, status.minor, INDEX_FSAL_lookupPath); 00277 00278 /* exits if this was the last lookup */ 00279 00280 if(b_is_last) 00281 { 00282 (*object_handle) = out_hdl; 00283 Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_lookupPath); 00284 } 00285 00286 /* proceed a step by step lookup */ 00287 00288 while(ptr_str[0]) 00289 { 00290 00291 posixfsal_handle_t in_hdl; 00292 char *dest_ptr; 00293 00294 /* preparing lookup */ 00295 00298 in_hdl = out_hdl; 00299 00300 /* compute next name */ 00301 dest_ptr = obj_name.name; 00302 obj_name.len = 0; 00303 while(ptr_str[0] != '\0' && ptr_str[0] != '/') 00304 { 00305 dest_ptr[0] = ptr_str[0]; 00306 dest_ptr++; 00307 ptr_str++; 00308 obj_name.len++; 00309 } 00310 /* final null char */ 00311 dest_ptr[0] = '\0'; 00312 00313 /* skip multiple slashes */ 00314 while(ptr_str[0] == '/') 00315 ptr_str++; 00316 00317 /* is the next name empty ? */ 00318 if(ptr_str[0] == '\0') 00319 b_is_last = TRUE; 00320 00321 /*call to FSAL_lookup */ 00322 status = POSIXFSAL_lookup(&in_hdl, /* parent directory handle */ 00323 &obj_name, /* object name */ 00324 p_context, /* user's p_contextentials */ 00325 &out_hdl, /* output root handle */ 00326 /* retrieves attributes if this is the last lookup : */ 00327 (b_is_last ? object_attributes : NULL)); 00328 00329 if(FSAL_IS_ERROR(status)) 00330 Return(status.major, status.minor, INDEX_FSAL_lookupPath); 00331 00332 /* ptr_str is ok, we are ready for next loop */ 00333 } 00334 00335 (*object_handle) = out_hdl; 00336 Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_lookupPath); 00337 00338 } 00339 00363 fsal_status_t POSIXFSAL_lookupJunction(fsal_handle_t * p_junction_handle, /* IN */ 00364 fsal_op_context_t * p_context, /* IN */ 00365 fsal_handle_t * p_fsoot_handle, /* OUT */ 00366 fsal_attrib_list_t * p_fsroot_attributes /* [ IN/OUT ] */ 00367 ) 00368 { 00369 Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_lookupJunction); 00370 }