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