@@ -130,7 +130,11 @@ static int uverbs_destroy_uobject(struct ib_uobject *uobj,
130
130
lockdep_assert_held (& ufile -> hw_destroy_rwsem );
131
131
assert_uverbs_usecnt (uobj , UVERBS_LOOKUP_WRITE );
132
132
133
- if (uobj -> object ) {
133
+ if (reason == RDMA_REMOVE_ABORT ) {
134
+ WARN_ON (!list_empty (& uobj -> list ));
135
+ WARN_ON (!uobj -> context );
136
+ uobj -> uapi_object -> type_class -> alloc_abort (uobj );
137
+ } else if (uobj -> object ) {
134
138
ret = uobj -> uapi_object -> type_class -> destroy_hw (uobj , reason ,
135
139
attrs );
136
140
if (ret ) {
@@ -146,12 +150,6 @@ static int uverbs_destroy_uobject(struct ib_uobject *uobj,
146
150
uobj -> object = NULL ;
147
151
}
148
152
149
- if (reason == RDMA_REMOVE_ABORT ) {
150
- WARN_ON (!list_empty (& uobj -> list ));
151
- WARN_ON (!uobj -> context );
152
- uobj -> uapi_object -> type_class -> alloc_abort (uobj );
153
- }
154
-
155
153
uobj -> context = NULL ;
156
154
157
155
/*
@@ -450,22 +448,40 @@ static struct ib_uobject *
450
448
alloc_begin_fd_uobject (const struct uverbs_api_object * obj ,
451
449
struct ib_uverbs_file * ufile )
452
450
{
451
+ const struct uverbs_obj_fd_type * fd_type =
452
+ container_of (obj -> type_attrs , struct uverbs_obj_fd_type , type );
453
453
int new_fd ;
454
454
struct ib_uobject * uobj ;
455
+ struct file * filp ;
456
+
457
+ if (WARN_ON (fd_type -> fops -> release != & uverbs_uobject_fd_release ))
458
+ return ERR_PTR (- EINVAL );
455
459
456
460
new_fd = get_unused_fd_flags (O_CLOEXEC );
457
461
if (new_fd < 0 )
458
462
return ERR_PTR (new_fd );
459
463
460
464
uobj = alloc_uobj (ufile , obj );
461
- if (IS_ERR (uobj )) {
462
- put_unused_fd (new_fd );
463
- return uobj ;
465
+ if (IS_ERR (uobj ))
466
+ goto err_fd ;
467
+
468
+ /* Note that uverbs_uobject_fd_release() is called during abort */
469
+ filp = anon_inode_getfile (fd_type -> name , fd_type -> fops , NULL ,
470
+ fd_type -> flags );
471
+ if (IS_ERR (filp )) {
472
+ uobj = ERR_CAST (filp );
473
+ goto err_uobj ;
464
474
}
475
+ uobj -> object = filp ;
465
476
466
477
uobj -> id = new_fd ;
467
478
uobj -> ufile = ufile ;
479
+ return uobj ;
468
480
481
+ err_uobj :
482
+ uverbs_uobject_put (uobj );
483
+ err_fd :
484
+ put_unused_fd (new_fd );
469
485
return uobj ;
470
486
}
471
487
@@ -539,6 +555,9 @@ static void remove_handle_idr_uobject(struct ib_uobject *uobj)
539
555
540
556
static void alloc_abort_fd_uobject (struct ib_uobject * uobj )
541
557
{
558
+ struct file * filp = uobj -> object ;
559
+
560
+ fput (filp );
542
561
put_unused_fd (uobj -> id );
543
562
}
544
563
@@ -560,7 +579,7 @@ static void remove_handle_fd_uobject(struct ib_uobject *uobj)
560
579
{
561
580
}
562
581
563
- static int alloc_commit_idr_uobject (struct ib_uobject * uobj )
582
+ static void alloc_commit_idr_uobject (struct ib_uobject * uobj )
564
583
{
565
584
struct ib_uverbs_file * ufile = uobj -> ufile ;
566
585
void * old ;
@@ -574,31 +593,12 @@ static int alloc_commit_idr_uobject(struct ib_uobject *uobj)
574
593
*/
575
594
old = xa_store (& ufile -> idr , uobj -> id , uobj , GFP_KERNEL );
576
595
WARN_ON (old != NULL );
577
-
578
- return 0 ;
579
596
}
580
597
581
- static int alloc_commit_fd_uobject (struct ib_uobject * uobj )
598
+ static void alloc_commit_fd_uobject (struct ib_uobject * uobj )
582
599
{
583
- const struct uverbs_obj_fd_type * fd_type = container_of (
584
- uobj -> uapi_object -> type_attrs , struct uverbs_obj_fd_type , type );
585
600
int fd = uobj -> id ;
586
- struct file * filp ;
587
-
588
- /*
589
- * The kref for uobj is moved into filp->private data and put in
590
- * uverbs_close_fd(). Once alloc_commit() succeeds
591
- * uverbs_uobject_fd_release() must be guaranteed to be called from
592
- * the provided fops release callback.
593
- */
594
- filp = anon_inode_getfile (fd_type -> name ,
595
- fd_type -> fops ,
596
- uobj ,
597
- fd_type -> flags );
598
- if (IS_ERR (filp ))
599
- return PTR_ERR (filp );
600
-
601
- uobj -> object = filp ;
601
+ struct file * filp = uobj -> object ;
602
602
603
603
/* Matching put will be done in uverbs_uobject_fd_release() */
604
604
kref_get (& uobj -> ufile -> ref );
@@ -610,29 +610,22 @@ static int alloc_commit_fd_uobject(struct ib_uobject *uobj)
610
610
* NOTE: Once we install the file we loose ownership of our kref on
611
611
* uobj. It will be put by uverbs_uobject_fd_release()
612
612
*/
613
+ filp -> private_data = uobj ;
613
614
fd_install (fd , filp );
614
-
615
- return 0 ;
616
615
}
617
616
618
617
/*
619
618
* In all cases rdma_alloc_commit_uobject() consumes the kref to uobj and the
620
619
* caller can no longer assume uobj is valid. If this function fails it
621
620
* destroys the uboject, including the attached HW object.
622
621
*/
623
- int __must_check rdma_alloc_commit_uobject (struct ib_uobject * uobj ,
624
- struct uverbs_attr_bundle * attrs )
622
+ void rdma_alloc_commit_uobject (struct ib_uobject * uobj ,
623
+ struct uverbs_attr_bundle * attrs )
625
624
{
626
625
struct ib_uverbs_file * ufile = attrs -> ufile ;
627
- int ret ;
628
626
629
627
/* alloc_commit consumes the uobj kref */
630
- ret = uobj -> uapi_object -> type_class -> alloc_commit (uobj );
631
- if (ret ) {
632
- uverbs_destroy_uobject (uobj , RDMA_REMOVE_ABORT , attrs );
633
- up_read (& ufile -> hw_destroy_rwsem );
634
- return ret ;
635
- }
628
+ uobj -> uapi_object -> type_class -> alloc_commit (uobj );
636
629
637
630
/* kref is held so long as the uobj is on the uobj list. */
638
631
uverbs_uobject_get (uobj );
@@ -645,8 +638,6 @@ int __must_check rdma_alloc_commit_uobject(struct ib_uobject *uobj,
645
638
646
639
/* Matches the down_read in rdma_alloc_begin_uobject */
647
640
up_read (& ufile -> hw_destroy_rwsem );
648
-
649
- return 0 ;
650
641
}
651
642
652
643
/*
@@ -658,7 +649,6 @@ void rdma_alloc_abort_uobject(struct ib_uobject *uobj,
658
649
{
659
650
struct ib_uverbs_file * ufile = uobj -> ufile ;
660
651
661
- uobj -> object = NULL ;
662
652
uverbs_destroy_uobject (uobj , RDMA_REMOVE_ABORT , attrs );
663
653
664
654
/* Matches the down_read in rdma_alloc_begin_uobject */
@@ -751,14 +741,23 @@ EXPORT_SYMBOL(uverbs_idr_class);
751
741
*/
752
742
int uverbs_uobject_fd_release (struct inode * inode , struct file * filp )
753
743
{
754
- struct ib_uobject * uobj = filp -> private_data ;
755
- struct ib_uverbs_file * ufile = uobj -> ufile ;
756
- struct uverbs_attr_bundle attrs = {
757
- .context = uobj -> context ,
758
- .ufile = ufile ,
759
- };
744
+ struct ib_uverbs_file * ufile ;
745
+ struct ib_uobject * uobj ;
746
+
747
+ /*
748
+ * This can only happen if the fput came from alloc_abort_fd_uobject()
749
+ */
750
+ if (!filp -> private_data )
751
+ return 0 ;
752
+ uobj = filp -> private_data ;
753
+ ufile = uobj -> ufile ;
760
754
761
755
if (down_read_trylock (& ufile -> hw_destroy_rwsem )) {
756
+ struct uverbs_attr_bundle attrs = {
757
+ .context = uobj -> context ,
758
+ .ufile = ufile ,
759
+ };
760
+
762
761
/*
763
762
* lookup_get_fd_uobject holds the kref on the struct file any
764
763
* time a FD uobj is locked, which prevents this release
@@ -770,7 +769,7 @@ int uverbs_uobject_fd_release(struct inode *inode, struct file *filp)
770
769
up_read (& ufile -> hw_destroy_rwsem );
771
770
}
772
771
773
- /* Matches the get in alloc_begin_fd_uobject */
772
+ /* Matches the get in alloc_commit_fd_uobject() */
774
773
kref_put (& ufile -> ref , ib_uverbs_release_file );
775
774
776
775
/* Pairs with filp->private_data in alloc_begin_fd_uobject */
@@ -938,12 +937,10 @@ uverbs_get_uobject_from_file(u16 object_id, enum uverbs_obj_access access,
938
937
}
939
938
}
940
939
941
- int uverbs_finalize_object (struct ib_uobject * uobj ,
942
- enum uverbs_obj_access access , bool commit ,
943
- struct uverbs_attr_bundle * attrs )
940
+ void uverbs_finalize_object (struct ib_uobject * uobj ,
941
+ enum uverbs_obj_access access , bool commit ,
942
+ struct uverbs_attr_bundle * attrs )
944
943
{
945
- int ret = 0 ;
946
-
947
944
/*
948
945
* refcounts should be handled at the object level and not at the
949
946
* uobject level. Refcounts of the objects themselves are done in
@@ -963,14 +960,11 @@ int uverbs_finalize_object(struct ib_uobject *uobj,
963
960
break ;
964
961
case UVERBS_ACCESS_NEW :
965
962
if (commit )
966
- ret = rdma_alloc_commit_uobject (uobj , attrs );
963
+ rdma_alloc_commit_uobject (uobj , attrs );
967
964
else
968
965
rdma_alloc_abort_uobject (uobj , attrs );
969
966
break ;
970
967
default :
971
968
WARN_ON (true);
972
- ret = - EOPNOTSUPP ;
973
969
}
974
-
975
- return ret ;
976
970
}
0 commit comments