@@ -3849,10 +3849,17 @@ static void wake_lock_waiters(struct rbd_device *rbd_dev, int result)
3849
3849
list_splice_tail_init (& rbd_dev -> acquiring_list , & rbd_dev -> running_list );
3850
3850
}
3851
3851
3852
- static int get_lock_owner_info (struct rbd_device * rbd_dev ,
3853
- struct ceph_locker * * lockers , u32 * num_lockers )
3852
+ static void free_locker (struct ceph_locker * locker )
3853
+ {
3854
+ if (locker )
3855
+ ceph_free_lockers (locker , 1 );
3856
+ }
3857
+
3858
+ static struct ceph_locker * get_lock_owner_info (struct rbd_device * rbd_dev )
3854
3859
{
3855
3860
struct ceph_osd_client * osdc = & rbd_dev -> rbd_client -> client -> osdc ;
3861
+ struct ceph_locker * lockers ;
3862
+ u32 num_lockers ;
3856
3863
u8 lock_type ;
3857
3864
char * lock_tag ;
3858
3865
int ret ;
@@ -3861,39 +3868,45 @@ static int get_lock_owner_info(struct rbd_device *rbd_dev,
3861
3868
3862
3869
ret = ceph_cls_lock_info (osdc , & rbd_dev -> header_oid ,
3863
3870
& rbd_dev -> header_oloc , RBD_LOCK_NAME ,
3864
- & lock_type , & lock_tag , lockers , num_lockers );
3865
- if (ret )
3866
- return ret ;
3871
+ & lock_type , & lock_tag , & lockers , & num_lockers );
3872
+ if (ret ) {
3873
+ rbd_warn (rbd_dev , "failed to retrieve lockers: %d" , ret );
3874
+ return ERR_PTR (ret );
3875
+ }
3867
3876
3868
- if (* num_lockers == 0 ) {
3877
+ if (num_lockers == 0 ) {
3869
3878
dout ("%s rbd_dev %p no lockers detected\n" , __func__ , rbd_dev );
3879
+ lockers = NULL ;
3870
3880
goto out ;
3871
3881
}
3872
3882
3873
3883
if (strcmp (lock_tag , RBD_LOCK_TAG )) {
3874
3884
rbd_warn (rbd_dev , "locked by external mechanism, tag %s" ,
3875
3885
lock_tag );
3876
- ret = - EBUSY ;
3877
- goto out ;
3886
+ goto err_busy ;
3878
3887
}
3879
3888
3880
3889
if (lock_type == CEPH_CLS_LOCK_SHARED ) {
3881
3890
rbd_warn (rbd_dev , "shared lock type detected" );
3882
- ret = - EBUSY ;
3883
- goto out ;
3891
+ goto err_busy ;
3884
3892
}
3885
3893
3886
- if (strncmp ((* lockers )[0 ].id .cookie , RBD_LOCK_COOKIE_PREFIX ,
3894
+ WARN_ON (num_lockers != 1 );
3895
+ if (strncmp (lockers [0 ].id .cookie , RBD_LOCK_COOKIE_PREFIX ,
3887
3896
strlen (RBD_LOCK_COOKIE_PREFIX ))) {
3888
3897
rbd_warn (rbd_dev , "locked by external mechanism, cookie %s" ,
3889
- (* lockers )[0 ].id .cookie );
3890
- ret = - EBUSY ;
3891
- goto out ;
3898
+ lockers [0 ].id .cookie );
3899
+ goto err_busy ;
3892
3900
}
3893
3901
3894
3902
out :
3895
3903
kfree (lock_tag );
3896
- return ret ;
3904
+ return lockers ;
3905
+
3906
+ err_busy :
3907
+ kfree (lock_tag );
3908
+ ceph_free_lockers (lockers , num_lockers );
3909
+ return ERR_PTR (- EBUSY );
3897
3910
}
3898
3911
3899
3912
static int find_watcher (struct rbd_device * rbd_dev ,
@@ -3947,51 +3960,56 @@ static int find_watcher(struct rbd_device *rbd_dev,
3947
3960
static int rbd_try_lock (struct rbd_device * rbd_dev )
3948
3961
{
3949
3962
struct ceph_client * client = rbd_dev -> rbd_client -> client ;
3950
- struct ceph_locker * lockers ;
3951
- u32 num_lockers ;
3963
+ struct ceph_locker * locker ;
3952
3964
int ret ;
3953
3965
3954
3966
for (;;) {
3967
+ locker = NULL ;
3968
+
3955
3969
ret = rbd_lock (rbd_dev );
3956
3970
if (ret != - EBUSY )
3957
- return ret ;
3971
+ goto out ;
3958
3972
3959
3973
/* determine if the current lock holder is still alive */
3960
- ret = get_lock_owner_info (rbd_dev , & lockers , & num_lockers );
3961
- if (ret )
3962
- return ret ;
3963
-
3964
- if (num_lockers == 0 )
3974
+ locker = get_lock_owner_info (rbd_dev );
3975
+ if (IS_ERR (locker )) {
3976
+ ret = PTR_ERR (locker );
3977
+ locker = NULL ;
3978
+ goto out ;
3979
+ }
3980
+ if (!locker )
3965
3981
goto again ;
3966
3982
3967
- ret = find_watcher (rbd_dev , lockers );
3983
+ ret = find_watcher (rbd_dev , locker );
3968
3984
if (ret )
3969
3985
goto out ; /* request lock or error */
3970
3986
3971
3987
rbd_warn (rbd_dev , "breaking header lock owned by %s%llu" ,
3972
- ENTITY_NAME (lockers [ 0 ]. id .name ));
3988
+ ENTITY_NAME (locker -> id .name ));
3973
3989
3974
3990
ret = ceph_monc_blocklist_add (& client -> monc ,
3975
- & lockers [ 0 ]. info .addr );
3991
+ & locker -> info .addr );
3976
3992
if (ret ) {
3977
- rbd_warn (rbd_dev , "blocklist of %s%llu failed : %d" ,
3978
- ENTITY_NAME (lockers [ 0 ]. id .name ), ret );
3993
+ rbd_warn (rbd_dev , "failed to blocklist %s%llu: %d" ,
3994
+ ENTITY_NAME (locker -> id .name ), ret );
3979
3995
goto out ;
3980
3996
}
3981
3997
3982
3998
ret = ceph_cls_break_lock (& client -> osdc , & rbd_dev -> header_oid ,
3983
3999
& rbd_dev -> header_oloc , RBD_LOCK_NAME ,
3984
- lockers [0 ].id .cookie ,
3985
- & lockers [0 ].id .name );
3986
- if (ret && ret != - ENOENT )
4000
+ locker -> id .cookie , & locker -> id .name );
4001
+ if (ret && ret != - ENOENT ) {
4002
+ rbd_warn (rbd_dev , "failed to break header lock: %d" ,
4003
+ ret );
3987
4004
goto out ;
4005
+ }
3988
4006
3989
4007
again :
3990
- ceph_free_lockers ( lockers , num_lockers );
4008
+ free_locker ( locker );
3991
4009
}
3992
4010
3993
4011
out :
3994
- ceph_free_lockers ( lockers , num_lockers );
4012
+ free_locker ( locker );
3995
4013
return ret ;
3996
4014
}
3997
4015
0 commit comments