summaryrefslogtreecommitdiffstats
path: root/drivers/block
diff options
context:
space:
mode:
authorIlya Dryomov <idryomov@gmail.com>2017-04-13 06:17:38 -0400
committerIlya Dryomov <idryomov@gmail.com>2017-05-04 03:19:23 -0400
commitbbead745d96cfd51aaa332bdeab300862c7a8061 (patch)
tree42814bbd4ace976b27042d519aa4cab401fae78e /drivers/block
parent5769ed0cb12dcd135251e546863196cec0b58e34 (diff)
rbd: ignore unlock errors
Currently the lock_state is set to UNLOCKED (preventing further I/O), but RELEASED_LOCK notification isn't sent. Be consistent with userspace and treat ceph_cls_unlock() errors as the image is unlocked. Signed-off-by: Ilya Dryomov <idryomov@gmail.com> Reviewed-by: Jason Dillaman <dillaman@redhat.com>
Diffstat (limited to 'drivers/block')
-rw-r--r--drivers/block/rbd.c32
1 files changed, 14 insertions, 18 deletions
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c
index 50395af7a9a6..423de775aabb 100644
--- a/drivers/block/rbd.c
+++ b/drivers/block/rbd.c
@@ -3097,7 +3097,7 @@ static int rbd_lock(struct rbd_device *rbd_dev)
3097/* 3097/*
3098 * lock_rwsem must be held for write 3098 * lock_rwsem must be held for write
3099 */ 3099 */
3100static int rbd_unlock(struct rbd_device *rbd_dev) 3100static void rbd_unlock(struct rbd_device *rbd_dev)
3101{ 3101{
3102 struct ceph_osd_client *osdc = &rbd_dev->rbd_client->client->osdc; 3102 struct ceph_osd_client *osdc = &rbd_dev->rbd_client->client->osdc;
3103 char cookie[32]; 3103 char cookie[32];
@@ -3105,19 +3105,16 @@ static int rbd_unlock(struct rbd_device *rbd_dev)
3105 3105
3106 WARN_ON(!__rbd_is_lock_owner(rbd_dev)); 3106 WARN_ON(!__rbd_is_lock_owner(rbd_dev));
3107 3107
3108 rbd_dev->lock_state = RBD_LOCK_STATE_UNLOCKED;
3109
3110 format_lock_cookie(rbd_dev, cookie); 3108 format_lock_cookie(rbd_dev, cookie);
3111 ret = ceph_cls_unlock(osdc, &rbd_dev->header_oid, &rbd_dev->header_oloc, 3109 ret = ceph_cls_unlock(osdc, &rbd_dev->header_oid, &rbd_dev->header_oloc,
3112 RBD_LOCK_NAME, cookie); 3110 RBD_LOCK_NAME, cookie);
3113 if (ret && ret != -ENOENT) { 3111 if (ret && ret != -ENOENT)
3114 rbd_warn(rbd_dev, "cls_unlock failed: %d", ret); 3112 rbd_warn(rbd_dev, "failed to unlock: %d", ret);
3115 return ret;
3116 }
3117 3113
3114 /* treat errors as the image is unlocked */
3115 rbd_dev->lock_state = RBD_LOCK_STATE_UNLOCKED;
3118 rbd_set_owner_cid(rbd_dev, &rbd_empty_cid); 3116 rbd_set_owner_cid(rbd_dev, &rbd_empty_cid);
3119 queue_work(rbd_dev->task_wq, &rbd_dev->released_lock_work); 3117 queue_work(rbd_dev->task_wq, &rbd_dev->released_lock_work);
3120 return 0;
3121} 3118}
3122 3119
3123static int __rbd_notify_op_lock(struct rbd_device *rbd_dev, 3120static int __rbd_notify_op_lock(struct rbd_device *rbd_dev,
@@ -3490,16 +3487,15 @@ static bool rbd_release_lock(struct rbd_device *rbd_dev)
3490 if (rbd_dev->lock_state != RBD_LOCK_STATE_RELEASING) 3487 if (rbd_dev->lock_state != RBD_LOCK_STATE_RELEASING)
3491 return false; 3488 return false;
3492 3489
3493 if (!rbd_unlock(rbd_dev)) 3490 rbd_unlock(rbd_dev);
3494 /* 3491 /*
3495 * Give others a chance to grab the lock - we would re-acquire 3492 * Give others a chance to grab the lock - we would re-acquire
3496 * almost immediately if we got new IO during ceph_osdc_sync() 3493 * almost immediately if we got new IO during ceph_osdc_sync()
3497 * otherwise. We need to ack our own notifications, so this 3494 * otherwise. We need to ack our own notifications, so this
3498 * lock_dwork will be requeued from rbd_wait_state_locked() 3495 * lock_dwork will be requeued from rbd_wait_state_locked()
3499 * after wake_requests() in rbd_handle_released_lock(). 3496 * after wake_requests() in rbd_handle_released_lock().
3500 */ 3497 */
3501 cancel_delayed_work(&rbd_dev->lock_dwork); 3498 cancel_delayed_work(&rbd_dev->lock_dwork);
3502
3503 return true; 3499 return true;
3504} 3500}
3505 3501