@@ -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);
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(+)