--- 2.3.20/fs/buffer.c Sun Oct 10 16:59:57 1999 +++ 2.3.20-pagecache/fs/buffer.c Sun Oct 10 19:57:36 1999 @@ -1205,6 +1205,18 @@ return 0; } +static void unmap_buffer(struct buffer_head * bh) +{ + if (buffer_mapped(bh)) + { + mark_buffer_clean(bh); + wait_on_buffer(bh); + clear_bit(BH_Uptodate, &bh->b_state); + clear_bit(BH_Mapped, &bh->b_state); + clear_bit(BH_Req, &bh->b_state); + } +} + /* * We don't have to release all buffers here, but * we have to be sure that no dirty buffer is left @@ -1231,16 +1243,8 @@ /* * is this block fully flushed? */ - if (offset <= curr_off) { - if (buffer_mapped(bh)) { - mark_buffer_clean(bh); - wait_on_buffer(bh); - clear_bit(BH_Uptodate, &bh->b_state); - clear_bit(BH_Mapped, &bh->b_state); - clear_bit(BH_Req, &bh->b_state); - bh->b_blocknr = 0; - } - } + if (offset <= curr_off) + unmap_buffer(bh); curr_off = next_off; bh = next; } while (bh != head); @@ -1286,6 +1290,19 @@ get_page(page); } +static void unmap_underlying_metadata(struct buffer_head * bh) +{ + bh = get_hash_table(bh->b_dev, bh->b_blocknr, bh->b_size); + if (bh) + { + unmap_buffer(bh); + /* Here we could run brelse or bforget. We use + bforget because it will try to put the buffer + in the freelist. */ + __bforget(bh); + } +} + /* * block_write_full_page() is SMP-safe - currently it's still * being called with the kernel lock held, but the code is ready. @@ -1331,6 +1348,7 @@ err = inode->i_op->get_block(inode, block, bh, 1); if (err) goto out; + unmap_underlying_metadata(bh); } set_bit(BH_Uptodate, &bh->b_state); mark_buffer_dirty(bh,0); @@ -1420,6 +1438,7 @@ err = inode->i_op->get_block(inode, block, bh, 1); if (err) goto out; + unmap_underlying_metadata(bh); } if (!buffer_uptodate(bh) && (start_offset || (end_bytes && (i == end_block)))) { @@ -1582,6 +1601,7 @@ err = inode->i_op->get_block(inode, block, bh, 1); if (err) goto out; + unmap_underlying_metadata(bh); } if (!buffer_uptodate(bh) && (start_offset || (end_bytes && (i == end_block)))) {