diff options
author | Ilya Dryomov <idryomov@gmail.com> | 2018-04-04 04:15:38 -0400 |
---|---|---|
committer | Ilya Dryomov <idryomov@gmail.com> | 2018-04-16 03:38:40 -0400 |
commit | 2f18d46683cb3047c41229d57cf7c6e2ee48676f (patch) | |
tree | f02375c879d665840d4516a0d22a272d2f3cc030 | |
parent | 60cc43fc888428bb2f18f08997432d426a243338 (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.c | 43 |
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 | */ |
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 | 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 | ||
3558 | static void rbd_queue_workfn(struct work_struct *work) | 3574 | static 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 | ||
5217 | static int rbd_add_acquire_lock(struct rbd_device *rbd_dev) | 5224 | static 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 | } |