@@ -51,6 +51,7 @@ static int uverbs_process_attr(struct ib_uverbs_file *ufile,
51
51
u16 attr_id ,
52
52
const struct uverbs_attr_spec_hash * attr_spec_bucket ,
53
53
struct uverbs_attr_bundle_hash * attr_bundle_h ,
54
+ struct uverbs_obj_attr * * destroy_attr ,
54
55
struct ib_uverbs_attr __user * uattr_ptr )
55
56
{
56
57
const struct uverbs_attr_spec * spec ;
@@ -148,6 +149,12 @@ static int uverbs_process_attr(struct ib_uverbs_file *ufile,
148
149
if (!object )
149
150
return - EINVAL ;
150
151
152
+ /* specs are allowed to have only one destroy attribute */
153
+ WARN_ON (spec -> u .obj .access == UVERBS_ACCESS_DESTROY &&
154
+ * destroy_attr );
155
+ if (spec -> u .obj .access == UVERBS_ACCESS_DESTROY )
156
+ * destroy_attr = o_attr ;
157
+
151
158
/*
152
159
* The type of uattr->data is u64 for UVERBS_ATTR_TYPE_IDR and
153
160
* s64 for UVERBS_ATTR_TYPE_FD. We can cast the u64 to s64
@@ -235,6 +242,7 @@ static int uverbs_uattrs_process(struct ib_uverbs_file *ufile,
235
242
size_t num_uattrs ,
236
243
const struct uverbs_method_spec * method ,
237
244
struct uverbs_attr_bundle * attr_bundle ,
245
+ struct uverbs_obj_attr * * destroy_attr ,
238
246
struct ib_uverbs_attr __user * uattr_ptr )
239
247
{
240
248
size_t i ;
@@ -268,7 +276,8 @@ static int uverbs_uattrs_process(struct ib_uverbs_file *ufile,
268
276
attr_spec_bucket = method -> attr_buckets [ret ];
269
277
ret = uverbs_process_attr (ufile , uattr , attr_id ,
270
278
attr_spec_bucket ,
271
- & attr_bundle -> hash [ret ], uattr_ptr ++ );
279
+ & attr_bundle -> hash [ret ], destroy_attr ,
280
+ uattr_ptr ++ );
272
281
if (ret ) {
273
282
uverbs_finalize_attrs (attr_bundle ,
274
283
method -> attr_buckets ,
@@ -322,9 +331,11 @@ static int uverbs_handle_method(struct ib_uverbs_attr __user *uattr_ptr,
322
331
int ret ;
323
332
int finalize_ret ;
324
333
int num_given_buckets ;
334
+ struct uverbs_obj_attr * destroy_attr = NULL ;
325
335
326
- num_given_buckets = uverbs_uattrs_process (
327
- ufile , uattrs , num_uattrs , method_spec , attr_bundle , uattr_ptr );
336
+ num_given_buckets =
337
+ uverbs_uattrs_process (ufile , uattrs , num_uattrs , method_spec ,
338
+ attr_bundle , & destroy_attr , uattr_ptr );
328
339
if (num_given_buckets <= 0 )
329
340
return - EINVAL ;
330
341
@@ -333,7 +344,18 @@ static int uverbs_handle_method(struct ib_uverbs_attr __user *uattr_ptr,
333
344
if (ret )
334
345
goto cleanup ;
335
346
347
+ /*
348
+ * We destroy the HW object before invoking the handler, handlers do
349
+ * not get to manipulate the HW objects.
350
+ */
351
+ if (destroy_attr ) {
352
+ ret = rdma_explicit_destroy (destroy_attr -> uobject );
353
+ if (ret )
354
+ goto cleanup ;
355
+ }
356
+
336
357
ret = method_spec -> handler (ibdev , ufile , attr_bundle );
358
+
337
359
cleanup :
338
360
finalize_ret = uverbs_finalize_attrs (attr_bundle ,
339
361
method_spec -> attr_buckets ,
0 commit comments