aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIlya Dryomov <idryomov@gmail.com>2018-04-04 04:15:38 -0400
committerIlya Dryomov <idryomov@gmail.com>2018-04-16 03:38:40 -0400
commit2f18d46683cb3047c41229d57cf7c6e2ee48676f (patch)
treef02375c879d665840d4516a0d22a272d2f3cc030
parent60cc43fc888428bb2f18f08997432d426a243338 (diff)
rbd: refactor rbd_wait_state_locked()
In preparation for lock_timeout option, make rbd_wait_state_locked() return error codes. Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
-rw-r--r--drivers/block/rbd.c43
1 files changed, 26 insertions, 17 deletions
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c
index 07dc5419bd63..f4b1b91e6d4d 100644
--- a/drivers/block/rbd.c
+++ b/drivers/block/rbd.c
@@ -3533,9 +3533,21 @@ static int rbd_obj_method_sync(struct rbd_device *rbd_dev,
3533/* 3533/*
3534 * lock_rwsem must be held for read 3534 * lock_rwsem must be held for read
3535 */ 3535 */
3536static void rbd_wait_state_locked(struct rbd_device *rbd_dev) 3536static int rbd_wait_state_locked(struct rbd_device *rbd_dev, bool may_acquire)
3537{ 3537{
3538 DEFINE_WAIT(wait); 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 do { 3552 do {
3541 /* 3553 /*
@@ -3549,10 +3561,14 @@ static void rbd_wait_state_locked(struct rbd_device *rbd_dev)
3549 up_read(&rbd_dev->lock_rwsem); 3561 up_read(&rbd_dev->lock_rwsem);
3550 schedule(); 3562 schedule();
3551 down_read(&rbd_dev->lock_rwsem); 3563 down_read(&rbd_dev->lock_rwsem);
3552 } while (rbd_dev->lock_state != RBD_LOCK_STATE_LOCKED && 3564 if (test_bit(RBD_DEV_FLAG_BLACKLISTED, &rbd_dev->flags)) {
3553 !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 finish_wait(&rbd_dev->lock_waitq, &wait); 3570 finish_wait(&rbd_dev->lock_waitq, &wait);
3571 return ret;
3556} 3572}
3557 3573
3558static void rbd_queue_workfn(struct work_struct *work) 3574static void rbd_queue_workfn(struct work_struct *work)
@@ -3638,19 +3654,10 @@ static void rbd_queue_workfn(struct work_struct *work)
3638 (op_type != OBJ_OP_READ || rbd_dev->opts->lock_on_read); 3654 (op_type != OBJ_OP_READ || rbd_dev->opts->lock_on_read);
3639 if (must_be_locked) { 3655 if (must_be_locked) {
3640 down_read(&rbd_dev->lock_rwsem); 3656 down_read(&rbd_dev->lock_rwsem);
3641 if (rbd_dev->lock_state != RBD_LOCK_STATE_LOCKED && 3657 result = rbd_wait_state_locked(rbd_dev,
3642 !test_bit(RBD_DEV_FLAG_BLACKLISTED, &rbd_dev->flags)) { 3658 !rbd_dev->opts->exclusive);
3643 if (rbd_dev->opts->exclusive) { 3659 if (result)
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;
3652 goto err_unlock; 3660 goto err_unlock;
3653 }
3654 } 3661 }
3655 3662
3656 img_request = rbd_img_request_create(rbd_dev, op_type, snapc); 3663 img_request = rbd_img_request_create(rbd_dev, op_type, snapc);
@@ -5216,6 +5223,8 @@ static void rbd_dev_image_unlock(struct rbd_device *rbd_dev)
5216 5223
5217static int rbd_add_acquire_lock(struct rbd_device *rbd_dev) 5224static int rbd_add_acquire_lock(struct rbd_device *rbd_dev)
5218{ 5225{
5226 int ret;
5227
5219 if (!(rbd_dev->header.features & RBD_FEATURE_EXCLUSIVE_LOCK)) { 5228 if (!(rbd_dev->header.features & RBD_FEATURE_EXCLUSIVE_LOCK)) {
5220 rbd_warn(rbd_dev, "exclusive-lock feature is not enabled"); 5229 rbd_warn(rbd_dev, "exclusive-lock feature is not enabled");
5221 return -EINVAL; 5230 return -EINVAL;
@@ -5223,9 +5232,9 @@ static int rbd_add_acquire_lock(struct rbd_device *rbd_dev)
5223 5232
5224 /* FIXME: "rbd map --exclusive" should be in interruptible */ 5233 /* FIXME: "rbd map --exclusive" should be in interruptible */
5225 down_read(&rbd_dev->lock_rwsem); 5234 down_read(&rbd_dev->lock_rwsem);
5226 rbd_wait_state_locked(rbd_dev); 5235 ret = rbd_wait_state_locked(rbd_dev, true);
5227 up_read(&rbd_dev->lock_rwsem); 5236 up_read(&rbd_dev->lock_rwsem);
5228 if (test_bit(RBD_DEV_FLAG_BLACKLISTED, &rbd_dev->flags)) { 5237 if (ret) {
5229 rbd_warn(rbd_dev, "failed to acquire exclusive lock"); 5238 rbd_warn(rbd_dev, "failed to acquire exclusive lock");
5230 return -EROFS; 5239 return -EROFS;
5231 } 5240 }