clean_blockdev_aliases is using the wrong thing to work out how many
filesystem blocks should be invalidated.  It invalidates too many, which can
cause live fs metadata buffers to be invalidated when they are pending
writeout.  It's a filesystem-wrecker, although seems very hard to hit.


Signed-off-by: Andrew Morton <akpm@osdl.org>
---

 25-akpm/fs/direct-io.c |    5 ++++-
 1 files changed, 4 insertions(+), 1 deletion(-)

diff -puN fs/direct-io.c~direct-io-invalidation-fix fs/direct-io.c
--- 25/fs/direct-io.c~direct-io-invalidation-fix	2004-06-02 19:29:29.300623696 -0700
+++ 25-akpm/fs/direct-io.c	2004-06-02 19:30:31.404182520 -0700
@@ -690,8 +690,11 @@ out:
 static void clean_blockdev_aliases(struct dio *dio)
 {
 	unsigned i;
+	unsigned nblocks;
 
-	for (i = 0; i < dio->blocks_available; i++) {
+	nblocks = dio->map_bh.b_size >> dio->inode->i_blkbits;
+
+	for (i = 0; i < nblocks; i++) {
 		unmap_underlying_metadata(dio->map_bh.b_bdev,
 					dio->map_bh.b_blocknr + i);
 	}
_