Commit 6d3b2673 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'ceph-for-7.1-rc5' of https://github.com/ceph/ceph-client

Pull ceph fix from Ilya Dryomov:
 "A fix for an 'rbd unmap' race condition which popped up on a
  production setup where many RBD devices are frequently mapped and
  unmapped, marked for stable"

* tag 'ceph-for-7.1-rc5' of https://github.com/ceph/ceph-client:
  rbd: eliminate a race in lock_dwork draining on unmap
parents 7acfa2c5 9fc75b71
Loading
Loading
Loading
Loading
+8 −12
Original line number Diff line number Diff line
@@ -4565,24 +4565,12 @@ static int rbd_register_watch(struct rbd_device *rbd_dev)
	return ret;
}

static void cancel_tasks_sync(struct rbd_device *rbd_dev)
{
	dout("%s rbd_dev %p\n", __func__, rbd_dev);

	cancel_work_sync(&rbd_dev->acquired_lock_work);
	cancel_work_sync(&rbd_dev->released_lock_work);
	cancel_delayed_work_sync(&rbd_dev->lock_dwork);
	cancel_work_sync(&rbd_dev->unlock_work);
}

/*
 * header_rwsem must not be held to avoid a deadlock with
 * rbd_dev_refresh() when flushing notifies.
 */
static void rbd_unregister_watch(struct rbd_device *rbd_dev)
{
	cancel_tasks_sync(rbd_dev);

	mutex_lock(&rbd_dev->watch_mutex);
	if (rbd_dev->watch_state == RBD_WATCH_STATE_REGISTERED)
		__rbd_unregister_watch(rbd_dev);
@@ -6548,10 +6536,18 @@ static int rbd_add_parse_args(const char *buf,

static void rbd_dev_image_unlock(struct rbd_device *rbd_dev)
{
	dout("%s rbd_dev %p\n", __func__, rbd_dev);

	disable_delayed_work_sync(&rbd_dev->lock_dwork);
	disable_work_sync(&rbd_dev->unlock_work);

	down_write(&rbd_dev->lock_rwsem);
	if (__rbd_is_lock_owner(rbd_dev))
		__rbd_release_lock(rbd_dev);
	up_write(&rbd_dev->lock_rwsem);

	flush_work(&rbd_dev->acquired_lock_work);
	flush_work(&rbd_dev->released_lock_work);
}

/*