@@ -3849,10 +3849,17 @@ static void wake_lock_waiters(struct rbd_device *rbd_dev, int result)
38493849 list_splice_tail_init (& rbd_dev -> acquiring_list , & rbd_dev -> running_list );
38503850}
38513851
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 )
38543859{
38553860 struct ceph_osd_client * osdc = & rbd_dev -> rbd_client -> client -> osdc ;
3861+ struct ceph_locker * lockers ;
3862+ u32 num_lockers ;
38563863 u8 lock_type ;
38573864 char * lock_tag ;
38583865 int ret ;
@@ -3861,39 +3868,45 @@ static int get_lock_owner_info(struct rbd_device *rbd_dev,
38613868
38623869 ret = ceph_cls_lock_info (osdc , & rbd_dev -> header_oid ,
38633870 & 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+ }
38673876
3868- if (* num_lockers == 0 ) {
3877+ if (num_lockers == 0 ) {
38693878 dout ("%s rbd_dev %p no lockers detected\n" , __func__ , rbd_dev );
3879+ lockers = NULL ;
38703880 goto out ;
38713881 }
38723882
38733883 if (strcmp (lock_tag , RBD_LOCK_TAG )) {
38743884 rbd_warn (rbd_dev , "locked by external mechanism, tag %s" ,
38753885 lock_tag );
3876- ret = - EBUSY ;
3877- goto out ;
3886+ goto err_busy ;
38783887 }
38793888
38803889 if (lock_type == CEPH_CLS_LOCK_SHARED ) {
38813890 rbd_warn (rbd_dev , "shared lock type detected" );
3882- ret = - EBUSY ;
3883- goto out ;
3891+ goto err_busy ;
38843892 }
38853893
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 ,
38873896 strlen (RBD_LOCK_COOKIE_PREFIX ))) {
38883897 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 ;
38923900 }
38933901
38943902out :
38953903 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 );
38973910}
38983911
38993912static int find_watcher (struct rbd_device * rbd_dev ,
@@ -3947,51 +3960,56 @@ static int find_watcher(struct rbd_device *rbd_dev,
39473960static int rbd_try_lock (struct rbd_device * rbd_dev )
39483961{
39493962 struct ceph_client * client = rbd_dev -> rbd_client -> client ;
3950- struct ceph_locker * lockers ;
3951- u32 num_lockers ;
3963+ struct ceph_locker * locker ;
39523964 int ret ;
39533965
39543966 for (;;) {
3967+ locker = NULL ;
3968+
39553969 ret = rbd_lock (rbd_dev );
39563970 if (ret != - EBUSY )
3957- return ret ;
3971+ goto out ;
39583972
39593973 /* 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 )
39653981 goto again ;
39663982
3967- ret = find_watcher (rbd_dev , lockers );
3983+ ret = find_watcher (rbd_dev , locker );
39683984 if (ret )
39693985 goto out ; /* request lock or error */
39703986
39713987 rbd_warn (rbd_dev , "breaking header lock owned by %s%llu" ,
3972- ENTITY_NAME (lockers [ 0 ]. id .name ));
3988+ ENTITY_NAME (locker -> id .name ));
39733989
39743990 ret = ceph_monc_blocklist_add (& client -> monc ,
3975- & lockers [ 0 ]. info .addr );
3991+ & locker -> info .addr );
39763992 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 );
39793995 goto out ;
39803996 }
39813997
39823998 ret = ceph_cls_break_lock (& client -> osdc , & rbd_dev -> header_oid ,
39833999 & 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 );
39874004 goto out ;
4005+ }
39884006
39894007again :
3990- ceph_free_lockers ( lockers , num_lockers );
4008+ free_locker ( locker );
39914009 }
39924010
39934011out :
3994- ceph_free_lockers ( lockers , num_lockers );
4012+ free_locker ( locker );
39954013 return ret ;
39964014}
39974015
0 commit comments