nfs-ganesha 1.4
|
00001 00009 #ifdef HAVE_CONFIG_H 00010 #include "config.h" 00011 #endif 00012 00013 #include "fsal.h" 00014 #include "fsal_internal.h" 00015 #include "fsal_convert.h" 00016 #include "HPSSclapiExt/hpssclapiext.h" 00017 00018 #include <hpss_uuid.h> 00019 #include <hpss_errno.h> 00020 #include <hpss_limits.h> 00021 00022 #if HPSS_LEVEL >= 730 00023 #include <hpss_xml.h> 00024 #endif 00025 00026 /* generic definitions for extended attributes */ 00027 00028 #define XATTR_FOR_FILE 0x00000001 00029 #define XATTR_FOR_DIR 0x00000002 00030 #define XATTR_FOR_SYMLINK 0x00000004 00031 #define XATTR_FOR_ALL 0x0000000F 00032 #define XATTR_RO 0x00000100 00033 #define XATTR_RW 0x00000200 00034 00035 /* function for getting an attribute value */ 00036 00037 typedef int (*xattr_getfunc_t) (hpssfsal_handle_t *, /* object handle */ 00038 hpssfsal_op_context_t *, /* context */ 00039 caddr_t, /* output buff */ 00040 size_t, /* output buff size */ 00041 size_t *); /* output size */ 00042 00043 typedef int (*xattr_setfunc_t) (hpssfsal_handle_t *, /* object handle */ 00044 hpssfsal_op_context_t *, /* context */ 00045 caddr_t, /* input buff */ 00046 size_t, /* input size */ 00047 int); /* creation flag */ 00048 00049 typedef int (*xattr_printfunc_t) (caddr_t, /* Input buffer */ 00050 size_t, /* Input size */ 00051 caddr_t, /* Output (ASCII) buffer */ 00052 size_t *); /* Output size */ 00053 00054 typedef struct fsal_xattr_def__ 00055 { 00056 char xattr_name[FSAL_MAX_NAME_LEN]; 00057 xattr_getfunc_t get_func; 00058 xattr_setfunc_t set_func; 00059 xattr_printfunc_t print_func; 00060 int flags; 00061 } fsal_xattr_def_t; 00062 00063 /* 00064 * function for getting extended attributes for HPSS 00065 */ 00066 00067 /* Class of service */ 00068 int get_file_cos(hpssfsal_handle_t * p_objecthandle, /* IN */ 00069 hpssfsal_op_context_t * p_context, /* IN */ 00070 caddr_t buffer_addr, /* IN/OUT */ 00071 size_t buffer_size, /* IN */ 00072 size_t * p_output_size) /* OUT */ 00073 { 00074 int rc; 00075 ns_ObjHandle_t hpss_hdl; 00076 hpss_Attrs_t hpss_attr; 00077 00078 if(!p_objecthandle || !p_context || !p_output_size) 00079 return ERR_FSAL_FAULT; 00080 00081 /* get attributes */ 00082 /* We use HPSSFSAL_GetRawAttrHandle for not chasing junctions 00083 * nor solving symlinks. What's more, we want hpss_Attrs_t. 00084 */ 00085 00086 TakeTokenFSCall(); 00087 00088 rc = HPSSFSAL_GetRawAttrHandle(&(p_objecthandle->data.ns_handle), NULL, &p_context->credential.hpss_usercred, FALSE, /* don't solve junctions */ 00089 &hpss_hdl, NULL, &hpss_attr); 00090 00091 ReleaseTokenFSCall(); 00092 00093 /* The HPSS_ENOENT error actually means that handle is STALE */ 00094 if(rc == HPSS_ENOENT) 00095 return ERR_FSAL_STALE; 00096 else if(rc) 00097 return hpss2fsal_error(rc); 00098 00099 /* then store cos id in the output buffer */ 00100 00101 if(buffer_size < sizeof(hpss_attr.COSId)) 00102 return ERR_FSAL_TOOSMALL; 00103 00104 memcpy(buffer_addr, &hpss_attr.COSId, sizeof(hpss_attr.COSId)); 00105 00106 *p_output_size = sizeof(hpss_attr.COSId); 00107 00108 return 0; 00109 00110 } 00111 00112 int print_file_cos(caddr_t InBuff, size_t InSize, caddr_t OutBuff, size_t * pOutSize) 00113 { 00114 unsigned int cosid = 0; 00115 00116 memcpy((char *)&cosid, InBuff, sizeof(cosid)); 00117 00118 *pOutSize = snprintf(OutBuff, *pOutSize, "%u\n", cosid); 00119 return 0; 00120 } /* print_file_cos */ 00121 00122 /* Storage levels */ 00123 int get_file_slevel(hpssfsal_handle_t * p_objecthandle, /* IN */ 00124 hpssfsal_op_context_t * p_context, /* IN */ 00125 caddr_t buffer_addr, /* IN/OUT */ 00126 size_t buffer_size, /* IN */ 00127 size_t * p_output_size) /* OUT */ 00128 { 00129 int rc, i; 00130 hpss_xfileattr_t hpss_xattr; 00131 char tmpstr[1024]; 00132 char *outbuff; 00133 unsigned int index; 00134 00135 if(!p_objecthandle || !p_context || !p_output_size) 00136 return ERR_FSAL_FAULT; 00137 00138 /* get storage info */ 00139 00140 TakeTokenFSCall(); 00141 00142 #if HPSS_LEVEL < 622 00143 rc = HPSSFSAL_FileGetXAttributesHandle(&(p_objecthandle->data.ns_handle), 00144 API_GET_STATS_FOR_ALL_LEVELS, 0, &hpss_xattr); 00145 #elif HPSS_LEVEL == 622 00146 rc = hpss_FileGetXAttributesHandle(&(p_objecthandle->data.ns_handle), 00147 NULL, 00148 &(p_context->credential.hpss_usercred), 00149 API_GET_STATS_FOR_ALL_LEVELS, 0, NULL, &hpss_xattr); 00150 #elif HPSS_MAJOR_VERSION >= 7 00151 rc = hpss_FileGetXAttributesHandle(&(p_objecthandle->data.ns_handle), 00152 NULL, 00153 &(p_context->credential.hpss_usercred), 00154 API_GET_STATS_FOR_ALL_LEVELS, 0, &hpss_xattr); 00155 #endif 00156 00157 ReleaseTokenFSCall(); 00158 00159 /* The HPSS_ENOENT error actually means that handle is STALE */ 00160 if(rc == HPSS_ENOENT) 00161 return ERR_FSAL_STALE; 00162 else if(rc) 00163 return hpss2fsal_error(rc); 00164 00165 /* now write info to buffer */ 00166 00167 outbuff = (char *)buffer_addr; 00168 outbuff[0] = '\0'; 00169 00170 for(index = 0; index < HPSS_MAX_STORAGE_LEVELS; index++) 00171 { 00172 if(hpss_xattr.SCAttrib[index].Flags == 0) 00173 continue; 00174 00175 if(hpss_xattr.SCAttrib[index].Flags & BFS_BFATTRS_LEVEL_IS_DISK) 00176 snprintf(tmpstr, 1024, "Level %u (disk): %llu bytes\n", index, 00177 hpss2fsal_64(hpss_xattr.SCAttrib[index].BytesAtLevel)); 00178 else if(hpss_xattr.SCAttrib[index].Flags & BFS_BFATTRS_LEVEL_IS_TAPE) 00179 snprintf(tmpstr, 1024, "Level %u (tape): %llu bytes\n", index, 00180 hpss2fsal_64(hpss_xattr.SCAttrib[index].BytesAtLevel)); 00181 else 00182 snprintf(tmpstr, 1024, "Level %u: %llu bytes\n", index, 00183 hpss2fsal_64(hpss_xattr.SCAttrib[index].BytesAtLevel)); 00184 00185 if(strlen(tmpstr) + strlen(outbuff) < buffer_size) 00186 strcat(outbuff, tmpstr); 00187 else 00188 break; 00189 00190 } 00191 00192 /* free the returned structure (Cf. HPSS ClAPI documentation) */ 00193 for ( i = 0; i < HPSS_MAX_STORAGE_LEVELS; i++ ) 00194 { 00195 int j; 00196 for ( j = 0; j < hpss_xattr.SCAttrib[i].NumberOfVVs; j++ ) 00197 { 00198 if ( hpss_xattr.SCAttrib[i].VVAttrib[j].PVList != NULL ) 00199 { 00200 free( hpss_xattr.SCAttrib[i].VVAttrib[j].PVList ); 00201 } 00202 } 00203 } 00204 00205 *p_output_size = strlen(outbuff) + 1; 00206 00207 return 0; 00208 } 00209 00210 int print_ns_handle(caddr_t InBuff, size_t InSize, caddr_t OutBuff, size_t * pOutSize) 00211 { 00212 unsigned int i = 0; 00213 *pOutSize = 0; 00214 00215 for(i = 0; i < InSize; i++) 00216 *pOutSize += 00217 sprintf(&(((char *)OutBuff)[i * 2]), "%02x", 00218 (unsigned char)(((char *)InBuff)[i])); 00219 00220 ((char *)OutBuff)[*pOutSize] = '\n'; 00221 *pOutSize += 1; 00222 00223 return 0; 00224 } /* print_ns_handle */ 00225 00226 /* Namespace handle */ 00227 int get_ns_handle(hpssfsal_handle_t * p_objecthandle, /* IN */ 00228 hpssfsal_op_context_t * p_context, /* IN */ 00229 caddr_t buffer_addr, /* IN/OUT */ 00230 size_t buffer_size, /* IN */ 00231 size_t * p_output_size) /* OUT */ 00232 { 00233 00234 if(buffer_size > sizeof(ns_ObjHandle_t)) 00235 { 00236 memcpy(buffer_addr, (caddr_t) & p_objecthandle->data.ns_handle, sizeof(ns_ObjHandle_t)); 00237 *p_output_size = sizeof(ns_ObjHandle_t); 00238 } 00239 else 00240 { 00241 memcpy(buffer_addr, (caddr_t) & p_objecthandle->data.ns_handle, buffer_size); 00242 *p_output_size = buffer_size; 00243 } 00244 00245 return 0; 00246 00247 } 00248 00249 /* Object type */ 00250 int get_obj_type(hpssfsal_handle_t * p_objecthandle, /* IN */ 00251 hpssfsal_op_context_t * p_context, /* IN */ 00252 caddr_t buffer_addr, /* IN/OUT */ 00253 size_t buffer_size, /* IN */ 00254 size_t * p_output_size) /* OUT */ 00255 { 00256 switch (p_objecthandle->data.obj_type) 00257 { 00258 case FSAL_TYPE_DIR: 00259 strncpy((char *)buffer_addr, "directory", buffer_size); 00260 break; 00261 00262 case FSAL_TYPE_FILE: 00263 strncpy((char *)buffer_addr, "file", buffer_size); 00264 break; 00265 00266 case FSAL_TYPE_LNK: 00267 strncpy((char *)buffer_addr, "symlink", buffer_size); 00268 break; 00269 00270 case FSAL_TYPE_JUNCTION: 00271 strncpy((char *)buffer_addr, "junction", buffer_size); 00272 break; 00273 00274 default: 00275 strncpy((char *)buffer_addr, "other/unknown", buffer_size); 00276 break; 00277 } 00278 ((char *)buffer_addr)[strlen((char *)buffer_addr)] = '\n'; 00279 *p_output_size = strlen((char *)buffer_addr) + 1; 00280 return 0; 00281 } 00282 00283 /* Bitfile ID */ 00284 int get_bfid(hpssfsal_handle_t * p_objecthandle, /* IN */ 00285 hpssfsal_op_context_t * p_context, /* IN */ 00286 caddr_t buffer_addr, /* IN/OUT */ 00287 size_t buffer_size, /* IN */ 00288 size_t * p_output_size) /* OUT */ 00289 { 00290 int rc; 00291 ns_ObjHandle_t hpss_hdl; 00292 hpss_Attrs_t hpss_attr; 00293 char *tmp_str_uuid; 00294 00295 if((rc = HPSSFSAL_GetRawAttrHandle(&(p_objecthandle->data.ns_handle), 00296 NULL, 00297 &(p_context->credential.hpss_usercred), 00298 FALSE, &hpss_hdl, NULL, &hpss_attr)) != 0) 00299 { 00300 return hpss2fsal_error(rc); 00301 } 00302 00303 uuid_to_string(&(hpss_attr.BitfileId.ObjectID), (char **)&tmp_str_uuid, &rc); 00304 if(rc != 0) 00305 { 00306 return hpss2fsal_error(rc); 00307 } 00308 00309 strncpy((char *)buffer_addr, tmp_str_uuid, buffer_size); 00310 *p_output_size = strlen((char *)buffer_addr) + 1; 00311 00312 /* HPSS returns a string that it has just allocated. 00313 * Free it to avoid memory leak. 00314 */ 00315 free(tmp_str_uuid); 00316 00317 return 0; 00318 } 00319 00320 static fsal_xattr_def_t xattr_list[] = { 00321 /* for all kind of entries */ 00322 {"ns_handle", get_ns_handle, NULL, print_ns_handle, XATTR_FOR_ALL | XATTR_RO}, 00323 {"type", get_obj_type, NULL, NULL, XATTR_FOR_ALL | XATTR_RO}, 00324 00325 /* for files only */ 00326 {"bitfile_id", get_bfid, NULL, NULL, XATTR_FOR_FILE | XATTR_RO}, 00327 {"class_of_service", get_file_cos, NULL, print_file_cos, XATTR_FOR_FILE | XATTR_RO}, 00328 {"storage_levels", get_file_slevel, NULL, NULL, XATTR_FOR_FILE | XATTR_RO} 00329 00330 }; 00331 00332 #define XATTR_COUNT 5 00333 00334 /* we assume that this number is < 254 */ 00335 #if ( XATTR_COUNT > 254 ) 00336 #error "ERROR: xattr count > 254" 00337 #endif 00338 00339 /* test if an object has a given attribute */ 00340 static int do_match_type(int xattr_flag, fsal_nodetype_t obj_type) 00341 { 00342 switch (obj_type) 00343 { 00344 case FSAL_TYPE_FILE: 00345 return ((xattr_flag & XATTR_FOR_FILE) == XATTR_FOR_FILE); 00346 00347 case FSAL_TYPE_DIR: 00348 return ((xattr_flag & XATTR_FOR_DIR) == XATTR_FOR_DIR); 00349 00350 case FSAL_TYPE_LNK: 00351 return ((xattr_flag & XATTR_FOR_SYMLINK) == XATTR_FOR_SYMLINK); 00352 00353 default: 00354 return ((xattr_flag & XATTR_FOR_ALL) == XATTR_FOR_ALL); 00355 } 00356 } 00357 00358 static int attr_is_read_only(unsigned int attr_index) 00359 { 00360 if(attr_index < XATTR_COUNT) 00361 { 00362 if(xattr_list[attr_index].flags & XATTR_RO) 00363 return TRUE; 00364 } 00365 /* else : UDA */ 00366 return FALSE; 00367 } 00368 00369 static int file_attributes_to_xattr_attrs(fsal_attrib_list_t * file_attrs, 00370 fsal_attrib_list_t * p_xattr_attrs, 00371 unsigned int attr_index) 00372 { 00373 00374 /* supported attributes are: 00375 * - owner (same as the objet) 00376 * - group (same as the objet) 00377 * - type FSAL_TYPE_XATTR 00378 * - fileid (attr index ? or (fileid^((index+1)<<24)) ) 00379 * - mode (config & file) 00380 * - atime, mtime, ctime = these of the object ? 00381 * - size=1block, used=1block 00382 * - rdev=0 00383 * - nlink=1 00384 */ 00385 fsal_attrib_mask_t supported = FSAL_ATTR_SUPPATTR | FSAL_ATTR_MODE | FSAL_ATTR_FILEID 00386 | FSAL_ATTR_TYPE | FSAL_ATTR_OWNER | FSAL_ATTR_GROUP 00387 | FSAL_ATTR_ATIME | FSAL_ATTR_MTIME | FSAL_ATTR_CTIME 00388 | FSAL_ATTR_CREATION | FSAL_ATTR_CHGTIME | FSAL_ATTR_SIZE 00389 | FSAL_ATTR_SPACEUSED | FSAL_ATTR_NUMLINKS | FSAL_ATTR_RAWDEV | FSAL_ATTR_FSID; 00390 fsal_attrib_mask_t unsupp; 00391 00392 /* only those supported by filesystem */ 00393 supported &= global_fs_info.supported_attrs; 00394 00395 if(p_xattr_attrs->asked_attributes == 0) 00396 { 00397 p_xattr_attrs->asked_attributes = supported; 00398 00399 LogCrit(COMPONENT_FSAL, 00400 "Error: p_xattr_attrs->asked_attributes was 0 in %s() line %d, file %s", 00401 __FUNCTION__, __LINE__, __FILE__); 00402 } 00403 00404 unsupp = p_xattr_attrs->asked_attributes & (~supported); 00405 00406 if(unsupp) 00407 { 00408 LogDebug(COMPONENT_FSAL, 00409 "Asking for unsupported attributes in %s(): %#llX removing it from asked attributes", 00410 __FUNCTION__, unsupp); 00411 00412 p_xattr_attrs->asked_attributes &= (~unsupp); 00413 } 00414 00415 if(p_xattr_attrs->asked_attributes & FSAL_ATTR_SUPPATTR) 00416 p_xattr_attrs->supported_attributes = supported; 00417 00418 if(p_xattr_attrs->asked_attributes & FSAL_ATTR_MODE) 00419 { 00420 p_xattr_attrs->mode = file_attrs->mode & global_fs_info.xattr_access_rights; 00421 00422 if(attr_is_read_only(attr_index)) 00423 p_xattr_attrs->mode &= ~(0222); 00424 } 00425 00426 if(p_xattr_attrs->asked_attributes & FSAL_ATTR_FILEID) 00427 { 00428 unsigned int i; 00429 unsigned long hash = attr_index + 1; 00430 char *str = (char *)&file_attrs->fileid; 00431 00432 for(i = 0; i < sizeof(p_xattr_attrs->fileid); i++, str++) 00433 { 00434 hash = (hash << 5) - hash + (unsigned long)(*str); 00435 } 00436 p_xattr_attrs->fileid = hash; 00437 } 00438 00439 if(p_xattr_attrs->asked_attributes & FSAL_ATTR_TYPE) 00440 p_xattr_attrs->type = FSAL_TYPE_XATTR; 00441 00442 if(p_xattr_attrs->asked_attributes & FSAL_ATTR_OWNER) 00443 p_xattr_attrs->owner = file_attrs->owner; 00444 00445 if(p_xattr_attrs->asked_attributes & FSAL_ATTR_GROUP) 00446 p_xattr_attrs->group = file_attrs->group; 00447 00448 if(p_xattr_attrs->asked_attributes & FSAL_ATTR_ATIME) 00449 p_xattr_attrs->atime = file_attrs->atime; 00450 00451 if(p_xattr_attrs->asked_attributes & FSAL_ATTR_MTIME) 00452 p_xattr_attrs->mtime = file_attrs->mtime; 00453 00454 if(p_xattr_attrs->asked_attributes & FSAL_ATTR_CTIME) 00455 p_xattr_attrs->ctime = file_attrs->ctime; 00456 00457 if(p_xattr_attrs->asked_attributes & FSAL_ATTR_CREATION) 00458 p_xattr_attrs->creation = file_attrs->creation; 00459 00460 if(p_xattr_attrs->asked_attributes & FSAL_ATTR_CHGTIME) 00461 { 00462 p_xattr_attrs->chgtime = file_attrs->chgtime; 00463 p_xattr_attrs->change = (uint64_t) p_xattr_attrs->chgtime.seconds; 00464 } 00465 00466 if(p_xattr_attrs->asked_attributes & FSAL_ATTR_SIZE) 00467 p_xattr_attrs->filesize = DEV_BSIZE; 00468 00469 if(p_xattr_attrs->asked_attributes & FSAL_ATTR_SPACEUSED) 00470 p_xattr_attrs->spaceused = DEV_BSIZE; 00471 00472 if(p_xattr_attrs->asked_attributes & FSAL_ATTR_NUMLINKS) 00473 p_xattr_attrs->numlinks = 1; 00474 00475 if(p_xattr_attrs->asked_attributes & FSAL_ATTR_RAWDEV) 00476 { 00477 p_xattr_attrs->rawdev.major = 0; 00478 p_xattr_attrs->rawdev.minor = 0; 00479 } 00480 00481 if(p_xattr_attrs->asked_attributes & FSAL_ATTR_FSID) 00482 { 00483 p_xattr_attrs->fsid = file_attrs->fsid; 00484 } 00485 00486 /* if mode==0, then owner is set to root and mode is set to 0600 */ 00487 if((p_xattr_attrs->asked_attributes & FSAL_ATTR_OWNER) 00488 && (p_xattr_attrs->asked_attributes & FSAL_ATTR_MODE) && (p_xattr_attrs->mode == 0)) 00489 { 00490 p_xattr_attrs->owner = 0; 00491 p_xattr_attrs->mode = 0600; 00492 if(attr_is_read_only(attr_index)) 00493 p_xattr_attrs->mode &= ~(0200); 00494 } 00495 00496 return 0; 00497 00498 } 00499 00508 fsal_status_t HPSSFSAL_GetXAttrAttrs(hpssfsal_handle_t * p_objecthandle, /* IN */ 00509 hpssfsal_op_context_t * p_context, /* IN */ 00510 unsigned int xattr_id, /* IN */ 00511 fsal_attrib_list_t * p_attrs 00513 ) 00514 { 00515 int rc; 00516 char buff[MAXNAMLEN]; 00517 fsal_status_t st; 00518 fsal_attrib_list_t file_attrs; 00519 00520 /* sanity checks */ 00521 if(!p_objecthandle || !p_context || !p_attrs) 00522 Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_GetXAttrAttrs); 00523 00524 /* check that this index match the type of entry */ 00525 if(xattr_id < XATTR_COUNT 00526 && !do_match_type(xattr_list[xattr_id].flags, p_objecthandle->data.obj_type)) 00527 { 00528 Return(ERR_FSAL_INVAL, 0, INDEX_FSAL_GetXAttrAttrs); 00529 } 00530 else if(xattr_id >= XATTR_COUNT) 00531 { 00532 /* This is UDA */ 00533 LogFullDebug(COMPONENT_FSAL, "Getting attributes for UDA #%u", 00534 xattr_id - XATTR_COUNT); 00535 } 00536 00537 /* object attributes we want to retrieve from parent */ 00538 file_attrs.asked_attributes = FSAL_ATTR_MODE | FSAL_ATTR_FILEID | FSAL_ATTR_OWNER 00539 | FSAL_ATTR_GROUP | FSAL_ATTR_ATIME | FSAL_ATTR_MTIME 00540 | FSAL_ATTR_CTIME | FSAL_ATTR_CREATION | FSAL_ATTR_CHGTIME | FSAL_ATTR_FSID; 00541 00542 /* don't retrieve attributes not asked */ 00543 00544 file_attrs.asked_attributes &= p_attrs->asked_attributes; 00545 00546 st = HPSSFSAL_getattrs(p_objecthandle, p_context, &file_attrs); 00547 00548 if(FSAL_IS_ERROR(st)) 00549 Return(st.major, st.minor, INDEX_FSAL_GetXAttrAttrs); 00550 00551 if((rc = file_attributes_to_xattr_attrs(&file_attrs, p_attrs, xattr_id))) 00552 { 00553 Return(ERR_FSAL_INVAL, rc, INDEX_FSAL_GetXAttrAttrs); 00554 } 00555 00556 Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_GetXAttrAttrs); 00557 00558 } /* FSAL_GetXAttrAttrs */ 00559 00560 static int hpss_uda_name_2_fsal(const char *src, char *out) 00561 { 00562 const char *curr_src = src; 00563 char *curr = out; 00564 00565 /* skip first '/' */ 00566 while((*curr_src == '/') && (*curr_src != '\0')) 00567 curr_src++; 00568 if(*curr_src == '\0') 00569 return ERR_FSAL_INVAL; 00570 00571 strcpy(curr, curr_src); 00572 while((curr = strchr(out, '/')) != NULL) 00573 { 00574 *curr = '.'; 00575 } 00576 return 0; 00577 } 00578 00579 static int fsal_xattr_name_2_uda(const char *src, char *out) 00580 { 00581 char *curr = out; 00582 00583 /* add first / */ 00584 *curr = '/'; 00585 curr++; 00586 00587 /* copy the xattr name */ 00588 strcpy(curr, src); 00589 00590 /* then replace '.' with '/' */ 00591 while((curr = strchr(out, '.')) != NULL) 00592 { 00593 *curr = '/'; 00594 } 00595 00596 /* UDA path must start with '/hpss/' */ 00597 if(strncmp(out, "/hpss/", 6) != 0) 00598 return ERR_FSAL_INVAL; 00599 00600 return 0; 00601 } 00602 00615 fsal_status_t HPSSFSAL_ListXAttrs(hpssfsal_handle_t * p_objecthandle, /* IN */ 00616 unsigned int argcookie, /* IN */ 00617 hpssfsal_op_context_t * p_context, /* IN */ 00618 fsal_xattrent_t * xattrs_tab, /* IN/OUT */ 00619 unsigned int xattrs_tabsize, /* IN */ 00620 unsigned int *p_nb_returned, /* OUT */ 00621 int *end_of_list /* OUT */ 00622 ) 00623 { 00624 unsigned int index; 00625 unsigned int out_index; 00626 fsal_status_t st; 00627 fsal_attrib_list_t file_attrs; 00628 int rc; 00629 unsigned int cookie = argcookie ; 00630 00631 /* sanity checks */ 00632 if(!p_objecthandle || !p_context || !xattrs_tab || !p_nb_returned || !end_of_list) 00633 Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_ListXAttrs); 00634 00635 /* Deal with special cookie */ 00636 if( argcookie == FSAL_XATTR_RW_COOKIE ) cookie = XATTR_COUNT ; 00637 00638 /* object attributes we want to retrieve from parent */ 00639 file_attrs.asked_attributes = FSAL_ATTR_MODE | FSAL_ATTR_FILEID | FSAL_ATTR_OWNER 00640 | FSAL_ATTR_GROUP | FSAL_ATTR_ATIME | FSAL_ATTR_MTIME 00641 | FSAL_ATTR_CTIME | FSAL_ATTR_CREATION | FSAL_ATTR_CHGTIME | FSAL_ATTR_FSID; 00642 00643 /* don't retrieve unsuipported attributes */ 00644 file_attrs.asked_attributes &= global_fs_info.supported_attrs; 00645 00646 st = FSAL_getattrs(p_objecthandle, p_context, &file_attrs); 00647 00648 if(FSAL_IS_ERROR(st)) 00649 Return(st.major, st.minor, INDEX_FSAL_ListXAttrs); 00650 00651 for(index = cookie, out_index = 0; 00652 index < XATTR_COUNT && out_index < xattrs_tabsize; index++) 00653 { 00654 if(do_match_type(xattr_list[index].flags, p_objecthandle->data.obj_type)) 00655 { 00656 00657 /* fills an xattr entry */ 00658 xattrs_tab[out_index].xattr_id = index; 00659 FSAL_str2name(xattr_list[index].xattr_name, FSAL_MAX_NAME_LEN, 00660 &xattrs_tab[out_index].xattr_name); 00661 xattrs_tab[out_index].xattr_cookie = index + 1; 00662 00663 /* set asked attributes (all supported) */ 00664 xattrs_tab[out_index].attributes.asked_attributes = 00665 global_fs_info.supported_attrs; 00666 00667 rc = file_attributes_to_xattr_attrs(&file_attrs, 00668 &xattrs_tab[out_index].attributes, index); 00669 00670 if(rc != 0) 00671 { 00672 /* set error flag */ 00673 LogDebug(COMPONENT_FSAL, 00674 "Error %d getting attributes for xattr '%s'", rc, 00675 xattrs_tab[out_index].xattr_name); 00676 xattrs_tab[out_index].attributes.asked_attributes = FSAL_ATTR_RDATTR_ERR; 00677 } 00678 00679 /* next output slot */ 00680 out_index++; 00681 } 00682 } 00683 00684 *end_of_list = (index == XATTR_COUNT); 00685 00686 #if HPSS_LEVEL >= 730 00687 { 00688 /* save a call if output array is full */ 00689 if(out_index == xattrs_tabsize) 00690 { 00691 *end_of_list = FALSE; 00692 *p_nb_returned = out_index; 00693 Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_ListXAttrs); 00694 } 00695 00696 /* get list of UDAs for this entry */ 00697 hpss_userattr_list_t attr_list; 00698 00699 memset(&attr_list, 0, sizeof(hpss_userattr_list_t)); 00700 00701 TakeTokenFSCall(); 00702 rc = hpss_UserAttrListAttrHandle(&(p_objecthandle->data.ns_handle), 00703 NULL, 00704 &(p_context->credential.hpss_usercred), 00705 &attr_list, XML_ATTR); 00706 ReleaseTokenFSCall(); 00707 00708 if(rc == 0) 00709 { 00710 unsigned int i; 00711 for(i = 0; (i < attr_list.len) && (out_index < xattrs_tabsize); i++) 00712 { 00713 char attr_name[FSAL_MAX_NAME_LEN]; 00714 00715 /* the id is XATTR_COUNT + index of HPSS UDA */ 00716 index = XATTR_COUNT + i; 00717 00718 /* continue while index < cookie */ 00719 if(index < cookie) 00720 continue; 00721 00722 xattrs_tab[out_index].xattr_id = index; 00723 00724 if(strlen(attr_list.Pair[i].Key) >= FSAL_MAX_NAME_LEN) 00725 Return(ERR_FSAL_NAMETOOLONG, 0, INDEX_FSAL_ListXAttrs); 00726 00727 /* HPSS UDAs namespace is slash-separated. 00728 * we convert '/' to '.' 00729 */ 00730 rc = hpss_uda_name_2_fsal(attr_list.Pair[i].Key, attr_name); 00731 00732 if(rc != ERR_FSAL_NO_ERROR) 00733 Return(rc, 0, INDEX_FSAL_ListXAttrs); 00734 00735 FSAL_str2name(attr_name, FSAL_MAX_NAME_LEN, 00736 &xattrs_tab[out_index].xattr_name); 00737 xattrs_tab[out_index].xattr_cookie = index + 1; 00738 00739 /* set asked attributes (all supported) */ 00740 xattrs_tab[out_index].attributes.asked_attributes = 00741 global_fs_info.supported_attrs; 00742 00743 rc = file_attributes_to_xattr_attrs(&file_attrs, 00744 &xattrs_tab[out_index].attributes, index); 00745 if(rc != 0) 00746 { 00747 /* set error flag */ 00748 LogDebug(COMPONENT_FSAL, 00749 "Error %d getting attributes for xattr \'%s\'", rc, 00750 xattrs_tab[out_index].xattr_name); 00751 xattrs_tab[out_index].attributes.asked_attributes = FSAL_ATTR_RDATTR_ERR; 00752 } 00753 /* we know the size here (+2 for \n\0) */ 00754 else if(attr_list.Pair[i].Value != NULL) 00755 xattrs_tab[out_index].attributes.filesize 00756 = strlen(attr_list.Pair[i].Value) + 2; 00757 00758 /* next output slot */ 00759 out_index++; 00760 } 00761 /* not end of list if there is more UDAs */ 00762 if(i < attr_list.len) 00763 *end_of_list = FALSE; 00764 else 00765 *end_of_list = TRUE; 00766 } 00767 } 00768 00769 #endif 00770 00771 *p_nb_returned = out_index; 00772 00773 Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_ListXAttrs); 00774 00775 } 00776 00787 fsal_status_t HPSSFSAL_GetXAttrValueById(hpssfsal_handle_t * p_objecthandle, /* IN */ 00788 unsigned int xattr_id, /* IN */ 00789 hpssfsal_op_context_t * p_context, /* IN */ 00790 caddr_t buffer_addr, /* IN/OUT */ 00791 size_t buffer_size, /* IN */ 00792 size_t * p_output_size /* OUT */ 00793 ) 00794 { 00795 int rc; 00796 char buff[MAXNAMLEN]; 00797 00798 /* sanity checks */ 00799 if(!p_objecthandle || !p_context || !p_output_size || !buffer_addr) 00800 Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_GetXAttrValue); 00801 00802 /* check that this index match the type of entry */ 00803 if(xattr_id < XATTR_COUNT 00804 && !do_match_type(xattr_list[xattr_id].flags, p_objecthandle->data.obj_type)) 00805 { 00806 Return(ERR_FSAL_INVAL, 0, INDEX_FSAL_GetXAttrValue); 00807 } 00808 else if(xattr_id >= XATTR_COUNT) 00809 { 00810 #if HPSS_LEVEL >= 730 00811 /* This is a UDA */ 00812 hpss_userattr_list_t attr_list; 00813 unsigned int i; 00814 memset(&attr_list, 0, sizeof(hpss_userattr_list_t)); 00815 00816 LogFullDebug(COMPONENT_FSAL, "Getting value for UDA #%u", 00817 xattr_id - XATTR_COUNT); 00818 00819 /* get list of UDAs for this entry, and return the good value */ 00820 00821 TakeTokenFSCall(); 00822 rc = hpss_UserAttrListAttrHandle(&(p_objecthandle->data.ns_handle), 00823 NULL, 00824 &(p_context->credential.hpss_usercred), 00825 &attr_list, XML_ATTR); 00826 ReleaseTokenFSCall(); 00827 00828 if(rc != 0) 00829 Return(hpss2fsal_error(rc), rc, INDEX_FSAL_GetXAttrValue); 00830 else if(xattr_id - XATTR_COUNT >= attr_list.len) 00831 /* this xattr does not exist anymore */ 00832 Return(ERR_FSAL_STALE, 0, INDEX_FSAL_GetXAttrValue); 00833 00834 if((attr_list.Pair[xattr_id - XATTR_COUNT].Value != NULL) 00835 && (attr_list.Pair[xattr_id - XATTR_COUNT].Value[0] != '\0')) 00836 snprintf((char *)buffer_addr, buffer_size, "%s\n", 00837 attr_list.Pair[xattr_id - XATTR_COUNT].Value); 00838 else 00839 strcpy((char *)buffer_addr, ""); 00840 00841 *p_output_size = strlen((char *)buffer_addr) + 1; 00842 00843 Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_GetXAttrValue); 00844 00845 #else 00846 /* udas are not supported. xattr_id is too high. */ 00847 Return(ERR_FSAL_INVAL, 0, INDEX_FSAL_GetXAttrValue); 00848 #endif 00849 } 00850 00851 /* get the value */ 00852 00853 if(xattr_list[xattr_id].print_func == NULL) 00854 { 00855 rc = xattr_list[xattr_id].get_func(p_objecthandle, 00856 p_context, 00857 buffer_addr, buffer_size, p_output_size); 00858 } 00859 else 00860 { 00861 rc = xattr_list[xattr_id].get_func(p_objecthandle, 00862 p_context, buff, MAXNAMLEN, p_output_size); 00863 00864 xattr_list[xattr_id].print_func(buff, MAXNAMLEN, buffer_addr, p_output_size); 00865 } 00866 00867 Return(rc, 0, INDEX_FSAL_GetXAttrValue); 00868 00869 } 00870 00880 fsal_status_t HPSSFSAL_GetXAttrIdByName(hpssfsal_handle_t * p_objecthandle, /* IN */ 00881 const fsal_name_t * xattr_name, /* IN */ 00882 hpssfsal_op_context_t * p_context, /* IN */ 00883 unsigned int *pxattr_id /* OUT */ 00884 ) 00885 { 00886 unsigned int index, i; 00887 int found = FALSE; 00888 00889 /* sanity checks */ 00890 if(!p_objecthandle || !xattr_name) 00891 Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_GetXAttrValue); 00892 00893 for(index = 0; index < XATTR_COUNT; index++) 00894 { 00895 if(do_match_type(xattr_list[index].flags, p_objecthandle->data.obj_type) 00896 && !strcmp(xattr_list[index].xattr_name, xattr_name->name)) 00897 { 00898 found = TRUE; 00899 break; 00900 } 00901 } 00902 00903 #if HPSS_LEVEL >= 730 00904 if(!found) 00905 { 00906 /* search for name in UDAs */ 00907 hpss_userattr_list_t attr_list; 00908 unsigned int i; 00909 int rc; 00910 char attrpath[FSAL_MAX_NAME_LEN]; 00911 00912 /* convert FSAL xattr name to HPSS attr path. 00913 * returns error if it is not a UDA name. 00914 */ 00915 if(fsal_xattr_name_2_uda(xattr_name->name, attrpath) == 0) 00916 { 00917 00918 memset(&attr_list, 0, sizeof(hpss_userattr_list_t)); 00919 00920 LogFullDebug(COMPONENT_FSAL, "looking for xattr '%s' in UDAs", 00921 xattr_name->name); 00922 00923 /* get list of UDAs for this entry, and return the good index */ 00924 00925 TakeTokenFSCall(); 00926 rc = hpss_UserAttrListAttrHandle(&(p_objecthandle->data.ns_handle), 00927 NULL, 00928 &(p_context->credential.hpss_usercred), 00929 &attr_list, XML_ATTR); 00930 ReleaseTokenFSCall(); 00931 00932 if(rc == 0) 00933 { 00934 00935 for(i = 0; i < attr_list.len; i++) 00936 { 00937 if(!strcmp(attr_list.Pair[i].Key, attrpath)) 00938 { 00939 /* xattr index is XATTR_COUNT + UDA index */ 00940 index = XATTR_COUNT + i; 00941 found = TRUE; 00942 break; 00943 } 00944 } 00945 } 00946 00947 } 00948 /* enf if valid UDA name */ 00949 } /* end if not found */ 00950 #endif 00951 00952 if(found) 00953 { 00954 *pxattr_id = index; 00955 Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_GetXAttrValue); 00956 } 00957 else 00958 Return(ERR_FSAL_NOENT, ENOENT, INDEX_FSAL_GetXAttrValue); 00959 } /* FSAL_GetXAttrIdByName */ 00960 00971 fsal_status_t HPSSFSAL_GetXAttrValueByName(hpssfsal_handle_t * p_objecthandle, /* IN */ 00972 const fsal_name_t * xattr_name, /* IN */ 00973 hpssfsal_op_context_t * p_context, /* IN */ 00974 caddr_t buffer_addr, /* IN/OUT */ 00975 size_t buffer_size, /* IN */ 00976 size_t * p_output_size /* OUT */ 00977 ) 00978 { 00979 unsigned int index; 00980 fsal_status_t st; 00981 #if HPSS_LEVEL >= 730 00982 char attrpath[MAXPATHLEN]; 00983 char attrval[MAXPATHLEN]; 00984 int rc; 00985 #endif 00986 00987 /* sanity checks */ 00988 if(!p_objecthandle || !p_context || !p_output_size || !buffer_addr || !xattr_name) 00989 Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_GetXAttrValue); 00990 00991 /* look for this name */ 00992 00993 for(index = 0; index < XATTR_COUNT; index++) 00994 { 00995 if(do_match_type(xattr_list[index].flags, p_objecthandle->data.obj_type) 00996 && !strcmp(xattr_list[index].xattr_name, xattr_name->name)) 00997 { 00998 00999 return FSAL_GetXAttrValueById(p_objecthandle, index, p_context, 01000 buffer_addr, buffer_size, p_output_size); 01001 01002 } 01003 } 01004 01005 #if HPSS_LEVEL >= 730 01006 if(fsal_xattr_name_2_uda(xattr_name->name, attrpath) == 0) 01007 { 01008 /* get uda value */ 01009 hpss_userattr_list_t attr; 01010 01011 attr.len = 1; 01012 /* use malloc because HPSS may free it */ 01013 attr.Pair = malloc(sizeof(hpss_userattr_t)); 01014 if(attr.Pair == NULL) 01015 Return(ERR_FSAL_NOMEM, errno, INDEX_FSAL_GetXAttrValue); 01016 01017 attr.Pair[0].Key = attrpath; 01018 attr.Pair[0].Value = attrval; 01019 01020 rc = hpss_UserAttrGetAttrHandle(&(p_objecthandle->data.ns_handle), 01021 NULL, &(p_context->credential.hpss_usercred), 01022 &attr, UDA_API_VALUE); 01023 if(rc) 01024 { 01025 free(attr.Pair); 01026 Return(hpss2fsal_error(rc), rc, INDEX_FSAL_GetXAttrValue); 01027 } 01028 01029 if(attr.len > 0) 01030 { 01031 if(attr.Pair[0].Value != NULL) 01032 { 01033 char *noxml = hpss_ChompXMLHeader(attr.Pair[0].Value, NULL); 01034 strcpy(attrval, noxml); 01035 free(noxml); 01036 strncpy((char *)buffer_addr, attrval, buffer_size); 01037 *p_output_size = strlen(attrval) + 1; 01038 } 01039 else 01040 { 01041 strcpy((char *)buffer_addr, ""); 01042 *p_output_size = 1; 01043 } 01044 01045 free(attr.Pair); 01046 Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_GetXAttrValue); 01047 } 01048 else 01049 { 01050 free(attr.Pair); 01051 Return(ERR_FSAL_NOENT, 0, INDEX_FSAL_GetXAttrValue); 01052 } 01053 } 01054 #endif 01055 01056 /* not found */ 01057 Return(ERR_FSAL_NOENT, 0, INDEX_FSAL_GetXAttrValue); 01058 01059 } 01060 01061 static void chomp_attr_value(char *str, size_t size) 01062 { 01063 int len; 01064 01065 if(str == NULL) 01066 return; 01067 01068 /* security: set last char to '\0' */ 01069 str[size - 1] = '\0'; 01070 01071 len = strnlen(str, size); 01072 if((len > 0) && (str[len - 1] == '\n')) 01073 str[len - 1] = '\0'; 01074 } 01075 01076 fsal_status_t HPSSFSAL_SetXAttrValue(hpssfsal_handle_t * p_objecthandle, /* IN */ 01077 const fsal_name_t * xattr_name, /* IN */ 01078 hpssfsal_op_context_t * p_context, /* IN */ 01079 caddr_t buffer_addr, /* IN */ 01080 size_t buffer_size, /* IN */ 01081 int create /* IN */ 01082 ) 01083 { 01084 #if HPSS_LEVEL >= 730 01085 int rc; 01086 char attrpath[FSAL_MAX_NAME_LEN]; 01087 hpss_userattr_list_t inAttr; 01088 01089 /* check that UDA name is valid */ 01090 if(fsal_xattr_name_2_uda(xattr_name->name, attrpath) != 0) 01091 Return(ERR_FSAL_INVAL, 0, INDEX_FSAL_SetXAttrValue); 01092 01093 /* remove '\n" */ 01094 chomp_attr_value((char *)buffer_addr, buffer_size); 01095 01096 /* Set the UDA value */ 01097 01098 inAttr.len = 1; 01099 /* must use malloc() here, because hpss clapi may free() it */ 01100 inAttr.Pair = malloc(inAttr.len * sizeof(hpss_userattr_t)); 01101 inAttr.Pair[0].Key = attrpath; 01102 inAttr.Pair[0].Value = (char *)buffer_addr; 01103 01104 TakeTokenFSCall(); 01105 rc = hpss_UserAttrSetAttrHandle(&(p_objecthandle->data.ns_handle), 01106 NULL, 01107 &(p_context->credential.hpss_usercred), &inAttr, NULL); 01108 ReleaseTokenFSCall(); 01109 01110 free(inAttr.Pair); 01111 01112 Return(hpss2fsal_error(rc), rc, INDEX_FSAL_SetXAttrValue); 01113 01114 #else 01115 Return(ERR_FSAL_PERM, 0, INDEX_FSAL_SetXAttrValue); 01116 #endif 01117 } 01118 01119 fsal_status_t HPSSFSAL_SetXAttrValueById(hpssfsal_handle_t * p_objecthandle, /* IN */ 01120 unsigned int xattr_id, /* IN */ 01121 hpssfsal_op_context_t * p_context, /* IN */ 01122 caddr_t buffer_addr, /* IN */ 01123 size_t buffer_size /* IN */ 01124 ) 01125 { 01126 #if HPSS_LEVEL >= 730 01127 hpss_userattr_list_t attr_list; 01128 hpss_userattr_list_t inAttr; 01129 unsigned int i; 01130 int rc; 01131 01132 if(attr_is_read_only(xattr_id)) 01133 Return(ERR_FSAL_PERM, 0, INDEX_FSAL_SetXAttrValue); 01134 else if(xattr_id < XATTR_COUNT) 01135 /* this is not a UDA (setattr not supported) */ 01136 Return(ERR_FSAL_PERM, 0, INDEX_FSAL_SetXAttrValue); 01137 01138 /* remove '\n" */ 01139 chomp_attr_value((char *)buffer_addr, buffer_size); 01140 01141 memset(&attr_list, 0, sizeof(hpss_userattr_list_t)); 01142 01143 LogFullDebug(COMPONENT_FSAL, "Getting name of UDA #%u", 01144 xattr_id - XATTR_COUNT); 01145 01146 TakeTokenFSCall(); 01147 rc = hpss_UserAttrListAttrHandle(&(p_objecthandle->data.ns_handle), 01148 NULL, 01149 &(p_context->credential.hpss_usercred), 01150 &attr_list, XML_ATTR); 01151 ReleaseTokenFSCall(); 01152 01153 if(rc != 0) 01154 Return(hpss2fsal_error(rc), rc, INDEX_FSAL_SetXAttrValue); 01155 else if(xattr_id - XATTR_COUNT >= attr_list.len) 01156 /* this xattr does not exist anymore */ 01157 Return(ERR_FSAL_STALE, 0, INDEX_FSAL_SetXAttrValue); 01158 01159 /* set the UDA by its name */ 01160 01161 inAttr.len = 1; 01162 /* must use malloc() here, because hpss clapi may free() it */ 01163 inAttr.Pair = malloc(inAttr.len * sizeof(hpss_userattr_t)); 01164 inAttr.Pair[0].Key = attr_list.Pair[xattr_id - XATTR_COUNT].Key; 01165 inAttr.Pair[0].Value = (char *)buffer_addr; 01166 01167 TakeTokenFSCall(); 01168 rc = hpss_UserAttrSetAttrHandle(&(p_objecthandle->data.ns_handle), 01169 NULL, 01170 &(p_context->credential.hpss_usercred), &inAttr, NULL); 01171 ReleaseTokenFSCall(); 01172 01173 free(inAttr.Pair); 01174 01175 Return(hpss2fsal_error(rc), rc, INDEX_FSAL_SetXAttrValue); 01176 01177 #else 01178 Return(ERR_FSAL_PERM, 0, INDEX_FSAL_SetXAttrValue); 01179 #endif 01180 } 01181 01189 fsal_status_t HPSSFSAL_RemoveXAttrById(hpssfsal_handle_t * p_objecthandle, /* IN */ 01190 hpssfsal_op_context_t * p_context, /* IN */ 01191 unsigned int xattr_id) /* IN */ 01192 { 01193 ReturnCode(ERR_FSAL_NO_ERROR, 0); 01194 } /* FSAL_RemoveXAttrById */ 01195 01203 fsal_status_t HPSSFSAL_RemoveXAttrByName(hpssfsal_handle_t * p_objecthandle, /* IN */ 01204 hpssfsal_op_context_t * p_context, /* IN */ 01205 const fsal_name_t * xattr_name) /* IN */ 01206 { 01207 ReturnCode(ERR_FSAL_NO_ERROR, 0); 01208 } /* FSAL_RemoveXAttrById */ 01209 01210 int HPSSFSAL_GetXattrOffsetSetable( void ) 01211 { 01212 return XATTR_COUNT ; 01213 }