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 --- 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); } _