diff options
author | Jan Kara <jack@suse.cz> | 2013-05-13 09:45:01 -0400 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2013-05-13 09:45:01 -0400 |
commit | e2555fde4159467fb579e6ae3c0a8fc33015d0f5 (patch) | |
tree | aacf8fc79d3180a2bd2bf265f1fb362e7b2b4c50 /include/linux/journal-head.h | |
parent | a549984b8c95acbecefd1fdd4bfdbea4d29b0588 (diff) | |
download | linux-stable-e2555fde4159467fb579e6ae3c0a8fc33015d0f5.tar.gz linux-stable-e2555fde4159467fb579e6ae3c0a8fc33015d0f5.tar.bz2 linux-stable-e2555fde4159467fb579e6ae3c0a8fc33015d0f5.zip |
jbd,jbd2: fix oops in jbd2_journal_put_journal_head()
Commit ae4647fb (jbd2: reduce journal_head size) introduced a
regression where we occasionally hit panic in
jbd2_journal_put_journal_head() because of wrong b_jcount. The bug is
caused by gcc making 64-bit access to 32-bit bitfield and thus
clobbering b_jcount.
At least for now, those 8 bytes saved in struct journal_head are not
worth the trouble with gcc bitfield handling so revert that part of
the patch.
Reported-by: EUNBONG SONG <eunb.song@samsung.com>
Reported-by: Tony Luck <tony.luck@gmail.com>
Signed-off-by: Jan Kara <jack@suse.cz>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Diffstat (limited to 'include/linux/journal-head.h')
-rw-r--r-- | include/linux/journal-head.h | 8 |
1 files changed, 6 insertions, 2 deletions
diff --git a/include/linux/journal-head.h b/include/linux/journal-head.h index 13a3da25ff07..98cd41bb39c8 100644 --- a/include/linux/journal-head.h +++ b/include/linux/journal-head.h @@ -30,15 +30,19 @@ struct journal_head { /* * Journalling list for this buffer [jbd_lock_bh_state()] + * NOTE: We *cannot* combine this with b_modified into a bitfield + * as gcc would then (which the C standard allows but which is + * very unuseful) make 64-bit accesses to the bitfield and clobber + * b_jcount if its update races with bitfield modification. */ - unsigned b_jlist:4; + unsigned b_jlist; /* * This flag signals the buffer has been modified by * the currently running transaction * [jbd_lock_bh_state()] */ - unsigned b_modified:1; + unsigned b_modified; /* * Copy of the buffer data frozen for writing to the log. |