Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2f18d466 authored by Ilya Dryomov's avatar Ilya Dryomov
Browse files

rbd: refactor rbd_wait_state_locked()



In preparation for lock_timeout option, make rbd_wait_state_locked()
return error codes.

Signed-off-by: default avatarIlya Dryomov <idryomov@gmail.com>
parent 60cc43fc
Loading
Loading
Loading
Loading
+26 −17
Original line number Original line Diff line number Diff line
@@ -3533,9 +3533,21 @@ static int rbd_obj_method_sync(struct rbd_device *rbd_dev,
/*
/*
 * lock_rwsem must be held for read
 * lock_rwsem must be held for read
 */
 */
static void rbd_wait_state_locked(struct rbd_device *rbd_dev)
static int rbd_wait_state_locked(struct rbd_device *rbd_dev, bool may_acquire)
{
{
	DEFINE_WAIT(wait);
	DEFINE_WAIT(wait);
	int ret = 0;

	if (test_bit(RBD_DEV_FLAG_BLACKLISTED, &rbd_dev->flags))
		return -EBLACKLISTED;

	if (rbd_dev->lock_state == RBD_LOCK_STATE_LOCKED)
		return 0;

	if (!may_acquire) {
		rbd_warn(rbd_dev, "exclusive lock required");
		return -EROFS;
	}


	do {
	do {
		/*
		/*
@@ -3549,10 +3561,14 @@ static void rbd_wait_state_locked(struct rbd_device *rbd_dev)
		up_read(&rbd_dev->lock_rwsem);
		up_read(&rbd_dev->lock_rwsem);
		schedule();
		schedule();
		down_read(&rbd_dev->lock_rwsem);
		down_read(&rbd_dev->lock_rwsem);
	} while (rbd_dev->lock_state != RBD_LOCK_STATE_LOCKED &&
		if (test_bit(RBD_DEV_FLAG_BLACKLISTED, &rbd_dev->flags)) {
		 !test_bit(RBD_DEV_FLAG_BLACKLISTED, &rbd_dev->flags));
			ret = -EBLACKLISTED;
			break;
		}
	} while (rbd_dev->lock_state != RBD_LOCK_STATE_LOCKED);


	finish_wait(&rbd_dev->lock_waitq, &wait);
	finish_wait(&rbd_dev->lock_waitq, &wait);
	return ret;
}
}


static void rbd_queue_workfn(struct work_struct *work)
static void rbd_queue_workfn(struct work_struct *work)
@@ -3638,20 +3654,11 @@ static void rbd_queue_workfn(struct work_struct *work)
	    (op_type != OBJ_OP_READ || rbd_dev->opts->lock_on_read);
	    (op_type != OBJ_OP_READ || rbd_dev->opts->lock_on_read);
	if (must_be_locked) {
	if (must_be_locked) {
		down_read(&rbd_dev->lock_rwsem);
		down_read(&rbd_dev->lock_rwsem);
		if (rbd_dev->lock_state != RBD_LOCK_STATE_LOCKED &&
		result = rbd_wait_state_locked(rbd_dev,
		    !test_bit(RBD_DEV_FLAG_BLACKLISTED, &rbd_dev->flags)) {
					       !rbd_dev->opts->exclusive);
			if (rbd_dev->opts->exclusive) {
		if (result)
				rbd_warn(rbd_dev, "exclusive lock required");
				result = -EROFS;
				goto err_unlock;
			}
			rbd_wait_state_locked(rbd_dev);
		}
		if (test_bit(RBD_DEV_FLAG_BLACKLISTED, &rbd_dev->flags)) {
			result = -EBLACKLISTED;
			goto err_unlock;
			goto err_unlock;
	}
	}
	}


	img_request = rbd_img_request_create(rbd_dev, op_type, snapc);
	img_request = rbd_img_request_create(rbd_dev, op_type, snapc);
	if (!img_request) {
	if (!img_request) {
@@ -5216,6 +5223,8 @@ static void rbd_dev_image_unlock(struct rbd_device *rbd_dev)


static int rbd_add_acquire_lock(struct rbd_device *rbd_dev)
static int rbd_add_acquire_lock(struct rbd_device *rbd_dev)
{
{
	int ret;

	if (!(rbd_dev->header.features & RBD_FEATURE_EXCLUSIVE_LOCK)) {
	if (!(rbd_dev->header.features & RBD_FEATURE_EXCLUSIVE_LOCK)) {
		rbd_warn(rbd_dev, "exclusive-lock feature is not enabled");
		rbd_warn(rbd_dev, "exclusive-lock feature is not enabled");
		return -EINVAL;
		return -EINVAL;
@@ -5223,9 +5232,9 @@ static int rbd_add_acquire_lock(struct rbd_device *rbd_dev)


	/* FIXME: "rbd map --exclusive" should be in interruptible */
	/* FIXME: "rbd map --exclusive" should be in interruptible */
	down_read(&rbd_dev->lock_rwsem);
	down_read(&rbd_dev->lock_rwsem);
	rbd_wait_state_locked(rbd_dev);
	ret = rbd_wait_state_locked(rbd_dev, true);
	up_read(&rbd_dev->lock_rwsem);
	up_read(&rbd_dev->lock_rwsem);
	if (test_bit(RBD_DEV_FLAG_BLACKLISTED, &rbd_dev->flags)) {
	if (ret) {
		rbd_warn(rbd_dev, "failed to acquire exclusive lock");
		rbd_warn(rbd_dev, "failed to acquire exclusive lock");
		return -EROFS;
		return -EROFS;
	}
	}