u16 attr_id,
const struct uverbs_attr_spec_hash *attr_spec_bucket,
struct uverbs_attr_bundle_hash *attr_bundle_h,
+ struct uverbs_obj_attr **destroy_attr,
struct ib_uverbs_attr __user *uattr_ptr)
{
const struct uverbs_attr_spec *spec;
if (!object)
return -EINVAL;
+ /* specs are allowed to have only one destroy attribute */
+ WARN_ON(spec->u.obj.access == UVERBS_ACCESS_DESTROY &&
+ *destroy_attr);
+ if (spec->u.obj.access == UVERBS_ACCESS_DESTROY)
+ *destroy_attr = o_attr;
+
/*
* The type of uattr->data is u64 for UVERBS_ATTR_TYPE_IDR and
* s64 for UVERBS_ATTR_TYPE_FD. We can cast the u64 to s64
size_t num_uattrs,
const struct uverbs_method_spec *method,
struct uverbs_attr_bundle *attr_bundle,
+ struct uverbs_obj_attr **destroy_attr,
struct ib_uverbs_attr __user *uattr_ptr)
{
size_t i;
attr_spec_bucket = method->attr_buckets[ret];
ret = uverbs_process_attr(ufile, uattr, attr_id,
attr_spec_bucket,
- &attr_bundle->hash[ret], uattr_ptr++);
+ &attr_bundle->hash[ret], destroy_attr,
+ uattr_ptr++);
if (ret) {
uverbs_finalize_attrs(attr_bundle,
method->attr_buckets,
int ret;
int finalize_ret;
int num_given_buckets;
+ struct uverbs_obj_attr *destroy_attr = NULL;
- num_given_buckets = uverbs_uattrs_process(
- ufile, uattrs, num_uattrs, method_spec, attr_bundle, uattr_ptr);
+ num_given_buckets =
+ uverbs_uattrs_process(ufile, uattrs, num_uattrs, method_spec,
+ attr_bundle, &destroy_attr, uattr_ptr);
if (num_given_buckets <= 0)
return -EINVAL;
if (ret)
goto cleanup;
+ /*
+ * We destroy the HW object before invoking the handler, handlers do
+ * not get to manipulate the HW objects.
+ */
+ if (destroy_attr) {
+ ret = rdma_explicit_destroy(destroy_attr->uobject);
+ if (ret)
+ goto cleanup;
+ }
+
ret = method_spec->handler(ibdev, ufile, attr_bundle);
+
cleanup:
finalize_ret = uverbs_finalize_attrs(attr_bundle,
method_spec->attr_buckets,
{
struct ib_uobject *uobj =
uverbs_attr_get_uobject(attrs, UVERBS_ATTR_DESTROY_CQ_HANDLE);
- struct ib_uverbs_destroy_cq_resp resp;
- struct ib_ucq_object *obj;
- int ret;
-
- if (IS_ERR(uobj))
- return PTR_ERR(uobj);
-
- obj = container_of(uobj, struct ib_ucq_object, uobject);
-
- ret = rdma_explicit_destroy(uobj);
- if (ret)
- return ret;
-
- resp.comp_events_reported = obj->comp_events_reported;
- resp.async_events_reported = obj->async_events_reported;
+ struct ib_ucq_object *obj =
+ container_of(uobj, struct ib_ucq_object, uobject);
+ struct ib_uverbs_destroy_cq_resp resp = {
+ .comp_events_reported = obj->comp_events_reported,
+ .async_events_reported = obj->async_events_reported
+ };
return uverbs_copy_to(attrs, UVERBS_ATTR_DESTROY_CQ_RESP, &resp,
sizeof(resp));