diff options
author | Felix Blyakher <felixb@sgi.com> | 2009-04-01 23:58:39 +0200 |
---|---|---|
committer | Felix Blyakher <felixb@sgi.com> | 2009-04-01 23:58:39 +0200 |
commit | f36345ff9a4a77f2cc576a2777b6256d5c8798fa (patch) | |
tree | 7ae4c607f6baae74060c2e385f744e171fbbf92b /fs/btrfs/locking.c | |
parent | Revert "xfs: increase the maximum number of supported ACL entries" (diff) | |
parent | Merge branch 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/aegl/... (diff) | |
download | linux-f36345ff9a4a77f2cc576a2777b6256d5c8798fa.tar.xz linux-f36345ff9a4a77f2cc576a2777b6256d5c8798fa.zip |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6 into for-linus
Diffstat (limited to 'fs/btrfs/locking.c')
-rw-r--r-- | fs/btrfs/locking.c | 21 |
1 files changed, 14 insertions, 7 deletions
diff --git a/fs/btrfs/locking.c b/fs/btrfs/locking.c index 47b0a88c12a2..a5310c0f41e2 100644 --- a/fs/btrfs/locking.c +++ b/fs/btrfs/locking.c @@ -71,12 +71,13 @@ void btrfs_clear_lock_blocking(struct extent_buffer *eb) static int btrfs_spin_on_block(struct extent_buffer *eb) { int i; + for (i = 0; i < 512; i++) { - cpu_relax(); if (!test_bit(EXTENT_BUFFER_BLOCKING, &eb->bflags)) return 1; if (need_resched()) break; + cpu_relax(); } return 0; } @@ -95,13 +96,15 @@ int btrfs_try_spin_lock(struct extent_buffer *eb) { int i; - spin_nested(eb); - if (!test_bit(EXTENT_BUFFER_BLOCKING, &eb->bflags)) - return 1; - spin_unlock(&eb->lock); - + if (btrfs_spin_on_block(eb)) { + spin_nested(eb); + if (!test_bit(EXTENT_BUFFER_BLOCKING, &eb->bflags)) + return 1; + spin_unlock(&eb->lock); + } /* spin for a bit on the BLOCKING flag */ for (i = 0; i < 2; i++) { + cpu_relax(); if (!btrfs_spin_on_block(eb)) break; @@ -148,6 +151,9 @@ int btrfs_tree_lock(struct extent_buffer *eb) DEFINE_WAIT(wait); wait.func = btrfs_wake_function; + if (!btrfs_spin_on_block(eb)) + goto sleep; + while(1) { spin_nested(eb); @@ -165,9 +171,10 @@ int btrfs_tree_lock(struct extent_buffer *eb) * spin for a bit, and if the blocking flag goes away, * loop around */ + cpu_relax(); if (btrfs_spin_on_block(eb)) continue; - +sleep: prepare_to_wait_exclusive(&eb->lock_wq, &wait, TASK_UNINTERRUPTIBLE); |