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 #include "HPSSclapiExt/hpssclapiext.h" 00022 00023 #include <hpss_errno.h> 00024 00060 fsal_status_t HPSSFSAL_lookup(hpssfsal_handle_t * parent_directory_handle, /* IN */ 00061 fsal_name_t * p_filename, /* IN */ 00062 hpssfsal_op_context_t * p_context, /* IN */ 00063 hpssfsal_handle_t * object_handle, /* OUT */ 00064 fsal_attrib_list_t * object_attributes /* [ IN/OUT ] */ 00065 ) 00066 { 00067 00068 int rc; 00069 fsal_status_t status; 00070 hpss_fileattr_t root_attr; 00071 00072 ns_ObjHandle_t obj_hdl; 00073 hpss_Attrs_t obj_attr; 00074 00075 /* sanity checks 00076 * note : object_attributes is optionnal 00077 * parent_directory_handle may be null for getting FS root. 00078 */ 00079 if(!object_handle || !p_context) 00080 Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_lookup); 00081 00082 if(!parent_directory_handle) 00083 { 00084 00085 /* check that p_filename is NULL, 00086 * else, parent_directory_handle should not 00087 * be NULL. 00088 */ 00089 if(p_filename != NULL) 00090 Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_lookup); 00091 00092 /* root handle = fileset root handle */ 00093 object_handle->data.obj_type = 00094 hpss2fsal_type(p_context->export_context->fileset_root_handle.Type); 00095 object_handle->data.ns_handle = p_context->export_context->fileset_root_handle; 00096 00097 /* retrieves root attributes, if asked. */ 00098 if(object_attributes) 00099 { 00100 fsal_status_t status; 00101 00102 status = HPSSFSAL_getattrs(object_handle, p_context, object_attributes); 00103 00104 /* On error, we set a flag in the returned attributes */ 00105 00106 if(FSAL_IS_ERROR(status)) 00107 { 00108 FSAL_CLEAR_MASK(object_attributes->asked_attributes); 00109 FSAL_SET_MASK(object_attributes->asked_attributes, FSAL_ATTR_RDATTR_ERR); 00110 } 00111 } 00112 00113 } 00114 else 00115 { 00116 00117 /* the filename should not be null */ 00118 if(p_filename == NULL) 00119 Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_lookup); 00120 00121 /* Be careful about junction crossing, symlinks, hardlinks,... */ 00122 00123 switch (parent_directory_handle->data.obj_type) 00124 { 00125 case FSAL_TYPE_DIR: 00126 /* OK */ 00127 break; 00128 00129 case FSAL_TYPE_JUNCTION: 00130 /* This is a junction */ 00131 Return(ERR_FSAL_XDEV, 0, INDEX_FSAL_lookup); 00132 00133 case FSAL_TYPE_FILE: 00134 case FSAL_TYPE_LNK: 00135 case FSAL_TYPE_XATTR: 00136 /* not a directory */ 00137 Return(ERR_FSAL_NOTDIR, 0, INDEX_FSAL_lookup); 00138 00139 default: 00140 Return(ERR_FSAL_SERVERFAULT, 0, INDEX_FSAL_lookup); 00141 } 00142 00143 /* call to HPSS client api */ 00144 /* We use hpss_GetRawAttrHandle for not chasing junctions nor symlinks. */ 00145 00146 TakeTokenFSCall(); 00147 00148 rc = HPSSFSAL_GetRawAttrHandle(&(parent_directory_handle->data.ns_handle), p_filename->name, &p_context->credential.hpss_usercred, FALSE, /* don't traverse junctions */ 00149 &obj_hdl, NULL, &obj_attr); 00150 00151 ReleaseTokenFSCall(); 00152 00158 if(rc == HPSS_ENOTDIR) 00159 { 00160 if(HPSSFSAL_IsStaleHandle(&parent_directory_handle->data.ns_handle, 00161 &p_context->credential.hpss_usercred)) 00162 { 00163 Return(ERR_FSAL_STALE, -rc, INDEX_FSAL_lookup); 00164 } 00165 } 00166 00167 if(rc) 00168 Return(hpss2fsal_error(rc), -rc, INDEX_FSAL_lookup); 00169 00170 /* set output handle */ 00171 memset( (char *)object_handle, 0, sizeof( hpssfsal_handle_t ) ) ; 00172 object_handle->data.obj_type = hpss2fsal_type(obj_hdl.Type); 00173 object_handle->data.ns_handle = obj_hdl; 00174 00175 if(object_attributes) 00176 { 00177 00178 /* convert hpss attributes to fsal attributes */ 00179 00180 status = hpss2fsal_attributes(&obj_hdl, &obj_attr, object_attributes); 00181 00182 if(FSAL_IS_ERROR(status)) 00183 Return(status.major, status.minor, INDEX_FSAL_lookup); 00184 00185 } 00186 00187 } 00188 00189 /* lookup complete ! */ 00190 Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_lookup); 00191 00192 } 00193 00221 fsal_status_t HPSSFSAL_lookupJunction(hpssfsal_handle_t * p_junction_handle, /* IN */ 00222 hpssfsal_op_context_t * p_context, /* IN */ 00223 hpssfsal_handle_t * p_fsoot_handle, /* OUT */ 00224 fsal_attrib_list_t * p_fsroot_attributes /* [ IN/OUT ] */ 00225 ) 00226 { 00227 int rc; 00228 fsal_status_t status; 00229 hpss_Attrs_t root_attr; 00230 00231 /* sanity checks 00232 * note : p_fsroot_attributes is optionnal 00233 */ 00234 if(!p_junction_handle || !p_fsoot_handle || !p_context) 00235 Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_lookupJunction); 00236 00237 if(p_junction_handle->data.obj_type != FSAL_TYPE_JUNCTION) 00238 Return(ERR_FSAL_INVAL, 0, INDEX_FSAL_lookupJunction); 00239 00240 /* call to HPSS client api */ 00241 /* We use hpss_GetRawAttrHandle for chasing junctions. */ 00242 00243 TakeTokenFSCall(); 00244 00245 rc = HPSSFSAL_GetRawAttrHandle(&(p_junction_handle->data.ns_handle), NULL, &p_context->credential.hpss_usercred, TRUE, /* do traverse junctions !!! */ 00246 NULL, NULL, &root_attr); 00247 00248 ReleaseTokenFSCall(); 00249 00250 if(rc) 00251 Return(hpss2fsal_error(rc), -rc, INDEX_FSAL_lookupJunction); 00252 00253 /* set output handle */ 00254 p_fsoot_handle->data.obj_type = hpss2fsal_type(root_attr.FilesetHandle.Type); 00255 p_fsoot_handle->data.ns_handle = root_attr.FilesetHandle; 00256 00257 if(p_fsroot_attributes) 00258 { 00259 00260 /* convert hpss attributes to fsal attributes */ 00261 00262 status = hpss2fsal_attributes(&root_attr.FilesetHandle, 00263 &root_attr, p_fsroot_attributes); 00264 00265 if(FSAL_IS_ERROR(status)) 00266 Return(status.major, status.minor, INDEX_FSAL_lookupJunction); 00267 00268 } 00269 00270 /* lookup complete ! */ 00271 Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_lookupJunction); 00272 } 00273 00308 fsal_status_t HPSSFSAL_lookupPath(fsal_path_t * p_path, /* IN */ 00309 hpssfsal_op_context_t * p_context, /* IN */ 00310 hpssfsal_handle_t * object_handle, /* OUT */ 00311 fsal_attrib_list_t * object_attributes /* [ IN/OUT ] */ 00312 ) 00313 { 00314 fsal_name_t obj_name = FSAL_NAME_INITIALIZER; /* empty string */ 00315 char *ptr_str; 00316 hpssfsal_handle_t out_hdl; 00317 fsal_status_t status; 00318 int b_is_last = FALSE; /* is it the last lookup ? */ 00319 00320 /* sanity checks 00321 * note : object_attributes is optionnal. 00322 */ 00323 00324 if(!object_handle || !p_context || !p_path) 00325 Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_lookupPath); 00326 00327 /* test whether the path begins with a slash */ 00328 00329 if(p_path->path[0] != '/') 00330 Return(ERR_FSAL_INVAL, 0, INDEX_FSAL_lookupPath); 00331 00332 /* the pointer now points on the next name in the path, 00333 * skipping slashes. 00334 */ 00335 00336 ptr_str = p_path->path + 1; 00337 while(ptr_str[0] == '/') 00338 ptr_str++; 00339 00340 /* is the next name empty ? */ 00341 00342 if(ptr_str[0] == '\0') 00343 b_is_last = TRUE; 00344 00345 /* retrieves root directory */ 00346 00347 status = HPSSFSAL_lookup(NULL, /* looking up for root */ 00348 NULL, /* empty string to get root handle */ 00349 p_context, /* user's credentials */ 00350 &out_hdl, /* output root handle */ 00351 /* retrieves attributes if this is the last lookup : */ 00352 (b_is_last ? object_attributes : NULL)); 00353 00354 if(FSAL_IS_ERROR(status)) 00355 Return(status.major, status.minor, INDEX_FSAL_lookupPath); 00356 00357 /* exits if this was the last lookup */ 00358 00359 if(b_is_last) 00360 { 00361 (*object_handle) = out_hdl; 00362 Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_lookupPath); 00363 } 00364 00365 /* proceed a step by step lookup */ 00366 00367 while(ptr_str[0]) 00368 { 00369 00370 hpssfsal_handle_t in_hdl; 00371 char *dest_ptr; 00372 00373 /* preparing lookup */ 00374 00377 in_hdl = out_hdl; 00378 00379 /* compute next name */ 00380 obj_name.len = 0; 00381 dest_ptr = obj_name.name; 00382 while(ptr_str[0] != '\0' && ptr_str[0] != '/') 00383 { 00384 dest_ptr[0] = ptr_str[0]; 00385 dest_ptr++; 00386 ptr_str++; 00387 obj_name.len++; 00388 } 00389 /* final null char */ 00390 dest_ptr[0] = '\0'; 00391 00392 /* skip multiple slashes */ 00393 while(ptr_str[0] == '/') 00394 ptr_str++; 00395 00396 /* is the next name empty ? */ 00397 if(ptr_str[0] == '\0') 00398 b_is_last = TRUE; 00399 00400 /*call to FSAL_lookup */ 00401 status = HPSSFSAL_lookup(&in_hdl, /* parent directory handle */ 00402 &obj_name, /* object name */ 00403 p_context, /* user's credentials */ 00404 &out_hdl, /* output root handle */ 00405 /* retrieves attributes if this is the last lookup : */ 00406 (b_is_last ? object_attributes : NULL)); 00407 00408 if(FSAL_IS_ERROR(status)) 00409 Return(status.major, status.minor, INDEX_FSAL_lookupPath); 00410 00411 /* if the target object is a junction, an we allow cross junction lookups, 00412 * we cross it. 00413 */ 00414 if(global_fs_info.auth_exportpath_xdev && (out_hdl.data.obj_type == FSAL_TYPE_JUNCTION)) 00415 { 00416 hpssfsal_handle_t tmp_hdl; 00417 00418 tmp_hdl = out_hdl; 00419 00420 /*call to FSAL_lookup */ 00421 status = HPSSFSAL_lookupJunction(&tmp_hdl, /* object handle */ 00422 p_context, /* user's credentials */ 00423 &out_hdl, /* output root handle */ 00424 /* retrieves attributes if this is the last lookup : */ 00425 (b_is_last ? object_attributes : NULL)); 00426 00427 } 00428 00429 /* ptr_str is ok, we are ready for next loop */ 00430 } 00431 00432 (*object_handle) = out_hdl; 00433 Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_lookupPath); 00434 00435 }