[10/11] rbd: introduce a lock_flag in rbd_dev to make some process exclusive-lock protected
diff mbox series

Message ID 1543841435-13652-11-git-send-email-dongsheng.yang@easystack.cn
State New
Headers show
Series
  • [01/11] libceph: support prefix and suffix in bio_iter
Related show

Commit Message

Dongsheng Yang Dec. 3, 2018, 12:50 p.m. UTC
When we are going to open journal, we don't want to release exclusive-lock in the
whole process. But we can release it after opening. So introduce a lock_flag in
rbd_dev to say, wait, we don't want to release exclusive-lock currently, please
wait for this flag cleared.

Signed-off-by: Dongsheng Yang <dongsheng.yang@easystack.cn>
---
 drivers/block/rbd.c | 26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

Patch
diff mbox series

diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c
index cc9ee8d..8db4c36 100644
--- a/drivers/block/rbd.c
+++ b/drivers/block/rbd.c
@@ -316,6 +316,10 @@  enum rbd_lock_state {
 	RBD_LOCK_STATE_RELEASING,
 };
 
+enum rbd_lock_flags {
+	RBD_LOCK_FLAG_RELEASE_WAIT,	// wait until this flag cleared in lock releasing
+};
+
 /* WatchNotify::ClientId */
 struct rbd_client_id {
 	u64 gid;
@@ -363,6 +367,8 @@  struct rbd_device {
 
 	struct rw_semaphore	lock_rwsem;
 	enum rbd_lock_state	lock_state;
+	unsigned long		lock_flags;
+	struct completion	lock_wait;
 	char			lock_cookie[32];
 	struct rbd_client_id	owner_cid;
 	struct work_struct	acquired_lock_work;
@@ -3080,6 +3086,19 @@  static void rbd_acquire_lock(struct work_struct *work)
 	}
 }
 
+static int rbd_lock_wait(struct rbd_device *rbd_dev)
+{
+	int ret = 0;
+
+	while (test_bit(RBD_LOCK_FLAG_RELEASE_WAIT, &rbd_dev->lock_flags)) {
+		ret = wait_for_completion_interruptible(&rbd_dev->lock_wait);
+		if (ret)
+			break;
+	}
+
+	return ret;
+}
+
 static int rbd_inflight_wait(struct rbd_device *rbd_dev)
 {
 	int ret = 0;
@@ -3108,6 +3127,12 @@  static bool rbd_release_lock(struct rbd_device *rbd_dev)
 	rbd_dev->lock_state = RBD_LOCK_STATE_RELEASING;
 	up_write(&rbd_dev->lock_rwsem);
 
+	ret = rbd_lock_wait(rbd_dev);
+	if (ret) {
+		down_write(&rbd_dev->lock_rwsem);
+		return false;
+	}
+
 	ret = rbd_inflight_wait(rbd_dev);
 	if (ret) {
 		down_write(&rbd_dev->lock_rwsem);
@@ -4428,6 +4453,7 @@  static struct rbd_device *__rbd_dev_create(struct rbd_client *rbdc,
 
 	init_rwsem(&rbd_dev->lock_rwsem);
 	rbd_dev->lock_state = RBD_LOCK_STATE_UNLOCKED;
+	init_completion(&rbd_dev->lock_wait);
 	INIT_WORK(&rbd_dev->acquired_lock_work, rbd_notify_acquired_lock);
 	INIT_WORK(&rbd_dev->released_lock_work, rbd_notify_released_lock);
 	INIT_DELAYED_WORK(&rbd_dev->lock_dwork, rbd_acquire_lock);