From: Chris Mason <mason@suse.com>

Hmpf, one more.  If one proc does a wait_on_buffer while another does
discard_buffer, bh->b_bdev might be null by the time __wait_on_buffer uses
it.  

Someone hit this with reiserfs, but it should be possible to trigger
anywhere.


---

 25-akpm/fs/buffer.c |    6 +++++-
 1 files changed, 5 insertions(+), 1 deletion(-)

diff -puN fs/buffer.c~per-backing_dev-unplugging-fix-42 fs/buffer.c
--- 25/fs/buffer.c~per-backing_dev-unplugging-fix-42	Mon Mar 15 14:13:44 2004
+++ 25-akpm/fs/buffer.c	Mon Mar 15 14:13:44 2004
@@ -132,7 +132,11 @@ void __wait_on_buffer(struct buffer_head
 	do {
 		prepare_to_wait(wqh, &wait, TASK_UNINTERRUPTIBLE);
 		if (buffer_locked(bh)) {
-			blk_run_address_space(bh->b_bdev->bd_inode->i_mapping);
+			struct block_device *bd;
+			smp_mb();
+			bd = bh->b_bdev;
+			if (bd)
+				blk_run_address_space(bd->bd_inode->i_mapping);
 			io_schedule();
 		}
 	} while (buffer_locked(bh));

_