--- /opt/kernel/linux-2.4.0-loop/drivers/block/loop.c Mon Jan 8 01:31:27 2001 +++ linux/drivers/block/loop.c Mon Jan 8 02:40:37 2001 @@ -292,9 +292,11 @@ { struct loop_device *lo = &loop_dev[MINOR(bh->b_dev)]; struct buffer_head *rbh = bh->b_private; - int rw = test_and_clear_bit(BH_Dirty, &bh->b_state); - if (rw == READ && uptodate) + /* + * only need to do transfer on (uptodate) READ + */ + if (!test_bit(BH_Dirty, &bh->b_state) && uptodate) uptodate = !lo_do_transfer(lo, READ, bh->b_data, rbh->b_data, bh->b_size, bh->b_blocknr); @@ -309,8 +311,8 @@ /* * any better ideas? one could argue that since - * (BUF_BUFFER & __GFP_WAIT) kmem_cache_alloc should - * always return an object + * (GFP_BUFFER & __GFP_WAIT) + * kmem_cache_alloc should always return an object */ do { if ((bh = kmem_cache_alloc(loop_bhp, SLAB_BUFFER))) @@ -321,6 +323,7 @@ memset(bh, 0, sizeof(*bh)); bh->b_size = rbh->b_size; + bh->b_dev = rbh->b_dev; bh->b_rdev = lo->lo_device; bh->b_state = (1 << BH_Req) | (1 << BH_Mapped) | (1 << BH_Lock);