diff options
| author | David Howells <dhowells@redhat.com> | 2007-04-27 18:26:30 -0400 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2007-04-27 18:26:30 -0400 |
| commit | 47051a2152f8b2355ee70249a0faaf7b682e8ce5 (patch) | |
| tree | cf144c4e220598df2ea414e8f7ef558afd91b269 | |
| parent | 1a028e50729b85d0a038fad13daf0ee201a37454 (diff) | |
[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: David Howells <dhowells@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
| -rw-r--r-- | fs/afs/vlocation.c | 17 |
1 files changed, 8 insertions, 9 deletions
diff --git a/fs/afs/vlocation.c b/fs/afs/vlocation.c index 74cce174882a..6c8e95a7c2c9 100644 --- a/fs/afs/vlocation.c +++ b/fs/afs/vlocation.c | |||
| @@ -416,8 +416,8 @@ fill_in_record: | |||
| 416 | goto error_abandon; | 416 | goto error_abandon; |
| 417 | spin_lock(&vl->lock); | 417 | spin_lock(&vl->lock); |
| 418 | vl->state = AFS_VL_VALID; | 418 | vl->state = AFS_VL_VALID; |
| 419 | wake_up(&vl->waitq); | ||
| 420 | spin_unlock(&vl->lock); | 419 | spin_unlock(&vl->lock); |
| 420 | wake_up(&vl->waitq); | ||
| 421 | 421 | ||
| 422 | /* schedule for regular updates */ | 422 | /* schedule for regular updates */ |
| 423 | afs_vlocation_queue_for_updates(vl); | 423 | afs_vlocation_queue_for_updates(vl); |
| @@ -442,7 +442,7 @@ found_in_memory: | |||
| 442 | 442 | ||
| 443 | _debug("invalid [state %d]", state); | 443 | _debug("invalid [state %d]", state); |
| 444 | 444 | ||
| 445 | if ((state == AFS_VL_NEW || state == AFS_VL_NO_VOLUME)) { | 445 | if (state == AFS_VL_NEW || state == AFS_VL_NO_VOLUME) { |
| 446 | vl->state = AFS_VL_CREATING; | 446 | vl->state = AFS_VL_CREATING; |
| 447 | spin_unlock(&vl->lock); | 447 | spin_unlock(&vl->lock); |
| 448 | goto fill_in_record; | 448 | goto fill_in_record; |
| @@ -453,11 +453,10 @@ found_in_memory: | |||
| 453 | _debug("wait"); | 453 | _debug("wait"); |
| 454 | 454 | ||
| 455 | spin_unlock(&vl->lock); | 455 | spin_unlock(&vl->lock); |
| 456 | ret = wait_event_interruptible( | 456 | ret = wait_event_interruptible(vl->waitq, |
| 457 | vl->waitq, | 457 | vl->state == AFS_VL_NEW || |
| 458 | vl->state == AFS_VL_NEW || | 458 | vl->state == AFS_VL_VALID || |
| 459 | vl->state == AFS_VL_VALID || | 459 | vl->state == AFS_VL_NO_VOLUME); |
| 460 | vl->state == AFS_VL_NO_VOLUME); | ||
| 461 | if (ret < 0) | 460 | if (ret < 0) |
| 462 | goto error; | 461 | goto error; |
| 463 | spin_lock(&vl->lock); | 462 | spin_lock(&vl->lock); |
| @@ -471,8 +470,8 @@ success: | |||
| 471 | error_abandon: | 470 | error_abandon: |
| 472 | spin_lock(&vl->lock); | 471 | spin_lock(&vl->lock); |
| 473 | vl->state = AFS_VL_NEW; | 472 | vl->state = AFS_VL_NEW; |
| 474 | wake_up(&vl->waitq); | ||
| 475 | spin_unlock(&vl->lock); | 473 | spin_unlock(&vl->lock); |
| 474 | wake_up(&vl->waitq); | ||
| 476 | error: | 475 | error: |
| 477 | ASSERT(vl != NULL); | 476 | ASSERT(vl != NULL); |
| 478 | afs_put_vlocation(vl); | 477 | afs_put_vlocation(vl); |
| @@ -675,7 +674,6 @@ static void afs_vlocation_updater(struct work_struct *work) | |||
| 675 | case 0: | 674 | case 0: |
| 676 | afs_vlocation_apply_update(vl, &vldb); | 675 | afs_vlocation_apply_update(vl, &vldb); |
| 677 | vl->state = AFS_VL_VALID; | 676 | vl->state = AFS_VL_VALID; |
| 678 | wake_up(&vl->waitq); | ||
| 679 | break; | 677 | break; |
| 680 | case -ENOMEDIUM: | 678 | case -ENOMEDIUM: |
| 681 | vl->state = AFS_VL_VOLUME_DELETED; | 679 | vl->state = AFS_VL_VOLUME_DELETED; |
| @@ -685,6 +683,7 @@ static void afs_vlocation_updater(struct work_struct *work) | |||
| 685 | break; | 683 | break; |
| 686 | } | 684 | } |
| 687 | spin_unlock(&vl->lock); | 685 | spin_unlock(&vl->lock); |
| 686 | wake_up(&vl->waitq); | ||
| 688 | 687 | ||
| 689 | /* and then reschedule */ | 688 | /* and then reschedule */ |
| 690 | _debug("reschedule"); | 689 | _debug("reschedule"); |
