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 "fsal_common.h" 00017 00018 #include <string.h> 00019 00020 /* generic definitions for extended attributes */ 00021 00022 #define XATTR_FOR_FILE 0x00000001 00023 #define XATTR_FOR_DIR 0x00000002 00024 #define XATTR_FOR_SYMLINK 0x00000004 00025 #define XATTR_FOR_ALL 0x0000000F 00026 #define XATTR_RO 0x00000100 00027 #define XATTR_RW 0x00000200 00028 00029 /* function for getting an attribute value */ 00030 00031 typedef int (*xattr_getfunc_t) (zfsfsal_handle_t *, /* object handle */ 00032 zfsfsal_op_context_t *, /* context */ 00033 caddr_t, /* output buff */ 00034 size_t, /* output buff size */ 00035 size_t *); /* output size */ 00036 00037 typedef int (*xattr_setfunc_t) (zfsfsal_handle_t *, /* object handle */ 00038 zfsfsal_op_context_t *, /* context */ 00039 caddr_t, /* input buff */ 00040 size_t, /* input size */ 00041 int); /* creation flag */ 00042 00043 typedef int (*xattr_printfunc_t) (caddr_t, /* Input buffer */ 00044 size_t, /* Input size */ 00045 caddr_t, /* Output (ASCII) buffer */ 00046 size_t *); /* Output size */ 00047 00048 typedef struct fsal_xattr_def__ 00049 { 00050 char xattr_name[FSAL_MAX_NAME_LEN]; 00051 xattr_getfunc_t get_func; 00052 xattr_setfunc_t set_func; 00053 xattr_printfunc_t print_func; 00054 int flags; 00055 } fsal_xattr_def_t; 00056 00057 /* 00058 * DEFINE HERE YOUR GET/SET FUNCTIONS 00059 */ 00060 00061 int get_generation(zfsfsal_handle_t * p_objecthandle, /* IN */ 00062 zfsfsal_op_context_t * p_context, /* IN */ 00063 caddr_t buffer_addr, /* IN/OUT */ 00064 size_t buffer_size, /* IN */ 00065 size_t * p_output_size) /* OUT */ 00066 { 00067 if(!p_objecthandle || !p_context || !p_output_size) 00068 return ERR_FSAL_FAULT; 00069 00070 memcpy(buffer_addr, &p_objecthandle->data.zfs_handle.generation, 00071 sizeof(p_objecthandle->data.zfs_handle.generation)); 00072 *p_output_size = sizeof(p_objecthandle->data.zfs_handle.generation); 00073 00074 return 0; 00075 } 00076 00077 int print_generation(caddr_t InBuff, size_t InSize, caddr_t OutBuff, size_t * pOutSize) 00078 { 00079 uint64_t generation; 00080 00081 memcpy((char *)&generation, InBuff, sizeof(generation)); 00082 00083 *pOutSize = snprintf(OutBuff, *pOutSize, "%"PRIu64, generation); 00084 00085 return 0; 00086 } 00087 00088 /* DEFINE HERE YOUR ATTRIBUTES LIST */ 00089 00090 static fsal_xattr_def_t xattr_list[] = { 00091 {"generation", get_generation, NULL, print_generation, XATTR_FOR_ALL}// | XATTR_RO} 00092 }; 00093 00094 #define XATTR_COUNT 1 00095 00096 /* we assume that this number is < 254 */ 00097 #if ( XATTR_COUNT > 254 ) 00098 #error "ERROR: xattr count > 254" 00099 #endif 00100 00101 /* YOUR SHOULD NOT HAVE TO MODIFY THE FOLLOWING FUNCTIONS */ 00102 00103 /* test if an object has a given attribute */ 00104 static int do_match_type(int xattr_flag, fsal_nodetype_t obj_type) 00105 { 00106 switch (obj_type) 00107 { 00108 case FSAL_TYPE_FILE: 00109 return ((xattr_flag & XATTR_FOR_FILE) == XATTR_FOR_FILE); 00110 00111 case FSAL_TYPE_DIR: 00112 return ((xattr_flag & XATTR_FOR_DIR) == XATTR_FOR_DIR); 00113 00114 case FSAL_TYPE_LNK: 00115 return ((xattr_flag & XATTR_FOR_SYMLINK) == XATTR_FOR_SYMLINK); 00116 00117 default: 00118 return ((xattr_flag & XATTR_FOR_ALL) == XATTR_FOR_ALL); 00119 } 00120 } 00121 00122 static int attr_is_read_only(unsigned int attr_index) 00123 { 00124 if(attr_index < XATTR_COUNT) 00125 { 00126 if(xattr_list[attr_index].flags & XATTR_RO) 00127 return TRUE; 00128 } 00129 /* else : standard xattr */ 00130 return FALSE; 00131 } 00132 00133 static int file_attributes_to_xattr_attrs(fsal_attrib_list_t * file_attrs, 00134 fsal_attrib_list_t * p_xattr_attrs, 00135 unsigned int attr_index) 00136 { 00137 /* supported attributes are: 00138 * - owner (same as the objet) 00139 * - group (same as the objet) 00140 * - type FSAL_TYPE_XATTR 00141 * - fileid (attr index ? or (fileid^((index+1)<<24)) ) 00142 * - mode (config & file) 00143 * - atime, mtime, ctime = these of the object ? 00144 * - size=1block, used=1block 00145 * - rdev=0 00146 * - nlink=1 00147 */ 00148 fsal_attrib_mask_t supported = FSAL_ATTR_SUPPATTR | FSAL_ATTR_MODE | FSAL_ATTR_FILEID 00149 | FSAL_ATTR_TYPE | FSAL_ATTR_OWNER | FSAL_ATTR_GROUP 00150 | FSAL_ATTR_ATIME | FSAL_ATTR_MTIME | FSAL_ATTR_CTIME 00151 | FSAL_ATTR_CREATION | FSAL_ATTR_CHGTIME | FSAL_ATTR_SIZE 00152 | FSAL_ATTR_SPACEUSED | FSAL_ATTR_NUMLINKS | FSAL_ATTR_RAWDEV | FSAL_ATTR_FSID; 00153 fsal_attrib_mask_t unsupp; 00154 00155 /* only those supported by filesystem */ 00156 supported &= global_fs_info.supported_attrs; 00157 00158 if(p_xattr_attrs->asked_attributes == 0) 00159 { 00160 p_xattr_attrs->asked_attributes = supported; 00161 00162 LogCrit(COMPONENT_FSAL, 00163 "Error: p_xattr_attrs->asked_attributes was 0 in %s() line %d, file %s", 00164 __FUNCTION__, __LINE__, __FILE__); 00165 } 00166 00167 unsupp = p_xattr_attrs->asked_attributes & (~supported); 00168 00169 if(unsupp) 00170 { 00171 LogDebug(COMPONENT_FSAL, 00172 "Asking for unsupported attributes in %s(): %#llX removing it from asked attributes", 00173 __FUNCTION__, unsupp); 00174 00175 p_xattr_attrs->asked_attributes &= (~unsupp); 00176 } 00177 00178 if(p_xattr_attrs->asked_attributes & FSAL_ATTR_SUPPATTR) 00179 p_xattr_attrs->supported_attributes = supported; 00180 00181 if(p_xattr_attrs->asked_attributes & FSAL_ATTR_MODE) 00182 { 00183 p_xattr_attrs->mode = file_attrs->mode & global_fs_info.xattr_access_rights; 00184 00185 if(attr_is_read_only(attr_index)) 00186 p_xattr_attrs->mode &= ~(0222); 00187 } 00188 00189 if(p_xattr_attrs->asked_attributes & FSAL_ATTR_FILEID) 00190 { 00191 unsigned int i; 00192 unsigned long hash = attr_index + 1; 00193 char *str = (char *)&file_attrs->fileid; 00194 00195 for(i = 0; i < sizeof(p_xattr_attrs->fileid); i++, str++) 00196 { 00197 hash = (hash << 5) - hash + (unsigned long)(*str); 00198 } 00199 p_xattr_attrs->fileid = hash; 00200 } 00201 00202 if(p_xattr_attrs->asked_attributes & FSAL_ATTR_TYPE) 00203 p_xattr_attrs->type = FSAL_TYPE_XATTR; 00204 00205 if(p_xattr_attrs->asked_attributes & FSAL_ATTR_OWNER) 00206 p_xattr_attrs->owner = file_attrs->owner; 00207 00208 if(p_xattr_attrs->asked_attributes & FSAL_ATTR_GROUP) 00209 p_xattr_attrs->group = file_attrs->group; 00210 00211 if(p_xattr_attrs->asked_attributes & FSAL_ATTR_ATIME) 00212 p_xattr_attrs->atime = file_attrs->atime; 00213 00214 if(p_xattr_attrs->asked_attributes & FSAL_ATTR_MTIME) 00215 p_xattr_attrs->mtime = file_attrs->mtime; 00216 00217 if(p_xattr_attrs->asked_attributes & FSAL_ATTR_CTIME) 00218 p_xattr_attrs->ctime = file_attrs->ctime; 00219 00220 if(p_xattr_attrs->asked_attributes & FSAL_ATTR_CREATION) 00221 p_xattr_attrs->creation = file_attrs->creation; 00222 00223 if(p_xattr_attrs->asked_attributes & FSAL_ATTR_CHGTIME) 00224 { 00225 p_xattr_attrs->chgtime = file_attrs->chgtime; 00226 p_xattr_attrs->change = (uint64_t) p_xattr_attrs->chgtime.seconds; 00227 } 00228 00229 if(p_xattr_attrs->asked_attributes & FSAL_ATTR_SIZE) 00230 p_xattr_attrs->filesize = DEV_BSIZE; 00231 00232 if(p_xattr_attrs->asked_attributes & FSAL_ATTR_SPACEUSED) 00233 p_xattr_attrs->spaceused = DEV_BSIZE; 00234 00235 if(p_xattr_attrs->asked_attributes & FSAL_ATTR_NUMLINKS) 00236 p_xattr_attrs->numlinks = 1; 00237 00238 if(p_xattr_attrs->asked_attributes & FSAL_ATTR_RAWDEV) 00239 { 00240 p_xattr_attrs->rawdev.major = 0; 00241 p_xattr_attrs->rawdev.minor = 0; 00242 } 00243 00244 if(p_xattr_attrs->asked_attributes & FSAL_ATTR_FSID) 00245 { 00246 p_xattr_attrs->fsid = file_attrs->fsid; 00247 } 00248 00249 /* if mode==0, then owner is set to root and mode is set to 0600 */ 00250 if((p_xattr_attrs->asked_attributes & FSAL_ATTR_OWNER) 00251 && (p_xattr_attrs->asked_attributes & FSAL_ATTR_MODE) && (p_xattr_attrs->mode == 0)) 00252 { 00253 p_xattr_attrs->owner = 0; 00254 p_xattr_attrs->mode = 0600; 00255 if(attr_is_read_only(attr_index)) 00256 p_xattr_attrs->mode &= ~(0200); 00257 } 00258 00259 return 0; 00260 00261 } 00262 00271 fsal_status_t ZFSFSAL_GetXAttrAttrs(fsal_handle_t * p_objecthandle, /* IN */ 00272 fsal_op_context_t * p_context, /* IN */ 00273 unsigned int xattr_id, /* IN */ 00274 fsal_attrib_list_t * p_attrs 00276 ) 00277 { 00278 int rc; 00279 fsal_status_t st; 00280 fsal_attrib_list_t file_attrs; 00281 00282 /* sanity checks */ 00283 if(!p_objecthandle || !p_context || !p_attrs) 00284 Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_GetXAttrAttrs); 00285 00286 /* object attributes we want to retrieve from parent */ 00287 file_attrs.asked_attributes = FSAL_ATTR_MODE | FSAL_ATTR_FILEID | FSAL_ATTR_OWNER 00288 | FSAL_ATTR_GROUP | FSAL_ATTR_ATIME | FSAL_ATTR_MTIME | FSAL_ATTR_TYPE 00289 | FSAL_ATTR_CTIME | FSAL_ATTR_CREATION | FSAL_ATTR_CHGTIME | FSAL_ATTR_FSID; 00290 00291 /* don't retrieve attributes not asked */ 00292 file_attrs.asked_attributes &= p_attrs->asked_attributes; 00293 00294 st = ZFSFSAL_getattrs(p_objecthandle, p_context, &file_attrs); 00295 00296 if(FSAL_IS_ERROR(st)) 00297 Return(st.major, st.minor, INDEX_FSAL_GetXAttrAttrs); 00298 00299 /* check that this index match the type of entry */ 00300 if(xattr_id < XATTR_COUNT 00301 && !do_match_type(xattr_list[xattr_id].flags, file_attrs.type)) 00302 { 00303 Return(ERR_FSAL_INVAL, 0, INDEX_FSAL_GetXAttrAttrs); 00304 } 00305 else if(xattr_id >= XATTR_COUNT) 00306 { 00307 /* This is user defined xattr */ 00308 LogFullDebug(COMPONENT_FSAL, 00309 "Getting attributes for xattr #%u", xattr_id - XATTR_COUNT); 00310 } 00311 00312 if((rc = file_attributes_to_xattr_attrs(&file_attrs, p_attrs, xattr_id))) 00313 { 00314 Return(ERR_FSAL_INVAL, rc, INDEX_FSAL_GetXAttrAttrs); 00315 } 00316 00317 Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_GetXAttrAttrs); 00318 00319 } 00320 00333 fsal_status_t ZFSFSAL_ListXAttrs(fsal_handle_t * obj_handle, /* IN */ 00334 unsigned int argcookie, /* IN */ 00335 fsal_op_context_t * p_context, /* IN */ 00336 fsal_xattrent_t * xattrs_tab, /* IN/OUT */ 00337 unsigned int xattrs_tabsize, /* IN */ 00338 unsigned int *p_nb_returned, /* OUT */ 00339 int *end_of_list /* OUT */ 00340 ) 00341 { 00342 unsigned int index; 00343 unsigned int out_index; 00344 fsal_status_t st; 00345 fsal_attrib_list_t file_attrs; 00346 int rc; 00347 creden_t cred; 00348 zfsfsal_handle_t *p_objecthandle = (zfsfsal_handle_t *)obj_handle; 00349 unsigned int cookie = argcookie ; 00350 00351 /* sanity checks */ 00352 if(!p_objecthandle || !p_context || !xattrs_tab || !p_nb_returned || !end_of_list) 00353 Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_ListXAttrs); 00354 00355 /* Deal with special cookie */ 00356 if( argcookie == FSAL_XATTR_RW_COOKIE ) cookie = XATTR_COUNT ; 00357 00358 /* object attributes we want to retrieve from parent */ 00359 file_attrs.asked_attributes = FSAL_ATTR_MODE | FSAL_ATTR_FILEID | FSAL_ATTR_OWNER 00360 | FSAL_ATTR_GROUP | FSAL_ATTR_ATIME | FSAL_ATTR_MTIME | FSAL_ATTR_TYPE 00361 | FSAL_ATTR_CTIME | FSAL_ATTR_CREATION | FSAL_ATTR_CHGTIME | FSAL_ATTR_FSID; 00362 00363 /* don't retrieve unsuipported attributes */ 00364 file_attrs.asked_attributes &= global_fs_info.supported_attrs; 00365 00366 st = ZFSFSAL_getattrs(obj_handle, p_context, &file_attrs); 00367 00368 if(FSAL_IS_ERROR(st)) 00369 Return(st.major, st.minor, INDEX_FSAL_ListXAttrs); 00370 00371 /* Get the right VFS */ 00372 ZFSFSAL_VFS_RDLock(); 00373 libzfswrap_vfs_t *p_vfs = ZFSFSAL_GetVFS(p_objecthandle); 00374 if(!p_vfs) 00375 { 00376 ZFSFSAL_VFS_Unlock(); 00377 Return(ERR_FSAL_NOENT, 0, INDEX_FSAL_ListXAttrs); 00378 } 00379 00380 00381 for(index = cookie, out_index = 0; 00382 index < XATTR_COUNT && out_index < xattrs_tabsize; index++) 00383 { 00384 if(do_match_type(xattr_list[index].flags, p_objecthandle->data.type)) 00385 { 00386 /* fills an xattr entry */ 00387 xattrs_tab[out_index].xattr_id = index; 00388 FSAL_str2name(xattr_list[index].xattr_name, FSAL_MAX_NAME_LEN, 00389 &xattrs_tab[out_index].xattr_name); 00390 xattrs_tab[out_index].xattr_cookie = index + 1; 00391 00392 /* set asked attributes (all supported) */ 00393 xattrs_tab[out_index].attributes.asked_attributes = 00394 global_fs_info.supported_attrs; 00395 00396 if(file_attributes_to_xattr_attrs 00397 (&file_attrs, &xattrs_tab[out_index].attributes, index)) 00398 { 00399 /* set error flag */ 00400 xattrs_tab[out_index].attributes.asked_attributes = FSAL_ATTR_RDATTR_ERR; 00401 } 00402 00403 /* next output slot */ 00404 out_index++; 00405 } 00406 } 00407 00408 /* Save a call if the output array is full */ 00409 if(out_index == xattrs_tabsize) 00410 { 00411 *end_of_list = FALSE; 00412 *p_nb_returned = out_index; 00413 ZFSFSAL_VFS_Unlock(); 00414 Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_ListXAttrs); 00415 } 00416 00417 /* List the extended attributes */ 00418 char *psz_buffer; 00419 size_t i_size; 00420 00421 cred.uid = p_context->credential.user; 00422 cred.gid = p_context->credential.group; 00423 00424 TakeTokenFSCall(); 00425 rc = libzfswrap_listxattr(p_vfs, &cred, 00426 p_objecthandle->data.zfs_handle, &psz_buffer, &i_size); 00427 ReleaseTokenFSCall(); 00428 ZFSFSAL_VFS_Unlock(); 00429 00430 if(rc) 00431 Return(posix2fsal_error(rc), 0, INDEX_FSAL_ListXAttrs); 00432 00433 if(i_size > 0) 00434 { 00435 size_t len = 0; 00436 char *ptr; 00437 int xattr_idx; 00438 00439 for(ptr = psz_buffer, xattr_idx = 0; 00440 (ptr < psz_buffer + i_size) && (out_index < xattrs_tabsize); 00441 xattr_idx++, ptr += len + 1) 00442 { 00443 len = strlen(ptr); 00444 index = XATTR_COUNT + xattr_idx; 00445 00446 /* Skip if the index is before the cookie */ 00447 if(index < cookie) 00448 continue; 00449 00450 xattrs_tab[out_index].xattr_id = index; 00451 FSAL_str2name(ptr, len + 1, &xattrs_tab[out_index].xattr_name); 00452 xattrs_tab[out_index].xattr_cookie = index + 1; 00453 00454 /* set asked attributes (all supported) */ 00455 xattrs_tab[out_index].attributes.asked_attributes = 00456 global_fs_info.supported_attrs; 00457 00458 if(file_attributes_to_xattr_attrs(&file_attrs, 00459 &xattrs_tab[out_index].attributes, 00460 index)) 00461 { 00462 /* set error flag */ 00463 xattrs_tab[out_index].attributes.asked_attributes = FSAL_ATTR_RDATTR_ERR; 00464 } 00465 00466 /* next output slot */ 00467 out_index++; 00468 } 00469 00470 /* Every xattrs are in the output array */ 00471 if(ptr >= psz_buffer + i_size) 00472 *end_of_list = TRUE; 00473 else 00474 *end_of_list = FALSE; 00475 } 00476 else 00477 *end_of_list = TRUE; 00478 free(psz_buffer); 00479 00480 *p_nb_returned = out_index; 00481 00482 Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_ListXAttrs); 00483 00484 } 00485 00486 static int xattr_id_to_name(libzfswrap_vfs_t *p_vfs, zfsfsal_op_context_t *p_context, zfsfsal_handle_t *p_objecthandle, unsigned int xattr_id, char *psz_name) 00487 { 00488 unsigned int index; 00489 unsigned int curr_idx; 00490 char *psz_buffer, *ptr; 00491 size_t i_size; 00492 size_t len; 00493 int rc; 00494 creden_t cred; 00495 00496 if(xattr_id < XATTR_COUNT) 00497 return ERR_FSAL_INVAL; 00498 00499 index = xattr_id - XATTR_COUNT; 00500 cred.uid = p_context->credential.user; 00501 cred.gid = p_context->credential.group; 00502 00503 /* get xattrs */ 00504 00505 TakeTokenFSCall(); 00506 rc = libzfswrap_listxattr(p_vfs, &cred, 00507 p_objecthandle->data.zfs_handle, &psz_buffer, &i_size); 00508 ReleaseTokenFSCall(); 00509 00510 if(rc) 00511 return posix2fsal_error(rc); 00512 00513 for(ptr = psz_buffer, curr_idx = 0; ptr < psz_buffer + i_size; curr_idx++, ptr += len + 1) 00514 { 00515 len = strlen(ptr); 00516 if(curr_idx == index) 00517 { 00518 strcpy(psz_name, ptr); 00519 free(psz_buffer); 00520 return ERR_FSAL_NO_ERROR; 00521 } 00522 } 00523 free(psz_buffer); 00524 return ERR_FSAL_NOENT; 00525 } 00526 00531 static int xattr_name_to_id(libzfswrap_vfs_t *p_vfs, zfsfsal_op_context_t *p_context, zfsfsal_handle_t *p_objecthandle, const char *psz_name, unsigned int *p_id) 00532 { 00533 unsigned int i; 00534 char *psz_buffer, *ptr; 00535 size_t i_size; 00536 creden_t cred; 00537 00538 cred.uid = p_context->credential.user; 00539 cred.gid = p_context->credential.group; 00540 00541 /* get xattrs */ 00542 TakeTokenFSCall(); 00543 int rc = libzfswrap_listxattr(p_vfs, &cred, 00544 p_objecthandle->data.zfs_handle, &psz_buffer, &i_size); 00545 ReleaseTokenFSCall(); 00546 00547 if(rc) 00548 return posix2fsal_error(rc); 00549 00550 for(ptr = psz_buffer, i = 0; ptr < psz_buffer + i_size; i++, ptr += strlen(ptr) + 1) 00551 { 00552 if(!strcmp(psz_name, ptr)) 00553 { 00554 *p_id = i + XATTR_COUNT; 00555 free(psz_buffer); 00556 return ERR_FSAL_NO_ERROR; 00557 } 00558 } 00559 free(psz_buffer); 00560 return ERR_FSAL_NOENT; 00561 } 00562 00573 fsal_status_t ZFSFSAL_GetXAttrValueById(fsal_handle_t * obj_handle, /* IN */ 00574 unsigned int xattr_id, /* IN */ 00575 fsal_op_context_t * context, /* IN */ 00576 caddr_t buffer_addr, /* IN/OUT */ 00577 size_t buffer_size, /* IN */ 00578 size_t * p_output_size /* OUT */ 00579 ) 00580 { 00581 int rc; 00582 char buff[MAXNAMLEN]; 00583 zfsfsal_handle_t *p_objecthandle = (zfsfsal_handle_t *)obj_handle; 00584 zfsfsal_op_context_t *p_context = (zfsfsal_op_context_t *)context; 00585 00586 /* sanity checks */ 00587 if(!p_objecthandle || !p_context || !p_output_size || !buffer_addr) 00588 Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_GetXAttrValue); 00589 00590 /* check that this index match the type of entry */ 00591 if(xattr_id < XATTR_COUNT 00592 && !do_match_type(xattr_list[xattr_id].flags, p_objecthandle->data.type)) 00593 { 00594 Return(ERR_FSAL_INVAL, 0, INDEX_FSAL_GetXAttrValue); 00595 } 00596 00597 /* Get the right VFS */ 00598 ZFSFSAL_VFS_RDLock(); 00599 libzfswrap_vfs_t *p_vfs = ZFSFSAL_GetVFS(p_objecthandle); 00600 if(!p_vfs) 00601 { 00602 ZFSFSAL_VFS_Unlock(); 00603 Return(ERR_FSAL_NOENT, 0, INDEX_FSAL_GetXAttrValue); 00604 } 00605 00606 if(xattr_id >= XATTR_COUNT) 00607 { 00608 char psz_attr_name[MAXPATHLEN]; 00609 char *psz_value; 00610 creden_t cred; 00611 00612 if((rc = xattr_id_to_name(p_vfs, p_context, p_objecthandle, xattr_id, psz_attr_name))) 00613 { 00614 ZFSFSAL_VFS_Unlock(); 00615 Return(rc, errno, INDEX_FSAL_GetXAttrValue); 00616 } 00617 cred.uid = p_context->credential.user; 00618 cred.gid = p_context->credential.group; 00619 00620 if((rc = libzfswrap_getxattr(p_vfs, &cred, 00621 p_objecthandle->data.zfs_handle, psz_attr_name, &psz_value))) 00622 { 00623 ZFSFSAL_VFS_Unlock(); 00624 Return(posix2fsal_error(rc), 0, INDEX_FSAL_GetXAttrValue); 00625 } 00626 00627 /* Copy the string (remove this call by changing the libzfswrap API) */ 00628 strncpy(buffer_addr, psz_value, buffer_size); 00629 buffer_addr[buffer_size - 1] = '\0'; 00630 *p_output_size = strlen(psz_value); 00631 free(psz_value); 00632 } 00633 else 00634 { 00635 rc = xattr_list[xattr_id].get_func(p_objecthandle, p_context, 00636 buffer_addr, buffer_size, 00637 p_output_size); 00638 /* Get the value */ 00639 if(xattr_list[xattr_id].print_func == NULL) 00640 rc = xattr_list[xattr_id].get_func(p_objecthandle, p_context, 00641 buffer_addr, buffer_size, p_output_size); 00642 else 00643 { 00644 rc = xattr_list[xattr_id].get_func(p_objecthandle, p_context, 00645 buff, MAXNAMLEN, p_output_size); 00646 xattr_list[xattr_id].print_func(buff, MAXNAMLEN, buffer_addr, p_output_size); 00647 } 00648 } 00649 00650 ZFSFSAL_VFS_Unlock(); 00651 Return(rc, 0, INDEX_FSAL_GetXAttrValue); 00652 } 00653 00663 fsal_status_t ZFSFSAL_GetXAttrIdByName(fsal_handle_t * obj_handle, /* IN */ 00664 const fsal_name_t * xattr_name, /* IN */ 00665 fsal_op_context_t * context, /* IN */ 00666 unsigned int *pxattr_id /* OUT */ 00667 ) 00668 { 00669 unsigned int index; 00670 int rc; 00671 int found = FALSE; 00672 zfsfsal_handle_t *p_objecthandle = (zfsfsal_handle_t *)obj_handle; 00673 zfsfsal_op_context_t *p_context = (zfsfsal_op_context_t *)context; 00674 00675 /* sanity checks */ 00676 if(!p_objecthandle || !xattr_name) 00677 Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_GetXAttrValue); 00678 00679 for(index = 0; index < XATTR_COUNT; index++) 00680 { 00681 if(!strcmp(xattr_list[index].xattr_name, xattr_name->name)) 00682 { 00683 found = TRUE; 00684 break; 00685 } 00686 } 00687 00688 if(!found) 00689 { 00690 00691 /* Get the right VFS */ 00692 ZFSFSAL_VFS_RDLock(); 00693 libzfswrap_vfs_t *p_vfs = ZFSFSAL_GetVFS(p_objecthandle); 00694 if(!p_vfs) 00695 { 00696 ZFSFSAL_VFS_Unlock(); 00697 Return(ERR_FSAL_NOENT, 0, INDEX_FSAL_access); 00698 } 00699 00700 if((rc = xattr_name_to_id(p_vfs, p_context, p_objecthandle, xattr_name->name, &index))) 00701 { 00702 ZFSFSAL_VFS_Unlock(); 00703 Return(rc, 0, INDEX_FSAL_GetXAttrValue); 00704 } 00705 found = TRUE; 00706 } 00707 00708 if(found) 00709 { 00710 *pxattr_id = index; 00711 Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_GetXAttrValue); 00712 } 00713 else 00714 Return(ERR_FSAL_NOENT, ENOENT, INDEX_FSAL_GetXAttrValue); 00715 } 00716 00727 fsal_status_t ZFSFSAL_GetXAttrValueByName(fsal_handle_t * obj_handle, /* IN */ 00728 const fsal_name_t * xattr_name, /* IN */ 00729 fsal_op_context_t * p_context, /* IN */ 00730 caddr_t buffer_addr, /* IN/OUT */ 00731 size_t buffer_size, /* IN */ 00732 size_t * p_output_size /* OUT */ 00733 ) 00734 { 00735 unsigned int index; 00736 char *psz_value; 00737 int rc; 00738 creden_t cred; 00739 zfsfsal_handle_t *p_objecthandle = (zfsfsal_handle_t *)obj_handle; 00740 00741 /* sanity checks */ 00742 if(!p_objecthandle || !p_context || !p_output_size || !buffer_addr || !xattr_name) 00743 Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_GetXAttrValue); 00744 00745 /* look for this name */ 00746 for(index = 0; index < XATTR_COUNT; index++) 00747 { 00748 if(do_match_type(xattr_list[index].flags, p_objecthandle->data.type) 00749 && !strcmp(xattr_list[index].xattr_name, xattr_name->name)) 00750 { 00751 00752 return ZFSFSAL_GetXAttrValueById((fsal_handle_t *)p_objecthandle, index, p_context, buffer_addr, 00753 buffer_size, p_output_size); 00754 } 00755 } 00756 00757 /* Get the right VFS */ 00758 libzfswrap_vfs_t *p_vfs = ZFSFSAL_GetVFS(p_objecthandle); 00759 if(!p_vfs) 00760 { 00761 ZFSFSAL_VFS_Unlock(); 00762 Return(ERR_FSAL_NOENT, 0, INDEX_FSAL_GetXAttrValue); 00763 } 00764 cred.uid = p_context->credential.user; 00765 cred.gid = p_context->credential.group; 00766 00767 TakeTokenFSCall(); 00768 if((rc = libzfswrap_getxattr(p_vfs, &cred, 00769 p_objecthandle->data.zfs_handle, xattr_name->name, &psz_value))) 00770 { 00771 ZFSFSAL_VFS_Unlock(); 00772 Return(posix2fsal_error(rc), 0, INDEX_FSAL_GetXAttrValue); 00773 } 00774 ZFSFSAL_VFS_Unlock(); 00775 00776 /* Copy the string (remove this call by changing the libzfswrap API) */ 00777 strncpy(buffer_addr, psz_value, buffer_size); 00778 buffer_addr[buffer_size - 1] = '\0'; 00779 *p_output_size = strlen(psz_value); 00780 free(psz_value); 00781 00782 Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_GetXAttrValue); 00783 00784 } 00785 00786 static void chomp_attr_value(char *str, size_t size) 00787 { 00788 int len; 00789 00790 if(str == NULL) 00791 return; 00792 00793 /* security: set last char to '\0' */ 00794 str[size - 1] = '\0'; 00795 00796 len = strnlen(str, size); 00797 if((len > 0) && (str[len - 1] == '\n')) 00798 str[len - 1] = '\0'; 00799 } 00800 00801 fsal_status_t ZFSFSAL_SetXAttrValue(fsal_handle_t * obj_handle, /* IN */ 00802 const fsal_name_t * xattr_name, /* IN */ 00803 fsal_op_context_t * p_context, /* IN */ 00804 caddr_t buffer_addr, /* IN */ 00805 size_t buffer_size, /* IN */ 00806 int create /* IN */ 00807 ) 00808 { 00809 //@TODO: use the create parameter ? 00810 int rc; 00811 creden_t cred; 00812 zfsfsal_handle_t * p_objecthandle = (zfsfsal_handle_t *)obj_handle; 00813 00814 /* Hook to prevent any modification in the snapshots */ 00815 if(p_objecthandle->data.i_snap != 0) 00816 Return(ERR_FSAL_ROFS, 0, INDEX_FSAL_SetXAttrValue); 00817 00818 /* Remove trailing '\n', if any */ 00819 chomp_attr_value((char*)buffer_addr, buffer_size); 00820 cred.uid = p_context->credential.user; 00821 cred.gid = p_context->credential.group; 00822 00823 TakeTokenFSCall(); 00824 rc = libzfswrap_setxattr(((zfsfsal_op_context_t *)p_context)->export_context->p_vfs, &cred, 00825 p_objecthandle->data.zfs_handle, xattr_name->name, (char*)buffer_addr); 00826 ReleaseTokenFSCall(); 00827 00828 if(rc) 00829 Return(posix2fsal_error(rc), 0, INDEX_FSAL_SetXAttrValue); 00830 00831 Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_SetXAttrValue); 00832 } 00833 00834 fsal_status_t ZFSFSAL_SetXAttrValueById(fsal_handle_t * obj_handle, /* IN */ 00835 unsigned int xattr_id, /* IN */ 00836 fsal_op_context_t * context, /* IN */ 00837 caddr_t buffer_addr, /* IN */ 00838 size_t buffer_size /* IN */ 00839 ) 00840 { 00841 int rc; 00842 char psz_name[FSAL_MAX_NAME_LEN]; 00843 fsal_name_t attr_name; 00844 zfsfsal_handle_t * p_objecthandle = (zfsfsal_handle_t *)obj_handle; 00845 zfsfsal_op_context_t *p_context = (zfsfsal_op_context_t *)context; 00846 00847 /* Hook to prevent any modification in the snapshots */ 00848 if(p_objecthandle->data.i_snap != 0) 00849 Return(ERR_FSAL_ROFS, 0, INDEX_FSAL_SetXAttrValue); 00850 00851 if(attr_is_read_only(xattr_id)) 00852 Return(ERR_FSAL_PERM, 0, INDEX_FSAL_SetXAttrValue); 00853 else if(xattr_id < XATTR_COUNT) 00854 Return(ERR_FSAL_PERM, 0, INDEX_FSAL_SetXAttrValue); 00855 00856 if((rc = xattr_id_to_name(p_context->export_context->p_vfs, p_context, p_objecthandle, 00857 xattr_id, psz_name))) 00858 Return(rc, 0, INDEX_FSAL_SetXAttrValue); 00859 00860 FSAL_str2name(psz_name, FSAL_MAX_NAME_LEN, &attr_name); 00861 00862 return ZFSFSAL_SetXAttrValue(obj_handle, &attr_name, context, 00863 buffer_addr, buffer_size, FALSE); 00864 } 00865 00873 fsal_status_t ZFSFSAL_RemoveXAttrById(fsal_handle_t * obj_handle, /* IN */ 00874 fsal_op_context_t * context, /* IN */ 00875 unsigned int xattr_id) /* IN */ 00876 { 00877 int rc; 00878 creden_t cred; 00879 char psz_name[FSAL_MAX_NAME_LEN]; 00880 zfsfsal_handle_t * p_objecthandle = (zfsfsal_handle_t *)obj_handle; 00881 zfsfsal_op_context_t *p_context = (zfsfsal_op_context_t *)context; 00882 00883 /* Hook to prevent any modification in the snapshots */ 00884 if(p_objecthandle->data.i_snap != 0) 00885 Return(ERR_FSAL_ROFS, 0, INDEX_FSAL_SetXAttrValue); 00886 00887 if((rc = xattr_id_to_name(p_context->export_context->p_vfs, p_context, p_objecthandle, 00888 xattr_id, psz_name))) 00889 Return(rc, 0, INDEX_FSAL_SetXAttrValue); 00890 00891 cred.uid = p_context->credential.user; 00892 cred.gid = p_context->credential.group; 00893 00894 TakeTokenFSCall(); 00895 rc = libzfswrap_removexattr(p_context->export_context->p_vfs, &cred, 00896 p_objecthandle->data.zfs_handle, psz_name); 00897 ReleaseTokenFSCall(); 00898 00899 if(rc) 00900 Return(posix2fsal_error(rc), 0, INDEX_FSAL_SetXAttrValue); 00901 Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_SetXAttrValue); 00902 } 00903 00911 fsal_status_t ZFSFSAL_RemoveXAttrByName(fsal_handle_t * obj_handle, /* IN */ 00912 fsal_op_context_t * p_context, /* IN */ 00913 const fsal_name_t * xattr_name) /* IN */ 00914 { 00915 int rc; 00916 creden_t cred; 00917 zfsfsal_handle_t * p_objecthandle = (zfsfsal_handle_t *)obj_handle; 00918 00919 /* Hook to prevent any modification in the snapshots */ 00920 if(p_objecthandle->data.i_snap != 0) 00921 Return(ERR_FSAL_ROFS, 0, INDEX_FSAL_SetXAttrValue); 00922 cred.uid = p_context->credential.user; 00923 cred.gid = p_context->credential.group; 00924 00925 TakeTokenFSCall(); 00926 rc = libzfswrap_removexattr(((zfsfsal_op_context_t *)p_context)->export_context->p_vfs, &cred, 00927 p_objecthandle->data.zfs_handle, xattr_name->name); 00928 ReleaseTokenFSCall(); 00929 00930 if(rc) 00931 Return(posix2fsal_error(rc), 0, INDEX_FSAL_SetXAttrValue); 00932 Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_SetXAttrValue); 00933 } 00934 00935 int ZFSFSAL_GetXattrOffsetSetable( void ) 00936 { 00937 return XATTR_COUNT ; 00938 }