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 "fsal.h" 00018 #include "fsal_internal.h" 00019 #include "fsal_convert.h" 00020 #include "fsal_common.h" 00021 00057 fsal_status_t FSAL_lookup(fsal_handle_t * parent_directory_handle, /* IN */ 00058 fsal_name_t * p_filename, /* IN */ 00059 fsal_op_context_t * p_context, /* IN */ 00060 fsal_handle_t * object_handle, /* OUT */ 00061 fsal_attrib_list_t * object_attributes /* [ IN/OUT ] */ 00062 ) 00063 { 00064 00065 int rc; 00066 fsal_status_t status; 00067 00068 /* sanity checks 00069 * note : object_attributes is optionnal 00070 * parent_directory_handle may be null for getting FS root. 00071 */ 00072 if(!object_handle || !p_context) 00073 Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_lookup); 00074 00075 /* retrieves root handle */ 00076 00077 if(!parent_directory_handle) 00078 { 00079 00080 /* check that p_filename is NULL, 00081 * else, parent_directory_handle should not 00082 * be NULL. 00083 */ 00084 if(p_filename != NULL) 00085 Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_lookup); 00086 00087 /* >> retrieve root handle filehandle here << */ 00088 00089 /* >> retrieves root attributes, if asked << */ 00090 00091 if(object_attributes) 00092 { 00093 fsal_status_t status; 00094 00095 status = FSAL_getattrs(object_handle, p_context, object_attributes); 00096 00097 /* On error, we set a flag in the returned attributes */ 00098 00099 if(FSAL_IS_ERROR(status)) 00100 { 00101 FSAL_CLEAR_MASK(object_attributes->asked_attributes); 00102 FSAL_SET_MASK(object_attributes->asked_attributes, FSAL_ATTR_RDATTR_ERR); 00103 } 00104 } 00105 00106 } 00107 else /* this is a real lookup(parent, name) */ 00108 { 00109 00110 /* the filename should not be null */ 00111 if(p_filename == NULL) 00112 Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_lookup); 00113 00114 /* >> Be careful about junction crossing, symlinks, hardlinks,... 00115 * You may check the parent type if it's sored into the handle << 00116 */ 00117 00118 switch (parent_directory_handle->object_type_reminder) 00119 { 00120 case FSAL_TYPE_DIR: 00121 /* OK */ 00122 break; 00123 00124 case FSAL_TYPE_JUNCTION: 00125 /* This is a junction */ 00126 Return(ERR_FSAL_XDEV, 0, INDEX_FSAL_lookup); 00127 00128 case FSAL_TYPE_FILE: 00129 case FSAL_TYPE_LNK: 00130 case FSAL_TYPE_XATTR: 00131 /* not a directory */ 00132 Return(ERR_FSAL_NOTDIR, 0, INDEX_FSAL_lookup); 00133 00134 default: 00135 Return(ERR_FSAL_SERVERFAULT, 0, INDEX_FSAL_lookup); 00136 } 00137 00138 TakeTokenFSCall(); 00139 00140 /* >> Call your filesystem lookup function here << */ 00141 /* >> Be carefull you don't traverse junction nor follow symlinks << */ 00142 00143 ReleaseTokenFSCall(); 00144 00145 /* >> convert the error code and return on error << */ 00146 00147 /* >> set output handle << */ 00148 00149 if(object_attributes) 00150 { 00151 /* >> fill object attributes if asked << */ 00152 } 00153 00154 } 00155 00156 /* lookup complete ! */ 00157 Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_lookup); 00158 00159 } 00160 00188 fsal_status_t FSAL_lookupJunction(fsal_handle_t * p_junction_handle, /* IN */ 00189 fsal_op_context_t * p_context, /* IN */ 00190 fsal_handle_t * p_fsoot_handle, /* OUT */ 00191 fsal_attrib_list_t * p_fsroot_attributes /* [ IN/OUT ] */ 00192 ) 00193 { 00194 int rc; 00195 fsal_status_t status; 00196 00197 /* sanity checks 00198 * note : p_fsroot_attributes is optionnal 00199 */ 00200 if(!p_junction_handle || !p_fsoot_handle || !p_context) 00201 Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_lookupJunction); 00202 00203 /* >> you can also check object type if it is in stored in the handle << */ 00204 00205 if(p_junction_handle->object_type_reminder != FSAL_TYPE_JUNCTION) 00206 Return(ERR_FSAL_INVAL, 0, INDEX_FSAL_lookupJunction); 00207 00208 TakeTokenFSCall(); 00209 00210 /* >> traverse the junction here << */ 00211 00212 ReleaseTokenFSCall(); 00213 00214 /* >> convert the error code and return on error << */ 00215 00216 /* >> set output handle << */ 00217 00218 if(p_fsroot_attributes) 00219 { 00220 00221 /* >> fill output attributes if asked << */ 00222 00223 } 00224 00225 /* lookup complete ! */ 00226 Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_lookupJunction); 00227 } 00228 00263 fsal_status_t FSAL_lookupPath(fsal_path_t * p_path, /* IN */ 00264 fsal_op_context_t * p_context, /* IN */ 00265 fsal_handle_t * object_handle, /* OUT */ 00266 fsal_attrib_list_t * object_attributes /* [ IN/OUT ] */ 00267 ) 00268 { 00269 fsal_name_t obj_name = FSAL_NAME_INITIALIZER; /* empty string */ 00270 char *ptr_str; 00271 fsal_handle_t out_hdl; 00272 fsal_status_t status; 00273 int b_is_last = FALSE; /* is it the last lookup ? */ 00274 00275 /*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 00276 * this function may be adapted to most FSALs 00277 *<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/ 00278 00279 /* sanity checks 00280 * note : object_attributes is optionnal. 00281 */ 00282 00283 if(!object_handle || !p_context || !p_path) 00284 Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_lookupPath); 00285 00286 /* test whether the path begins with a slash */ 00287 00288 if(p_path->path[0] != '/') 00289 Return(ERR_FSAL_INVAL, 0, INDEX_FSAL_lookupPath); 00290 00291 /* the pointer now points on the next name in the path, 00292 * skipping slashes. 00293 */ 00294 00295 ptr_str = p_path->path + 1; 00296 while(ptr_str[0] == '/') 00297 ptr_str++; 00298 00299 /* is the next name empty ? */ 00300 00301 if(ptr_str[0] == '\0') 00302 b_is_last = TRUE; 00303 00304 /* retrieves root directory */ 00305 00306 status = FSAL_lookup(NULL, /* looking up for root */ 00307 NULL, /* empty string to get root handle */ 00308 p_context, /* user's credentials */ 00309 &out_hdl, /* output root handle */ 00310 /* retrieves attributes if this is the last lookup : */ 00311 (b_is_last ? object_attributes : NULL)); 00312 00313 if(FSAL_IS_ERROR(status)) 00314 Return(status.major, status.minor, INDEX_FSAL_lookupPath); 00315 00316 /* exits if this was the last lookup */ 00317 00318 if(b_is_last) 00319 { 00320 (*object_handle) = out_hdl; 00321 Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_lookupPath); 00322 } 00323 00324 /* proceed a step by step lookup */ 00325 00326 while(ptr_str[0]) 00327 { 00328 00329 fsal_handle_t in_hdl; 00330 char *dest_ptr; 00331 00332 /* preparing lookup */ 00333 00334 in_hdl = out_hdl; 00335 00336 /* compute next name */ 00337 obj_name.len = 0; 00338 dest_ptr = obj_name.name; 00339 while(ptr_str[0] != '\0' && ptr_str[0] != '/') 00340 { 00341 dest_ptr[0] = ptr_str[0]; 00342 dest_ptr++; 00343 ptr_str++; 00344 obj_name.len++; 00345 } 00346 /* final null char */ 00347 dest_ptr[0] = '\0'; 00348 00349 /* skip multiple slashes */ 00350 while(ptr_str[0] == '/') 00351 ptr_str++; 00352 00353 /* is the next name empty ? */ 00354 if(ptr_str[0] == '\0') 00355 b_is_last = TRUE; 00356 00357 /*call to FSAL_lookup */ 00358 status = FSAL_lookup(&in_hdl, /* parent directory handle */ 00359 &obj_name, /* object name */ 00360 p_context, /* user's credentials */ 00361 &out_hdl, /* output root handle */ 00362 /* retrieves attributes if this is the last lookup : */ 00363 (b_is_last ? object_attributes : NULL)); 00364 00365 if(FSAL_IS_ERROR(status)) 00366 Return(status.major, status.minor, INDEX_FSAL_lookupPath); 00367 00368 /* if the target object is a junction, an we allow cross junction lookups, 00369 * we cross it. 00370 */ 00371 if(global_fs_info.auth_exportpath_xdev 00372 && (out_hdl.object_type_reminder == FSAL_TYPE_JUNCTION)) 00373 { 00374 fsal_handle_t tmp_hdl; 00375 00376 tmp_hdl = out_hdl; 00377 00378 /*call to FSAL_lookup */ 00379 status = FSAL_lookupJunction(&tmp_hdl, /* object handle */ 00380 p_context, /* user's credentials */ 00381 &out_hdl, /* output root handle */ 00382 /* retrieves attributes if this is the last lookup : */ 00383 (b_is_last ? object_attributes : NULL)); 00384 00385 } 00386 00387 /* ptr_str is ok, we are ready for next loop */ 00388 } 00389 00390 (*object_handle) = out_hdl; 00391 Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_lookupPath); 00392 00393 }