@@ -1256,8 +1256,11 @@ static int ocfs2_test_bg_bit_allocatable(struct buffer_head *bg_bh,
if (ocfs2_test_bit(nr, (unsigned long *)bg->bg_bitmap))
return 0;
- if (!buffer_jbd(bg_bh))
+ jbd_lock_bh_journal_head(bg_bh);
+ if (!buffer_jbd(bg_bh)){
+ jbd_unlock_bh_journal_head(bg_bh);
return 1;
+ }
jh = bh2jh(bg_bh);
spin_lock(&jh->b_state_lock);
@@ -1267,6 +1270,7 @@ static int ocfs2_test_bg_bit_allocatable(struct buffer_head *bg_bh,
else
ret = 1;
spin_unlock(&jh->b_state_lock);
+ jbd_unlock_bh_journal_head(bg_bh);
return ret;
}
Encountered a race between ocfs2_test_bg_bit_allocatable() and jbd2_journal_put_journal_head() due to which ocfs2_test_bg_bit_allocatable() dereferenced NULL pointer. When ocfs2_test_bg_bit_allocatable() called bh2jh(bg_bh), the bg_bh->b_private was NULL as jbd2_journal_put_journal_head() raced and released the journal_head from the buffer head. Needed to take bit lock for the bit 'BH_JournalHead' to fix this race. Signed-off-by: Gautham Ananthakrishna <gautham.ananthakrishna@oracle.com> --- fs/ocfs2/suballoc.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)