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

Commit 47051a21 authored by David Howells's avatar David Howells Committed by David S. Miller
Browse files

[AFS]: Fix VLocation record update wakeup



Fix the wakeup transitions after a VLocation record update completes
one way or another.  This builds on Dave Miller's partial fix.

Also move wakeups outside the spinlocked sections.

Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 1a028e50
Loading
Loading
Loading
Loading
+8 −9
Original line number Diff line number Diff line
@@ -416,8 +416,8 @@ struct afs_vlocation *afs_vlocation_lookup(struct afs_cell *cell,
		goto error_abandon;
	spin_lock(&vl->lock);
	vl->state = AFS_VL_VALID;
	wake_up(&vl->waitq);
	spin_unlock(&vl->lock);
	wake_up(&vl->waitq);

	/* schedule for regular updates */
	afs_vlocation_queue_for_updates(vl);
@@ -442,7 +442,7 @@ struct afs_vlocation *afs_vlocation_lookup(struct afs_cell *cell,

		_debug("invalid [state %d]", state);

		if ((state == AFS_VL_NEW || state == AFS_VL_NO_VOLUME)) {
		if (state == AFS_VL_NEW || state == AFS_VL_NO_VOLUME) {
			vl->state = AFS_VL_CREATING;
			spin_unlock(&vl->lock);
			goto fill_in_record;
@@ -453,8 +453,7 @@ struct afs_vlocation *afs_vlocation_lookup(struct afs_cell *cell,
		_debug("wait");

		spin_unlock(&vl->lock);
		ret = wait_event_interruptible(
			vl->waitq,
		ret = wait_event_interruptible(vl->waitq,
					       vl->state == AFS_VL_NEW ||
					       vl->state == AFS_VL_VALID ||
					       vl->state == AFS_VL_NO_VOLUME);
@@ -471,8 +470,8 @@ struct afs_vlocation *afs_vlocation_lookup(struct afs_cell *cell,
error_abandon:
	spin_lock(&vl->lock);
	vl->state = AFS_VL_NEW;
	wake_up(&vl->waitq);
	spin_unlock(&vl->lock);
	wake_up(&vl->waitq);
error:
	ASSERT(vl != NULL);
	afs_put_vlocation(vl);
@@ -675,7 +674,6 @@ static void afs_vlocation_updater(struct work_struct *work)
	case 0:
		afs_vlocation_apply_update(vl, &vldb);
		vl->state = AFS_VL_VALID;
		wake_up(&vl->waitq);
		break;
	case -ENOMEDIUM:
		vl->state = AFS_VL_VOLUME_DELETED;
@@ -685,6 +683,7 @@ static void afs_vlocation_updater(struct work_struct *work)
		break;
	}
	spin_unlock(&vl->lock);
	wake_up(&vl->waitq);

	/* and then reschedule */
	_debug("reschedule");