Let's have a look at this piece of code in __bread_slow: get_bh(bh); bh->b_end_io = end_buffer_read_sync; submit_bh(REQ_OP_READ, 0, bh); wait_on_buffer(bh); if (buffer_uptodate(bh)) return bh; Neither wait_on_buffer nor buffer_uptodate contain a memory barrier. Consequently, if someone calls sb_bread and then reads the buffer data, the read of buffer data may be speculatively executed before wait_on_buffer(bh) and it may return invalid data. Also, there is this pattern present several times: wait_on_buffer(bh); if (!buffer_uptodate(bh)) err = -EIO; It may be possible that buffer_uptodate is executed before wait_on_buffer and it may return spurious error. Fix these bugs by adding a read memory barrier to wait_on_buffer(). Signed-off-by: Mikulas Patocka <mpatocka@xxxxxxxxxx> Cc: stable@xxxxxxxxxxxxxxx Index: linux-2.6/include/linux/buffer_head.h =================================================================== --- linux-2.6.orig/include/linux/buffer_head.h +++ linux-2.6/include/linux/buffer_head.h @@ -353,6 +353,11 @@ static inline void wait_on_buffer(struct might_sleep(); if (buffer_locked(bh)) __wait_on_buffer(bh); + /* + * Make sure that the following accesses to buffer state or buffer data + * are not reordered with buffer_locked(bh). + */ + smp_rmb(); } static inline int trylock_buffer(struct buffer_head *bh)