diff options
author | Chris Mason <clm@fb.com> | 2015-10-13 02:24:40 +0300 |
---|---|---|
committer | Chris Mason <clm@fb.com> | 2015-10-13 02:24:40 +0300 |
commit | 6db4a7335dd701a0e20275440ee057d3db2a7ae3 (patch) | |
tree | c0734d7411806ef91bfeb615bf528ffb349938fe /fs/btrfs/transaction.c | |
parent | 62fb50ab7c903357c92cef2f7677235b92ac575f (diff) | |
parent | ee86395458072760d62e66aad10a5e9e8902b8cf (diff) | |
download | linux-6db4a7335dd701a0e20275440ee057d3db2a7ae3.tar.xz |
Merge branch 'fix/waitqueue-barriers' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux into for-linus-4.4
Diffstat (limited to 'fs/btrfs/transaction.c')
-rw-r--r-- | fs/btrfs/transaction.c | 9 |
1 files changed, 9 insertions, 0 deletions
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c index 76354bb1312c..47fd27031a20 100644 --- a/fs/btrfs/transaction.c +++ b/fs/btrfs/transaction.c @@ -82,6 +82,12 @@ void btrfs_put_transaction(struct btrfs_transaction *transaction) static void clear_btree_io_tree(struct extent_io_tree *tree) { spin_lock(&tree->lock); + /* + * Do a single barrier for the waitqueue_active check here, the state + * of the waitqueue should not change once clear_btree_io_tree is + * called. + */ + smp_mb(); while (!RB_EMPTY_ROOT(&tree->state)) { struct rb_node *node; struct extent_state *state; @@ -856,6 +862,9 @@ static int __btrfs_end_transaction(struct btrfs_trans_handle *trans, atomic_dec(&cur_trans->num_writers); extwriter_counter_dec(cur_trans, trans->type); + /* + * Make sure counter is updated before we wake up waiters. + */ smp_mb(); if (waitqueue_active(&cur_trans->writer_wait)) wake_up(&cur_trans->writer_wait); |