@@ -3533,9 +3533,21 @@ static int rbd_obj_method_sync(struct rbd_device *rbd_dev,
3533
3533
/*
3534
3534
* lock_rwsem must be held for read
3535
3535
*/
3536
- static void rbd_wait_state_locked (struct rbd_device * rbd_dev )
3536
+ static int rbd_wait_state_locked (struct rbd_device * rbd_dev , bool may_acquire )
3537
3537
{
3538
3538
DEFINE_WAIT (wait );
3539
+ int ret = 0 ;
3540
+
3541
+ if (test_bit (RBD_DEV_FLAG_BLACKLISTED , & rbd_dev -> flags ))
3542
+ return - EBLACKLISTED ;
3543
+
3544
+ if (rbd_dev -> lock_state == RBD_LOCK_STATE_LOCKED )
3545
+ return 0 ;
3546
+
3547
+ if (!may_acquire ) {
3548
+ rbd_warn (rbd_dev , "exclusive lock required" );
3549
+ return - EROFS ;
3550
+ }
3539
3551
3540
3552
do {
3541
3553
/*
@@ -3549,10 +3561,14 @@ static void rbd_wait_state_locked(struct rbd_device *rbd_dev)
3549
3561
up_read (& rbd_dev -> lock_rwsem );
3550
3562
schedule ();
3551
3563
down_read (& rbd_dev -> lock_rwsem );
3552
- } while (rbd_dev -> lock_state != RBD_LOCK_STATE_LOCKED &&
3553
- !test_bit (RBD_DEV_FLAG_BLACKLISTED , & rbd_dev -> flags ));
3564
+ if (test_bit (RBD_DEV_FLAG_BLACKLISTED , & rbd_dev -> flags )) {
3565
+ ret = - EBLACKLISTED ;
3566
+ break ;
3567
+ }
3568
+ } while (rbd_dev -> lock_state != RBD_LOCK_STATE_LOCKED );
3554
3569
3555
3570
finish_wait (& rbd_dev -> lock_waitq , & wait );
3571
+ return ret ;
3556
3572
}
3557
3573
3558
3574
static void rbd_queue_workfn (struct work_struct * work )
@@ -3638,19 +3654,10 @@ static void rbd_queue_workfn(struct work_struct *work)
3638
3654
(op_type != OBJ_OP_READ || rbd_dev -> opts -> lock_on_read );
3639
3655
if (must_be_locked ) {
3640
3656
down_read (& rbd_dev -> lock_rwsem );
3641
- if (rbd_dev -> lock_state != RBD_LOCK_STATE_LOCKED &&
3642
- !test_bit (RBD_DEV_FLAG_BLACKLISTED , & rbd_dev -> flags )) {
3643
- if (rbd_dev -> opts -> exclusive ) {
3644
- rbd_warn (rbd_dev , "exclusive lock required" );
3645
- result = - EROFS ;
3646
- goto err_unlock ;
3647
- }
3648
- rbd_wait_state_locked (rbd_dev );
3649
- }
3650
- if (test_bit (RBD_DEV_FLAG_BLACKLISTED , & rbd_dev -> flags )) {
3651
- result = - EBLACKLISTED ;
3657
+ result = rbd_wait_state_locked (rbd_dev ,
3658
+ !rbd_dev -> opts -> exclusive );
3659
+ if (result )
3652
3660
goto err_unlock ;
3653
- }
3654
3661
}
3655
3662
3656
3663
img_request = rbd_img_request_create (rbd_dev , op_type , snapc );
@@ -5216,16 +5223,18 @@ static void rbd_dev_image_unlock(struct rbd_device *rbd_dev)
5216
5223
5217
5224
static int rbd_add_acquire_lock (struct rbd_device * rbd_dev )
5218
5225
{
5226
+ int ret ;
5227
+
5219
5228
if (!(rbd_dev -> header .features & RBD_FEATURE_EXCLUSIVE_LOCK )) {
5220
5229
rbd_warn (rbd_dev , "exclusive-lock feature is not enabled" );
5221
5230
return - EINVAL ;
5222
5231
}
5223
5232
5224
5233
/* FIXME: "rbd map --exclusive" should be in interruptible */
5225
5234
down_read (& rbd_dev -> lock_rwsem );
5226
- rbd_wait_state_locked (rbd_dev );
5235
+ ret = rbd_wait_state_locked (rbd_dev , true );
5227
5236
up_read (& rbd_dev -> lock_rwsem );
5228
- if (test_bit ( RBD_DEV_FLAG_BLACKLISTED , & rbd_dev -> flags ) ) {
5237
+ if (ret ) {
5229
5238
rbd_warn (rbd_dev , "failed to acquire exclusive lock" );
5230
5239
return - EROFS ;
5231
5240
}
0 commit comments