fsal_status_t tank_setextattr_value_by_id(struct fsal_obj_handle *obj_hdl, unsigned int xattr_id, caddr_t buffer_addr, size_t buffer_size) { char name[MAXNAMLEN]; 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); if (attr_is_read_only(xattr_id)) return fsalstat(ERR_FSAL_PERM, 0); else if (xattr_id < XATTR_COUNT) return fsalstat(ERR_FSAL_PERM, 0); cred.uid = op_ctx->creds->caller_uid; cred.gid = op_ctx->creds->caller_gid; retval = xattr_id_to_name(ZFSFSAL_GetVFS(obj_handle->handle), &cred, obj_handle->handle->zfs_handle, xattr_id, name); if (retval) return fsalstat(retval, 0); return tank_setextattr_value(obj_hdl, name, buffer_addr, buffer_size, false); }
fsal_status_t tank_remove_extattr_by_id(struct fsal_obj_handle *obj_hdl, unsigned int xattr_id) { char name[MAXNAMLEN]; struct zfs_fsal_obj_handle *obj_handle = NULL; int retval = 0; creden_t cred; obj_handle = container_of(obj_hdl, struct zfs_fsal_obj_handle, obj_handle); cred.uid = op_ctx->creds->caller_uid; cred.gid = op_ctx->creds->caller_gid; retval = xattr_id_to_name(ZFSFSAL_GetVFS(obj_handle->handle), &cred, obj_handle->handle->zfs_handle, xattr_id, name); if (retval) return fsalstat(retval, 0); retval = libzfswrap_removexattr(ZFSFSAL_GetVFS(obj_handle->handle), &cred, obj_handle->handle->zfs_handle, name); if (retval != 0) return fsalstat(posix2fsal_error(retval), retval); return fsalstat(ERR_FSAL_NO_ERROR, 0); }
fsal_status_t ZFSFSAL_SetXAttrValueById(fsal_handle_t * obj_handle, /* IN */ unsigned int xattr_id, /* IN */ fsal_op_context_t * context, /* IN */ caddr_t buffer_addr, /* IN */ size_t buffer_size /* IN */ ) { int rc; char psz_name[FSAL_MAX_NAME_LEN]; fsal_name_t attr_name; zfsfsal_handle_t * p_objecthandle = (zfsfsal_handle_t *)obj_handle; zfsfsal_op_context_t *p_context = (zfsfsal_op_context_t *)context; /* Hook to prevent any modification in the snapshots */ if(p_objecthandle->data.i_snap != 0) Return(ERR_FSAL_ROFS, 0, INDEX_FSAL_SetXAttrValue); if(attr_is_read_only(xattr_id)) Return(ERR_FSAL_PERM, 0, INDEX_FSAL_SetXAttrValue); else if(xattr_id < XATTR_COUNT) Return(ERR_FSAL_PERM, 0, INDEX_FSAL_SetXAttrValue); if((rc = xattr_id_to_name(p_context->export_context->p_vfs, p_context, p_objecthandle, xattr_id, psz_name))) Return(rc, 0, INDEX_FSAL_SetXAttrValue); FSAL_str2name(psz_name, FSAL_MAX_NAME_LEN, &attr_name); return ZFSFSAL_SetXAttrValue(obj_handle, &attr_name, context, buffer_addr, buffer_size, FALSE); }
/** * Removes a xattr by Id * * \param p_objecthandle Handle of the object you want to get attribute for. * \param p_context pointer to the current security context. * \param xattr_id xattr's id */ fsal_status_t ZFSFSAL_RemoveXAttrById(fsal_handle_t * obj_handle, /* IN */ fsal_op_context_t * context, /* IN */ unsigned int xattr_id) /* IN */ { int rc; creden_t cred; char psz_name[FSAL_MAX_NAME_LEN]; zfsfsal_handle_t * p_objecthandle = (zfsfsal_handle_t *)obj_handle; zfsfsal_op_context_t *p_context = (zfsfsal_op_context_t *)context; /* Hook to prevent any modification in the snapshots */ if(p_objecthandle->data.i_snap != 0) Return(ERR_FSAL_ROFS, 0, INDEX_FSAL_SetXAttrValue); if((rc = xattr_id_to_name(p_context->export_context->p_vfs, p_context, p_objecthandle, xattr_id, psz_name))) Return(rc, 0, INDEX_FSAL_SetXAttrValue); cred.uid = p_context->credential.user; cred.gid = p_context->credential.group; TakeTokenFSCall(); rc = libzfswrap_removexattr(p_context->export_context->p_vfs, &cred, p_objecthandle->data.zfs_handle, psz_name); ReleaseTokenFSCall(); if(rc) Return(posix2fsal_error(rc), 0, INDEX_FSAL_SetXAttrValue); Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_SetXAttrValue); }
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); } }
fsal_status_t vfs_remove_extattr_by_id(struct fsal_obj_handle *obj_hdl, const struct req_op_context *opctx, unsigned int xattr_id) { int rc; char name[MAXNAMLEN]; struct vfs_fsal_obj_handle *obj_handle = NULL; int fd = -1; fsal_errors_t fe; obj_handle = container_of(obj_hdl, struct vfs_fsal_obj_handle, obj_handle); fd = (obj_hdl->type == DIRECTORY) ? vfs_fsal_open(obj_handle, O_DIRECTORY, &fe) : vfs_fsal_open(obj_handle, O_RDWR, &fe); if (fd < 0) return fsalstat(fe, -fd); rc = xattr_id_to_name(fd, xattr_id, name); if (rc) { close(fd); return fsalstat(rc, errno); } rc = fremovexattr(fd, name); close(fd); if (rc != 0) return fsalstat(posix2fsal_error(errno), errno); return fsalstat(ERR_FSAL_NO_ERROR, 0); }
fsal_status_t vfs_getextattr_value_by_id(struct fsal_obj_handle *obj_hdl, const struct req_op_context *opctx, unsigned int xattr_id, caddr_t buffer_addr, size_t buffer_size, size_t *p_output_size) { struct vfs_fsal_obj_handle *obj_handle = NULL; int fd = -1; int rc = 0; obj_handle = container_of(obj_hdl, struct vfs_fsal_obj_handle, obj_handle); /* check that this index match the type of entry */ if ((xattr_id < XATTR_COUNT) && !do_match_type(xattr_list[xattr_id].flags, obj_hdl->attributes.type)) { return fsalstat(ERR_FSAL_INVAL, 0); } else if (xattr_id >= XATTR_COUNT) { char attr_name[MAXPATHLEN]; fsal_errors_t fe; fd = (obj_hdl->type == DIRECTORY) ? vfs_fsal_open(obj_handle, O_DIRECTORY, &fe) : vfs_fsal_open(obj_handle, O_RDWR, &fe); if (fd < 0) return fsalstat(fe, -fd); /* get the name for this attr */ rc = xattr_id_to_name(fd, xattr_id, attr_name); if (rc) { close(fd); return fsalstat(rc, errno); } rc = fgetxattr(fd, attr_name, buffer_addr, buffer_size); if (rc < 0) { close(fd); return fsalstat(posix2fsal_error(errno), errno); } /* the xattr value can be a binary, or a string. * trying to determine its type... */ *p_output_size = rc; close(fd); rc = ERR_FSAL_NO_ERROR; } else { /* built-in attr */ /* get the value */ rc = xattr_list[xattr_id].get_func(obj_hdl, buffer_addr, buffer_size, p_output_size, xattr_list[xattr_id].arg); } return fsalstat(rc, 0); }
fsal_status_t vfs_setextattr_value_by_id(struct fsal_obj_handle *obj_hdl, const struct req_op_context *opctx, unsigned int xattr_id, caddr_t buffer_addr, size_t buffer_size) { char name[MAXNAMLEN]; struct vfs_fsal_obj_handle *obj_handle = NULL; int fd = -1; fsal_errors_t fe; int rc = 0; obj_handle = container_of(obj_hdl, struct vfs_fsal_obj_handle, obj_handle); if (attr_is_read_only(xattr_id)) return fsalstat(ERR_FSAL_PERM, 0); else if (xattr_id < XATTR_COUNT) return fsalstat(ERR_FSAL_PERM, 0); /* build fid path in lustre */ fd = (obj_hdl->type == DIRECTORY) ? vfs_fsal_open(obj_handle, O_DIRECTORY, &fe) : vfs_fsal_open(obj_handle, O_RDWR, &fe); if (fd < 0) return fsalstat(fe, -fd); rc = xattr_id_to_name(fd, xattr_id, name); close(fd); if (rc) return fsalstat(rc, errno); return vfs_setextattr_value(obj_hdl, opctx, name, buffer_addr, buffer_size, FALSE); }
/** * 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); }