aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/locking.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/btrfs/locking.c')
-rw-r--r--fs/btrfs/locking.c14
1 files changed, 9 insertions, 5 deletions
diff --git a/fs/btrfs/locking.c b/fs/btrfs/locking.c
index 272f911203ff..a44eff074805 100644
--- a/fs/btrfs/locking.c
+++ b/fs/btrfs/locking.c
@@ -78,13 +78,15 @@ void btrfs_clear_lock_blocking_rw(struct extent_buffer *eb, int rw)
78 write_lock(&eb->lock); 78 write_lock(&eb->lock);
79 WARN_ON(atomic_read(&eb->spinning_writers)); 79 WARN_ON(atomic_read(&eb->spinning_writers));
80 atomic_inc(&eb->spinning_writers); 80 atomic_inc(&eb->spinning_writers);
81 if (atomic_dec_and_test(&eb->blocking_writers)) 81 if (atomic_dec_and_test(&eb->blocking_writers) &&
82 waitqueue_active(&eb->write_lock_wq))
82 wake_up(&eb->write_lock_wq); 83 wake_up(&eb->write_lock_wq);
83 } else if (rw == BTRFS_READ_LOCK_BLOCKING) { 84 } else if (rw == BTRFS_READ_LOCK_BLOCKING) {
84 BUG_ON(atomic_read(&eb->blocking_readers) == 0); 85 BUG_ON(atomic_read(&eb->blocking_readers) == 0);
85 read_lock(&eb->lock); 86 read_lock(&eb->lock);
86 atomic_inc(&eb->spinning_readers); 87 atomic_inc(&eb->spinning_readers);
87 if (atomic_dec_and_test(&eb->blocking_readers)) 88 if (atomic_dec_and_test(&eb->blocking_readers) &&
89 waitqueue_active(&eb->read_lock_wq))
88 wake_up(&eb->read_lock_wq); 90 wake_up(&eb->read_lock_wq);
89 } 91 }
90 return; 92 return;
@@ -199,7 +201,8 @@ void btrfs_tree_read_unlock_blocking(struct extent_buffer *eb)
199 } 201 }
200 btrfs_assert_tree_read_locked(eb); 202 btrfs_assert_tree_read_locked(eb);
201 WARN_ON(atomic_read(&eb->blocking_readers) == 0); 203 WARN_ON(atomic_read(&eb->blocking_readers) == 0);
202 if (atomic_dec_and_test(&eb->blocking_readers)) 204 if (atomic_dec_and_test(&eb->blocking_readers) &&
205 waitqueue_active(&eb->read_lock_wq))
203 wake_up(&eb->read_lock_wq); 206 wake_up(&eb->read_lock_wq);
204 atomic_dec(&eb->read_locks); 207 atomic_dec(&eb->read_locks);
205} 208}
@@ -247,8 +250,9 @@ void btrfs_tree_unlock(struct extent_buffer *eb)
247 if (blockers) { 250 if (blockers) {
248 WARN_ON(atomic_read(&eb->spinning_writers)); 251 WARN_ON(atomic_read(&eb->spinning_writers));
249 atomic_dec(&eb->blocking_writers); 252 atomic_dec(&eb->blocking_writers);
250 smp_wmb(); 253 smp_mb();
251 wake_up(&eb->write_lock_wq); 254 if (waitqueue_active(&eb->write_lock_wq))
255 wake_up(&eb->write_lock_wq);
252 } else { 256 } else {
253 WARN_ON(atomic_read(&eb->spinning_writers) != 1); 257 WARN_ON(atomic_read(&eb->spinning_writers) != 1);
254 atomic_dec(&eb->spinning_writers); 258 atomic_dec(&eb->spinning_writers);