summaryrefslogtreecommitdiffstats
path: root/fs/btrfs/locking.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/btrfs/locking.c')
-rw-r--r--fs/btrfs/locking.c50
1 files changed, 26 insertions, 24 deletions
diff --git a/fs/btrfs/locking.c b/fs/btrfs/locking.c
index 1da768e5ef75..7201d000f61d 100644
--- a/fs/btrfs/locking.c
+++ b/fs/btrfs/locking.c
@@ -14,35 +14,37 @@
14 14
15static void btrfs_assert_tree_read_locked(struct extent_buffer *eb); 15static void btrfs_assert_tree_read_locked(struct extent_buffer *eb);
16 16
17/* 17void btrfs_set_lock_blocking_read(struct extent_buffer *eb)
18 * if we currently have a spinning reader or writer lock
19 * (indicated by the rw flag) this will bump the count
20 * of blocking holders and drop the spinlock.
21 */
22void btrfs_set_lock_blocking_rw(struct extent_buffer *eb, int rw)
23{ 18{
24 /* 19 /*
25 * no lock is required. The lock owner may change if 20 * No lock is required. The lock owner may change if we have a read
26 * we have a read lock, but it won't change to or away 21 * lock, but it won't change to or away from us. If we have the write
27 * from us. If we have the write lock, we are the owner 22 * lock, we are the owner and it'll never change.
28 * and it'll never change.
29 */ 23 */
30 if (eb->lock_nested && current->pid == eb->lock_owner) 24 if (eb->lock_nested && current->pid == eb->lock_owner)
31 return; 25 return;
32 if (rw == BTRFS_WRITE_LOCK) { 26 btrfs_assert_tree_read_locked(eb);
33 if (atomic_read(&eb->blocking_writers) == 0) { 27 atomic_inc(&eb->blocking_readers);
34 WARN_ON(atomic_read(&eb->spinning_writers) != 1); 28 WARN_ON(atomic_read(&eb->spinning_readers) == 0);
35 atomic_dec(&eb->spinning_writers); 29 atomic_dec(&eb->spinning_readers);
36 btrfs_assert_tree_locked(eb); 30 read_unlock(&eb->lock);
37 atomic_inc(&eb->blocking_writers); 31}
38 write_unlock(&eb->lock); 32
39 } 33void btrfs_set_lock_blocking_write(struct extent_buffer *eb)
40 } else if (rw == BTRFS_READ_LOCK) { 34{
41 btrfs_assert_tree_read_locked(eb); 35 /*
42 atomic_inc(&eb->blocking_readers); 36 * No lock is required. The lock owner may change if we have a read
43 WARN_ON(atomic_read(&eb->spinning_readers) == 0); 37 * lock, but it won't change to or away from us. If we have the write
44 atomic_dec(&eb->spinning_readers); 38 * lock, we are the owner and it'll never change.
45 read_unlock(&eb->lock); 39 */
40 if (eb->lock_nested && current->pid == eb->lock_owner)
41 return;
42 if (atomic_read(&eb->blocking_writers) == 0) {
43 WARN_ON(atomic_read(&eb->spinning_writers) != 1);
44 atomic_dec(&eb->spinning_writers);
45 btrfs_assert_tree_locked(eb);
46 atomic_inc(&eb->blocking_writers);
47 write_unlock(&eb->lock);
46 } 48 }
47} 49}
48 50