Whamcloud - gitweb
57d12ee999e6a9b7f69391c2073a7019f7fdc634
[fs/lustre-release.git] / lustre / kernel_patches / patches / fix-forever-in-do_get_write_access.patch
1 commit 229309caebe4508d650bb6d8f7d51f2b116f5bbd
2 Author: Jan Kara <jack@suse.cz>
3 Date:   Sun May 8 19:09:53 2011 -0400
4
5 jbd2: Fix forever sleeping process in do_get_write_access()
6
7 In do_get_write_access() we wait on BH_Unshadow bit for buffer to get
8 from shadow state. The waking code in journal_commit_transaction() has
9 a bug because it does not issue a memory barrier after the buffer is
10 moved from the shadow state and before wake_up_bit() is called. Thus a
11 waitqueue check can happen before the buffer is actually moved from
12 the shadow state and waiting process may never be woken. Fix the
13 problem by issuing proper barrier.
14
15 Reported-by: Tao Ma <boyu.mt@taobao.com>
16 Signed-off-by: Jan Kara <jack@suse.cz>
17 Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
18 ---
19  fs/jbd2/commit.c |    9 +++++++--
20  1 files changed, 7 insertions(+), 2 deletions(-)
21
22 Index: linux-2.6.18.4/fs/jbd2/commit.c
23 ===================================================================
24 --- linux-2.6.18.4.orig/fs/jbd2/commit.c
25 +++ linux-2.6.18.4/fs/jbd2/commit.c
26 @@ -788,8 +788,13 @@ wait_for_iobuf:
27                     required. */
28                 JBUFFER_TRACE(jh, "file as BJ_Forget");
29                 jbd2_journal_file_buffer(jh, commit_transaction, BJ_Forget);
30 -               /* Wake up any transactions which were waiting for this
31 -                  IO to complete */
32 +               /*
33 +                * Wake up any transactions which were waiting for this IO to
34 +                * complete. The barrier must be here so that changes by
35 +                * jbd2_journal_file_buffer() take effect before wake_up_bit()
36 +                * does the waitqueue check.
37 +                */
38 +               smp_mb();
39                 wake_up_bit(&bh->b_state, BH_Unshadow);
40                 JBUFFER_TRACE(jh, "brelse shadowed buffer");
41                 __brelse(bh);