fsal_status_t tank_getextattr_value_by_id(struct fsal_obj_handle *obj_hdl, unsigned int xattr_id, caddr_t buffer_addr, size_t buffer_size, size_t *p_output_size) { struct zfs_fsal_obj_handle *obj_handle = NULL; int retval = -1; creden_t cred; obj_handle = container_of(obj_hdl, struct zfs_fsal_obj_handle, obj_handle); /* sanity checks */ if (!obj_hdl || !p_output_size || !buffer_addr) return fsalstat(ERR_FSAL_FAULT, 0); cred.uid = op_ctx->creds->caller_uid; cred.gid = op_ctx->creds->caller_gid; /* check that this index match the type of entry */ if ((xattr_id < XATTR_COUNT) && !do_match_type(xattr_list[xattr_id].flags, obj_hdl->type)) { return fsalstat(ERR_FSAL_INVAL, 0); } else if (xattr_id >= XATTR_COUNT) { char attr_name[MAXPATHLEN]; /* get the name for this attr */ retval = xattr_id_to_name(ZFSFSAL_GetVFS(obj_handle->handle), &cred, obj_handle->handle->zfs_handle, xattr_id, attr_name); if (retval) return fsalstat(retval, 0); retval = libzfswrap_getxattr(ZFSFSAL_GetVFS(obj_handle->handle), &cred, obj_handle->handle->zfs_handle, attr_name, &buffer_addr); if (retval) return fsalstat(posix2fsal_error(retval), retval); /* the xattr value can be a binary, or a string. * trying to determine its type... */ *p_output_size = strnlen(buffer_addr, buffer_size); xattr_format_value(buffer_addr, p_output_size, buffer_size); return fsalstat(ERR_FSAL_NO_ERROR, 0); } else { /* built-in attr */ /* get the value */ retval = xattr_list[xattr_id].get_func(obj_hdl, buffer_addr, buffer_size, p_output_size, xattr_list[xattr_id] .arg); return fsalstat(retval, 0); } }
/** * Get the value of an extended attribute from its name. * * \param p_objecthandle Handle of the object you want to get attribute for. * \param xattr_name the name of the attribute to be read. * \param p_context pointer to the current security context. * \param buffer_addr address of the buffer where the xattr value is to be stored. * \param buffer_size size of the buffer where the xattr value is to be stored. * \param p_output_size size of the data actually stored into the buffer. */ fsal_status_t ZFSFSAL_GetXAttrValueByName(fsal_handle_t * obj_handle, /* IN */ const fsal_name_t * xattr_name, /* IN */ fsal_op_context_t * p_context, /* IN */ caddr_t buffer_addr, /* IN/OUT */ size_t buffer_size, /* IN */ size_t * p_output_size /* OUT */ ) { unsigned int index; char *psz_value; int rc; creden_t cred; zfsfsal_handle_t *p_objecthandle = (zfsfsal_handle_t *)obj_handle; /* sanity checks */ if(!p_objecthandle || !p_context || !p_output_size || !buffer_addr || !xattr_name) Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_GetXAttrValue); /* look for this name */ for(index = 0; index < XATTR_COUNT; index++) { if(do_match_type(xattr_list[index].flags, p_objecthandle->data.type) && !strcmp(xattr_list[index].xattr_name, xattr_name->name)) { return ZFSFSAL_GetXAttrValueById((fsal_handle_t *)p_objecthandle, index, p_context, buffer_addr, buffer_size, p_output_size); } } /* Get the right VFS */ libzfswrap_vfs_t *p_vfs = ZFSFSAL_GetVFS(p_objecthandle); if(!p_vfs) { ZFSFSAL_VFS_Unlock(); Return(ERR_FSAL_NOENT, 0, INDEX_FSAL_GetXAttrValue); } cred.uid = p_context->credential.user; cred.gid = p_context->credential.group; TakeTokenFSCall(); if((rc = libzfswrap_getxattr(p_vfs, &cred, p_objecthandle->data.zfs_handle, xattr_name->name, &psz_value))) { ZFSFSAL_VFS_Unlock(); Return(posix2fsal_error(rc), 0, INDEX_FSAL_GetXAttrValue); } ZFSFSAL_VFS_Unlock(); /* Copy the string (remove this call by changing the libzfswrap API) */ strncpy(buffer_addr, psz_value, buffer_size); buffer_addr[buffer_size - 1] = '\0'; *p_output_size = strlen(psz_value); free(psz_value); Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_GetXAttrValue); }
fsal_status_t tank_getextattr_value_by_name(struct fsal_obj_handle *obj_hdl, const char *xattr_name, caddr_t buffer_addr, size_t buffer_size, size_t *p_output_size) { struct zfs_fsal_obj_handle *obj_handle = NULL; unsigned int index; creden_t cred; int retval = 0; obj_handle = container_of(obj_hdl, struct zfs_fsal_obj_handle, obj_handle); /* sanity checks */ if (!obj_hdl || !p_output_size || !buffer_addr || !xattr_name) return fsalstat(ERR_FSAL_FAULT, 0); cred.uid = op_ctx->creds->caller_uid; cred.gid = op_ctx->creds->caller_gid; /* look for this name */ for (index = 0; index < XATTR_COUNT; index++) { if (do_match_type(xattr_list[index].flags, obj_hdl->attributes.type) && !strcmp(xattr_list[index].xattr_name, xattr_name)) { return tank_getextattr_value_by_id(obj_hdl, index, buffer_addr, buffer_size, p_output_size); } } /* is it an xattr? */ retval = libzfswrap_getxattr(ZFSFSAL_GetVFS(obj_handle->handle), &cred, obj_handle->handle->zfs_handle, xattr_name, &buffer_addr); if (retval) return fsalstat(posix2fsal_error(retval), retval); /* the xattr value can be a binary, or a string. * trying to determine its type... */ *p_output_size = strnlen(buffer_addr, buffer_size); xattr_format_value(buffer_addr, p_output_size, buffer_size); return fsalstat(ERR_FSAL_NO_ERROR, 0); }
/** * Get the value of an extended attribute from its index. * * \param p_objecthandle Handle of the object you want to get attribute for. * \param xattr_name the name of the attribute to be read. * \param p_context pointer to the current security context. * \param buffer_addr address of the buffer where the xattr value is to be stored. * \param buffer_size size of the buffer where the xattr value is to be stored. * \param p_output_size size of the data actually stored into the buffer. */ fsal_status_t ZFSFSAL_GetXAttrValueById(fsal_handle_t * obj_handle, /* IN */ unsigned int xattr_id, /* IN */ fsal_op_context_t * context, /* IN */ caddr_t buffer_addr, /* IN/OUT */ size_t buffer_size, /* IN */ size_t * p_output_size /* OUT */ ) { int rc; char buff[MAXNAMLEN]; zfsfsal_handle_t *p_objecthandle = (zfsfsal_handle_t *)obj_handle; zfsfsal_op_context_t *p_context = (zfsfsal_op_context_t *)context; /* sanity checks */ if(!p_objecthandle || !p_context || !p_output_size || !buffer_addr) Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_GetXAttrValue); /* check that this index match the type of entry */ if(xattr_id < XATTR_COUNT && !do_match_type(xattr_list[xattr_id].flags, p_objecthandle->data.type)) { Return(ERR_FSAL_INVAL, 0, INDEX_FSAL_GetXAttrValue); } /* Get the right VFS */ ZFSFSAL_VFS_RDLock(); libzfswrap_vfs_t *p_vfs = ZFSFSAL_GetVFS(p_objecthandle); if(!p_vfs) { ZFSFSAL_VFS_Unlock(); Return(ERR_FSAL_NOENT, 0, INDEX_FSAL_GetXAttrValue); } if(xattr_id >= XATTR_COUNT) { char psz_attr_name[MAXPATHLEN]; char *psz_value; creden_t cred; if((rc = xattr_id_to_name(p_vfs, p_context, p_objecthandle, xattr_id, psz_attr_name))) { ZFSFSAL_VFS_Unlock(); Return(rc, errno, INDEX_FSAL_GetXAttrValue); } cred.uid = p_context->credential.user; cred.gid = p_context->credential.group; if((rc = libzfswrap_getxattr(p_vfs, &cred, p_objecthandle->data.zfs_handle, psz_attr_name, &psz_value))) { ZFSFSAL_VFS_Unlock(); Return(posix2fsal_error(rc), 0, INDEX_FSAL_GetXAttrValue); } /* Copy the string (remove this call by changing the libzfswrap API) */ strncpy(buffer_addr, psz_value, buffer_size); buffer_addr[buffer_size - 1] = '\0'; *p_output_size = strlen(psz_value); free(psz_value); } else { rc = xattr_list[xattr_id].get_func(p_objecthandle, p_context, buffer_addr, buffer_size, p_output_size); /* Get the value */ if(xattr_list[xattr_id].print_func == NULL) rc = xattr_list[xattr_id].get_func(p_objecthandle, p_context, buffer_addr, buffer_size, p_output_size); else { rc = xattr_list[xattr_id].get_func(p_objecthandle, p_context, buff, MAXNAMLEN, p_output_size); xattr_list[xattr_id].print_func(buff, MAXNAMLEN, buffer_addr, p_output_size); } } ZFSFSAL_VFS_Unlock(); Return(rc, 0, INDEX_FSAL_GetXAttrValue); }