nfs-ganesha 1.4
|
00001 /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil; -*- 00002 * vim:expandtab:shiftwidth=4:tabstop=4: 00003 */ 00011 #ifdef HAVE_CONFIG_H 00012 #include "config.h" 00013 #endif 00014 00015 #include "fsal.h" 00016 #include "fsal_internal.h" 00017 #include "fsal_convert.h" 00018 00019 #include <string.h> 00020 #include <time.h> 00021 #include <ctype.h> 00022 #include <sys/types.h> 00023 #include <attr/xattr.h> 00024 00025 /* generic definitions for extended attributes */ 00026 00027 #define XATTR_FOR_FILE 0x00000001 00028 #define XATTR_FOR_DIR 0x00000002 00029 #define XATTR_FOR_SYMLINK 0x00000004 00030 #define XATTR_FOR_ALL 0x0000000F 00031 #define XATTR_RO 0x00000100 00032 #define XATTR_RW 0x00000200 00033 00034 /* function for getting an attribute value */ 00035 00036 typedef int (*xattr_getfunc_t) (vfsfsal_handle_t *, /* object handle */ 00037 vfsfsal_op_context_t *, /* context */ 00038 caddr_t, /* output buff */ 00039 size_t, /* output buff size */ 00040 size_t *, /* output size */ 00041 void *arg); /* optionnal argument */ 00042 00043 typedef int (*xattr_setfunc_t) (vfsfsal_handle_t *, /* object handle */ 00044 vfsfsal_op_context_t *, /* context */ 00045 caddr_t, /* input buff */ 00046 size_t, /* input size */ 00047 int, /* creation flag */ 00048 void *arg); /* optionnal argument */ 00049 00050 typedef struct fsal_xattr_def__ 00051 { 00052 char xattr_name[FSAL_MAX_NAME_LEN]; 00053 xattr_getfunc_t get_func; 00054 xattr_setfunc_t set_func; 00055 int flags; 00056 void *arg; 00057 } fsal_xattr_def_t; 00058 00059 /* 00060 * DEFINE GET/SET FUNCTIONS 00061 */ 00062 00063 int print_vfshandle(vfsfsal_handle_t * p_objecthandle, /* object handle */ 00064 vfsfsal_op_context_t * print_vfshandlep_context, /* IN */ 00065 caddr_t buffer_addr, /* IN/OUT */ 00066 size_t buffer_size, /* IN */ 00067 size_t * p_output_size, /* OUT */ 00068 void *arg) 00069 { 00070 *p_output_size = snprintf( buffer_addr, buffer_size, "(not yet implemented)" ) ; 00071 00072 return 0; 00073 } /* print_fid */ 00074 00075 /* DEFINE HERE YOUR ATTRIBUTES LIST */ 00076 00077 static fsal_xattr_def_t xattr_list[] = { 00078 {"vfshandle", print_vfshandle, NULL, XATTR_FOR_ALL | XATTR_RO, NULL}, 00079 }; 00080 00081 #define XATTR_COUNT 1 00082 00083 /* we assume that this number is < 254 */ 00084 #if ( XATTR_COUNT > 254 ) 00085 #error "ERROR: xattr count > 254" 00086 #endif 00087 00088 /* YOUR SHOULD NOT HAVE TO MODIFY THE FOLLOWING FUNCTIONS */ 00089 00090 /* test if an object has a given attribute */ 00091 static int do_match_type(int xattr_flag, fsal_nodetype_t obj_type) 00092 { 00093 switch (obj_type) 00094 { 00095 case FSAL_TYPE_FILE: 00096 return ((xattr_flag & XATTR_FOR_FILE) == XATTR_FOR_FILE); 00097 00098 case FSAL_TYPE_DIR: 00099 return ((xattr_flag & XATTR_FOR_DIR) == XATTR_FOR_DIR); 00100 00101 case FSAL_TYPE_LNK: 00102 return ((xattr_flag & XATTR_FOR_SYMLINK) == XATTR_FOR_SYMLINK); 00103 00104 default: 00105 return ((xattr_flag & XATTR_FOR_ALL) == XATTR_FOR_ALL); 00106 } 00107 } 00108 00109 static int attr_is_read_only(unsigned int attr_index) 00110 { 00111 if(attr_index < XATTR_COUNT) 00112 { 00113 if(xattr_list[attr_index].flags & XATTR_RO) 00114 return TRUE; 00115 } 00116 /* else : standard xattr */ 00117 return FALSE; 00118 } 00119 00120 static int file_attributes_to_xattr_attrs(fsal_attrib_list_t * file_attrs, 00121 fsal_attrib_list_t * p_xattr_attrs, 00122 unsigned int attr_index) 00123 { 00124 /* supported attributes are: 00125 * - owner (same as the objet) 00126 * - group (same as the objet) 00127 * - type FSAL_TYPE_XATTR 00128 * - fileid (attr index ? or (fileid^((index+1)<<24)) ) 00129 * - mode (config & file) 00130 * - atime, mtime, ctime = these of the object ? 00131 * - size=1block, used=1block 00132 * - rdev=0 00133 * - nlink=1 00134 */ 00135 fsal_attrib_mask_t supported = FSAL_ATTR_SUPPATTR | FSAL_ATTR_MODE | FSAL_ATTR_FILEID 00136 | FSAL_ATTR_TYPE | FSAL_ATTR_OWNER | FSAL_ATTR_GROUP 00137 | FSAL_ATTR_ATIME | FSAL_ATTR_MTIME | FSAL_ATTR_CTIME 00138 | FSAL_ATTR_CREATION | FSAL_ATTR_CHGTIME | FSAL_ATTR_SIZE 00139 | FSAL_ATTR_SPACEUSED | FSAL_ATTR_NUMLINKS | FSAL_ATTR_RAWDEV | FSAL_ATTR_FSID; 00140 fsal_attrib_mask_t unsupp; 00141 00142 /* only those supported by filesystem */ 00143 supported &= global_fs_info.supported_attrs; 00144 00145 if(p_xattr_attrs->asked_attributes == 0) 00146 { 00147 p_xattr_attrs->asked_attributes = supported; 00148 00149 LogCrit(COMPONENT_FSAL, 00150 "Error: p_xattr_attrs->asked_attributes was 0 in %s() line %d, file %s", 00151 __FUNCTION__, __LINE__, __FILE__); 00152 } 00153 00154 unsupp = p_xattr_attrs->asked_attributes & (~supported); 00155 00156 if(unsupp) 00157 { 00158 LogDebug(COMPONENT_FSAL, 00159 "Asking for unsupported attributes in %s(): %#llX removing it from asked attributes", 00160 __FUNCTION__, unsupp); 00161 00162 p_xattr_attrs->asked_attributes &= (~unsupp); 00163 } 00164 00165 if(p_xattr_attrs->asked_attributes & FSAL_ATTR_SUPPATTR) 00166 p_xattr_attrs->supported_attributes = supported; 00167 00168 if(p_xattr_attrs->asked_attributes & FSAL_ATTR_MODE) 00169 { 00170 p_xattr_attrs->mode = file_attrs->mode & global_fs_info.xattr_access_rights; 00171 00172 if(attr_is_read_only(attr_index)) 00173 p_xattr_attrs->mode &= ~(0222); 00174 } 00175 00176 if(p_xattr_attrs->asked_attributes & FSAL_ATTR_FILEID) 00177 { 00178 unsigned int i; 00179 unsigned long hash = attr_index + 1; 00180 char *str = (char *)&file_attrs->fileid; 00181 00182 for(i = 0; i < sizeof(p_xattr_attrs->fileid); i++, str++) 00183 { 00184 hash = (hash << 5) - hash + (unsigned long)(*str); 00185 } 00186 p_xattr_attrs->fileid = hash; 00187 } 00188 00189 if(p_xattr_attrs->asked_attributes & FSAL_ATTR_TYPE) 00190 p_xattr_attrs->type = FSAL_TYPE_XATTR; 00191 00192 if(p_xattr_attrs->asked_attributes & FSAL_ATTR_OWNER) 00193 p_xattr_attrs->owner = file_attrs->owner; 00194 00195 if(p_xattr_attrs->asked_attributes & FSAL_ATTR_GROUP) 00196 p_xattr_attrs->group = file_attrs->group; 00197 00198 if(p_xattr_attrs->asked_attributes & FSAL_ATTR_ATIME) 00199 p_xattr_attrs->atime = file_attrs->atime; 00200 00201 if(p_xattr_attrs->asked_attributes & FSAL_ATTR_MTIME) 00202 p_xattr_attrs->mtime = file_attrs->mtime; 00203 00204 if(p_xattr_attrs->asked_attributes & FSAL_ATTR_CTIME) 00205 p_xattr_attrs->ctime = file_attrs->ctime; 00206 00207 if(p_xattr_attrs->asked_attributes & FSAL_ATTR_CREATION) 00208 p_xattr_attrs->creation = file_attrs->creation; 00209 00210 if(p_xattr_attrs->asked_attributes & FSAL_ATTR_CHGTIME) 00211 { 00212 p_xattr_attrs->chgtime = file_attrs->chgtime; 00213 p_xattr_attrs->change = (uint64_t) p_xattr_attrs->chgtime.seconds; 00214 } 00215 00216 if(p_xattr_attrs->asked_attributes & FSAL_ATTR_SIZE) 00217 p_xattr_attrs->filesize = DEV_BSIZE; 00218 00219 if(p_xattr_attrs->asked_attributes & FSAL_ATTR_SPACEUSED) 00220 p_xattr_attrs->spaceused = DEV_BSIZE; 00221 00222 if(p_xattr_attrs->asked_attributes & FSAL_ATTR_NUMLINKS) 00223 p_xattr_attrs->numlinks = 1; 00224 00225 if(p_xattr_attrs->asked_attributes & FSAL_ATTR_RAWDEV) 00226 { 00227 p_xattr_attrs->rawdev.major = 0; 00228 p_xattr_attrs->rawdev.minor = 0; 00229 } 00230 00231 if(p_xattr_attrs->asked_attributes & FSAL_ATTR_FSID) 00232 { 00233 p_xattr_attrs->fsid = file_attrs->fsid; 00234 } 00235 00236 /* if mode==0, then owner is set to root and mode is set to 0600 */ 00237 if((p_xattr_attrs->asked_attributes & FSAL_ATTR_OWNER) 00238 && (p_xattr_attrs->asked_attributes & FSAL_ATTR_MODE) && (p_xattr_attrs->mode == 0)) 00239 { 00240 p_xattr_attrs->owner = 0; 00241 p_xattr_attrs->mode = 0600; 00242 if(attr_is_read_only(attr_index)) 00243 p_xattr_attrs->mode &= ~(0200); 00244 } 00245 00246 return 0; 00247 00248 } 00249 00258 fsal_status_t VFSFSAL_GetXAttrAttrs(fsal_handle_t * p_objecthandle, /* IN */ 00259 fsal_op_context_t * p_context, /* IN */ 00260 unsigned int xattr_id, /* IN */ 00261 fsal_attrib_list_t * p_attrs 00263 ) 00264 { 00265 int rc; 00266 fsal_status_t st; 00267 fsal_attrib_list_t file_attrs; 00268 00269 /* sanity checks */ 00270 if(!p_objecthandle || !p_context || !p_attrs) 00271 Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_GetXAttrAttrs); 00272 00273 /* object attributes we want to retrieve from parent */ 00274 file_attrs.asked_attributes = FSAL_ATTR_MODE | FSAL_ATTR_FILEID | FSAL_ATTR_OWNER 00275 | FSAL_ATTR_GROUP | FSAL_ATTR_ATIME | FSAL_ATTR_MTIME | FSAL_ATTR_TYPE 00276 | FSAL_ATTR_CTIME | FSAL_ATTR_CREATION | FSAL_ATTR_CHGTIME | FSAL_ATTR_FSID; 00277 00278 /* don't retrieve attributes not asked */ 00279 file_attrs.asked_attributes &= p_attrs->asked_attributes; 00280 00281 st = VFSFSAL_getattrs(p_objecthandle, p_context, &file_attrs); 00282 00283 if(FSAL_IS_ERROR(st)) 00284 Return(st.major, st.minor, INDEX_FSAL_GetXAttrAttrs); 00285 00286 /* check that this index match the type of entry */ 00287 if(xattr_id < XATTR_COUNT 00288 && !do_match_type(xattr_list[xattr_id].flags, file_attrs.type)) 00289 { 00290 Return(ERR_FSAL_INVAL, 0, INDEX_FSAL_GetXAttrAttrs); 00291 } 00292 else if(xattr_id >= XATTR_COUNT) 00293 { 00294 /* This is user defined xattr */ 00295 LogFullDebug(COMPONENT_FSAL, 00296 "Getting attributes for xattr #%u", xattr_id - XATTR_COUNT); 00297 } 00298 00299 if((rc = file_attributes_to_xattr_attrs(&file_attrs, p_attrs, xattr_id))) 00300 { 00301 Return(ERR_FSAL_INVAL, rc, INDEX_FSAL_GetXAttrAttrs); 00302 } 00303 00304 Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_GetXAttrAttrs); 00305 00306 } /* FSAL_GetXAttrAttrs */ 00307 00320 fsal_status_t VFSFSAL_ListXAttrs(fsal_handle_t * p_objecthandle, /* IN */ 00321 unsigned int argcookie, /* IN */ 00322 fsal_op_context_t * p_context, /* IN */ 00323 fsal_xattrent_t * xattrs_tab, /* IN/OUT */ 00324 unsigned int xattrs_tabsize, /* IN */ 00325 unsigned int *p_nb_returned, /* OUT */ 00326 int *end_of_list /* OUT */ 00327 ) 00328 { 00329 unsigned int index; 00330 unsigned int out_index; 00331 fsal_status_t st; 00332 fsal_attrib_list_t file_attrs; 00333 int fd; 00334 unsigned int cookie = argcookie ; 00335 00336 char names[MAXPATHLEN], *ptr; 00337 size_t namesize; 00338 int xattr_idx; 00339 00340 /* sanity checks */ 00341 if(!p_objecthandle || !p_context || !xattrs_tab || !p_nb_returned || !end_of_list) 00342 Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_ListXAttrs); 00343 00344 /* Deal with special cookie */ 00345 if( argcookie == FSAL_XATTR_RW_COOKIE ) cookie = XATTR_COUNT ; 00346 00347 /* object attributes we want to retrieve from parent */ 00348 file_attrs.asked_attributes = FSAL_ATTR_MODE | FSAL_ATTR_FILEID | FSAL_ATTR_OWNER 00349 | FSAL_ATTR_GROUP | FSAL_ATTR_ATIME | FSAL_ATTR_MTIME | FSAL_ATTR_TYPE 00350 | FSAL_ATTR_CTIME | FSAL_ATTR_CREATION | FSAL_ATTR_CHGTIME | FSAL_ATTR_FSID; 00351 00352 /* don't retrieve unsuipported attributes */ 00353 file_attrs.asked_attributes &= global_fs_info.supported_attrs; 00354 00355 st = VFSFSAL_getattrs(p_objecthandle, p_context, &file_attrs); 00356 00357 if(FSAL_IS_ERROR(st)) 00358 Return(st.major, st.minor, INDEX_FSAL_ListXAttrs); 00359 00360 for(index = cookie, out_index = 0; 00361 index < XATTR_COUNT && out_index < xattrs_tabsize; index++) 00362 { 00363 if(do_match_type(xattr_list[index].flags, file_attrs.type)) 00364 { 00365 /* fills an xattr entry */ 00366 xattrs_tab[out_index].xattr_id = index; 00367 FSAL_str2name(xattr_list[index].xattr_name, FSAL_MAX_NAME_LEN, 00368 &xattrs_tab[out_index].xattr_name); 00369 xattrs_tab[out_index].xattr_cookie = index + 1; 00370 00371 /* set asked attributes (all supported) */ 00372 xattrs_tab[out_index].attributes.asked_attributes = 00373 global_fs_info.supported_attrs; 00374 00375 if(file_attributes_to_xattr_attrs 00376 (&file_attrs, &xattrs_tab[out_index].attributes, index)) 00377 { 00378 /* set error flag */ 00379 xattrs_tab[out_index].attributes.asked_attributes = FSAL_ATTR_RDATTR_ERR; 00380 } 00381 00382 /* next output slot */ 00383 out_index++; 00384 } 00385 } 00386 00387 /* save a call if output array is full */ 00388 if(out_index == xattrs_tabsize) 00389 { 00390 *end_of_list = FALSE; 00391 *p_nb_returned = out_index; 00392 Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_ListXAttrs); 00393 } 00394 00395 /* get the path of the file in Lustre */ 00396 TakeTokenFSCall(); 00397 st = fsal_internal_handle2fd(p_context, p_objecthandle, &fd, O_RDWR); 00398 ReleaseTokenFSCall(); 00399 if(FSAL_IS_ERROR(st)) 00400 ReturnStatus(st, INDEX_FSAL_ListXAttrs); 00401 00402 /* get xattrs */ 00403 00404 TakeTokenFSCall(); 00405 namesize = flistxattr(fd, names, sizeof(names)); 00406 ReleaseTokenFSCall(); 00407 00408 if(namesize >= 0) 00409 { 00410 size_t len = 0; 00411 00412 errno = 0; 00413 00414 for(ptr = names, xattr_idx = 0; 00415 (ptr < names + namesize) && (out_index < xattrs_tabsize); 00416 xattr_idx++, ptr += len + 1) 00417 { 00418 len = strlen(ptr); 00419 index = XATTR_COUNT + xattr_idx; 00420 00421 /* skip if index is before cookie */ 00422 if(index < cookie) 00423 continue; 00424 00425 /* fills an xattr entry */ 00426 xattrs_tab[out_index].xattr_id = index; 00427 FSAL_str2name(ptr, len + 1, &xattrs_tab[out_index].xattr_name); 00428 xattrs_tab[out_index].xattr_cookie = index + 1; 00429 00430 /* set asked attributes (all supported) */ 00431 xattrs_tab[out_index].attributes.asked_attributes = 00432 global_fs_info.supported_attrs; 00433 00434 if(file_attributes_to_xattr_attrs(&file_attrs, 00435 &xattrs_tab[out_index].attributes, index)) 00436 { 00437 /* set error flag */ 00438 xattrs_tab[out_index].attributes.asked_attributes = FSAL_ATTR_RDATTR_ERR; 00439 } 00440 00441 /* next output slot */ 00442 out_index++; 00443 } 00444 /* all xattrs are in the output array */ 00445 if(ptr >= names + namesize) 00446 *end_of_list = TRUE; 00447 else 00448 *end_of_list = FALSE; 00449 } 00450 else /* no xattrs */ 00451 *end_of_list = TRUE; 00452 00453 *p_nb_returned = out_index; 00454 00455 close(fd); 00456 Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_ListXAttrs); 00457 00458 } 00459 00460 static int xattr_id_to_name(int fd, unsigned int xattr_id, char *name) 00461 { 00462 unsigned int index; 00463 unsigned int curr_idx; 00464 char names[MAXPATHLEN], *ptr; 00465 size_t namesize; 00466 size_t len = 0; 00467 00468 if(xattr_id < XATTR_COUNT) 00469 return ERR_FSAL_INVAL; 00470 00471 index = xattr_id - XATTR_COUNT; 00472 00473 /* get xattrs */ 00474 00475 TakeTokenFSCall(); 00476 namesize = flistxattr(fd, names, sizeof(names)); 00477 ReleaseTokenFSCall(); 00478 00479 if(namesize < 0) 00480 return ERR_FSAL_NOENT; 00481 00482 errno = 0; 00483 00484 for(ptr = names, curr_idx = 0; ptr < names + namesize; curr_idx++, ptr += len + 1) 00485 { 00486 len = strlen(ptr); 00487 if(curr_idx == index) 00488 { 00489 strcpy(name, ptr); 00490 return ERR_FSAL_NO_ERROR; 00491 } 00492 } 00493 return ERR_FSAL_NOENT; 00494 } 00495 00500 static int xattr_name_to_id(int fd, const char *name) 00501 { 00502 unsigned int i; 00503 char names[MAXPATHLEN], *ptr; 00504 size_t namesize; 00505 00506 /* get xattrs */ 00507 00508 TakeTokenFSCall(); 00509 namesize = flistxattr(fd, names, sizeof(names)); 00510 ReleaseTokenFSCall(); 00511 00512 if(namesize < 0) 00513 return -ERR_FSAL_NOENT; 00514 00515 for(ptr = names, i = 0; ptr < names + namesize; i++, ptr += strlen(ptr) + 1) 00516 { 00517 if(!strcmp(name, ptr)) 00518 return i + XATTR_COUNT; 00519 } 00520 return -ERR_FSAL_NOENT; 00521 } 00522 00523 static int xattr_format_value(caddr_t buffer, size_t * datalen, size_t maxlen) 00524 { 00525 size_t size_in = *datalen; 00526 size_t len = strnlen((char *)buffer, size_in); 00527 int i; 00528 00529 if(len == size_in - 1 || len == size_in) 00530 { 00531 int ascii = TRUE; 00532 char *str = buffer; 00533 int i; 00534 00535 for(i = 0; i < len; i++) 00536 { 00537 if(!isprint(str[i]) && !isspace(str[i])) 00538 { 00539 ascii = FALSE; 00540 break; 00541 } 00542 } 00543 00544 if(ascii) 00545 { 00546 *datalen = size_in; 00547 /* add additional '\n', if missing */ 00548 if((size_in + 1 < maxlen) && (str[len - 1] != '\n')) 00549 { 00550 str[len] = '\n'; 00551 str[len + 1] = '\0'; 00552 (*datalen) += 2; 00553 } 00554 return ERR_FSAL_NO_ERROR; 00555 } 00556 } 00557 00558 /* byte, word, 32 or 64 bits */ 00559 if(size_in == 1) 00560 { 00561 unsigned char val = *((unsigned char *)buffer); 00562 *datalen = 1 + snprintf((char *)buffer, maxlen, "%hhu\n", val); 00563 return ERR_FSAL_NO_ERROR; 00564 } 00565 else if(size_in == 2) 00566 { 00567 unsigned short val = *((unsigned short *)buffer); 00568 *datalen = 1 + snprintf((char *)buffer, maxlen, "%hu\n", val); 00569 return ERR_FSAL_NO_ERROR; 00570 } 00571 else if(size_in == 4) 00572 { 00573 unsigned int val = *((unsigned int *)buffer); 00574 *datalen = 1 + snprintf((char *)buffer, maxlen, "%u\n", val); 00575 return ERR_FSAL_NO_ERROR; 00576 } 00577 else if(size_in == 8) 00578 { 00579 unsigned long long val = *((unsigned long long *)buffer); 00580 *datalen = 1 + snprintf((char *)buffer, maxlen, "%llu\n", val); 00581 return ERR_FSAL_NO_ERROR; 00582 } 00583 else 00584 { 00585 /* 2 bytes per initial byte +'0x' +\n +\0 */ 00586 char *curr_out; 00587 char *tmp_buf = (char *)gsh_malloc(3 * size_in + 4); 00588 if(!tmp_buf) 00589 return ERR_FSAL_NOMEM; 00590 curr_out = tmp_buf; 00591 curr_out += sprintf(curr_out, "0x"); 00592 /* hexa representation */ 00593 for(i = 0; i < size_in; i++) 00594 { 00595 unsigned char *p8 = (unsigned char *)(buffer + i); 00596 if((i % 4 == 3) && (i != size_in - 1)) 00597 curr_out += sprintf(curr_out, "%02hhX.", *p8); 00598 else 00599 curr_out += sprintf(curr_out, "%02hhX", *p8); 00600 } 00601 *curr_out = '\n'; 00602 curr_out++; 00603 *curr_out = '\0'; 00604 curr_out++; 00605 strncpy((char *)buffer, tmp_buf, maxlen); 00606 *datalen = strlen(tmp_buf) + 1; 00607 if(*datalen > maxlen) 00608 *datalen = maxlen; 00609 gsh_free(tmp_buf); 00610 return ERR_FSAL_NO_ERROR; 00611 } 00612 } 00613 00624 fsal_status_t VFSFSAL_GetXAttrValueById(fsal_handle_t * p_objecthandle, /* IN */ 00625 unsigned int xattr_id, /* IN */ 00626 fsal_op_context_t * p_context, /* IN */ 00627 caddr_t buffer_addr, /* IN/OUT */ 00628 size_t buffer_size, /* IN */ 00629 size_t * p_output_size /* OUT */ 00630 ) 00631 { 00632 int rc; 00633 fsal_attrib_list_t file_attrs; 00634 int fd; 00635 fsal_status_t st; 00636 00637 /* sanity checks */ 00638 if(!p_objecthandle || !p_context || !p_output_size || !buffer_addr) 00639 Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_GetXAttrValue); 00640 00641 /* get type for checking it */ 00642 file_attrs.asked_attributes = FSAL_ATTR_TYPE; 00643 00644 st = VFSFSAL_getattrs(p_objecthandle, p_context, &file_attrs); 00645 00646 if(FSAL_IS_ERROR(st)) 00647 ReturnStatus(st, INDEX_FSAL_GetXAttrValue); 00648 00649 /* check that this index match the type of entry */ 00650 if((xattr_id < XATTR_COUNT) 00651 && !do_match_type(xattr_list[xattr_id].flags, file_attrs.type)) 00652 { 00653 Return(ERR_FSAL_INVAL, 0, INDEX_FSAL_GetXAttrValue); 00654 } 00655 else if(xattr_id >= XATTR_COUNT) 00656 { 00657 char attr_name[MAXPATHLEN]; 00658 00659 TakeTokenFSCall(); 00660 st = fsal_internal_handle2fd(p_context, p_objecthandle, &fd, O_RDWR); 00661 ReleaseTokenFSCall(); 00662 if(FSAL_IS_ERROR(st)) 00663 ReturnStatus(st, INDEX_FSAL_GetXAttrValue); 00664 00665 /* get the name for this attr */ 00666 rc = xattr_id_to_name(fd, xattr_id, attr_name); 00667 if(rc) 00668 { 00669 close(fd); 00670 Return(rc, errno, INDEX_FSAL_GetXAttrValue); 00671 } 00672 00673 rc = fgetxattr(fd, attr_name, buffer_addr, buffer_size); 00674 if(rc < 0) 00675 { 00676 close(fd); 00677 Return(posix2fsal_error(errno), errno, INDEX_FSAL_GetXAttrValue); 00678 } 00679 00680 /* the xattr value can be a binary, or a string. 00681 * trying to determine its type... 00682 */ 00683 *p_output_size = rc; 00684 xattr_format_value(buffer_addr, p_output_size, buffer_size); 00685 00686 close(fd); 00687 Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_GetXAttrValue); 00688 } 00689 else /* built-in attr */ 00690 { 00691 /* get the value */ 00692 rc = xattr_list[xattr_id].get_func(p_objecthandle, p_context, 00693 buffer_addr, buffer_size, 00694 p_output_size, xattr_list[xattr_id].arg); 00695 Return(rc, 0, INDEX_FSAL_GetXAttrValue); 00696 } 00697 00698 } 00699 00710 fsal_status_t VFSFSAL_GetXAttrIdByName(fsal_handle_t * p_objecthandle, /* IN */ 00711 const fsal_name_t * xattr_name, /* IN */ 00712 fsal_op_context_t * p_context, /* IN */ 00713 unsigned int *pxattr_id /* OUT */ 00714 ) 00715 { 00716 fsal_status_t st; 00717 unsigned int index; 00718 int rc; 00719 int found = FALSE; 00720 int fd; 00721 00722 /* sanity checks */ 00723 if(!p_objecthandle || !xattr_name) 00724 Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_GetXAttrValue); 00725 00726 for(index = 0; index < XATTR_COUNT; index++) 00727 { 00728 if(!strcmp(xattr_list[index].xattr_name, xattr_name->name)) 00729 { 00730 found = TRUE; 00731 break; 00732 } 00733 } 00734 00735 /* search in xattrs */ 00736 if(!found) 00737 { 00738 00739 TakeTokenFSCall(); 00740 st = fsal_internal_handle2fd(p_context, p_objecthandle, &fd, O_RDWR); 00741 ReleaseTokenFSCall(); 00742 if(FSAL_IS_ERROR(st)) 00743 ReturnStatus(st, INDEX_FSAL_GetXAttrValue); 00744 00745 errno = 0; 00746 rc = xattr_name_to_id(fd, xattr_name->name); 00747 if(rc < 0) 00748 { 00749 close(fd); 00750 Return(-rc, errno, INDEX_FSAL_GetXAttrValue); 00751 } 00752 else 00753 { 00754 index = rc; 00755 found = TRUE; 00756 } 00757 } 00758 00759 close(fd); 00760 00761 if(found) 00762 { 00763 *pxattr_id = index; 00764 Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_GetXAttrValue); 00765 } 00766 else 00767 Return(ERR_FSAL_NOENT, ENOENT, INDEX_FSAL_GetXAttrValue); 00768 } /* FSAL_GetXAttrIdByName */ 00769 00780 fsal_status_t VFSFSAL_GetXAttrValueByName(fsal_handle_t * p_objecthandle, /* IN */ 00781 const fsal_name_t * xattr_name, /* IN */ 00782 fsal_op_context_t * p_context, /* IN */ 00783 caddr_t buffer_addr, /* IN/OUT */ 00784 size_t buffer_size, /* IN */ 00785 size_t * p_output_size /* OUT */ 00786 ) 00787 { 00788 unsigned int index; 00789 fsal_attrib_list_t file_attrs; 00790 fsal_status_t st; 00791 int rc; 00792 int fd; 00793 00794 /* sanity checks */ 00795 if(!p_objecthandle || !p_context || !p_output_size || !buffer_addr || !xattr_name) 00796 Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_GetXAttrValue); 00797 00798 /* get type for checking it */ 00799 file_attrs.asked_attributes = FSAL_ATTR_TYPE; 00800 00801 st = VFSFSAL_getattrs(p_objecthandle, p_context, &file_attrs); 00802 00803 if(FSAL_IS_ERROR(st)) 00804 ReturnStatus(st, INDEX_FSAL_GetXAttrValue); 00805 00806 /* look for this name */ 00807 00808 for(index = 0; index < XATTR_COUNT; index++) 00809 { 00810 if(do_match_type(xattr_list[index].flags, file_attrs.type) 00811 && !strcmp(xattr_list[index].xattr_name, xattr_name->name)) 00812 { 00813 00814 return VFSFSAL_GetXAttrValueById(p_objecthandle, index, p_context, buffer_addr, 00815 buffer_size, p_output_size); 00816 } 00817 } 00818 00819 TakeTokenFSCall(); 00820 st = fsal_internal_handle2fd(p_context, p_objecthandle, &fd, O_RDWR); 00821 ReleaseTokenFSCall(); 00822 if(FSAL_IS_ERROR(st)) 00823 ReturnStatus(st, INDEX_FSAL_GetXAttrValue); 00824 00825 /* is it an xattr? */ 00826 rc = fgetxattr(fd, xattr_name->name, buffer_addr, buffer_size); 00827 if(rc < 0) 00828 { 00829 close(fd); 00830 Return(posix2fsal_error(errno), errno, INDEX_FSAL_GetXAttrValue); 00831 } 00832 /* the xattr value can be a binary, or a string. 00833 * trying to determine its type... 00834 */ 00835 *p_output_size = rc; 00836 xattr_format_value(buffer_addr, p_output_size, buffer_size); 00837 00838 close(fd); 00839 Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_GetXAttrValue); 00840 } 00841 00842 static void chomp_attr_value(char *str, size_t size) 00843 { 00844 int len; 00845 00846 if(str == NULL) 00847 return; 00848 00849 /* security: set last char to '\0' */ 00850 str[size - 1] = '\0'; 00851 00852 len = strnlen(str, size); 00853 if((len > 0) && (str[len - 1] == '\n')) 00854 str[len - 1] = '\0'; 00855 } 00856 00857 fsal_status_t VFSFSAL_SetXAttrValue(fsal_handle_t * p_objecthandle, /* IN */ 00858 const fsal_name_t * xattr_name, /* IN */ 00859 fsal_op_context_t * p_context, /* IN */ 00860 caddr_t buffer_addr, /* IN */ 00861 size_t buffer_size, /* IN */ 00862 int create /* IN */ 00863 ) 00864 { 00865 int rc; 00866 fsal_status_t st; 00867 int fd = 0; 00868 size_t len; 00869 00870 /* remove final '\n', if any */ 00871 chomp_attr_value((char *)buffer_addr, buffer_size); 00872 00873 /* build fid path in lustre */ 00874 TakeTokenFSCall(); 00875 st = fsal_internal_handle2fd(p_context, p_objecthandle, &fd, O_RDWR); 00876 ReleaseTokenFSCall(); 00877 if(FSAL_IS_ERROR(st)) 00878 ReturnStatus(st, INDEX_FSAL_SetXAttrValue); 00879 00880 len = strnlen((char *)buffer_addr, buffer_size); 00881 00882 TakeTokenFSCall(); 00883 if(len == 0) 00884 rc = fsetxattr(fd, xattr_name->name, "", 1, create ? XATTR_CREATE : XATTR_REPLACE); 00885 else 00886 rc = fsetxattr(fd, xattr_name->name, (char *)buffer_addr, 00887 len, create ? XATTR_CREATE : XATTR_REPLACE); 00888 00889 ReleaseTokenFSCall(); 00890 00891 close(fd); 00892 00893 if(rc != 0) 00894 Return(posix2fsal_error(errno), errno, INDEX_FSAL_SetXAttrValue); 00895 else 00896 Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_SetXAttrValue); 00897 } 00898 00899 fsal_status_t VFSFSAL_SetXAttrValueById(fsal_handle_t * p_objecthandle, /* IN */ 00900 unsigned int xattr_id, /* IN */ 00901 fsal_op_context_t * p_context, /* IN */ 00902 caddr_t buffer_addr, /* IN */ 00903 size_t buffer_size /* IN */ 00904 ) 00905 { 00906 int rc; 00907 fsal_status_t st; 00908 int fd = 0; 00909 fsal_name_t attr_name; 00910 char name[FSAL_MAX_NAME_LEN]; 00911 00912 if(attr_is_read_only(xattr_id)) 00913 Return(ERR_FSAL_PERM, 0, INDEX_FSAL_SetXAttrValue); 00914 else if(xattr_id < XATTR_COUNT) 00915 /* this is not a UDA (setattr not supported) */ 00916 Return(ERR_FSAL_PERM, 0, INDEX_FSAL_SetXAttrValue); 00917 00918 /* build fid path in lustre */ 00919 TakeTokenFSCall(); 00920 st = fsal_internal_handle2fd(p_context, p_objecthandle, &fd, O_RDWR); 00921 ReleaseTokenFSCall(); 00922 if(FSAL_IS_ERROR(st)) 00923 ReturnStatus(st, INDEX_FSAL_SetXAttrValue); 00924 00925 rc = xattr_id_to_name(fd, xattr_id, name); 00926 close(fd); 00927 if(rc) 00928 Return(rc, errno, INDEX_FSAL_SetXAttrValue); 00929 00930 FSAL_str2name(name, FSAL_MAX_NAME_LEN, &attr_name); 00931 00932 return VFSFSAL_SetXAttrValue(p_objecthandle, &attr_name, 00933 p_context, buffer_addr, buffer_size, FALSE); 00934 } 00935 00943 fsal_status_t VFSFSAL_RemoveXAttrById(fsal_handle_t * p_objecthandle, /* IN */ 00944 fsal_op_context_t * p_context, /* IN */ 00945 unsigned int xattr_id) /* IN */ 00946 { 00947 int rc; 00948 fsal_status_t st; 00949 int fd = 0; 00950 char name[FSAL_MAX_NAME_LEN]; 00951 00952 TakeTokenFSCall(); 00953 st = fsal_internal_handle2fd(p_context, p_objecthandle, &fd, O_RDWR); 00954 ReleaseTokenFSCall(); 00955 if(FSAL_IS_ERROR(st)) 00956 ReturnStatus(st, INDEX_FSAL_SetXAttrValue); 00957 00958 rc = xattr_id_to_name(fd, xattr_id, name); 00959 if(rc) 00960 Return(rc, errno, INDEX_FSAL_SetXAttrValue); 00961 00962 TakeTokenFSCall(); 00963 rc = fremovexattr(fd, name); 00964 ReleaseTokenFSCall(); 00965 00966 close(fd); 00967 00968 if(rc != 0) 00969 ReturnCode(posix2fsal_error(errno), errno); 00970 00971 ReturnCode(ERR_FSAL_NO_ERROR, 0); 00972 } /* FSAL_RemoveXAttrById */ 00973 00981 fsal_status_t VFSFSAL_RemoveXAttrByName(fsal_handle_t * p_objecthandle, /* IN */ 00982 fsal_op_context_t * p_context, /* IN */ 00983 const fsal_name_t * xattr_name) /* IN */ 00984 { 00985 int rc; 00986 fsal_status_t st; 00987 int fd = 0; 00988 00989 TakeTokenFSCall(); 00990 st = fsal_internal_handle2fd(p_context, p_objecthandle, &fd, O_RDWR); 00991 ReleaseTokenFSCall(); 00992 if(FSAL_IS_ERROR(st)) 00993 ReturnStatus(st, INDEX_FSAL_SetXAttrValue); 00994 00995 TakeTokenFSCall(); 00996 rc = fremovexattr(fd, xattr_name->name); 00997 ReleaseTokenFSCall(); 00998 00999 close(fd); 01000 01001 if(rc != 0) 01002 ReturnCode(posix2fsal_error(errno), errno); 01003 01004 ReturnCode(ERR_FSAL_NO_ERROR, 0); 01005 } /* FSAL_RemoveXAttrById */ 01006 01007 int VFSFSAL_GetXattrOffsetSetable( void ) 01008 { 01009 return XATTR_COUNT ; 01010 }